From 1e78a7db56c2946ae84d57cdf43051ce96cc06aa Mon Sep 17 00:00:00 2001 From: Erich Keane Date: Fri, 14 Dec 2018 22:41:18 +0000 Subject: Revert "Add extension to always default-initialize nullptr_t." This reverts commit 46efdf2ccc2a80aefebf8433dbf9c7c959f6e629. Richard Smith commented just after I submitted this that this is the wrong solution. Reverting so that I can fix differently. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349206 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaInit.cpp | 7 ------- test/Analysis/nullptr.cpp | 17 +++++++++++------ test/SemaCXX/ast-print-crash.cpp | 2 +- test/SemaCXX/nullptr_t-init.cpp | 10 ---------- 4 files changed, 12 insertions(+), 24 deletions(-) delete mode 100644 test/SemaCXX/nullptr_t-init.cpp diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index 57277f6e82..c2f14229d8 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -4881,13 +4881,6 @@ static void TryDefaultInitialization(Sema &S, return; } - // As an extension, and to fix Core issue 1013, zero initialize nullptr_t. - // Since there is only 1 valid value of nullptr_t, we can just use that. - if (DestType->isNullPtrType()) { - Sequence.AddZeroInitializationStep(Entity.getType()); - return; - } - // - otherwise, no initialization is performed. // If a program calls for the default initialization of an object of diff --git a/test/Analysis/nullptr.cpp b/test/Analysis/nullptr.cpp index 1d913c11d3..38e099b7fb 100644 --- a/test/Analysis/nullptr.cpp +++ b/test/Analysis/nullptr.cpp @@ -125,16 +125,21 @@ struct Type { }; void shouldNotCrash() { - decltype(nullptr) p; // expected-note{{'p' initialized to a null pointer value}} + decltype(nullptr) p; // expected-note{{'p' declared without an initial value}} if (getSymbol()) // expected-note {{Assuming the condition is false}} // expected-note@-1{{Taking false branch}} - // expected-note@-2{{Assuming the condition is true}} - // expected-note@-3{{Taking true branch}} - invokeF(p); // expected-note{{Passing null pointer value via 1st parameter 'x'}} - // expected-note@-1{{Calling 'invokeF'}} + // expected-note@-2{{Assuming the condition is false}} + // expected-note@-3{{Taking false branch}} + // expected-note@-4{{Assuming the condition is true}} + // expected-note@-5{{Taking true branch}} + invokeF(p); // expected-warning{{1st function call argument is an uninitialized value}} + // expected-note@-1{{1st function call argument is an uninitialized value}} if (getSymbol()) // expected-note {{Assuming the condition is false}} // expected-note@-1{{Taking false branch}} - invokeF(nullptr); + // expected-note@-2{{Assuming the condition is true}} + // expected-note@-3{{Taking true branch}} + invokeF(nullptr); // expected-note {{Calling 'invokeF'}} + // expected-note@-1{{Passing null pointer value via 1st parameter 'x'}} if (getSymbol()) { // expected-note {{Assuming the condition is true}} // expected-note@-1{{Taking true branch}} X *xx = Type().x; // expected-note {{Null pointer value stored to field 'x'}} diff --git a/test/SemaCXX/ast-print-crash.cpp b/test/SemaCXX/ast-print-crash.cpp index 33edc34823..c108f666d7 100644 --- a/test/SemaCXX/ast-print-crash.cpp +++ b/test/SemaCXX/ast-print-crash.cpp @@ -7,6 +7,6 @@ // CHECK: struct { // CHECK-NEXT: } dont_crash_on_syntax_error; -// CHECK-NEXT: decltype(nullptr) p(/*implicit*/(decltype(nullptr))0); +// CHECK-NEXT: decltype(nullptr) p; struct { } dont_crash_on_syntax_error /* missing ; */ decltype(nullptr) p; diff --git a/test/SemaCXX/nullptr_t-init.cpp b/test/SemaCXX/nullptr_t-init.cpp deleted file mode 100644 index f7843de1bc..0000000000 --- a/test/SemaCXX/nullptr_t-init.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -ffreestanding -Wuninitialized %s -// expected-no-diagnostics -typedef decltype(nullptr) nullptr_t; - -// Ensure no 'uninitialized when used here' warnings (Wuninitialized), for -// nullptr_t always-initialized extension. -nullptr_t default_init() { - nullptr_t a; - return a; -} -- cgit v1.2.3 From dbc2921ae291f4c4cd719e04cdad35941913fca3 Mon Sep 17 00:00:00 2001 From: Erich Keane Date: Fri, 14 Dec 2018 23:17:34 +0000 Subject: Add AddressSpace mangling to MS mode All of the symbols demangle on llvm-undname and demangler.com. This address space qualifier is useful for when we want to use opencl C++ in Windows mode. Additionally, C++ address-space using functions will now be usable on windows. Differential Revision: https://reviews.llvm.org/D55715 Change-Id: Ife4506613c3cce778a783456d62117fbf7d83c26 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349209 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/AST/MicrosoftMangle.cpp | 72 +++++++++++++++++++++++++++++++- test/CodeGenCXX/mangle-address-space.cpp | 55 ++++++++++++++++++++++-- 2 files changed, 123 insertions(+), 4 deletions(-) diff --git a/lib/AST/MicrosoftMangle.cpp b/lib/AST/MicrosoftMangle.cpp index 821112e7a9..db0d770d9a 100644 --- a/lib/AST/MicrosoftMangle.cpp +++ b/lib/AST/MicrosoftMangle.cpp @@ -311,6 +311,7 @@ public: void mangleTagTypeKind(TagTypeKind TK); void mangleArtificialTagType(TagTypeKind TK, StringRef UnqualifiedName, ArrayRef NestedNames = None); + void mangleAddressSpaceType(QualType T, Qualifiers Quals, SourceRange Range); void mangleType(QualType T, SourceRange Range, QualifierMangleMode QMM = QMM_Mangle); void mangleFunctionType(const FunctionType *T, @@ -1777,12 +1778,77 @@ void MicrosoftCXXNameMangler::manglePassObjectSizeArg( } } +void MicrosoftCXXNameMangler::mangleAddressSpaceType(QualType T, + Qualifiers Quals, + SourceRange Range) { + // Address space is mangled as an unqualified templated type in the __clang + // namespace. The demangled version of this is: + // In the case of a language specific address space: + // __clang::struct _AS[language_addr_space] + // where: + // ::= | + // ::= "CL" [ "global" | "local" | "constant" | + // "private"| "generic" ] + // ::= "CU" [ "device" | "constant" | "shared" ] + // Note that the above were chosen to match the Itanium mangling for this. + // + // In the case of a non-language specific address space: + // __clang::struct _AS + assert(Quals.hasAddressSpace() && "Not valid without address space"); + llvm::SmallString<32> ASMangling; + llvm::raw_svector_ostream Stream(ASMangling); + MicrosoftCXXNameMangler Extra(Context, Stream); + Stream << "?$"; + + LangAS AS = Quals.getAddressSpace(); + if (Context.getASTContext().addressSpaceMapManglingFor(AS)) { + unsigned TargetAS = Context.getASTContext().getTargetAddressSpace(AS); + Extra.mangleSourceName("_AS"); + Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(TargetAS), + /*IsBoolean*/ false); + } else { + switch (AS) { + default: + llvm_unreachable("Not a language specific address space"); + case LangAS::opencl_global: + Extra.mangleSourceName("_ASCLglobal"); + break; + case LangAS::opencl_local: + Extra.mangleSourceName("_ASCLlocal"); + break; + case LangAS::opencl_constant: + Extra.mangleSourceName("_ASCLconstant"); + break; + case LangAS::opencl_private: + Extra.mangleSourceName("_ASCLprivate"); + break; + case LangAS::opencl_generic: + Extra.mangleSourceName("_ASCLgeneric"); + break; + case LangAS::cuda_device: + Extra.mangleSourceName("_ASCUdevice"); + break; + case LangAS::cuda_constant: + Extra.mangleSourceName("_ASCUconstant"); + break; + case LangAS::cuda_shared: + Extra.mangleSourceName("_ASCUshared"); + break; + } + } + + Extra.mangleType(T, Range, QMM_Escape); + mangleQualifiers(Qualifiers(), false); + mangleArtificialTagType(TTK_Struct, ASMangling, {"__clang"}); +} + void MicrosoftCXXNameMangler::mangleType(QualType T, SourceRange Range, QualifierMangleMode QMM) { // Don't use the canonical types. MSVC includes things like 'const' on // pointer arguments to function pointers that canonicalization strips away. T = T.getDesugaredType(getASTContext()); Qualifiers Quals = T.getLocalQualifiers(); + if (const ArrayType *AT = getASTContext().getAsArrayType(T)) { // If there were any Quals, getAsArrayType() pushed them onto the array // element type. @@ -2488,7 +2554,11 @@ void MicrosoftCXXNameMangler::mangleType(const PointerType *T, Qualifiers Quals, QualType PointeeType = T->getPointeeType(); manglePointerCVQualifiers(Quals); manglePointerExtQualifiers(Quals, PointeeType); - mangleType(PointeeType, Range); + + if (PointeeType.getQualifiers().hasAddressSpace()) + mangleAddressSpaceType(PointeeType, PointeeType.getQualifiers(), Range); + else + mangleType(PointeeType, Range); } void MicrosoftCXXNameMangler::mangleType(const ObjCObjectPointerType *T, diff --git a/test/CodeGenCXX/mangle-address-space.cpp b/test/CodeGenCXX/mangle-address-space.cpp index cd10384594..549ae54dfb 100644 --- a/test/CodeGenCXX/mangle-address-space.cpp +++ b/test/CodeGenCXX/mangle-address-space.cpp @@ -1,15 +1,64 @@ -// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -o - %s | FileCheck %s +// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -o - %s | FileCheck %s --check-prefixes=CHECK,CHECKNOOCL +// RUN: %clang_cc1 -emit-llvm -triple x86_64-windows-msvc -o - %s | FileCheck %s --check-prefixes=WIN,WINNOOCL +// RUN: %clang_cc1 -cl-std=c++ -emit-llvm -triple %itanium_abi_triple -o - %s | FileCheck %s --check-prefixes=CHECK,CHECKOCL +// RUN: %clang_cc1 -cl-std=c++ -emit-llvm -triple x86_64-windows-msvc -o - %s | FileCheck %s --check-prefixes=WIN,WINOCL -// CHECK-LABEL: define {{.*}}void @_Z2f0Pc +// CHECKNOOCL-LABEL: define {{.*}}void @_Z2f0Pc +// WINNOOCL-LABEL: define {{.*}}void @"?f0@@YAXPEAD@Z" +// CHECKOCL-LABEL: define {{.*}}void @_Z2f0PU9CLgenericc +// WINOCL-LABEL: define {{.*}}void @"?f0@@YAXPEAU?$_ASCLgeneric@$$CAD@__clang@@@Z" void f0(char *p) { } // CHECK-LABEL: define {{.*}}void @_Z2f0PU3AS1c +// WIN-LABEL: define {{.*}}void @"?f0@@YAXPEAU?$_AS@$00$$CAD@__clang@@@Z" void f0(char __attribute__((address_space(1))) *p) { } struct OpaqueType; typedef OpaqueType __attribute__((address_space(100))) * OpaqueTypePtr; // CHECK-LABEL: define {{.*}}void @_Z2f0PU5AS10010OpaqueType +// WIN-LABEL: define {{.*}}void @"?f0@@YAXPEAU?$_AS@$0GE@$$CAUOpaqueType@@@__clang@@@Z" void f0(OpaqueTypePtr) { } // CHECK-LABEL: define {{.*}}void @_Z2f1PU3AS1Kc -void f1(char __attribute__((address_space(1))) const *p) {} \ No newline at end of file +// WIN-LABEL: define {{.*}}void @"?f1@@YAXPEAU?$_AS@$00$$CBD@__clang@@@Z" +void f1(char __attribute__((address_space(1))) const *p) {} + +// Ensure we can do return values, which change in MS mode. +// CHECK-LABEL: define {{.*}}float addrspace(1)* @_Z2f1PU3AS2Kc +// WIN-LABEL: define {{.*}}float addrspace(1)* @"?f1@@YAPEAU?$_AS@$00$$CAM@__clang@@PEAU?$_AS@$01$$CBD@2@@Z" +__attribute__((address_space(1))) float *f1(char __attribute__((address_space(2))) const *p) { return 0;} + +#if !defined(__OPENCL_CPP_VERSION__) +// Return value of address space without a pointer is invalid in opencl. +// Ensure we skip return values, since non-pointers aren't supposed to have an AS. +// CHECKNOOCL-LABEL: define {{.*}}float @_Z2f2PU3AS2Kc +// WINNOOCL-LABEL: define {{.*}}float @"?f2@@YA?AMQEAU?$_AS@$01$$CBD@__clang@@@Z" +__attribute__((address_space(1))) float f2(char __attribute__((address_space(2))) const * const p) { return 0;} +#endif + +#ifdef __OPENCL_CPP_VERSION__ +// CHECKOCL-LABEL: define {{.*}}void @_Z6ocl_f0PU9CLprivatec +// WINOCL-LABEL: define {{.*}}void @"?ocl_f0@@YAXPEAU?$_ASCLprivate@$$CAD@__clang@@@Z" +void ocl_f0(char __private *p) { } + +struct ocl_OpaqueType; +typedef ocl_OpaqueType __global * ocl_OpaqueTypePtr; + +// CHECKOCL-LABEL: define {{.*}}void @_Z6ocl_f0PU8CLglobal14ocl_OpaqueType +// WINOCL-LABEL: define {{.*}}void @"?ocl_f0@@YAXPEAU?$_ASCLglobal@$$CAUocl_OpaqueType@@@__clang@@@Z" +void ocl_f0(ocl_OpaqueTypePtr) { } + +// CHECKOCL-LABEL: define {{.*}}void @_Z6ocl_f1PU10CLconstantKc +// WINOCL-LABEL: define {{.*}}void @"?ocl_f1@@YAXPEAU?$_ASCLconstant@$$CBD@__clang@@@Z" +void ocl_f1(char __constant const *p) {} + +// Ensure we can do return values, which change in MS mode. +// CHECKOCL-LABEL: define {{.*}}float* @_Z6ocl_f1PU9CLgenericKc +// WINOCL-LABEL: define {{.*}}float* @"?ocl_f1@@YAPEAU?$_ASCLconstant@$$CAM@__clang@@PEAU?$_ASCLgeneric@$$CBD@2@@Z" +__constant float *ocl_f1(char __generic const *p) { return 0;} + +// Ensure we skip return values, since non-pointers aren't supposed to have an AS. +// CHECKOCL-LABEL: define {{.*}}float* @_Z6ocl_f2PU9CLgenericKc +// WINOCL-LABEL: define {{.*}}float* @"?ocl_f2@@YAPEAU?$_ASCLgeneric@$$CAM@__clang@@QEAU?$_ASCLgeneric@$$CBD@2@@Z" +__generic float *ocl_f2(__generic char const * const p) { return 0;} +#endif -- cgit v1.2.3 From 64edf237781c8205a87368b4642af7ee8df0f505 Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Fri, 14 Dec 2018 23:42:59 +0000 Subject: Mangle calling conventions into function pointer types where GCC does Summary: GCC 5.1 began mangling these Windows calling conventions into function types, since they can be used for overloading. They've always been mangled in the MS ABI, but they are new to the Itanium mangler. Note that the calling convention doesn't appear as part of the main declaration, it only appears on function parameter types and other types. Fixes PR39860 Reviewers: rjmccall, efriedma Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D55672 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349212 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/AST/ItaniumMangle.cpp | 15 ++++++--- test/CodeGenCXX/mangle-win-ccs.cpp | 61 ++++++++++++++++++++++++++++++++++++ test/CodeGenCXX/mangle-win64-ccs.cpp | 26 +++++++++++++++ 3 files changed, 97 insertions(+), 5 deletions(-) create mode 100644 test/CodeGenCXX/mangle-win-ccs.cpp create mode 100644 test/CodeGenCXX/mangle-win64-ccs.cpp diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp index d8d56216b1..8231ebe88b 100644 --- a/lib/AST/ItaniumMangle.cpp +++ b/lib/AST/ItaniumMangle.cpp @@ -2648,13 +2648,8 @@ StringRef CXXNameMangler::getCallingConvQualifierName(CallingConv CC) { case CC_C: return ""; - case CC_X86StdCall: - case CC_X86FastCall: - case CC_X86ThisCall: case CC_X86VectorCall: case CC_X86Pascal: - case CC_Win64: - case CC_X86_64SysV: case CC_X86RegCall: case CC_AAPCS: case CC_AAPCS_VFP: @@ -2667,6 +2662,16 @@ StringRef CXXNameMangler::getCallingConvQualifierName(CallingConv CC) { // FIXME: we should be mangling all of the above. return ""; + case CC_X86StdCall: + return "stdcall"; + case CC_X86FastCall: + return "fastcall"; + case CC_X86ThisCall: + return "thiscall"; + case CC_X86_64SysV: + return "sysv_abi"; + case CC_Win64: + return "ms_abi"; case CC_Swift: return "swiftcall"; } diff --git a/test/CodeGenCXX/mangle-win-ccs.cpp b/test/CodeGenCXX/mangle-win-ccs.cpp new file mode 100644 index 0000000000..5336d1d726 --- /dev/null +++ b/test/CodeGenCXX/mangle-win-ccs.cpp @@ -0,0 +1,61 @@ +// RUN: %clang_cc1 %s -emit-llvm -triple i686-windows-gnu -o - | FileCheck %s +// RUN: %clang_cc1 %s -emit-llvm -triple i686-windows-itanium -o - | FileCheck %s + +// GCC 5.1 began mangling these Windows calling conventions into function +// types, since they can be used for overloading. They've always been mangled +// in the MS ABI, but they are new to the Itanium mangler. Note that the main +// function definition does not use a calling convention. Only function types +// that appear later use it. + +template static int func_as_ptr(Fn fn) { return int(fn); } + +void f_cdecl(int, int); +void __attribute__((stdcall)) f_stdcall(int, int); +void __attribute__((fastcall)) f_fastcall(int, int); +void __attribute__((thiscall)) f_thiscall(int, int); + +int as_cdecl() { return func_as_ptr(f_cdecl); } +int as_stdcall() { return func_as_ptr(f_stdcall); } +int as_fastcall() { return func_as_ptr(f_fastcall); } +int as_thiscall() { return func_as_ptr(f_thiscall); } + +// CHECK: define dso_local i32 @_Z8as_cdeclv() +// CHECK: call i32 @_ZL11func_as_ptrIPFviiEEiT_(void (i32, i32)* @_Z7f_cdeclii) + +// CHECK: define dso_local i32 @_Z10as_stdcallv() +// CHECK: call i32 @_ZL11func_as_ptrIPU7stdcallFviiEEiT_(void (i32, i32)* @"\01__Z9f_stdcallii@8") + +// CHECK: define dso_local i32 @_Z11as_fastcallv() +// CHECK: call i32 @_ZL11func_as_ptrIPU8fastcallFviiEEiT_(void (i32, i32)* @"\01@_Z10f_fastcallii@8") + +// CHECK: define dso_local i32 @_Z11as_thiscallv() +// CHECK: call i32 @_ZL11func_as_ptrIPU8thiscallFviiEEiT_(void (i32, i32)* @_Z10f_thiscallii) + +// CHECK: define dso_local void @_Z11funcRefTypeRU8fastcallFviiE(void (i32, i32)* %fr) +void funcRefType(void(__attribute__((fastcall)) & fr)(int, int)) { + fr(1, 2); +} + +// CHECK: define dso_local void @_Z12memptrCCTypeR3FooMS_U8fastcallFviiE(%struct.Foo* {{.*}}, { i32, i32 }* byval{{.*}}) +struct Foo { void bar(int, int); }; +void memptrCCType(Foo &o, void (__attribute__((fastcall)) Foo::*mp)(int, int)) { + (o.*mp)(1, 2); +} + +// CHECK: define dso_local i32 @_Z17useTemplateFnTypev() +// CHECK: call i32 @_ZL14templateFnTypeIU8fastcallFviiEElPT_(void (i32, i32)* @"\01@_Z10f_fastcallii@8") +template static long templateFnType(Fn *fn) { return long(fn); } +long useTemplateFnType() { return templateFnType(f_fastcall); } + +// CHECK: define weak_odr dso_local x86_fastcallcc void @"\01@_Z10fnTemplateIsEvv@0"() +// CHECK: define dso_local x86_fastcallcc void @"\01@_Z10fnTemplateIiEvv@0"() +template void __attribute__((fastcall)) fnTemplate() {} +template void __attribute__((fastcall)) fnTemplate(); +template <> void __attribute__((fastcall)) fnTemplate() {} + +// CHECK: define weak_odr dso_local x86_fastcallcc void (i32, i32)* @"\01@_Z12fnTempReturnIsEPU8fastcallFviiEv@0"() +// CHECK: define dso_local x86_fastcallcc void (i32, i32)* @"\01@_Z12fnTempReturnIiEPU8fastcallFviiEv@0"() +typedef void (__attribute__((fastcall)) *fp_cc_t)(int, int); +template fp_cc_t __attribute__((fastcall)) fnTempReturn() { return nullptr; } +template fp_cc_t __attribute__((fastcall)) fnTempReturn(); +template <> fp_cc_t __attribute__((fastcall)) fnTempReturn() { return nullptr; } diff --git a/test/CodeGenCXX/mangle-win64-ccs.cpp b/test/CodeGenCXX/mangle-win64-ccs.cpp new file mode 100644 index 0000000000..10c0430117 --- /dev/null +++ b/test/CodeGenCXX/mangle-win64-ccs.cpp @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -triple x86_64-windows-gnu -o - -emit-llvm %s | FileCheck %s -check-prefix CHECK-WIN +// RUN: %clang_cc1 -triple x86_64-linux-gnu -o - -emit-llvm %s | FileCheck %s -check-prefix CHECK-LIN + +typedef __PTRDIFF_TYPE__ ptrdiff_t; +template ptrdiff_t func_as_int(FTy *fp) { return ptrdiff_t(fp); } + +int f_plain(int); +int __attribute__((sysv_abi)) f_sysvabi(int); +int __attribute__((ms_abi)) f_msabi(int); +ptrdiff_t useThem() { + ptrdiff_t rv = 0; + rv += func_as_int(f_plain); + rv += func_as_int(f_sysvabi); + rv += func_as_int(f_msabi); + return rv; +} + +// CHECK-WIN: define dso_local i64 @_Z7useThemv() +// CHECK-WIN: call i64 @_Z11func_as_intIFiiEExPT_(i32 (i32)* @_Z7f_plaini) +// CHECK-WIN: call i64 @_Z11func_as_intIU8sysv_abiFiiEExPT_(i32 (i32)* @_Z9f_sysvabii) +// CHECK-WIN: call i64 @_Z11func_as_intIFiiEExPT_(i32 (i32)* @_Z7f_msabii) + +// CHECK-LIN: define i64 @_Z7useThemv() +// CHECK-LIN: call i64 @_Z11func_as_intIFiiEElPT_(i32 (i32)* @_Z7f_plaini) +// CHECK-LIN: call i64 @_Z11func_as_intIFiiEElPT_(i32 (i32)* @_Z9f_sysvabii) +// CHECK-LIN: call i64 @_Z11func_as_intIU6ms_abiFiiEElPT_(i32 (i32)* @_Z7f_msabii) -- cgit v1.2.3 From 1fa6f0a871e70af7a02920ce8f00af2a1d8c1bd8 Mon Sep 17 00:00:00 2001 From: Artem Dergachev Date: Sat, 15 Dec 2018 01:50:58 +0000 Subject: [analyzer] MoveChecker: NFC: De-duplicate a few checks. No functional change intended. Differential Revision: https://reviews.llvm.org/D55387 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349225 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/StaticAnalyzer/Checkers/MoveChecker.cpp | 170 ++++++++++++++-------------- 1 file changed, 88 insertions(+), 82 deletions(-) diff --git a/lib/StaticAnalyzer/Checkers/MoveChecker.cpp b/lib/StaticAnalyzer/Checkers/MoveChecker.cpp index dd83ce02e0..d387e0bea7 100644 --- a/lib/StaticAnalyzer/Checkers/MoveChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/MoveChecker.cpp @@ -89,6 +89,20 @@ private: "weak_ptr", }; + // Should we bother tracking the state of the object? + bool shouldBeTracked(ObjectKind OK) const { + // In non-aggressive mode, only warn on use-after-move of local variables + // (or local rvalue references) and of STL objects. The former is possible + // because local variables (or local rvalue references) are not tempting + // their user to re-use the storage. The latter is possible because STL + // objects are known to end up in a valid but unspecified state after the + // move and their state-reset methods are also known, which allows us to + // predict precisely when use-after-move is invalid. In aggressive mode, + // warn on any use-after-move because the user has intentionally asked us + // to completely eliminate use-after-move in his code. + return IsAggressive || OK.Local || OK.STL; + } + // Obtains ObjectKind of an object. Because class declaration cannot always // be easily obtained from the memory region, it is supplied separately. ObjectKind classifyObject(const MemRegion *MR, const CXXRecordDecl *RD) const; @@ -136,8 +150,20 @@ public: private: mutable std::unique_ptr BT; + + // Check if the given form of potential misuse of a given object + // should be reported. If so, get it reported. The callback from which + // this function was called should immediately return after the call + // because this function adds one or two transitions. + void modelUse(ProgramStateRef State, const MemRegion *Region, + const CXXRecordDecl *RD, MisuseKind MK, + CheckerContext &C) const; + + // Returns the exploded node against which the report was emitted. + // The caller *must* add any further transitions against this node. ExplodedNode *reportBug(const MemRegion *Region, const CXXRecordDecl *RD, CheckerContext &C, MisuseKind MK) const; + bool isInMoveSafeContext(const LocationContext *LC) const; bool isStateResetMethod(const CXXMethodDecl *MethodDec) const; bool isMoveSafeMethod(const CXXMethodDecl *MethodDec) const; @@ -236,6 +262,25 @@ const ExplodedNode *MoveChecker::getMoveLocation(const ExplodedNode *N, return MoveNode; } +void MoveChecker::modelUse(ProgramStateRef State, const MemRegion *Region, + const CXXRecordDecl *RD, MisuseKind MK, + CheckerContext &C) const { + assert(!C.isDifferent() && "No transitions should have been made by now"); + const RegionState *RS = State->get(Region); + + if (!RS || isAnyBaseRegionReported(State, Region) + || isInMoveSafeContext(C.getLocationContext())) { + // Finalize changes made by the caller. + C.addTransition(State); + return; + } + + ExplodedNode *N = reportBug(Region, RD, C, MK); + + State = State->set(Region, RegionState::getReported()); + C.addTransition(State, N); +} + ExplodedNode *MoveChecker::reportBug(const MemRegion *Region, const CXXRecordDecl *RD, CheckerContext &C, @@ -294,12 +339,10 @@ void MoveChecker::checkPostCall(const CallEvent &Call, if (!MethodDecl) return; - const auto *ConstructorDecl = dyn_cast(MethodDecl); - - const auto *CC = dyn_cast_or_null(&Call); // Check if an object became moved-from. // Object can become moved from after a call to move assignment operator or // move constructor . + const auto *ConstructorDecl = dyn_cast(MethodDecl); if (ConstructorDecl && !ConstructorDecl->isMoveConstructor()) return; @@ -310,23 +353,11 @@ void MoveChecker::checkPostCall(const CallEvent &Call, if (!ArgRegion) return; - // In non-aggressive mode, only warn on use-after-move of local variables (or - // local rvalue references) and of STL objects. The former is possible because - // local variables (or local rvalue references) are not tempting their user to - // re-use the storage. The latter is possible because STL objects are known - // to end up in a valid but unspecified state after the move and their - // state-reset methods are also known, which allows us to predict - // precisely when use-after-move is invalid. - // In aggressive mode, warn on any use-after-move because the user - // has intentionally asked us to completely eliminate use-after-move - // in his code. - ObjectKind OK = classifyObject(ArgRegion, MethodDecl->getParent()); - if (!IsAggressive && !OK.Local && !OK.STL) - return; - // Skip moving the object to itself. + const auto *CC = dyn_cast_or_null(&Call); if (CC && CC->getCXXThisVal().getAsRegion() == ArgRegion) return; + if (const auto *IC = dyn_cast(AFC)) if (IC->getCXXThisVal().getAsRegion() == ArgRegion) return; @@ -340,9 +371,16 @@ void MoveChecker::checkPostCall(const CallEvent &Call, if (State->get(ArgRegion)) return; - // Mark object as moved-from. - State = State->set(ArgRegion, RegionState::getMoved()); - C.addTransition(State); + + const CXXRecordDecl *RD = MethodDecl->getParent(); + ObjectKind OK = classifyObject(ArgRegion, RD); + if (shouldBeTracked(OK)) { + // Mark object as moved-from. + State = State->set(ArgRegion, RegionState::getMoved()); + C.addTransition(State); + return; + } + assert(!C.isDifferent() && "Should not have made transitions on this path!"); } bool MoveChecker::isMoveSafeMethod(const CXXMethodDecl *MethodDec) const { @@ -435,8 +473,6 @@ MoveChecker::explainObject(llvm::raw_ostream &OS, const MemRegion *MR, void MoveChecker::checkPreCall(const CallEvent &Call, CheckerContext &C) const { ProgramStateRef State = C.getState(); - const LocationContext *LC = C.getLocationContext(); - ExplodedNode *N = nullptr; // Remove the MemRegions from the map on which a ctor/dtor call or assignment // happened. @@ -448,21 +484,11 @@ void MoveChecker::checkPreCall(const CallEvent &Call, CheckerContext &C) const { // Check for copying a moved-from object and report the bug. if (CtorDec && CtorDec->isCopyOrMoveConstructor()) { const MemRegion *ArgRegion = CC->getArgSVal(0).getAsRegion(); - const RegionState *ArgState = State->get(ArgRegion); - if (ArgState && ArgState->isMoved()) { - if (!isInMoveSafeContext(LC)) { - const CXXRecordDecl *RD = CtorDec->getParent(); - if(CtorDec->isMoveConstructor()) - N = reportBug(ArgRegion, RD, C, MK_Move); - else - N = reportBug(ArgRegion, RD, C, MK_Copy); - State = State->set(ArgRegion, - RegionState::getReported()); - } - } + const CXXRecordDecl *RD = CtorDec->getParent(); + MisuseKind MK = CtorDec->isMoveConstructor() ? MK_Move : MK_Copy; + modelUse(State, ArgRegion, RD, MK, C); + return; } - C.addTransition(State, N); - return; } const auto IC = dyn_cast(&Call); @@ -477,47 +503,14 @@ void MoveChecker::checkPreCall(const CallEvent &Call, CheckerContext &C) const { if (!ThisRegion) return; + // The remaining part is check only for method call on a moved-from object. const auto MethodDecl = dyn_cast_or_null(IC->getDecl()); if (!MethodDecl) return; - // Store class declaration as well, for bug reporting purposes. - const CXXRecordDecl *RD = MethodDecl->getParent(); - - // Checking assignment operators. - bool OperatorEq = MethodDecl->isOverloadedOperator() && - MethodDecl->getOverloadedOperator() == OO_Equal; - // Remove the tracked object for every assignment operator, but report bug - // only for move or copy assignment's argument. - if (OperatorEq) { - State = removeFromState(State, ThisRegion); - if (MethodDecl->isCopyAssignmentOperator() || - MethodDecl->isMoveAssignmentOperator()) { - const RegionState *ArgState = - State->get(IC->getArgSVal(0).getAsRegion()); - if (ArgState && ArgState->isMoved() && !isInMoveSafeContext(LC)) { - const MemRegion *ArgRegion = IC->getArgSVal(0).getAsRegion(); - if(MethodDecl->isMoveAssignmentOperator()) - N = reportBug(ArgRegion, RD, C, MK_Move); - else - N = reportBug(ArgRegion, RD, C, MK_Copy); - State = - State->set(ArgRegion, RegionState::getReported()); - } - } - C.addTransition(State, N); - return; - } - - // The remaining part is check only for method call on a moved-from object. - // We want to investigate the whole object, not only sub-object of a parent // class in which the encountered method defined. - while (const auto *BR = dyn_cast(ThisRegion)) - ThisRegion = BR->getSuperRegion(); - - if (isMoveSafeMethod(MethodDecl)) - return; + ThisRegion = ThisRegion->getMostDerivedObjectRegion(); if (isStateResetMethod(MethodDecl)) { State = removeFromState(State, ThisRegion); @@ -525,21 +518,34 @@ void MoveChecker::checkPreCall(const CallEvent &Call, CheckerContext &C) const { return; } - // If it is already reported then we don't report the bug again. - const RegionState *ThisState = State->get(ThisRegion); - if (!(ThisState && ThisState->isMoved())) + if (isMoveSafeMethod(MethodDecl)) return; - // Don't report it in case if any base region is already reported - if (isAnyBaseRegionReported(State, ThisRegion)) - return; + // Store class declaration as well, for bug reporting purposes. + const CXXRecordDecl *RD = MethodDecl->getParent(); - if (isInMoveSafeContext(LC)) - return; + if (MethodDecl->isOverloadedOperator()) { + OverloadedOperatorKind OOK = MethodDecl->getOverloadedOperator(); - N = reportBug(ThisRegion, RD, C, MK_FunCall); - State = State->set(ThisRegion, RegionState::getReported()); - C.addTransition(State, N); + if (OOK == OO_Equal) { + // Remove the tracked object for every assignment operator, but report bug + // only for move or copy assignment's argument. + State = removeFromState(State, ThisRegion); + + if (MethodDecl->isCopyAssignmentOperator() || + MethodDecl->isMoveAssignmentOperator()) { + const MemRegion *ArgRegion = IC->getArgSVal(0).getAsRegion(); + MisuseKind MK = + MethodDecl->isMoveAssignmentOperator() ? MK_Move : MK_Copy; + modelUse(State, ArgRegion, RD, MK, C); + return; + } + C.addTransition(State); + return; + } + } + + modelUse(State, ThisRegion, RD, MK_FunCall, C); } void MoveChecker::checkDeadSymbols(SymbolReaper &SymReaper, -- cgit v1.2.3 From ccef7bd78fb2f1f30edb022018c935072a53d03d Mon Sep 17 00:00:00 2001 From: Artem Dergachev Date: Sat, 15 Dec 2018 01:53:38 +0000 Subject: [analyzer] MoveChecker: Add checks for dereferencing a smart pointer after move. Calling operator*() or operator->() on a null STL smart pointer is undefined behavior. Smart pointers are specified to become null after being moved from. So we can't warn on arbitrary method calls, but these two operators definitely make no sense. The new bug is fatal because it's an immediate UB, unlike other use-after-move bugs. The work on a more generic null smart pointer dereference checker is still pending. Differential Revision: https://reviews.llvm.org/D55388 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349226 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/StaticAnalyzer/Checkers/MoveChecker.cpp | 200 +++++++++++++++++++++------- test/Analysis/use-after-move.cpp | 34 ++++- 2 files changed, 178 insertions(+), 56 deletions(-) diff --git a/lib/StaticAnalyzer/Checkers/MoveChecker.cpp b/lib/StaticAnalyzer/Checkers/MoveChecker.cpp index d387e0bea7..6256696c6f 100644 --- a/lib/StaticAnalyzer/Checkers/MoveChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/MoveChecker.cpp @@ -61,19 +61,35 @@ public: const char *NL, const char *Sep) const override; private: - enum MisuseKind { MK_FunCall, MK_Copy, MK_Move }; + enum MisuseKind { MK_FunCall, MK_Copy, MK_Move, MK_Dereference }; + enum StdObjectKind { SK_NonStd, SK_Unsafe, SK_Safe, SK_SmartPtr }; + + static bool misuseCausesCrash(MisuseKind MK) { + return MK == MK_Dereference; + } struct ObjectKind { - bool Local : 1; // Is this a local variable or a local rvalue reference? - bool STL : 1; // Is this an object of a standard type? + // Is this a local variable or a local rvalue reference? + bool IsLocal : 1; + // Is this an STL object? If so, of what kind? + StdObjectKind StdKind : 2; + }; + + // STL smart pointers are automatically re-initialized to null when moved + // from. So we can't warn on many methods, but we can warn when it is + // dereferenced, which is UB even if the resulting lvalue never gets read. + const llvm::StringSet<> StdSmartPtrClasses = { + "shared_ptr", + "unique_ptr", + "weak_ptr", }; // Not all of these are entirely move-safe, but they do provide *some* // guarantees, and it means that somebody is using them after move // in a valid manner. - // TODO: We can still try to identify *unsafe* use after move, such as - // dereference of a moved-from smart pointer (which is guaranteed to be null). - const llvm::StringSet<> StandardMoveSafeClasses = { + // TODO: We can still try to identify *unsafe* use after move, + // like we did with smart pointers. + const llvm::StringSet<> StdSafeClasses = { "basic_filebuf", "basic_ios", "future", @@ -82,11 +98,8 @@ private: "promise", "shared_future", "shared_lock", - "shared_ptr", "thread", - "unique_ptr", "unique_lock", - "weak_ptr", }; // Should we bother tracking the state of the object? @@ -97,10 +110,25 @@ private: // their user to re-use the storage. The latter is possible because STL // objects are known to end up in a valid but unspecified state after the // move and their state-reset methods are also known, which allows us to - // predict precisely when use-after-move is invalid. In aggressive mode, - // warn on any use-after-move because the user has intentionally asked us - // to completely eliminate use-after-move in his code. - return IsAggressive || OK.Local || OK.STL; + // predict precisely when use-after-move is invalid. + // Some STL objects are known to conform to additional contracts after move, + // so they are not tracked. However, smart pointers specifically are tracked + // because we can perform extra checking over them. + // In aggressive mode, warn on any use-after-move because the user has + // intentionally asked us to completely eliminate use-after-move + // in his code. + return IsAggressive || OK.IsLocal + || OK.StdKind == SK_Unsafe || OK.StdKind == SK_SmartPtr; + } + + // Some objects only suffer from some kinds of misuses, but we need to track + // them anyway because we cannot know in advance what misuse will we find. + bool shouldWarnAbout(ObjectKind OK, MisuseKind MK) const { + // Additionally, only warn on smart pointers when they are dereferenced (or + // local or we are aggressive). + return shouldBeTracked(OK) && + (IsAggressive || OK.IsLocal + || OK.StdKind != SK_SmartPtr || MK == MK_Dereference); } // Obtains ObjectKind of an object. Because class declaration cannot always @@ -108,17 +136,17 @@ private: ObjectKind classifyObject(const MemRegion *MR, const CXXRecordDecl *RD) const; // Classifies the object and dumps a user-friendly description string to - // the stream. Return value is equivalent to classifyObject. - ObjectKind explainObject(llvm::raw_ostream &OS, - const MemRegion *MR, const CXXRecordDecl *RD) const; + // the stream. + void explainObject(llvm::raw_ostream &OS, const MemRegion *MR, + const CXXRecordDecl *RD, MisuseKind MK) const; - bool isStandardMoveSafeClass(const CXXRecordDecl *RD) const; + bool belongsTo(const CXXRecordDecl *RD, const llvm::StringSet<> &Set) const; class MovedBugVisitor : public BugReporterVisitor { public: - MovedBugVisitor(const MoveChecker &Chk, - const MemRegion *R, const CXXRecordDecl *RD) - : Chk(Chk), Region(R), RD(RD), Found(false) {} + MovedBugVisitor(const MoveChecker &Chk, const MemRegion *R, + const CXXRecordDecl *RD, MisuseKind MK) + : Chk(Chk), Region(R), RD(RD), MK(MK), Found(false) {} void Profile(llvm::FoldingSetNodeID &ID) const override { static int X = 0; @@ -140,6 +168,8 @@ private: const MemRegion *Region; // The class of the tracked object. const CXXRecordDecl *RD; + // How exactly the object was misused. + const MisuseKind MK; bool Found; }; @@ -232,18 +262,37 @@ MoveChecker::MovedBugVisitor::VisitNode(const ExplodedNode *N, SmallString<128> Str; llvm::raw_svector_ostream OS(Str); - OS << "Object"; - ObjectKind OK = Chk.explainObject(OS, Region, RD); - if (OK.STL) - OS << " is left in a valid but unspecified state after move"; - else - OS << " is moved"; + ObjectKind OK = Chk.classifyObject(Region, RD); + switch (OK.StdKind) { + case SK_SmartPtr: + if (MK == MK_Dereference) { + OS << "Smart pointer"; + Chk.explainObject(OS, Region, RD, MK); + OS << " is reset to null when moved from"; + break; + } + + // If it's not a dereference, we don't care if it was reset to null + // or that it is even a smart pointer. + LLVM_FALLTHROUGH; + case SK_NonStd: + case SK_Safe: + OS << "Object"; + Chk.explainObject(OS, Region, RD, MK); + OS << " is moved"; + break; + case SK_Unsafe: + OS << "Object"; + Chk.explainObject(OS, Region, RD, MK); + OS << " is left in a valid but unspecified state after move"; + break; + } // Generate the extra diagnostic. PathDiagnosticLocation Pos(S, BRC.getSourceManager(), N->getLocationContext()); return std::make_shared(Pos, OS.str(), true); - } +} const ExplodedNode *MoveChecker::getMoveLocation(const ExplodedNode *N, const MemRegion *Region, @@ -267,25 +316,48 @@ void MoveChecker::modelUse(ProgramStateRef State, const MemRegion *Region, CheckerContext &C) const { assert(!C.isDifferent() && "No transitions should have been made by now"); const RegionState *RS = State->get(Region); + ObjectKind OK = classifyObject(Region, RD); + + // Just in case: if it's not a smart pointer but it does have operator *, + // we shouldn't call the bug a dereference. + if (MK == MK_Dereference && OK.StdKind != SK_SmartPtr) + MK = MK_FunCall; - if (!RS || isAnyBaseRegionReported(State, Region) + if (!RS || !shouldWarnAbout(OK, MK) || isInMoveSafeContext(C.getLocationContext())) { // Finalize changes made by the caller. C.addTransition(State); return; } + // Don't report it in case if any base region is already reported. + // But still generate a sink in case of UB. + // And still finalize changes made by the caller. + if (isAnyBaseRegionReported(State, Region)) { + if (misuseCausesCrash(MK)) { + C.generateSink(State, C.getPredecessor()); + } else { + C.addTransition(State); + } + return; + } + ExplodedNode *N = reportBug(Region, RD, C, MK); + // If the program has already crashed on this path, don't bother. + if (N->isSink()) + return; + State = State->set(Region, RegionState::getReported()); C.addTransition(State, N); } ExplodedNode *MoveChecker::reportBug(const MemRegion *Region, - const CXXRecordDecl *RD, - CheckerContext &C, + const CXXRecordDecl *RD, CheckerContext &C, MisuseKind MK) const { - if (ExplodedNode *N = C.generateNonFatalErrorNode()) { + if (ExplodedNode *N = misuseCausesCrash(MK) ? C.generateErrorNode() + : C.generateNonFatalErrorNode()) { + if (!BT) BT.reset(new BugType(this, "Use-after-move", "C++ move semantics")); @@ -304,24 +376,28 @@ ExplodedNode *MoveChecker::reportBug(const MemRegion *Region, switch(MK) { case MK_FunCall: OS << "Method called on moved-from object"; - explainObject(OS, Region, RD); + explainObject(OS, Region, RD, MK); break; case MK_Copy: OS << "Moved-from object"; - explainObject(OS, Region, RD); + explainObject(OS, Region, RD, MK); OS << " is copied"; break; case MK_Move: OS << "Moved-from object"; - explainObject(OS, Region, RD); + explainObject(OS, Region, RD, MK); OS << " is moved"; break; + case MK_Dereference: + OS << "Dereference of null smart pointer"; + explainObject(OS, Region, RD, MK); + break; } auto R = llvm::make_unique(*BT, OS.str(), N, LocUsedForUniqueing, MoveNode->getLocationContext()->getDecl()); - R->addVisitor(llvm::make_unique(*this, Region, RD)); + R->addVisitor(llvm::make_unique(*this, Region, RD, MK)); C.emitReport(std::move(R)); return N; } @@ -433,9 +509,10 @@ bool MoveChecker::isInMoveSafeContext(const LocationContext *LC) const { return false; } -bool MoveChecker::isStandardMoveSafeClass(const CXXRecordDecl *RD) const { +bool MoveChecker::belongsTo(const CXXRecordDecl *RD, + const llvm::StringSet<> &Set) const { const IdentifierInfo *II = RD->getIdentifier(); - return II && StandardMoveSafeClasses.count(II->getName()); + return II && Set.count(II->getName()); } MoveChecker::ObjectKind @@ -445,18 +522,23 @@ MoveChecker::classifyObject(const MemRegion *MR, // For the purposes of this checker, we classify move-safe STL types // as not-"STL" types, because that's how the checker treats them. MR = unwrapRValueReferenceIndirection(MR); - return { - /*Local=*/ - MR && isa(MR) && isa(MR->getMemorySpace()), - /*STL=*/ - RD && RD->getDeclContext()->isStdNamespace() && - !isStandardMoveSafeClass(RD) - }; + bool IsLocal = + MR && isa(MR) && isa(MR->getMemorySpace()); + + if (!RD || !RD->getDeclContext()->isStdNamespace()) + return { IsLocal, SK_NonStd }; + + if (belongsTo(RD, StdSmartPtrClasses)) + return { IsLocal, SK_SmartPtr }; + + if (belongsTo(RD, StdSafeClasses)) + return { IsLocal, SK_Safe }; + + return { IsLocal, SK_Unsafe }; } -MoveChecker::ObjectKind -MoveChecker::explainObject(llvm::raw_ostream &OS, const MemRegion *MR, - const CXXRecordDecl *RD) const { +void MoveChecker::explainObject(llvm::raw_ostream &OS, const MemRegion *MR, + const CXXRecordDecl *RD, MisuseKind MK) const { // We may need a leading space every time we actually explain anything, // and we never know if we are to explain anything until we try. if (const auto DR = @@ -464,11 +546,22 @@ MoveChecker::explainObject(llvm::raw_ostream &OS, const MemRegion *MR, const auto *RegionDecl = cast(DR->getDecl()); OS << " '" << RegionDecl->getNameAsString() << "'"; } + ObjectKind OK = classifyObject(MR, RD); - if (OK.STL) { - OS << " of type '" << RD->getQualifiedNameAsString() << "'"; - } - return OK; + switch (OK.StdKind) { + case SK_NonStd: + case SK_Safe: + break; + case SK_SmartPtr: + if (MK != MK_Dereference) + break; + + // We only care about the type if it's a dereference. + LLVM_FALLTHROUGH; + case SK_Unsafe: + OS << " of type '" << RD->getQualifiedNameAsString() << "'"; + break; + }; } void MoveChecker::checkPreCall(const CallEvent &Call, CheckerContext &C) const { @@ -543,6 +636,11 @@ void MoveChecker::checkPreCall(const CallEvent &Call, CheckerContext &C) const { C.addTransition(State); return; } + + if (OOK == OO_Star || OOK == OO_Arrow) { + modelUse(State, ThisRegion, RD, MK_Dereference, C); + return; + } } modelUse(State, ThisRegion, RD, MK_FunCall, C); diff --git a/test/Analysis/use-after-move.cpp b/test/Analysis/use-after-move.cpp index 18e1b3da6a..3cd319ff5a 100644 --- a/test/Analysis/use-after-move.cpp +++ b/test/Analysis/use-after-move.cpp @@ -1,20 +1,26 @@ // RUN: %clang_analyze_cc1 -analyzer-checker=alpha.cplusplus.Move -verify %s\ // RUN: -std=c++11 -analyzer-output=text -analyzer-config eagerly-assume=false\ -// RUN: -analyzer-config exploration_strategy=unexplored_first_queue +// RUN: -analyzer-config exploration_strategy=unexplored_first_queue\ +// RUN: -analyzer-checker debug.ExprInspection // RUN: %clang_analyze_cc1 -analyzer-checker=alpha.cplusplus.Move -verify %s\ // RUN: -std=c++11 -analyzer-output=text -analyzer-config eagerly-assume=false\ -// RUN: -analyzer-config exploration_strategy=dfs -DDFS=1 +// RUN: -analyzer-config exploration_strategy=dfs -DDFS=1\ +// RUN: -analyzer-checker debug.ExprInspection // RUN: %clang_analyze_cc1 -analyzer-checker=alpha.cplusplus.Move -verify %s\ // RUN: -std=c++11 -analyzer-output=text -analyzer-config eagerly-assume=false\ // RUN: -analyzer-config exploration_strategy=unexplored_first_queue\ -// RUN: -analyzer-config alpha.cplusplus.Move:Aggressive=true -DAGGRESSIVE +// RUN: -analyzer-config alpha.cplusplus.Move:Aggressive=true -DAGGRESSIVE\ +// RUN: -analyzer-checker debug.ExprInspection // RUN: %clang_analyze_cc1 -analyzer-checker=alpha.cplusplus.Move -verify %s\ // RUN: -std=c++11 -analyzer-output=text -analyzer-config eagerly-assume=false\ // RUN: -analyzer-config exploration_strategy=dfs -DDFS=1\ -// RUN: -analyzer-config alpha.cplusplus.Move:Aggressive=true -DAGGRESSIVE +// RUN: -analyzer-config alpha.cplusplus.Move:Aggressive=true -DAGGRESSIVE\ +// RUN: -analyzer-checker debug.ExprInspection #include "Inputs/system-header-simulator-cxx.h" +void clang_analyzer_warnIfReached(); + class B { public: B() = default; @@ -810,7 +816,19 @@ class HasSTLField { // expected-note@-4{{Object 'P' is moved}} // expected-note@-4{{Method called on moved-from object 'P'}} #endif - *P += 1; // FIXME: Should warn that the pointer is null. + + // Because that well-defined state is null, dereference is still UB. + // Note that in aggressive mode we already warned about 'P', + // so no extra warning is generated. + *P += 1; +#ifndef AGGRESSIVE + // expected-warning@-2{{Dereference of null smart pointer 'P' of type 'std::unique_ptr'}} + // expected-note@-14{{Smart pointer 'P' of type 'std::unique_ptr' is reset to null when moved from}} + // expected-note@-4{{Dereference of null smart pointer 'P' of type 'std::unique_ptr'}} +#endif + + // The program should have crashed by now. + clang_analyzer_warnIfReached(); // no-warning } }; @@ -827,3 +845,9 @@ void localUniquePtr(std::unique_ptr P) { P.get(); // expected-warning{{Method called on moved-from object 'P'}} // expected-note@-1{{Method called on moved-from object 'P'}} } + +void localUniquePtrWithArrow(std::unique_ptr P) { + std::unique_ptr Q = std::move(P); // expected-note{{Smart pointer 'P' of type 'std::unique_ptr' is reset to null when moved from}} + P->foo(); // expected-warning{{Dereference of null smart pointer 'P' of type 'std::unique_ptr'}} + // expected-note@-1{{Dereference of null smart pointer 'P' of type 'std::unique_ptr'}} +} -- cgit v1.2.3 From 3f894f43adbc9b83099587e1898fc339cda98f8b Mon Sep 17 00:00:00 2001 From: Artem Dergachev Date: Sat, 15 Dec 2018 02:06:13 +0000 Subject: [analyzer] ObjCContainers: Track index values. Use trackExpressionValue() (previously known as trackNullOrUndefValue()) to track index value in the report, so that the user knew what Static Analyzer thinks the index is. Additionally, implement printState() to help debugging the checker later. Differential Revision: https://reviews.llvm.org/D55458 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349227 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Checkers/ObjCContainersChecker.cpp | 17 ++++++++++ test/Analysis/CFContainers.mm | 39 +++++++++++++++++----- 2 files changed, 47 insertions(+), 9 deletions(-) diff --git a/lib/StaticAnalyzer/Checkers/ObjCContainersChecker.cpp b/lib/StaticAnalyzer/Checkers/ObjCContainersChecker.cpp index fb05ca630b..faaf2493d4 100644 --- a/lib/StaticAnalyzer/Checkers/ObjCContainersChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/ObjCContainersChecker.cpp @@ -57,6 +57,9 @@ public: const InvalidatedSymbols &Escaped, const CallEvent *Call, PointerEscapeKind Kind) const; + + void printState(raw_ostream &OS, ProgramStateRef State, + const char *NL, const char *Sep) const; }; } // end anonymous namespace @@ -144,6 +147,8 @@ void ObjCContainersChecker::checkPreStmt(const CallExpr *CE, initBugType(); auto R = llvm::make_unique(*BT, "Index is out of bounds", N); R->addRange(IdxExpr->getSourceRange()); + bugreporter::trackExpressionValue(N, IdxExpr, *R, + /*EnableNullFPSuppression=*/false); C.emitReport(std::move(R)); return; } @@ -166,6 +171,18 @@ ObjCContainersChecker::checkPointerEscape(ProgramStateRef State, return State; } +void ObjCContainersChecker::printState(raw_ostream &OS, ProgramStateRef State, + const char *NL, const char *Sep) const { + ArraySizeMapTy Map = State->get(); + if (Map.isEmpty()) + return; + + OS << Sep << "ObjC container sizes :" << NL; + for (auto I : Map) { + OS << I.first << " : " << I.second << NL; + } +} + /// Register checker. void ento::registerObjCContainersChecker(CheckerManager &mgr) { mgr.registerChecker(); diff --git a/test/Analysis/CFContainers.mm b/test/Analysis/CFContainers.mm index 0a45bffe5a..2e094d3cb7 100644 --- a/test/Analysis/CFContainers.mm +++ b/test/Analysis/CFContainers.mm @@ -1,4 +1,7 @@ -// RUN: %clang_analyze_cc1 -analyzer-checker=osx.coreFoundation.containers.PointerSizedValues,osx.coreFoundation.containers.OutOfBounds -analyzer-store=region -triple x86_64-apple-darwin -verify %s +// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin -analyzer-output=text\ +// RUN: -analyzer-checker=osx.coreFoundation.containers.PointerSizedValues\ +// RUN: -analyzer-checker=osx.coreFoundation.containers.OutOfBounds\ +// RUN: -verify %s typedef const struct __CFAllocator * CFAllocatorRef; typedef const struct __CFString * CFStringRef; @@ -94,17 +97,21 @@ CFSetRef CFSetCreate(CFAllocatorRef allocator, const void **values, CFIndex numV #define CFSTR(cStr) ((CFStringRef) __builtin___CFStringMakeConstantString ("" cStr "")) #define NULL __null -// Done with the headers. +// Done with the headers. // Test alpha.osx.cocoa.ContainerAPI checker. void testContainers(int **xNoWarn, CFIndex count) { int x[] = { 1, 2, 3 }; - CFArrayRef foo = CFArrayCreate(kCFAllocatorDefault, (const void **) x, sizeof(x) / sizeof(x[0]), 0);// expected-warning {{The second argument to 'CFArrayCreate' must be a C array of pointer-sized}} + CFArrayRef foo = CFArrayCreate(kCFAllocatorDefault, (const void **) x, sizeof(x) / sizeof(x[0]), 0); + // expected-warning@-1 {{The second argument to 'CFArrayCreate' must be a C array of pointer-sized}} + // expected-note@-2 {{The second argument to 'CFArrayCreate' must be a C array of pointer-sized}} CFArrayRef fooNoWarn = CFArrayCreate(kCFAllocatorDefault, (const void **) xNoWarn, sizeof(xNoWarn) / sizeof(xNoWarn[0]), 0); // no warning CFArrayRef fooNoWarn2 = CFArrayCreate(kCFAllocatorDefault, 0, sizeof(xNoWarn) / sizeof(xNoWarn[0]), 0);// no warning, passing in 0 CFArrayRef fooNoWarn3 = CFArrayCreate(kCFAllocatorDefault, NULL, sizeof(xNoWarn) / sizeof(xNoWarn[0]), 0);// no warning, passing in NULL - CFSetRef set = CFSetCreate(NULL, (const void **)x, 3, &kCFTypeSetCallBacks); // expected-warning {{The second argument to 'CFSetCreate' must be a C array of pointer-sized values}} + CFSetRef set = CFSetCreate(NULL, (const void **)x, 3, &kCFTypeSetCallBacks); + // expected-warning@-1 {{The second argument to 'CFSetCreate' must be a C array of pointer-sized values}} + // expected-note@-2 {{The second argument to 'CFSetCreate' must be a C array of pointer-sized values}} CFArrayRef* pairs = new CFArrayRef[count]; CFSetRef fSet = CFSetCreate(kCFAllocatorDefault, (const void**) pairs, count - 1, &kCFTypeSetCallBacks);// no warning } @@ -126,8 +133,13 @@ void CreateDict(int *elems) { const CFDictionaryKeyCallBacks keyCB = kCFCopyStringDictionaryKeyCallBacks; const CFDictionaryValueCallBacks valCB = kCFTypeDictionaryValueCallBacks; CFDictionaryRef dict1 = CFDictionaryCreate(kCFAllocatorDefault, (const void**)keys, (const void**)values, numValues, &keyCB, &valCB); // no warning - CFDictionaryRef dict2 = CFDictionaryCreate(kCFAllocatorDefault, (const void**)elems[0], (const void**)values, numValues, &keyCB, &valCB); //expected-warning {{The second argument to 'CFDictionaryCreate' must be a C array of}} expected-warning {{cast to 'const void **' from smaller integer type 'int'}} - CFDictionaryRef dict3 = CFDictionaryCreate(kCFAllocatorDefault, (const void**)keys, (const void**)elems, numValues, &keyCB, &valCB); // expected-warning {{The third argument to 'CFDictionaryCreate' must be a C array of pointer-sized values}} + CFDictionaryRef dict2 = CFDictionaryCreate(kCFAllocatorDefault, (const void**)elems[0], (const void**)values, numValues, &keyCB, &valCB); + // expected-warning@-1 {{The second argument to 'CFDictionaryCreate' must be a C array of}} + // expected-note@-2 {{The second argument to 'CFDictionaryCreate' must be a C array of}} + // expected-warning@-3{{cast to 'const void **' from smaller integer type 'int'}} + CFDictionaryRef dict3 = CFDictionaryCreate(kCFAllocatorDefault, (const void**)keys, (const void**)elems, numValues, &keyCB, &valCB); + // expected-warning@-1 {{The third argument to 'CFDictionaryCreate' must be a C array of pointer-sized values}} + // expected-note@-2 {{The third argument to 'CFDictionaryCreate' must be a C array of pointer-sized values}} } void OutOfBoundsSymbolicOffByOne(const void ** input, CFIndex S) { @@ -136,6 +148,7 @@ void OutOfBoundsSymbolicOffByOne(const void ** input, CFIndex S) { const void *s1 = CFArrayGetValueAtIndex(array, 0); // no warning const void *s2 = CFArrayGetValueAtIndex(array, S-1); // no warning const void *s3 = CFArrayGetValueAtIndex(array, S); // expected-warning {{Index is out of bounds}} + // expected-note@-1 {{Index is out of bounds}} } void OutOfBoundsConst(const void ** input, CFIndex S) { @@ -144,6 +157,7 @@ void OutOfBoundsConst(const void ** input, CFIndex S) { const void *s1 = CFArrayGetValueAtIndex(array, 0); // no warning const void *s2 = CFArrayGetValueAtIndex(array, 2); // no warning const void *s3 = CFArrayGetValueAtIndex(array, 5); // expected-warning {{Index is out of bounds}} + // expected-note@-1 {{Index is out of bounds}} // TODO: The solver is probably not strong enough here. CFIndex sIndex; @@ -157,13 +171,16 @@ void OutOfBoundsZiro(const void ** input, CFIndex S) { // The API allows to set the size to 0. Check that we don't undeflow when the size is 0. array = CFArrayCreate(kCFAllocatorDefault, 0, 0, 0); const void *s1 = CFArrayGetValueAtIndex(array, 0); // expected-warning {{Index is out of bounds}} + // expected-note@-1 {{Index is out of bounds}} } void TestGetCount(CFArrayRef A, CFIndex sIndex) { - CFIndex sCount = CFArrayGetCount(A); - if (sCount > sIndex) + CFIndex sCount = CFArrayGetCount(A); // expected-note{{'sCount' initialized here}} + if (sCount > sIndex) // expected-note{{Assuming 'sCount' is <= 'sIndex'}} + // expected-note@-1{{Taking false branch}} const void *s1 = CFArrayGetValueAtIndex(A, sIndex); const void *s2 = CFArrayGetValueAtIndex(A, sCount);// expected-warning {{Index is out of bounds}} + // expected-note@-1 {{Index is out of bounds}} } typedef void* XX[3]; @@ -179,10 +196,13 @@ void TestPointerToArray(int *elems, void *p1, void *p2, void *p3, unsigned count CFArrayCreate(0, (const void **) &fn, count, 0); // false negative CFArrayCreate(0, (const void **) fn, count, 0); // no warning CFArrayCreate(0, (const void **) cp, count, 0); // expected-warning {{The second argument to 'CFArrayCreate' must be a C array of pointer-sized}} + // expected-note@-1 {{The second argument to 'CFArrayCreate' must be a C array of pointer-sized}} char cc[] = { 0, 2, 3 }; CFArrayCreate(0, (const void **) &cc, count, 0); // expected-warning {{The second argument to 'CFArrayCreate' must be a C array of pointer-sized}} + // expected-note@-1 {{The second argument to 'CFArrayCreate' must be a C array of pointer-sized}} CFArrayCreate(0, (const void **) cc, count, 0); // expected-warning {{The second argument to 'CFArrayCreate' must be a C array of pointer-sized}} + // expected-note@-1 {{The second argument to 'CFArrayCreate' must be a C array of pointer-sized}} } void TestUndef(CFArrayRef A, CFIndex sIndex, void* x[]) { @@ -217,10 +237,11 @@ void TestCFMutableArrayRefEscapeViaMutableArgument(CFMutableArrayRef a) { } void TestCFMutableArrayRefEscapeViaImmutableArgument(CFMutableArrayRef a) { - CFIndex aLen = CFArrayGetCount(a); + CFIndex aLen = CFArrayGetCount(a); // expected-note{{'aLen' initialized here}} ArrayRefEscape(a); // ArrayRefEscape is declared to take a CFArrayRef (i.e, an immutable array) // so we assume it does not change the length of a. CFArrayGetValueAtIndex(a, aLen); // expected-warning {{Index is out of bounds}} + // expected-note@-1 {{Index is out of bounds}} } -- cgit v1.2.3 From 2b29b6937bcb5f43b5572b70837a6374b43927c5 Mon Sep 17 00:00:00 2001 From: Artem Dergachev Date: Sat, 15 Dec 2018 02:09:02 +0000 Subject: [analyzer] ObjCDealloc: Fix a crash when a class attempts to deallocate a class. The checker wasn't prepared to see the dealloc message sent to the class itself rather than to an instance, as if it was +dealloc. Additionally, it wasn't prepared for pure-unknown or undefined self values. The new guard covers that as well, but it is annoying to test because both kinds of values shouldn't really appear and we generally want to get rid of all of them (by modeling unknown values with symbols and by warning on use of undefined values before they are used). The CHECK: directive for FileCheck at the end of the test looks useless, so i removed it. Differential Revision: https://reviews.llvm.org/D55680 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349228 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp | 4 ++++ test/Analysis/MissingDealloc.m | 15 ++++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp b/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp index c330d7504b..faee82895b 100644 --- a/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp +++ b/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp @@ -715,6 +715,10 @@ bool ObjCDeallocChecker::diagnoseExtraRelease(SymbolRef ReleasedValue, bool ObjCDeallocChecker::diagnoseMistakenDealloc(SymbolRef DeallocedValue, const ObjCMethodCall &M, CheckerContext &C) const { + // TODO: Apart from unknown/undefined receivers, this may happen when + // dealloc is called as a class method. Should we warn? + if (!DeallocedValue) + return false; // Find the property backing the instance variable that M // is dealloc'ing. diff --git a/test/Analysis/MissingDealloc.m b/test/Analysis/MissingDealloc.m index bedd1e7fc2..bdba93c881 100644 --- a/test/Analysis/MissingDealloc.m +++ b/test/Analysis/MissingDealloc.m @@ -183,4 +183,17 @@ __attribute__((objc_root_class)) @implementation NonNSObjectMissingDealloc @end -// CHECK: 4 warnings generated. + +//===------------------------------------------------------------------------=== +// Don't crash on calls to dealloc as a class method. + +@interface DeallocingClass : NSObject {} +@end +@implementation DeallocingClass +- (void)dealloc { + [DeallocingClass dealloc]; // FIXME: Should we warn on this specifically? +} +#if NON_ARC +// expected-warning@-2{{method possibly missing a [super dealloc] call}} +#endif +@end -- cgit v1.2.3 From e1138b8165f43da9921b5545b4958431ba7c7195 Mon Sep 17 00:00:00 2001 From: Artem Dergachev Date: Sat, 15 Dec 2018 02:13:26 +0000 Subject: [analyzer] Fix unknown block calls to have zero parameters. Right now they report to have one parameter with null decl, because initializing an ArrayRef of pointers with a nullptr yields an ArrayRef to an array of one null pointer. Fixes a crash in the OSObject section of RetainCountChecker. Differential Revision: https://reviews.llvm.org/D55671 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349229 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/StaticAnalyzer/Core/CallEvent.cpp | 2 +- test/Analysis/osobject-retain-release.cpp | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/lib/StaticAnalyzer/Core/CallEvent.cpp b/lib/StaticAnalyzer/Core/CallEvent.cpp index 767116630f..8d9338b21c 100644 --- a/lib/StaticAnalyzer/Core/CallEvent.cpp +++ b/lib/StaticAnalyzer/Core/CallEvent.cpp @@ -837,7 +837,7 @@ const BlockDataRegion *BlockCall::getBlockRegion() const { ArrayRef BlockCall::parameters() const { const BlockDecl *D = getDecl(); if (!D) - return nullptr; + return None; return D->parameters(); } diff --git a/test/Analysis/osobject-retain-release.cpp b/test/Analysis/osobject-retain-release.cpp index b8eb462d20..c8bc4aeaa0 100644 --- a/test/Analysis/osobject-retain-release.cpp +++ b/test/Analysis/osobject-retain-release.cpp @@ -1,4 +1,5 @@ -// RUN: %clang_analyze_cc1 -analyze -analyzer-checker=core,osx -analyzer-output=text -verify %s +// RUN: %clang_analyze_cc1 -fblocks -analyze -analyzer-output=text\ +// RUN: -analyzer-checker=core,osx -verify %s struct OSMetaClass; @@ -399,3 +400,11 @@ unsigned int ok_release_with_unknown_source(ArrayOwner *owner) { arr->release(); // +0 return arr->getCount(); } + +OSObject *getObject(); +typedef bool (^Blk)(OSObject *); + +void test_escape_to_unknown_block(Blk blk) { + blk(getObject()); // no-crash +} + -- cgit v1.2.3 From cbd56c79bdef48f8d856d7d7b252c6453972494e Mon Sep 17 00:00:00 2001 From: Richard Trieu Date: Sat, 15 Dec 2018 02:30:16 +0000 Subject: Move static analyzer core diagnostics to common. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349230 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/DiagnosticCommonKinds.td | 6 ++++++ include/clang/Basic/DiagnosticFrontendKinds.td | 5 ----- lib/StaticAnalyzer/Core/CheckerRegistry.cpp | 1 - 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/clang/Basic/DiagnosticCommonKinds.td b/include/clang/Basic/DiagnosticCommonKinds.td index 5a3378c869..34ce489e50 100644 --- a/include/clang/Basic/DiagnosticCommonKinds.td +++ b/include/clang/Basic/DiagnosticCommonKinds.td @@ -290,4 +290,10 @@ def err_openclcxx_not_supported : Error< // OpenMP def err_omp_more_one_clause : Error< "directive '#pragma omp %0' cannot contain more than one '%1' clause%select{| with '%3' name modifier| with 'source' dependence}2">; + +// Static Analyzer Core +def err_unknown_analyzer_checker : Error< + "no analyzer checkers are associated with '%0'">; +def note_suggest_disabling_all_checkers : Note< + "use -analyzer-disable-all-checks to disable all static analyzer checkers">; } diff --git a/include/clang/Basic/DiagnosticFrontendKinds.td b/include/clang/Basic/DiagnosticFrontendKinds.td index b2fcb9ca14..927b8cbc24 100644 --- a/include/clang/Basic/DiagnosticFrontendKinds.td +++ b/include/clang/Basic/DiagnosticFrontendKinds.td @@ -160,11 +160,6 @@ def warn_unknown_warning_specifier : Warning< "unknown %0 warning specifier: '%1'">, InGroup; -def err_unknown_analyzer_checker : Error< - "no analyzer checkers are associated with '%0'">; -def note_suggest_disabling_all_checkers : Note< - "use -analyzer-disable-all-checks to disable all static analyzer checkers">; - def warn_incompatible_analyzer_plugin_api : Warning< "checker plugin '%0' is not compatible with this version of the analyzer">, InGroup >; diff --git a/lib/StaticAnalyzer/Core/CheckerRegistry.cpp b/lib/StaticAnalyzer/Core/CheckerRegistry.cpp index 00475c04fd..e7dfac7479 100644 --- a/lib/StaticAnalyzer/Core/CheckerRegistry.cpp +++ b/lib/StaticAnalyzer/Core/CheckerRegistry.cpp @@ -10,7 +10,6 @@ #include "clang/StaticAnalyzer/Core/CheckerRegistry.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/LLVM.h" -#include "clang/Frontend/FrontendDiagnostic.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" #include "clang/StaticAnalyzer/Core/AnalyzerOptions.h" #include "llvm/ADT/STLExtras.h" -- cgit v1.2.3 From 4bf3a5359d9117a765b416253f2f12046afa1313 Mon Sep 17 00:00:00 2001 From: Artem Dergachev Date: Sat, 15 Dec 2018 02:55:55 +0000 Subject: Revert "[analyzer] MoveChecker: Add checks for dereferencing a smart pointer..." This reverts commit r349226. Fails on an MSVC buildbot. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349233 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/StaticAnalyzer/Checkers/MoveChecker.cpp | 200 +++++++--------------------- test/Analysis/use-after-move.cpp | 34 +---- 2 files changed, 56 insertions(+), 178 deletions(-) diff --git a/lib/StaticAnalyzer/Checkers/MoveChecker.cpp b/lib/StaticAnalyzer/Checkers/MoveChecker.cpp index 6256696c6f..d387e0bea7 100644 --- a/lib/StaticAnalyzer/Checkers/MoveChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/MoveChecker.cpp @@ -61,35 +61,19 @@ public: const char *NL, const char *Sep) const override; private: - enum MisuseKind { MK_FunCall, MK_Copy, MK_Move, MK_Dereference }; - enum StdObjectKind { SK_NonStd, SK_Unsafe, SK_Safe, SK_SmartPtr }; - - static bool misuseCausesCrash(MisuseKind MK) { - return MK == MK_Dereference; - } + enum MisuseKind { MK_FunCall, MK_Copy, MK_Move }; struct ObjectKind { - // Is this a local variable or a local rvalue reference? - bool IsLocal : 1; - // Is this an STL object? If so, of what kind? - StdObjectKind StdKind : 2; - }; - - // STL smart pointers are automatically re-initialized to null when moved - // from. So we can't warn on many methods, but we can warn when it is - // dereferenced, which is UB even if the resulting lvalue never gets read. - const llvm::StringSet<> StdSmartPtrClasses = { - "shared_ptr", - "unique_ptr", - "weak_ptr", + bool Local : 1; // Is this a local variable or a local rvalue reference? + bool STL : 1; // Is this an object of a standard type? }; // Not all of these are entirely move-safe, but they do provide *some* // guarantees, and it means that somebody is using them after move // in a valid manner. - // TODO: We can still try to identify *unsafe* use after move, - // like we did with smart pointers. - const llvm::StringSet<> StdSafeClasses = { + // TODO: We can still try to identify *unsafe* use after move, such as + // dereference of a moved-from smart pointer (which is guaranteed to be null). + const llvm::StringSet<> StandardMoveSafeClasses = { "basic_filebuf", "basic_ios", "future", @@ -98,8 +82,11 @@ private: "promise", "shared_future", "shared_lock", + "shared_ptr", "thread", + "unique_ptr", "unique_lock", + "weak_ptr", }; // Should we bother tracking the state of the object? @@ -110,25 +97,10 @@ private: // their user to re-use the storage. The latter is possible because STL // objects are known to end up in a valid but unspecified state after the // move and their state-reset methods are also known, which allows us to - // predict precisely when use-after-move is invalid. - // Some STL objects are known to conform to additional contracts after move, - // so they are not tracked. However, smart pointers specifically are tracked - // because we can perform extra checking over them. - // In aggressive mode, warn on any use-after-move because the user has - // intentionally asked us to completely eliminate use-after-move - // in his code. - return IsAggressive || OK.IsLocal - || OK.StdKind == SK_Unsafe || OK.StdKind == SK_SmartPtr; - } - - // Some objects only suffer from some kinds of misuses, but we need to track - // them anyway because we cannot know in advance what misuse will we find. - bool shouldWarnAbout(ObjectKind OK, MisuseKind MK) const { - // Additionally, only warn on smart pointers when they are dereferenced (or - // local or we are aggressive). - return shouldBeTracked(OK) && - (IsAggressive || OK.IsLocal - || OK.StdKind != SK_SmartPtr || MK == MK_Dereference); + // predict precisely when use-after-move is invalid. In aggressive mode, + // warn on any use-after-move because the user has intentionally asked us + // to completely eliminate use-after-move in his code. + return IsAggressive || OK.Local || OK.STL; } // Obtains ObjectKind of an object. Because class declaration cannot always @@ -136,17 +108,17 @@ private: ObjectKind classifyObject(const MemRegion *MR, const CXXRecordDecl *RD) const; // Classifies the object and dumps a user-friendly description string to - // the stream. - void explainObject(llvm::raw_ostream &OS, const MemRegion *MR, - const CXXRecordDecl *RD, MisuseKind MK) const; + // the stream. Return value is equivalent to classifyObject. + ObjectKind explainObject(llvm::raw_ostream &OS, + const MemRegion *MR, const CXXRecordDecl *RD) const; - bool belongsTo(const CXXRecordDecl *RD, const llvm::StringSet<> &Set) const; + bool isStandardMoveSafeClass(const CXXRecordDecl *RD) const; class MovedBugVisitor : public BugReporterVisitor { public: - MovedBugVisitor(const MoveChecker &Chk, const MemRegion *R, - const CXXRecordDecl *RD, MisuseKind MK) - : Chk(Chk), Region(R), RD(RD), MK(MK), Found(false) {} + MovedBugVisitor(const MoveChecker &Chk, + const MemRegion *R, const CXXRecordDecl *RD) + : Chk(Chk), Region(R), RD(RD), Found(false) {} void Profile(llvm::FoldingSetNodeID &ID) const override { static int X = 0; @@ -168,8 +140,6 @@ private: const MemRegion *Region; // The class of the tracked object. const CXXRecordDecl *RD; - // How exactly the object was misused. - const MisuseKind MK; bool Found; }; @@ -262,37 +232,18 @@ MoveChecker::MovedBugVisitor::VisitNode(const ExplodedNode *N, SmallString<128> Str; llvm::raw_svector_ostream OS(Str); - ObjectKind OK = Chk.classifyObject(Region, RD); - switch (OK.StdKind) { - case SK_SmartPtr: - if (MK == MK_Dereference) { - OS << "Smart pointer"; - Chk.explainObject(OS, Region, RD, MK); - OS << " is reset to null when moved from"; - break; - } - - // If it's not a dereference, we don't care if it was reset to null - // or that it is even a smart pointer. - LLVM_FALLTHROUGH; - case SK_NonStd: - case SK_Safe: - OS << "Object"; - Chk.explainObject(OS, Region, RD, MK); - OS << " is moved"; - break; - case SK_Unsafe: - OS << "Object"; - Chk.explainObject(OS, Region, RD, MK); - OS << " is left in a valid but unspecified state after move"; - break; - } + OS << "Object"; + ObjectKind OK = Chk.explainObject(OS, Region, RD); + if (OK.STL) + OS << " is left in a valid but unspecified state after move"; + else + OS << " is moved"; // Generate the extra diagnostic. PathDiagnosticLocation Pos(S, BRC.getSourceManager(), N->getLocationContext()); return std::make_shared(Pos, OS.str(), true); -} + } const ExplodedNode *MoveChecker::getMoveLocation(const ExplodedNode *N, const MemRegion *Region, @@ -316,48 +267,25 @@ void MoveChecker::modelUse(ProgramStateRef State, const MemRegion *Region, CheckerContext &C) const { assert(!C.isDifferent() && "No transitions should have been made by now"); const RegionState *RS = State->get(Region); - ObjectKind OK = classifyObject(Region, RD); - - // Just in case: if it's not a smart pointer but it does have operator *, - // we shouldn't call the bug a dereference. - if (MK == MK_Dereference && OK.StdKind != SK_SmartPtr) - MK = MK_FunCall; - if (!RS || !shouldWarnAbout(OK, MK) + if (!RS || isAnyBaseRegionReported(State, Region) || isInMoveSafeContext(C.getLocationContext())) { // Finalize changes made by the caller. C.addTransition(State); return; } - // Don't report it in case if any base region is already reported. - // But still generate a sink in case of UB. - // And still finalize changes made by the caller. - if (isAnyBaseRegionReported(State, Region)) { - if (misuseCausesCrash(MK)) { - C.generateSink(State, C.getPredecessor()); - } else { - C.addTransition(State); - } - return; - } - ExplodedNode *N = reportBug(Region, RD, C, MK); - // If the program has already crashed on this path, don't bother. - if (N->isSink()) - return; - State = State->set(Region, RegionState::getReported()); C.addTransition(State, N); } ExplodedNode *MoveChecker::reportBug(const MemRegion *Region, - const CXXRecordDecl *RD, CheckerContext &C, + const CXXRecordDecl *RD, + CheckerContext &C, MisuseKind MK) const { - if (ExplodedNode *N = misuseCausesCrash(MK) ? C.generateErrorNode() - : C.generateNonFatalErrorNode()) { - + if (ExplodedNode *N = C.generateNonFatalErrorNode()) { if (!BT) BT.reset(new BugType(this, "Use-after-move", "C++ move semantics")); @@ -376,28 +304,24 @@ ExplodedNode *MoveChecker::reportBug(const MemRegion *Region, switch(MK) { case MK_FunCall: OS << "Method called on moved-from object"; - explainObject(OS, Region, RD, MK); + explainObject(OS, Region, RD); break; case MK_Copy: OS << "Moved-from object"; - explainObject(OS, Region, RD, MK); + explainObject(OS, Region, RD); OS << " is copied"; break; case MK_Move: OS << "Moved-from object"; - explainObject(OS, Region, RD, MK); + explainObject(OS, Region, RD); OS << " is moved"; break; - case MK_Dereference: - OS << "Dereference of null smart pointer"; - explainObject(OS, Region, RD, MK); - break; } auto R = llvm::make_unique(*BT, OS.str(), N, LocUsedForUniqueing, MoveNode->getLocationContext()->getDecl()); - R->addVisitor(llvm::make_unique(*this, Region, RD, MK)); + R->addVisitor(llvm::make_unique(*this, Region, RD)); C.emitReport(std::move(R)); return N; } @@ -509,10 +433,9 @@ bool MoveChecker::isInMoveSafeContext(const LocationContext *LC) const { return false; } -bool MoveChecker::belongsTo(const CXXRecordDecl *RD, - const llvm::StringSet<> &Set) const { +bool MoveChecker::isStandardMoveSafeClass(const CXXRecordDecl *RD) const { const IdentifierInfo *II = RD->getIdentifier(); - return II && Set.count(II->getName()); + return II && StandardMoveSafeClasses.count(II->getName()); } MoveChecker::ObjectKind @@ -522,23 +445,18 @@ MoveChecker::classifyObject(const MemRegion *MR, // For the purposes of this checker, we classify move-safe STL types // as not-"STL" types, because that's how the checker treats them. MR = unwrapRValueReferenceIndirection(MR); - bool IsLocal = - MR && isa(MR) && isa(MR->getMemorySpace()); - - if (!RD || !RD->getDeclContext()->isStdNamespace()) - return { IsLocal, SK_NonStd }; - - if (belongsTo(RD, StdSmartPtrClasses)) - return { IsLocal, SK_SmartPtr }; - - if (belongsTo(RD, StdSafeClasses)) - return { IsLocal, SK_Safe }; - - return { IsLocal, SK_Unsafe }; + return { + /*Local=*/ + MR && isa(MR) && isa(MR->getMemorySpace()), + /*STL=*/ + RD && RD->getDeclContext()->isStdNamespace() && + !isStandardMoveSafeClass(RD) + }; } -void MoveChecker::explainObject(llvm::raw_ostream &OS, const MemRegion *MR, - const CXXRecordDecl *RD, MisuseKind MK) const { +MoveChecker::ObjectKind +MoveChecker::explainObject(llvm::raw_ostream &OS, const MemRegion *MR, + const CXXRecordDecl *RD) const { // We may need a leading space every time we actually explain anything, // and we never know if we are to explain anything until we try. if (const auto DR = @@ -546,22 +464,11 @@ void MoveChecker::explainObject(llvm::raw_ostream &OS, const MemRegion *MR, const auto *RegionDecl = cast(DR->getDecl()); OS << " '" << RegionDecl->getNameAsString() << "'"; } - ObjectKind OK = classifyObject(MR, RD); - switch (OK.StdKind) { - case SK_NonStd: - case SK_Safe: - break; - case SK_SmartPtr: - if (MK != MK_Dereference) - break; - - // We only care about the type if it's a dereference. - LLVM_FALLTHROUGH; - case SK_Unsafe: - OS << " of type '" << RD->getQualifiedNameAsString() << "'"; - break; - }; + if (OK.STL) { + OS << " of type '" << RD->getQualifiedNameAsString() << "'"; + } + return OK; } void MoveChecker::checkPreCall(const CallEvent &Call, CheckerContext &C) const { @@ -636,11 +543,6 @@ void MoveChecker::checkPreCall(const CallEvent &Call, CheckerContext &C) const { C.addTransition(State); return; } - - if (OOK == OO_Star || OOK == OO_Arrow) { - modelUse(State, ThisRegion, RD, MK_Dereference, C); - return; - } } modelUse(State, ThisRegion, RD, MK_FunCall, C); diff --git a/test/Analysis/use-after-move.cpp b/test/Analysis/use-after-move.cpp index 3cd319ff5a..18e1b3da6a 100644 --- a/test/Analysis/use-after-move.cpp +++ b/test/Analysis/use-after-move.cpp @@ -1,26 +1,20 @@ // RUN: %clang_analyze_cc1 -analyzer-checker=alpha.cplusplus.Move -verify %s\ // RUN: -std=c++11 -analyzer-output=text -analyzer-config eagerly-assume=false\ -// RUN: -analyzer-config exploration_strategy=unexplored_first_queue\ -// RUN: -analyzer-checker debug.ExprInspection +// RUN: -analyzer-config exploration_strategy=unexplored_first_queue // RUN: %clang_analyze_cc1 -analyzer-checker=alpha.cplusplus.Move -verify %s\ // RUN: -std=c++11 -analyzer-output=text -analyzer-config eagerly-assume=false\ -// RUN: -analyzer-config exploration_strategy=dfs -DDFS=1\ -// RUN: -analyzer-checker debug.ExprInspection +// RUN: -analyzer-config exploration_strategy=dfs -DDFS=1 // RUN: %clang_analyze_cc1 -analyzer-checker=alpha.cplusplus.Move -verify %s\ // RUN: -std=c++11 -analyzer-output=text -analyzer-config eagerly-assume=false\ // RUN: -analyzer-config exploration_strategy=unexplored_first_queue\ -// RUN: -analyzer-config alpha.cplusplus.Move:Aggressive=true -DAGGRESSIVE\ -// RUN: -analyzer-checker debug.ExprInspection +// RUN: -analyzer-config alpha.cplusplus.Move:Aggressive=true -DAGGRESSIVE // RUN: %clang_analyze_cc1 -analyzer-checker=alpha.cplusplus.Move -verify %s\ // RUN: -std=c++11 -analyzer-output=text -analyzer-config eagerly-assume=false\ // RUN: -analyzer-config exploration_strategy=dfs -DDFS=1\ -// RUN: -analyzer-config alpha.cplusplus.Move:Aggressive=true -DAGGRESSIVE\ -// RUN: -analyzer-checker debug.ExprInspection +// RUN: -analyzer-config alpha.cplusplus.Move:Aggressive=true -DAGGRESSIVE #include "Inputs/system-header-simulator-cxx.h" -void clang_analyzer_warnIfReached(); - class B { public: B() = default; @@ -816,19 +810,7 @@ class HasSTLField { // expected-note@-4{{Object 'P' is moved}} // expected-note@-4{{Method called on moved-from object 'P'}} #endif - - // Because that well-defined state is null, dereference is still UB. - // Note that in aggressive mode we already warned about 'P', - // so no extra warning is generated. - *P += 1; -#ifndef AGGRESSIVE - // expected-warning@-2{{Dereference of null smart pointer 'P' of type 'std::unique_ptr'}} - // expected-note@-14{{Smart pointer 'P' of type 'std::unique_ptr' is reset to null when moved from}} - // expected-note@-4{{Dereference of null smart pointer 'P' of type 'std::unique_ptr'}} -#endif - - // The program should have crashed by now. - clang_analyzer_warnIfReached(); // no-warning + *P += 1; // FIXME: Should warn that the pointer is null. } }; @@ -845,9 +827,3 @@ void localUniquePtr(std::unique_ptr P) { P.get(); // expected-warning{{Method called on moved-from object 'P'}} // expected-note@-1{{Method called on moved-from object 'P'}} } - -void localUniquePtrWithArrow(std::unique_ptr P) { - std::unique_ptr Q = std::move(P); // expected-note{{Smart pointer 'P' of type 'std::unique_ptr' is reset to null when moved from}} - P->foo(); // expected-warning{{Dereference of null smart pointer 'P' of type 'std::unique_ptr'}} - // expected-note@-1{{Dereference of null smart pointer 'P' of type 'std::unique_ptr'}} -} -- cgit v1.2.3 From fdb0118eb0129ef4f9907ac91f853df5db12ac1a Mon Sep 17 00:00:00 2001 From: Richard Trieu Date: Sat, 15 Dec 2018 04:25:19 +0000 Subject: Fix includes and dependencies for libclang Remove unneeded includes Add needed include Remove dependency on Serialization git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349237 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/libclang/CIndex.cpp | 2 -- tools/libclang/CIndexCodeCompletion.cpp | 1 - tools/libclang/CIndexDiagnostic.cpp | 1 - tools/libclang/CMakeLists.txt | 1 - tools/libclang/CXStoredDiagnostic.cpp | 2 +- 5 files changed, 1 insertion(+), 6 deletions(-) diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp index 4de73649a3..ca8b4baf6c 100644 --- a/tools/libclang/CIndex.cpp +++ b/tools/libclang/CIndex.cpp @@ -31,14 +31,12 @@ #include "clang/Basic/Version.h" #include "clang/Frontend/ASTUnit.h" #include "clang/Frontend/CompilerInstance.h" -#include "clang/Frontend/FrontendDiagnostic.h" #include "clang/Index/CodegenNameGenerator.h" #include "clang/Index/CommentToXML.h" #include "clang/Lex/HeaderSearch.h" #include "clang/Lex/Lexer.h" #include "clang/Lex/PreprocessingRecord.h" #include "clang/Lex/Preprocessor.h" -#include "clang/Serialization/SerializationDiagnostic.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringSwitch.h" diff --git a/tools/libclang/CIndexCodeCompletion.cpp b/tools/libclang/CIndexCodeCompletion.cpp index 752d7a10e0..c5cece52ac 100644 --- a/tools/libclang/CIndexCodeCompletion.cpp +++ b/tools/libclang/CIndexCodeCompletion.cpp @@ -26,7 +26,6 @@ #include "clang/Basic/SourceManager.h" #include "clang/Frontend/ASTUnit.h" #include "clang/Frontend/CompilerInstance.h" -#include "clang/Frontend/FrontendDiagnostic.h" #include "clang/Sema/CodeCompleteConsumer.h" #include "clang/Sema/Sema.h" #include "llvm/ADT/SmallString.h" diff --git a/tools/libclang/CIndexDiagnostic.cpp b/tools/libclang/CIndexDiagnostic.cpp index 4e47b25a4b..a4e75e2aae 100644 --- a/tools/libclang/CIndexDiagnostic.cpp +++ b/tools/libclang/CIndexDiagnostic.cpp @@ -19,7 +19,6 @@ #include "clang/Basic/DiagnosticOptions.h" #include "clang/Frontend/ASTUnit.h" #include "clang/Frontend/DiagnosticRenderer.h" -#include "clang/Frontend/FrontendDiagnostic.h" #include "llvm/ADT/SmallString.h" #include "llvm/Support/raw_ostream.h" diff --git a/tools/libclang/CMakeLists.txt b/tools/libclang/CMakeLists.txt index 32333b011a..729d5560b6 100644 --- a/tools/libclang/CMakeLists.txt +++ b/tools/libclang/CMakeLists.txt @@ -40,7 +40,6 @@ set(LIBS clangIndex clangLex clangSema - clangSerialization clangTooling ) diff --git a/tools/libclang/CXStoredDiagnostic.cpp b/tools/libclang/CXStoredDiagnostic.cpp index f2e9c1da28..6bd2f67466 100644 --- a/tools/libclang/CXStoredDiagnostic.cpp +++ b/tools/libclang/CXStoredDiagnostic.cpp @@ -17,8 +17,8 @@ #include "CXSourceLocation.h" #include "CXString.h" +#include "clang/Basic/DiagnosticIDs.h" #include "clang/Frontend/ASTUnit.h" -#include "clang/Frontend/FrontendDiagnostic.h" #include "llvm/ADT/Twine.h" using namespace clang; -- cgit v1.2.3 From 58231a6ef9898e7dd5a147da579f1d05304f4334 Mon Sep 17 00:00:00 2001 From: Martin Storsjo Date: Sat, 15 Dec 2018 08:08:11 +0000 Subject: [MinGW] Produce a vtable and RTTI for dllexported classes without a key function This matches what GCC does in these situations. This fixes compiling Qt in debug mode. In release mode, references to the vtable of this particular class ends up optimized away, but in debug mode, the compiler creates references to the vtable, which is expected to be dllexported from a different DLL. Make sure the dllexported version actually ends up emitted. Differential Revision: https://reviews.llvm.org/D55698 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349256 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaDeclCXX.cpp | 3 +++ test/CodeGenCXX/dllexport-missing-key.cpp | 22 ++++++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 test/CodeGenCXX/dllexport-missing-key.cpp diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 4a7ab11c71..d56c880311 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -5528,6 +5528,9 @@ static void ReferenceDllExportedMembers(Sema &S, CXXRecordDecl *Class) { // declaration. return; + if (S.Context.getTargetInfo().getTriple().isWindowsGNUEnvironment()) + S.MarkVTableUsed(Class->getLocation(), Class, true); + for (Decl *Member : Class->decls()) { // Defined static variables that are members of an exported base // class must be marked export too. diff --git a/test/CodeGenCXX/dllexport-missing-key.cpp b/test/CodeGenCXX/dllexport-missing-key.cpp new file mode 100644 index 0000000000..90e736f6fa --- /dev/null +++ b/test/CodeGenCXX/dllexport-missing-key.cpp @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -triple x86_64-windows-gnu -emit-llvm -std=c++11 -o - %s | FileCheck --check-prefix=GNU %s + +class __declspec(dllexport) QAbstractLayoutStyleInfo { +public: + QAbstractLayoutStyleInfo() : m_isWindow(false) {} + virtual ~QAbstractLayoutStyleInfo() {} + + virtual bool hasChangedCore() const { return false; } + + virtual void invalidate() {} + + virtual double windowMargin(bool orientation) const = 0; + + bool isWindow() const { return m_isWindow; } + +protected: + bool m_isWindow; +}; + +// GNU-DAG: @_ZTV24QAbstractLayoutStyleInfo = weak_odr dso_local dllexport +// GNU-DAG: @_ZTS24QAbstractLayoutStyleInfo = linkonce_odr +// GNU-DAG: @_ZTI24QAbstractLayoutStyleInfo = linkonce_odr -- cgit v1.2.3 From a674a04e68bcf09f9a0423f3f589589596bc01a6 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 15 Dec 2018 08:54:06 +0000 Subject: [libclang] Add dependency on clangSerialization to unbreak -DBUILD_SHARED_LIBS=1 build after rC349237 Frontend headers have undefined reference on the symbol `clang::PCHContainerOperations::PCHContainerOperations()` through some shared_ptr usage. Any dependents will get the undefined reference which can only be resolved by explicit dependency on clangSerialization (due to -z defs). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349259 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/libclang/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/libclang/CMakeLists.txt b/tools/libclang/CMakeLists.txt index 729d5560b6..32333b011a 100644 --- a/tools/libclang/CMakeLists.txt +++ b/tools/libclang/CMakeLists.txt @@ -40,6 +40,7 @@ set(LIBS clangIndex clangLex clangSema + clangSerialization clangTooling ) -- cgit v1.2.3 From b1e9e90f5d1f8fd83845996e549368c11cf1f4ea Mon Sep 17 00:00:00 2001 From: Gabor Horvath Date: Sat, 15 Dec 2018 13:20:33 +0000 Subject: [analyzer] Assume that we always have a SubEngine available The removed codepath was dead. Differential Revision: https://reviews.llvm.org/D55697 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349266 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Core/PathSensitive/ProgramState.h | 8 +-- .../Checkers/AnalysisOrderChecker.cpp | 2 +- lib/StaticAnalyzer/Core/CallEvent.cpp | 8 +-- lib/StaticAnalyzer/Core/ExprEngine.cpp | 4 +- lib/StaticAnalyzer/Core/ProgramState.cpp | 59 +++++++++------------- lib/StaticAnalyzer/Core/RegionStore.cpp | 8 ++- lib/StaticAnalyzer/Core/SValBuilder.cpp | 2 +- lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp | 2 +- 8 files changed, 40 insertions(+), 53 deletions(-) diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h index f544204497..c3a7028d87 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h @@ -555,15 +555,15 @@ public: MemRegionManager& getRegionManager() { return svalBuilder->getRegionManager(); } - const MemRegionManager& getRegionManager() const { + const MemRegionManager &getRegionManager() const { return svalBuilder->getRegionManager(); } CallEventManager &getCallEventManager() { return *CallEventMgr; } - StoreManager& getStoreManager() { return *StoreMgr; } - ConstraintManager& getConstraintManager() { return *ConstraintMgr; } - SubEngine* getOwningEngine() { return Eng; } + StoreManager &getStoreManager() { return *StoreMgr; } + ConstraintManager &getConstraintManager() { return *ConstraintMgr; } + SubEngine &getOwningEngine() { return *Eng; } ProgramStateRef removeDeadBindings(ProgramStateRef St, const StackFrameContext *LCtx, diff --git a/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp b/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp index f9cf97e508..590bdd20ad 100644 --- a/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp @@ -56,7 +56,7 @@ class AnalysisOrderChecker bool isCallbackEnabled(ProgramStateRef State, StringRef CallbackName) const { AnalyzerOptions &Opts = State->getStateManager().getOwningEngine() - ->getAnalysisManager().getAnalyzerOptions(); + .getAnalysisManager().getAnalyzerOptions(); return isCallbackEnabled(Opts, CallbackName); } diff --git a/lib/StaticAnalyzer/Core/CallEvent.cpp b/lib/StaticAnalyzer/Core/CallEvent.cpp index 8d9338b21c..20baa30265 100644 --- a/lib/StaticAnalyzer/Core/CallEvent.cpp +++ b/lib/StaticAnalyzer/Core/CallEvent.cpp @@ -550,15 +550,15 @@ RuntimeDefinition AnyFunctionCall::getRuntimeDefinition() const { return RuntimeDefinition(Decl); } - SubEngine *Engine = getState()->getStateManager().getOwningEngine(); - AnalyzerOptions &Opts = Engine->getAnalysisManager().options; + SubEngine &Engine = getState()->getStateManager().getOwningEngine(); + AnalyzerOptions &Opts = Engine.getAnalysisManager().options; // Try to get CTU definition only if CTUDir is provided. if (!Opts.IsNaiveCTUEnabled) return {}; cross_tu::CrossTranslationUnitContext &CTUCtx = - *Engine->getCrossTranslationUnitContext(); + *Engine.getCrossTranslationUnitContext(); llvm::Expected CTUDeclOrError = CTUCtx.getCrossTUDefinition(FD, Opts.CTUDir, Opts.CTUIndexName, Opts.DisplayCTUProgress); @@ -1087,7 +1087,7 @@ bool ObjCMethodCall::canBeOverridenInSubclass(ObjCInterfaceDecl *IDecl, Selector Sel) const { assert(IDecl); AnalysisManager &AMgr = - getState()->getStateManager().getOwningEngine()->getAnalysisManager(); + getState()->getStateManager().getOwningEngine().getAnalysisManager(); // If the class interface is declared inside the main file, assume it is not // subcassed. // TODO: It could actually be subclassed if the subclass is private as well. diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp index 45d0df7ae4..151eef56fe 100644 --- a/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -2951,8 +2951,8 @@ struct DOTGraphTraits : public DefaultDOTGraphTraits { DOTGraphTraits (bool isSimple = false) : DefaultDOTGraphTraits(isSimple) {} static bool nodeHasBugReport(const ExplodedNode *N) { - BugReporter &BR = static_cast( - N->getState()->getStateManager().getOwningEngine())->getBugReporter(); + BugReporter &BR = static_cast( + N->getState()->getStateManager().getOwningEngine()).getBugReporter(); const auto EQClasses = llvm::make_range(BR.EQClasses_begin(), BR.EQClasses_end()); diff --git a/lib/StaticAnalyzer/Core/ProgramState.cpp b/lib/StaticAnalyzer/Core/ProgramState.cpp index ceb4fbdf78..2e2e2ec94f 100644 --- a/lib/StaticAnalyzer/Core/ProgramState.cpp +++ b/lib/StaticAnalyzer/Core/ProgramState.cpp @@ -125,8 +125,8 @@ ProgramStateRef ProgramState::bindLoc(Loc LV, ProgramStateRef newState = makeWithStore(Mgr.StoreMgr->Bind(getStore(), LV, V)); const MemRegion *MR = LV.getAsRegion(); - if (MR && Mgr.getOwningEngine() && notifyChanges) - return Mgr.getOwningEngine()->processRegionChange(newState, MR, LCtx); + if (MR && notifyChanges) + return Mgr.getOwningEngine().processRegionChange(newState, MR, LCtx); return newState; } @@ -138,9 +138,7 @@ ProgramState::bindDefaultInitial(SVal loc, SVal V, const MemRegion *R = loc.castAs().getRegion(); const StoreRef &newStore = Mgr.StoreMgr->BindDefaultInitial(getStore(), R, V); ProgramStateRef new_state = makeWithStore(newStore); - return Mgr.getOwningEngine() - ? Mgr.getOwningEngine()->processRegionChange(new_state, R, LCtx) - : new_state; + return Mgr.getOwningEngine().processRegionChange(new_state, R, LCtx); } ProgramStateRef @@ -149,9 +147,7 @@ ProgramState::bindDefaultZero(SVal loc, const LocationContext *LCtx) const { const MemRegion *R = loc.castAs().getRegion(); const StoreRef &newStore = Mgr.StoreMgr->BindDefaultZero(getStore(), R); ProgramStateRef new_state = makeWithStore(newStore); - return Mgr.getOwningEngine() - ? Mgr.getOwningEngine()->processRegionChange(new_state, R, LCtx) - : new_state; + return Mgr.getOwningEngine().processRegionChange(new_state, R, LCtx); } typedef ArrayRef RegionList; @@ -196,41 +192,34 @@ ProgramState::invalidateRegionsImpl(ValueList Values, RegionAndSymbolInvalidationTraits *ITraits, const CallEvent *Call) const { ProgramStateManager &Mgr = getStateManager(); - SubEngine* Eng = Mgr.getOwningEngine(); + SubEngine &Eng = Mgr.getOwningEngine(); - InvalidatedSymbols Invalidated; + InvalidatedSymbols InvalidatedSyms; if (!IS) - IS = &Invalidated; + IS = &InvalidatedSyms; RegionAndSymbolInvalidationTraits ITraitsLocal; if (!ITraits) ITraits = &ITraitsLocal; - if (Eng) { - StoreManager::InvalidatedRegions TopLevelInvalidated; - StoreManager::InvalidatedRegions Invalidated; - const StoreRef &newStore - = Mgr.StoreMgr->invalidateRegions(getStore(), Values, E, Count, LCtx, Call, - *IS, *ITraits, &TopLevelInvalidated, - &Invalidated); - - ProgramStateRef newState = makeWithStore(newStore); - - if (CausedByPointerEscape) { - newState = Eng->notifyCheckersOfPointerEscape(newState, IS, - TopLevelInvalidated, - Call, - *ITraits); - } + StoreManager::InvalidatedRegions TopLevelInvalidated; + StoreManager::InvalidatedRegions Invalidated; + const StoreRef &newStore + = Mgr.StoreMgr->invalidateRegions(getStore(), Values, E, Count, LCtx, Call, + *IS, *ITraits, &TopLevelInvalidated, + &Invalidated); + + ProgramStateRef newState = makeWithStore(newStore); - return Eng->processRegionChanges(newState, IS, TopLevelInvalidated, - Invalidated, LCtx, Call); + if (CausedByPointerEscape) { + newState = Eng.notifyCheckersOfPointerEscape(newState, IS, + TopLevelInvalidated, + Call, + *ITraits); } - const StoreRef &newStore = - Mgr.StoreMgr->invalidateRegions(getStore(), Values, E, Count, LCtx, Call, - *IS, *ITraits, nullptr, nullptr); - return makeWithStore(newStore); + return Eng.processRegionChanges(newState, IS, TopLevelInvalidated, + Invalidated, LCtx, Call); } ProgramStateRef ProgramState::killBinding(Loc LV) const { @@ -474,7 +463,7 @@ void ProgramState::print(raw_ostream &Out, printTaint(Out, NL); // Print checker-specific data. - Mgr.getOwningEngine()->printState(Out, this, NL, Sep, LC); + Mgr.getOwningEngine().printState(Out, this, NL, Sep, LC); } void ProgramState::printDOT(raw_ostream &Out, @@ -503,7 +492,7 @@ void ProgramState::dumpTaint() const { } AnalysisManager& ProgramState::getAnalysisManager() const { - return stateMgr->getOwningEngine()->getAnalysisManager(); + return stateMgr->getOwningEngine().getAnalysisManager(); } //===----------------------------------------------------------------------===// diff --git a/lib/StaticAnalyzer/Core/RegionStore.cpp b/lib/StaticAnalyzer/Core/RegionStore.cpp index f5eb9b5e72..b2339be4f2 100644 --- a/lib/StaticAnalyzer/Core/RegionStore.cpp +++ b/lib/StaticAnalyzer/Core/RegionStore.cpp @@ -347,11 +347,9 @@ public: : StoreManager(mgr), Features(f), RBFactory(mgr.getAllocator()), CBFactory(mgr.getAllocator()), SmallStructLimit(0) { - if (SubEngine *Eng = StateMgr.getOwningEngine()) { - AnalyzerOptions &Options = Eng->getAnalysisManager().options; - SmallStructLimit = - Options.RegionStoreSmallStructLimit; - } + SubEngine &Eng = StateMgr.getOwningEngine(); + AnalyzerOptions &Options = Eng.getAnalysisManager().options; + SmallStructLimit = Options.RegionStoreSmallStructLimit; } diff --git a/lib/StaticAnalyzer/Core/SValBuilder.cpp b/lib/StaticAnalyzer/Core/SValBuilder.cpp index 617c4ba27d..aeb27fefed 100644 --- a/lib/StaticAnalyzer/Core/SValBuilder.cpp +++ b/lib/StaticAnalyzer/Core/SValBuilder.cpp @@ -384,7 +384,7 @@ SVal SValBuilder::makeSymExprValNN(BinaryOperator::Opcode Op, // TODO: When the Max Complexity is reached, we should conjure a symbol // instead of generating an Unknown value and propagate the taint info to it. const unsigned MaxComp = StateMgr.getOwningEngine() - ->getAnalysisManager() + .getAnalysisManager() .options.MaxSymbolComplexity; if (symLHS && symRHS && diff --git a/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp b/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp index 2f6a0c8ffc..fc57cecac9 100644 --- a/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp +++ b/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp @@ -454,7 +454,7 @@ static Optional tryRearrange(ProgramStateRef State, QualType SingleTy; auto &Opts = - StateMgr.getOwningEngine()->getAnalysisManager().getAnalyzerOptions(); + StateMgr.getOwningEngine().getAnalysisManager().getAnalyzerOptions(); // FIXME: After putting complexity threshold to the symbols we can always // rearrange additive operations but rearrange comparisons only if -- cgit v1.2.3 From 8242d2a1d43d4a75401567c382fbada25e8b1399 Mon Sep 17 00:00:00 2001 From: Kristof Umann Date: Sat, 15 Dec 2018 15:44:05 +0000 Subject: [analyzer] Prefer returns values to out-params in CheckerRegistry.cpp Renaming collectCheckers to getEnabledCheckers Changing the functionality to acquire all enabled checkers, rather then collect checkers for a specific CheckerOptInfo (for example, collecting all checkers for { "core", true }, which meant enabling all checkers from the core package, which was an unnecessary complication). Removing CheckerOptInfo, instead of storing whether the option was claimed via a field, we handle errors immediately, as getEnabledCheckers can now access a DiagnosticsEngine. Realize that the remaining information it stored is directly accessible through AnalyzerOptions.CheckerControlList. Fix a test with -analyzer-disable-checker -verify accidentally left in. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349274 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../clang/StaticAnalyzer/Core/CheckerRegistry.h | 7 +- .../StaticAnalyzer/Frontend/FrontendActions.h | 3 +- lib/FrontendTool/ExecuteCompilerInvocation.cpp | 3 +- lib/StaticAnalyzer/Core/CheckerRegistry.cpp | 143 +++++++-------------- .../Frontend/CheckerRegistration.cpp | 5 +- test/Analysis/disable-all-checks.c | 15 ++- 6 files changed, 75 insertions(+), 101 deletions(-) diff --git a/include/clang/StaticAnalyzer/Core/CheckerRegistry.h b/include/clang/StaticAnalyzer/Core/CheckerRegistry.h index 740754090d..589a258852 100644 --- a/include/clang/StaticAnalyzer/Core/CheckerRegistry.h +++ b/include/clang/StaticAnalyzer/Core/CheckerRegistry.h @@ -95,6 +95,7 @@ public: }; using CheckerInfoList = std::vector; + using CheckerInfoSet = llvm::SetVector; private: template @@ -131,9 +132,13 @@ public: /// Prints the name and description of all checkers in this registry. /// This output is not intended to be machine-parseable. void printHelp(raw_ostream &out, size_t maxNameChars = 30) const; - void printList(raw_ostream &out, const AnalyzerOptions &opts) const; + void printList(raw_ostream &out, const AnalyzerOptions &opts, + DiagnosticsEngine &diags) const; private: + CheckerInfoSet getEnabledCheckers(const AnalyzerOptions &Opts, + DiagnosticsEngine &diags) const; + mutable CheckerInfoList Checkers; mutable llvm::StringMap Packages; }; diff --git a/include/clang/StaticAnalyzer/Frontend/FrontendActions.h b/include/clang/StaticAnalyzer/Frontend/FrontendActions.h index 8fd45bf102..20b71ef69d 100644 --- a/include/clang/StaticAnalyzer/Frontend/FrontendActions.h +++ b/include/clang/StaticAnalyzer/Frontend/FrontendActions.h @@ -54,7 +54,8 @@ private: void printCheckerHelp(raw_ostream &OS, ArrayRef plugins); void printEnabledCheckerList(raw_ostream &OS, ArrayRef plugins, - const AnalyzerOptions &opts); + const AnalyzerOptions &opts, + DiagnosticsEngine &diags); void printAnalyzerConfigList(raw_ostream &OS); } // end GR namespace diff --git a/lib/FrontendTool/ExecuteCompilerInvocation.cpp b/lib/FrontendTool/ExecuteCompilerInvocation.cpp index df360de857..5239a7e6f8 100644 --- a/lib/FrontendTool/ExecuteCompilerInvocation.cpp +++ b/lib/FrontendTool/ExecuteCompilerInvocation.cpp @@ -246,7 +246,8 @@ bool ExecuteCompilerInvocation(CompilerInstance *Clang) { if (Clang->getAnalyzerOpts()->ShowEnabledCheckerList) { ento::printEnabledCheckerList(llvm::outs(), Clang->getFrontendOpts().Plugins, - *Clang->getAnalyzerOpts()); + *Clang->getAnalyzerOpts(), + Clang->getDiagnostics()); } // Honor -analyzer-config-help. diff --git a/lib/StaticAnalyzer/Core/CheckerRegistry.cpp b/lib/StaticAnalyzer/Core/CheckerRegistry.cpp index e7dfac7479..6a38e96efc 100644 --- a/lib/StaticAnalyzer/Core/CheckerRegistry.cpp +++ b/lib/StaticAnalyzer/Core/CheckerRegistry.cpp @@ -18,50 +18,11 @@ #include "llvm/ADT/StringRef.h" #include "llvm/Support/raw_ostream.h" #include -#include -#include using namespace clang; using namespace ento; -static const char PackageSeparator = '.'; - -using CheckerInfoSet = llvm::SetVector; - -namespace { -/// Represents a request to include or exclude a checker or package from a -/// specific analysis run. -/// -/// \sa CheckerRegistry::initializeManager -class CheckerOptInfo { - StringRef Name; - bool Enable; - bool Claimed; - -public: - CheckerOptInfo(StringRef name, bool enable) - : Name(name), Enable(enable), Claimed(false) { } - - StringRef getName() const { return Name; } - bool isEnabled() const { return Enable; } - bool isDisabled() const { return !isEnabled(); } - - bool isClaimed() const { return Claimed; } - bool isUnclaimed() const { return !isClaimed(); } - void claim() { Claimed = true; } -}; - -} // end of anonymous namespace - -static SmallVector -getCheckerOptList(const AnalyzerOptions &opts) { - SmallVector checkerOpts; - for (unsigned i = 0, e = opts.CheckersControlList.size(); i != e; ++i) { - const std::pair &opt = opts.CheckersControlList[i]; - checkerOpts.push_back(CheckerOptInfo(opt.first, opt.second)); - } - return checkerOpts; -} +static constexpr char PackageSeparator = '.'; static bool checkerNameLT(const CheckerRegistry::CheckerInfo &a, const CheckerRegistry::CheckerInfo &b) { @@ -85,40 +46,49 @@ static bool isInPackage(const CheckerRegistry::CheckerInfo &checker, return false; } -/// Collects the checkers for the supplied \p opt option into \p collected. -static void collectCheckers(const CheckerRegistry::CheckerInfoList &checkers, - const llvm::StringMap &packageSizes, - CheckerOptInfo &opt, CheckerInfoSet &collected) { - // Use a binary search to find the possible start of the package. - CheckerRegistry::CheckerInfo packageInfo(nullptr, opt.getName(), ""); - auto end = checkers.cend(); - auto i = std::lower_bound(checkers.cbegin(), end, packageInfo, checkerNameLT); - - // If we didn't even find a possible package, give up. - if (i == end) - return; - - // If what we found doesn't actually start the package, give up. - if (!isInPackage(*i, opt.getName())) - return; - - // There is at least one checker in the package; claim the option. - opt.claim(); - - // See how large the package is. - // If the package doesn't exist, assume the option refers to a single checker. - size_t size = 1; - llvm::StringMap::const_iterator packageSize = - packageSizes.find(opt.getName()); - if (packageSize != packageSizes.end()) - size = packageSize->getValue(); - - // Step through all the checkers in the package. - for (auto checkEnd = i+size; i != checkEnd; ++i) - if (opt.isEnabled()) - collected.insert(&*i); - else - collected.remove(&*i); +CheckerRegistry::CheckerInfoSet CheckerRegistry::getEnabledCheckers( + const AnalyzerOptions &Opts, + DiagnosticsEngine &diags) const { + + assert(std::is_sorted(Checkers.begin(), Checkers.end(), checkerNameLT) && + "In order to efficiently gather checkers, this function expects them " + "to be already sorted!"); + + CheckerInfoSet enabledCheckers; + const auto end = Checkers.cend(); + + for (const std::pair &opt : Opts.CheckersControlList) { + // Use a binary search to find the possible start of the package. + CheckerRegistry::CheckerInfo packageInfo(nullptr, opt.first, ""); + auto firstRelatedChecker = + std::lower_bound(Checkers.cbegin(), end, packageInfo, checkerNameLT); + + if (firstRelatedChecker == end || + !isInPackage(*firstRelatedChecker, opt.first)) { + diags.Report(diag::err_unknown_analyzer_checker) << opt.first; + diags.Report(diag::note_suggest_disabling_all_checkers); + return {}; + } + + // See how large the package is. + // If the package doesn't exist, assume the option refers to a single + // checker. + size_t size = 1; + llvm::StringMap::const_iterator packageSize = + Packages.find(opt.first); + if (packageSize != Packages.end()) + size = packageSize->getValue(); + + // Step through all the checkers in the package. + for (auto lastRelatedChecker = firstRelatedChecker+size; + firstRelatedChecker != lastRelatedChecker; ++firstRelatedChecker) + if (opt.second) + enabledCheckers.insert(&*firstRelatedChecker); + else + enabledCheckers.remove(&*firstRelatedChecker); + } + + return enabledCheckers; } void CheckerRegistry::addChecker(InitializationFunction fn, StringRef name, @@ -140,26 +110,14 @@ void CheckerRegistry::initializeManager(CheckerManager &checkerMgr, // Sort checkers for efficient collection. llvm::sort(Checkers, checkerNameLT); - llvm::SmallVector checkerOpts = getCheckerOptList(Opts); // Collect checkers enabled by the options. - CheckerInfoSet enabledCheckers; - for (auto &i : checkerOpts) - collectCheckers(Checkers, Packages, i, enabledCheckers); + CheckerInfoSet enabledCheckers = getEnabledCheckers(Opts, diags); // Initialize the CheckerManager with all enabled checkers. - for (const auto *i :enabledCheckers) { + for (const auto *i : enabledCheckers) { checkerMgr.setCurrentCheckName(CheckName(i->FullName)); i->Initialize(checkerMgr); } - - for (unsigned i = 0, e = checkerOpts.size(); i != e; ++i) { - if (checkerOpts[i].isUnclaimed()) { - diags.Report(diag::err_unknown_analyzer_checker) - << checkerOpts[i].getName(); - diags.Report(diag::note_suggest_disabling_all_checkers); - } - - } } void CheckerRegistry::validateCheckerOptions(const AnalyzerOptions &opts, @@ -222,14 +180,13 @@ void CheckerRegistry::printHelp(raw_ostream &out, } void CheckerRegistry::printList(raw_ostream &out, - const AnalyzerOptions &opts) const { + const AnalyzerOptions &opts, + DiagnosticsEngine &diags) const { + // Sort checkers for efficient collection. llvm::sort(Checkers, checkerNameLT); - llvm::SmallVector checkerOpts = getCheckerOptList(opts); // Collect checkers enabled by the options. - CheckerInfoSet enabledCheckers; - for (auto &i : checkerOpts) - collectCheckers(Checkers, Packages, i, enabledCheckers); + CheckerInfoSet enabledCheckers = getEnabledCheckers(opts, diags); for (const auto *i : enabledCheckers) out << i->FullName << '\n'; diff --git a/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp b/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp index 70997e34a1..c82ed12cac 100644 --- a/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp +++ b/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp @@ -130,10 +130,11 @@ void ento::printCheckerHelp(raw_ostream &out, ArrayRef plugins) { void ento::printEnabledCheckerList(raw_ostream &out, ArrayRef plugins, - const AnalyzerOptions &opts) { + const AnalyzerOptions &opts, + DiagnosticsEngine &diags) { out << "OVERVIEW: Clang Static Analyzer Enabled Checkers List\n\n"; - ClangCheckerRegistry(plugins).printList(out, opts); + ClangCheckerRegistry(plugins).printList(out, opts, diags); } void ento::printAnalyzerConfigList(raw_ostream &out) { diff --git a/test/Analysis/disable-all-checks.c b/test/Analysis/disable-all-checks.c index eb55799c25..fba53429ab 100644 --- a/test/Analysis/disable-all-checks.c +++ b/test/Analysis/disable-all-checks.c @@ -1,9 +1,18 @@ -// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-store=region -analyzer-disable-all-checks -verify %s -// RUN: %clang_analyze_cc1 -analyzer-disable-all-checks -analyzer-checker=core -analyzer-store=region -verify %s +// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-store=region \ +// RUN: -analyzer-disable-all-checks -verify %s +// +// RUN: %clang_analyze_cc1 -analyzer-disable-all-checks -analyzer-checker=core \ +// RUN: -analyzer-store=region -verify %s +// // RUN: %clang_analyze_cc1 -analyzer-disable-all-checks -verify %s -// RUN: not %clang_analyze_cc1 -analyzer-checker=core -analyzer-store=region -analyzer-disable-checker -verify %s 2>&1 | FileCheck %s +// +// RUN: not %clang_analyze_cc1 -analyzer-checker=core -analyzer-store=region \ +// RUN: -analyzer-disable-checker non.existant.Checker -verify %s 2>&1 \ +// RUN: | FileCheck %s +// // expected-no-diagnostics +// CHECK: no analyzer checkers are associated with 'non.existant.Checker' // CHECK: use -analyzer-disable-all-checks to disable all static analyzer checkers int buggy() { int x = 0; -- cgit v1.2.3 From 308797c8199bdd0b71b257eb14d759edf217c71c Mon Sep 17 00:00:00 2001 From: Kristof Umann Date: Sat, 15 Dec 2018 16:23:51 +0000 Subject: [analyzer][NFC] Move CheckerRegistry from the Core directory to Frontend ClangCheckerRegistry is a very non-obvious, poorly documented, weird concept. It derives from CheckerRegistry, and is placed in lib/StaticAnalyzer/Frontend, whereas it's base is located in lib/StaticAnalyzer/Core. It was, from what I can imagine, used to circumvent the problem that the registry functions of the checkers are located in the clangStaticAnalyzerCheckers library, but that library depends on clangStaticAnalyzerCore. However, clangStaticAnalyzerFrontend depends on both of those libraries. One can make the observation however, that CheckerRegistry has no place in Core, it isn't used there at all! The only place where it is used is Frontend, which is where it ultimately belongs. This move implies that since include/clang/StaticAnalyzer/Checkers/ClangCheckers.h only contained a single function: class CheckerRegistry; void registerBuiltinCheckers(CheckerRegistry ®istry); it had to re purposed, as CheckerRegistry is no longer available to clangStaticAnalyzerCheckers. It was renamed to BuiltinCheckerRegistration.h, which actually describes it a lot better -- it does not contain the registration functions for checkers, but only those generated by the tblgen files. Differential Revision: https://reviews.llvm.org/D54436 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349275 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Checkers/BuiltinCheckerRegistration.h | 37 ++++ .../clang/StaticAnalyzer/Checkers/ClangCheckers.h | 22 --- .../clang/StaticAnalyzer/Core/CheckerRegistry.h | 150 ---------------- .../StaticAnalyzer/Frontend/CheckerRegistry.h | 150 ++++++++++++++++ .../Checkers/AnalysisOrderChecker.cpp | 2 +- .../Checkers/AnalyzerStatsChecker.cpp | 2 +- lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp | 2 +- .../Checkers/ArrayBoundCheckerV2.cpp | 2 +- .../Checkers/BasicObjCFoundationChecks.cpp | 2 +- .../Checkers/BlockInCriticalSectionChecker.cpp | 2 +- .../Checkers/BoolAssignmentChecker.cpp | 2 +- .../Checkers/BuiltinFunctionChecker.cpp | 2 +- lib/StaticAnalyzer/Checkers/CMakeLists.txt | 1 - lib/StaticAnalyzer/Checkers/CStringChecker.cpp | 2 +- .../Checkers/CStringSyntaxChecker.cpp | 2 +- .../Checkers/CXXSelfAssignmentChecker.cpp | 2 +- .../Checkers/CallAndMessageChecker.cpp | 2 +- lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp | 2 +- .../Checkers/CastToStructChecker.cpp | 2 +- lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp | 2 +- .../Checkers/CheckObjCInstMethSignature.cpp | 2 +- .../Checkers/CheckSecuritySyntaxOnly.cpp | 2 +- lib/StaticAnalyzer/Checkers/CheckSizeofPointer.cpp | 2 +- .../Checkers/CheckerDocumentation.cpp | 2 +- lib/StaticAnalyzer/Checkers/ChrootChecker.cpp | 2 +- lib/StaticAnalyzer/Checkers/ClangCheckers.cpp | 32 ---- lib/StaticAnalyzer/Checkers/ClangSACheckers.h | 37 ---- lib/StaticAnalyzer/Checkers/CloneChecker.cpp | 2 +- lib/StaticAnalyzer/Checkers/ConversionChecker.cpp | 2 +- lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp | 2 +- lib/StaticAnalyzer/Checkers/DebugCheckers.cpp | 2 +- .../Checkers/DeleteWithNonVirtualDtorChecker.cpp | 2 +- lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp | 2 +- .../Checkers/DirectIvarAssignment.cpp | 2 +- lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp | 2 +- lib/StaticAnalyzer/Checkers/DynamicTypeChecker.cpp | 2 +- .../Checkers/DynamicTypePropagation.cpp | 2 +- .../Checkers/EnumCastOutOfRangeChecker.cpp | 2 +- .../Checkers/ExprInspectionChecker.cpp | 2 +- .../Checkers/FixedAddressChecker.cpp | 2 +- .../Checkers/GCDAntipatternChecker.cpp | 2 +- lib/StaticAnalyzer/Checkers/GTestChecker.cpp | 2 +- .../Checkers/GenericTaintChecker.cpp | 2 +- .../Checkers/IdenticalExprChecker.cpp | 2 +- .../Checkers/InnerPointerChecker.cpp | 2 +- lib/StaticAnalyzer/Checkers/IteratorChecker.cpp | 2 +- .../Checkers/IvarInvalidationChecker.cpp | 2 +- .../Checkers/LLVMConventionsChecker.cpp | 2 +- .../Checkers/LocalizationChecker.cpp | 2 +- .../Checkers/MPI-Checker/MPIChecker.cpp | 2 +- .../Checkers/MacOSKeychainAPIChecker.cpp | 2 +- lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp | 2 +- lib/StaticAnalyzer/Checkers/MallocChecker.cpp | 2 +- .../Checkers/MallocOverflowSecurityChecker.cpp | 2 +- .../Checkers/MallocSizeofChecker.cpp | 2 +- .../Checkers/MmapWriteExecChecker.cpp | 2 +- lib/StaticAnalyzer/Checkers/MoveChecker.cpp | 2 +- .../Checkers/NSAutoreleasePoolChecker.cpp | 2 +- lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp | 2 +- .../Checkers/NoReturnFunctionChecker.cpp | 2 +- .../Checkers/NonNullParamChecker.cpp | 2 +- .../Checkers/NonnullGlobalConstantsChecker.cpp | 2 +- lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp | 2 +- .../Checkers/NumberObjectConversionChecker.cpp | 2 +- lib/StaticAnalyzer/Checkers/ObjCAtSyncChecker.cpp | 2 +- .../Checkers/ObjCAutoreleaseWriteChecker.cpp | 2 +- .../Checkers/ObjCContainersASTChecker.cpp | 2 +- .../Checkers/ObjCContainersChecker.cpp | 2 +- .../Checkers/ObjCMissingSuperCallChecker.cpp | 2 +- .../Checkers/ObjCPropertyChecker.cpp | 2 +- .../Checkers/ObjCSelfInitChecker.cpp | 2 +- .../Checkers/ObjCSuperDeallocChecker.cpp | 2 +- .../Checkers/ObjCUnusedIVarsChecker.cpp | 2 +- lib/StaticAnalyzer/Checkers/PaddingChecker.cpp | 2 +- .../Checkers/PointerArithChecker.cpp | 2 +- lib/StaticAnalyzer/Checkers/PointerSubChecker.cpp | 2 +- lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp | 2 +- .../RetainCountChecker/RetainCountChecker.h | 2 +- .../Checkers/ReturnPointerRangeChecker.cpp | 2 +- lib/StaticAnalyzer/Checkers/ReturnUndefChecker.cpp | 2 +- .../Checkers/RunLoopAutoreleaseLeakChecker.cpp | 2 +- .../Checkers/SimpleStreamChecker.cpp | 2 +- .../Checkers/StackAddrEscapeChecker.cpp | 2 +- .../Checkers/StdLibraryFunctionsChecker.cpp | 2 +- lib/StaticAnalyzer/Checkers/StreamChecker.cpp | 2 +- lib/StaticAnalyzer/Checkers/TaintTesterChecker.cpp | 2 +- .../Checkers/TestAfterDivZeroChecker.cpp | 2 +- lib/StaticAnalyzer/Checkers/TraversalChecker.cpp | 2 +- .../Checkers/TrustNonnullChecker.cpp | 2 +- lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp | 2 +- .../Checkers/UndefCapturedBlockVarChecker.cpp | 2 +- lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp | 2 +- .../Checkers/UndefinedArraySubscriptChecker.cpp | 2 +- .../Checkers/UndefinedAssignmentChecker.cpp | 2 +- .../UninitializedObjectChecker.cpp | 2 +- .../UninitializedObject/UninitializedPointee.cpp | 1 - lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp | 2 +- .../Checkers/UnreachableCodeChecker.cpp | 2 +- lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp | 2 +- lib/StaticAnalyzer/Checkers/ValistChecker.cpp | 2 +- lib/StaticAnalyzer/Checkers/VforkChecker.cpp | 2 +- lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp | 2 +- lib/StaticAnalyzer/Core/CMakeLists.txt | 1 - lib/StaticAnalyzer/Core/CheckerRegistry.cpp | 193 --------------------- lib/StaticAnalyzer/Frontend/CMakeLists.txt | 1 + .../Frontend/CheckerRegistration.cpp | 11 +- lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp | 193 +++++++++++++++++++++ .../StaticAnalyzer/RegisterCustomCheckersTest.cpp | 2 +- 108 files changed, 484 insertions(+), 535 deletions(-) create mode 100644 include/clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h delete mode 100644 include/clang/StaticAnalyzer/Checkers/ClangCheckers.h delete mode 100644 include/clang/StaticAnalyzer/Core/CheckerRegistry.h create mode 100644 include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h delete mode 100644 lib/StaticAnalyzer/Checkers/ClangCheckers.cpp delete mode 100644 lib/StaticAnalyzer/Checkers/ClangSACheckers.h delete mode 100644 lib/StaticAnalyzer/Core/CheckerRegistry.cpp create mode 100644 lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp diff --git a/include/clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h b/include/clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h new file mode 100644 index 0000000000..cd42cd6cd3 --- /dev/null +++ b/include/clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h @@ -0,0 +1,37 @@ +//===--- ClangSACheckers.h - Registration functions for Checkers *- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Declares the registation functions for the checkers defined in +// libclangStaticAnalyzerCheckers. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_CLANGSACHECKERS_H +#define LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_CLANGSACHECKERS_H + +#include "clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h" + +namespace clang { + +namespace ento { +class CheckerManager; +class CheckerRegistry; + +#define GET_CHECKERS +#define CHECKER(FULLNAME, CLASS, HELPTEXT) \ + void register##CLASS(CheckerManager &mgr); +#include "clang/StaticAnalyzer/Checkers/Checkers.inc" +#undef CHECKER +#undef GET_CHECKERS + +} // end ento namespace + +} // end clang namespace + +#endif diff --git a/include/clang/StaticAnalyzer/Checkers/ClangCheckers.h b/include/clang/StaticAnalyzer/Checkers/ClangCheckers.h deleted file mode 100644 index cf0a30a73d..0000000000 --- a/include/clang/StaticAnalyzer/Checkers/ClangCheckers.h +++ /dev/null @@ -1,22 +0,0 @@ -//===--- ClangCheckers.h - Provides builtin checkers ------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_STATICANALYZER_CHECKERS_CLANGCHECKERS_H -#define LLVM_CLANG_STATICANALYZER_CHECKERS_CLANGCHECKERS_H - -namespace clang { -namespace ento { -class CheckerRegistry; - -void registerBuiltinCheckers(CheckerRegistry ®istry); - -} // end namespace ento -} // end namespace clang - -#endif diff --git a/include/clang/StaticAnalyzer/Core/CheckerRegistry.h b/include/clang/StaticAnalyzer/Core/CheckerRegistry.h deleted file mode 100644 index 589a258852..0000000000 --- a/include/clang/StaticAnalyzer/Core/CheckerRegistry.h +++ /dev/null @@ -1,150 +0,0 @@ -//===- CheckerRegistry.h - Maintains all available checkers -----*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_STATICANALYZER_CORE_CHECKERREGISTRY_H -#define LLVM_CLANG_STATICANALYZER_CORE_CHECKERREGISTRY_H - -#include "clang/Basic/LLVM.h" -#include "clang/StaticAnalyzer/Core/CheckerManager.h" -#include "llvm/ADT/StringMap.h" -#include "llvm/ADT/StringRef.h" -#include -#include - -// FIXME: move this information to an HTML file in docs/. -// At the very least, a checker plugin is a dynamic library that exports -// clang_analyzerAPIVersionString. This should be defined as follows: -// -// extern "C" -// const char clang_analyzerAPIVersionString[] = -// CLANG_ANALYZER_API_VERSION_STRING; -// -// This is used to check whether the current version of the analyzer is known to -// be incompatible with a plugin. Plugins with incompatible version strings, -// or without a version string at all, will not be loaded. -// -// To add a custom checker to the analyzer, the plugin must also define the -// function clang_registerCheckers. For example: -// -// extern "C" -// void clang_registerCheckers (CheckerRegistry ®istry) { -// registry.addChecker("example.MainCallChecker", -// "Disallows calls to functions called main"); -// } -// -// The first method argument is the full name of the checker, including its -// enclosing package. By convention, the registered name of a checker is the -// name of the associated class (the template argument). -// The second method argument is a short human-readable description of the -// checker. -// -// The clang_registerCheckers function may add any number of checkers to the -// registry. If any checkers require additional initialization, use the three- -// argument form of CheckerRegistry::addChecker. -// -// To load a checker plugin, specify the full path to the dynamic library as -// the argument to the -load option in the cc1 frontend. You can then enable -// your custom checker using the -analyzer-checker: -// -// clang -cc1 -load -analyze -// -analyzer-checker= -// -// For a complete working example, see examples/analyzer-plugin. - -#ifndef CLANG_ANALYZER_API_VERSION_STRING -// FIXME: The Clang version string is not particularly granular; -// the analyzer infrastructure can change a lot between releases. -// Unfortunately, this string has to be statically embedded in each plugin, -// so we can't just use the functions defined in Version.h. -#include "clang/Basic/Version.h" -#define CLANG_ANALYZER_API_VERSION_STRING CLANG_VERSION_STRING -#endif - -namespace clang { - -class AnalyzerOptions; -class DiagnosticsEngine; - -namespace ento { - -/// Manages a set of available checkers for running a static analysis. -/// The checkers are organized into packages by full name, where including -/// a package will recursively include all subpackages and checkers within it. -/// For example, the checker "core.builtin.NoReturnFunctionChecker" will be -/// included if initializeManager() is called with an option of "core", -/// "core.builtin", or the full name "core.builtin.NoReturnFunctionChecker". -class CheckerRegistry { -public: - /// Initialization functions perform any necessary setup for a checker. - /// They should include a call to CheckerManager::registerChecker. - using InitializationFunction = void (*)(CheckerManager &); - - struct CheckerInfo { - InitializationFunction Initialize; - StringRef FullName; - StringRef Desc; - - CheckerInfo(InitializationFunction fn, StringRef name, StringRef desc) - : Initialize(fn), FullName(name), Desc(desc) {} - }; - - using CheckerInfoList = std::vector; - using CheckerInfoSet = llvm::SetVector; - -private: - template - static void initializeManager(CheckerManager &mgr) { - mgr.registerChecker(); - } - -public: - /// Adds a checker to the registry. Use this non-templated overload when your - /// checker requires custom initialization. - void addChecker(InitializationFunction fn, StringRef fullName, - StringRef desc); - - /// Adds a checker to the registry. Use this templated overload when your - /// checker does not require any custom initialization. - template - void addChecker(StringRef fullName, StringRef desc) { - // Avoid MSVC's Compiler Error C2276: - // http://msdn.microsoft.com/en-us/library/850cstw1(v=VS.80).aspx - addChecker(&CheckerRegistry::initializeManager, fullName, desc); - } - - /// Initializes a CheckerManager by calling the initialization functions for - /// all checkers specified by the given CheckerOptInfo list. The order of this - /// list is significant; later options can be used to reverse earlier ones. - /// This can be used to exclude certain checkers in an included package. - void initializeManager(CheckerManager &mgr, const AnalyzerOptions &Opts, - DiagnosticsEngine &diags) const; - - /// Check if every option corresponds to a specific checker or package. - void validateCheckerOptions(const AnalyzerOptions &opts, - DiagnosticsEngine &diags) const; - - /// Prints the name and description of all checkers in this registry. - /// This output is not intended to be machine-parseable. - void printHelp(raw_ostream &out, size_t maxNameChars = 30) const; - void printList(raw_ostream &out, const AnalyzerOptions &opts, - DiagnosticsEngine &diags) const; - -private: - CheckerInfoSet getEnabledCheckers(const AnalyzerOptions &Opts, - DiagnosticsEngine &diags) const; - - mutable CheckerInfoList Checkers; - mutable llvm::StringMap Packages; -}; - -} // namespace ento - -} // namespace clang - -#endif // LLVM_CLANG_STATICANALYZER_CORE_CHECKERREGISTRY_H diff --git a/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h b/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h new file mode 100644 index 0000000000..589a258852 --- /dev/null +++ b/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h @@ -0,0 +1,150 @@ +//===- CheckerRegistry.h - Maintains all available checkers -----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_STATICANALYZER_CORE_CHECKERREGISTRY_H +#define LLVM_CLANG_STATICANALYZER_CORE_CHECKERREGISTRY_H + +#include "clang/Basic/LLVM.h" +#include "clang/StaticAnalyzer/Core/CheckerManager.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" +#include +#include + +// FIXME: move this information to an HTML file in docs/. +// At the very least, a checker plugin is a dynamic library that exports +// clang_analyzerAPIVersionString. This should be defined as follows: +// +// extern "C" +// const char clang_analyzerAPIVersionString[] = +// CLANG_ANALYZER_API_VERSION_STRING; +// +// This is used to check whether the current version of the analyzer is known to +// be incompatible with a plugin. Plugins with incompatible version strings, +// or without a version string at all, will not be loaded. +// +// To add a custom checker to the analyzer, the plugin must also define the +// function clang_registerCheckers. For example: +// +// extern "C" +// void clang_registerCheckers (CheckerRegistry ®istry) { +// registry.addChecker("example.MainCallChecker", +// "Disallows calls to functions called main"); +// } +// +// The first method argument is the full name of the checker, including its +// enclosing package. By convention, the registered name of a checker is the +// name of the associated class (the template argument). +// The second method argument is a short human-readable description of the +// checker. +// +// The clang_registerCheckers function may add any number of checkers to the +// registry. If any checkers require additional initialization, use the three- +// argument form of CheckerRegistry::addChecker. +// +// To load a checker plugin, specify the full path to the dynamic library as +// the argument to the -load option in the cc1 frontend. You can then enable +// your custom checker using the -analyzer-checker: +// +// clang -cc1 -load -analyze +// -analyzer-checker= +// +// For a complete working example, see examples/analyzer-plugin. + +#ifndef CLANG_ANALYZER_API_VERSION_STRING +// FIXME: The Clang version string is not particularly granular; +// the analyzer infrastructure can change a lot between releases. +// Unfortunately, this string has to be statically embedded in each plugin, +// so we can't just use the functions defined in Version.h. +#include "clang/Basic/Version.h" +#define CLANG_ANALYZER_API_VERSION_STRING CLANG_VERSION_STRING +#endif + +namespace clang { + +class AnalyzerOptions; +class DiagnosticsEngine; + +namespace ento { + +/// Manages a set of available checkers for running a static analysis. +/// The checkers are organized into packages by full name, where including +/// a package will recursively include all subpackages and checkers within it. +/// For example, the checker "core.builtin.NoReturnFunctionChecker" will be +/// included if initializeManager() is called with an option of "core", +/// "core.builtin", or the full name "core.builtin.NoReturnFunctionChecker". +class CheckerRegistry { +public: + /// Initialization functions perform any necessary setup for a checker. + /// They should include a call to CheckerManager::registerChecker. + using InitializationFunction = void (*)(CheckerManager &); + + struct CheckerInfo { + InitializationFunction Initialize; + StringRef FullName; + StringRef Desc; + + CheckerInfo(InitializationFunction fn, StringRef name, StringRef desc) + : Initialize(fn), FullName(name), Desc(desc) {} + }; + + using CheckerInfoList = std::vector; + using CheckerInfoSet = llvm::SetVector; + +private: + template + static void initializeManager(CheckerManager &mgr) { + mgr.registerChecker(); + } + +public: + /// Adds a checker to the registry. Use this non-templated overload when your + /// checker requires custom initialization. + void addChecker(InitializationFunction fn, StringRef fullName, + StringRef desc); + + /// Adds a checker to the registry. Use this templated overload when your + /// checker does not require any custom initialization. + template + void addChecker(StringRef fullName, StringRef desc) { + // Avoid MSVC's Compiler Error C2276: + // http://msdn.microsoft.com/en-us/library/850cstw1(v=VS.80).aspx + addChecker(&CheckerRegistry::initializeManager, fullName, desc); + } + + /// Initializes a CheckerManager by calling the initialization functions for + /// all checkers specified by the given CheckerOptInfo list. The order of this + /// list is significant; later options can be used to reverse earlier ones. + /// This can be used to exclude certain checkers in an included package. + void initializeManager(CheckerManager &mgr, const AnalyzerOptions &Opts, + DiagnosticsEngine &diags) const; + + /// Check if every option corresponds to a specific checker or package. + void validateCheckerOptions(const AnalyzerOptions &opts, + DiagnosticsEngine &diags) const; + + /// Prints the name and description of all checkers in this registry. + /// This output is not intended to be machine-parseable. + void printHelp(raw_ostream &out, size_t maxNameChars = 30) const; + void printList(raw_ostream &out, const AnalyzerOptions &opts, + DiagnosticsEngine &diags) const; + +private: + CheckerInfoSet getEnabledCheckers(const AnalyzerOptions &Opts, + DiagnosticsEngine &diags) const; + + mutable CheckerInfoList Checkers; + mutable llvm::StringMap Packages; +}; + +} // namespace ento + +} // namespace clang + +#endif // LLVM_CLANG_STATICANALYZER_CORE_CHECKERREGISTRY_H diff --git a/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp b/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp index 590bdd20ad..b5d0f6620a 100644 --- a/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp @@ -14,7 +14,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/ExprCXX.h" #include "clang/Analysis/CFGStmtMap.h" #include "clang/StaticAnalyzer/Core/Checker.h" diff --git a/lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp b/lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp index aadc6bac8d..5e01012401 100644 --- a/lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp @@ -8,7 +8,7 @@ //===----------------------------------------------------------------------===// // This file reports various statistics about analyzer visitation. //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/DeclObjC.h" #include "clang/Basic/SourceManager.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" diff --git a/lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp b/lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp index c092610afe..20f3092fdb 100644 --- a/lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" diff --git a/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp b/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp index 933380d494..26887be9f2 100644 --- a/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp +++ b/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/CharUnits.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" diff --git a/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp b/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp index d7f305aea9..577b5349f6 100644 --- a/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp +++ b/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp @@ -13,7 +13,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/ASTContext.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/Expr.h" diff --git a/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp b/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp index c31f2794df..00d08b371f 100644 --- a/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp @@ -15,7 +15,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" diff --git a/lib/StaticAnalyzer/Checkers/BoolAssignmentChecker.cpp b/lib/StaticAnalyzer/Checkers/BoolAssignmentChecker.cpp index f26f73129e..3008eddd39 100644 --- a/lib/StaticAnalyzer/Checkers/BoolAssignmentChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/BoolAssignmentChecker.cpp @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" diff --git a/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp b/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp index 3541b7f269..f98027942e 100644 --- a/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp @@ -11,7 +11,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/Basic/Builtins.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" diff --git a/lib/StaticAnalyzer/Checkers/CMakeLists.txt b/lib/StaticAnalyzer/Checkers/CMakeLists.txt index 47dbac634a..10fb0bd353 100644 --- a/lib/StaticAnalyzer/Checkers/CMakeLists.txt +++ b/lib/StaticAnalyzer/Checkers/CMakeLists.txt @@ -22,7 +22,6 @@ add_clang_library(clangStaticAnalyzerCheckers CheckSizeofPointer.cpp CheckerDocumentation.cpp ChrootChecker.cpp - ClangCheckers.cpp CloneChecker.cpp ConversionChecker.cpp CXXSelfAssignmentChecker.cpp diff --git a/lib/StaticAnalyzer/Checkers/CStringChecker.cpp b/lib/StaticAnalyzer/Checkers/CStringChecker.cpp index ed68df93be..9d0ccb0390 100644 --- a/lib/StaticAnalyzer/Checkers/CStringChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/CStringChecker.cpp @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "InterCheckerAPI.h" #include "clang/Basic/CharInfo.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" diff --git a/lib/StaticAnalyzer/Checkers/CStringSyntaxChecker.cpp b/lib/StaticAnalyzer/Checkers/CStringSyntaxChecker.cpp index b486443ac0..bbeb41c5f3 100644 --- a/lib/StaticAnalyzer/Checkers/CStringSyntaxChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/CStringSyntaxChecker.cpp @@ -12,7 +12,7 @@ // of bytes to copy. // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/Expr.h" #include "clang/AST/OperationKinds.h" #include "clang/AST/StmtVisitor.h" diff --git a/lib/StaticAnalyzer/Checkers/CXXSelfAssignmentChecker.cpp b/lib/StaticAnalyzer/Checkers/CXXSelfAssignmentChecker.cpp index d1d37c75df..0b539e1188 100644 --- a/lib/StaticAnalyzer/Checkers/CXXSelfAssignmentChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/CXXSelfAssignmentChecker.cpp @@ -18,7 +18,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" diff --git a/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp b/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp index 400b719cfd..ef30dc74c3 100644 --- a/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/ParentMap.h" #include "clang/Basic/TargetInfo.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" diff --git a/lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp b/lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp index 059553b219..5deb62d323 100644 --- a/lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp @@ -11,7 +11,7 @@ // whether the size of the symbolic region is a multiple of the size of T. // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/CharUnits.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" diff --git a/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp b/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp index 00e9033557..2bd3879627 100644 --- a/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp @@ -13,7 +13,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/RecursiveASTVisitor.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" diff --git a/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp b/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp index faee82895b..eeff47ba82 100644 --- a/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp +++ b/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp @@ -28,7 +28,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/Attr.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/Expr.h" diff --git a/lib/StaticAnalyzer/Checkers/CheckObjCInstMethSignature.cpp b/lib/StaticAnalyzer/Checkers/CheckObjCInstMethSignature.cpp index cc4c0c3db8..fe6715595e 100644 --- a/lib/StaticAnalyzer/Checkers/CheckObjCInstMethSignature.cpp +++ b/lib/StaticAnalyzer/Checkers/CheckObjCInstMethSignature.cpp @@ -13,7 +13,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/ASTContext.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/Type.h" diff --git a/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp b/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp index 87d7d90ee2..a4f782c68f 100644 --- a/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp +++ b/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp @@ -11,7 +11,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/StmtVisitor.h" #include "clang/Analysis/AnalysisDeclContext.h" #include "clang/Basic/TargetInfo.h" diff --git a/lib/StaticAnalyzer/Checkers/CheckSizeofPointer.cpp b/lib/StaticAnalyzer/Checkers/CheckSizeofPointer.cpp index e079a8cb12..7688b713b0 100644 --- a/lib/StaticAnalyzer/Checkers/CheckSizeofPointer.cpp +++ b/lib/StaticAnalyzer/Checkers/CheckSizeofPointer.cpp @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/StmtVisitor.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" #include "clang/StaticAnalyzer/Core/Checker.h" diff --git a/lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp b/lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp index e5f2937300..44fac0278b 100644 --- a/lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp +++ b/lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" diff --git a/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp b/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp index b38992b0e0..673608db1a 100644 --- a/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp @@ -11,7 +11,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" diff --git a/lib/StaticAnalyzer/Checkers/ClangCheckers.cpp b/lib/StaticAnalyzer/Checkers/ClangCheckers.cpp deleted file mode 100644 index d12e421d31..0000000000 --- a/lib/StaticAnalyzer/Checkers/ClangCheckers.cpp +++ /dev/null @@ -1,32 +0,0 @@ -//===--- ClangCheckers.h - Provides builtin checkers ------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "clang/StaticAnalyzer/Checkers/ClangCheckers.h" -#include "clang/StaticAnalyzer/Core/CheckerRegistry.h" - -// FIXME: This is only necessary as long as there are checker registration -// functions that do additional work besides mgr.registerChecker(). -// The only checkers that currently do this are: -// - NSAutoreleasePoolChecker -// - NSErrorChecker -// - ObjCAtSyncChecker -// It's probably worth including this information in Checkers.td to minimize -// boilerplate code. -#include "ClangSACheckers.h" - -using namespace clang; -using namespace ento; - -void ento::registerBuiltinCheckers(CheckerRegistry ®istry) { -#define GET_CHECKERS -#define CHECKER(FULLNAME, CLASS, HELPTEXT) \ - registry.addChecker(register##CLASS, FULLNAME, HELPTEXT); -#include "clang/StaticAnalyzer/Checkers/Checkers.inc" -#undef GET_CHECKERS -} diff --git a/lib/StaticAnalyzer/Checkers/ClangSACheckers.h b/lib/StaticAnalyzer/Checkers/ClangSACheckers.h deleted file mode 100644 index cd42cd6cd3..0000000000 --- a/lib/StaticAnalyzer/Checkers/ClangSACheckers.h +++ /dev/null @@ -1,37 +0,0 @@ -//===--- ClangSACheckers.h - Registration functions for Checkers *- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Declares the registation functions for the checkers defined in -// libclangStaticAnalyzerCheckers. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_CLANGSACHECKERS_H -#define LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_CLANGSACHECKERS_H - -#include "clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h" - -namespace clang { - -namespace ento { -class CheckerManager; -class CheckerRegistry; - -#define GET_CHECKERS -#define CHECKER(FULLNAME, CLASS, HELPTEXT) \ - void register##CLASS(CheckerManager &mgr); -#include "clang/StaticAnalyzer/Checkers/Checkers.inc" -#undef CHECKER -#undef GET_CHECKERS - -} // end ento namespace - -} // end clang namespace - -#endif diff --git a/lib/StaticAnalyzer/Checkers/CloneChecker.cpp b/lib/StaticAnalyzer/Checkers/CloneChecker.cpp index 427b9c4ad2..89354b8660 100644 --- a/lib/StaticAnalyzer/Checkers/CloneChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/CloneChecker.cpp @@ -13,7 +13,7 @@ /// //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/Analysis/CloneDetection.h" #include "clang/Basic/Diagnostic.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" diff --git a/lib/StaticAnalyzer/Checkers/ConversionChecker.cpp b/lib/StaticAnalyzer/Checkers/ConversionChecker.cpp index 208f94451c..a5c67c2a5b 100644 --- a/lib/StaticAnalyzer/Checkers/ConversionChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/ConversionChecker.cpp @@ -24,7 +24,7 @@ // is an alternative to those checks. // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/ParentMap.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" diff --git a/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp b/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp index 7446eadf34..4e0f6d3bed 100644 --- a/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/ASTContext.h" #include "clang/AST/Attr.h" #include "clang/AST/ParentMap.h" diff --git a/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp b/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp index 60027f4a8b..5840ee7913 100644 --- a/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp +++ b/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp @@ -11,7 +11,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/Analysis/Analyses/Dominators.h" #include "clang/Analysis/Analyses/LiveVariables.h" #include "clang/Analysis/CallGraph.h" diff --git a/lib/StaticAnalyzer/Checkers/DeleteWithNonVirtualDtorChecker.cpp b/lib/StaticAnalyzer/Checkers/DeleteWithNonVirtualDtorChecker.cpp index 4d0ed7088c..adf5a8e77a 100644 --- a/lib/StaticAnalyzer/Checkers/DeleteWithNonVirtualDtorChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/DeleteWithNonVirtualDtorChecker.cpp @@ -21,7 +21,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" diff --git a/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp b/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp index 368d5ce357..d01a889d25 100644 --- a/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/ExprObjC.h" #include "clang/AST/ExprOpenMP.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" diff --git a/lib/StaticAnalyzer/Checkers/DirectIvarAssignment.cpp b/lib/StaticAnalyzer/Checkers/DirectIvarAssignment.cpp index 5efb9096f2..2a559422df 100644 --- a/lib/StaticAnalyzer/Checkers/DirectIvarAssignment.cpp +++ b/lib/StaticAnalyzer/Checkers/DirectIvarAssignment.cpp @@ -21,7 +21,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/Attr.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/StmtVisitor.h" diff --git a/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp b/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp index 5e10fa99fb..a220a0513e 100644 --- a/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" diff --git a/lib/StaticAnalyzer/Checkers/DynamicTypeChecker.cpp b/lib/StaticAnalyzer/Checkers/DynamicTypeChecker.cpp index 953994ddaa..803d7ae22a 100644 --- a/lib/StaticAnalyzer/Checkers/DynamicTypeChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/DynamicTypeChecker.cpp @@ -17,7 +17,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" diff --git a/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp b/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp index f83a0ec075..31d4eebe89 100644 --- a/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp +++ b/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp @@ -21,7 +21,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/ParentMap.h" #include "clang/AST/RecursiveASTVisitor.h" #include "clang/Basic/Builtins.h" diff --git a/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp b/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp index f3a35daf07..4e51cffaa7 100644 --- a/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp @@ -20,7 +20,7 @@ // enumeration value //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" diff --git a/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp b/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp index 0752dba49c..742266bfe6 100644 --- a/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Checkers/SValExplainer.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" diff --git a/lib/StaticAnalyzer/Checkers/FixedAddressChecker.cpp b/lib/StaticAnalyzer/Checkers/FixedAddressChecker.cpp index 059203fca7..165a4e4490 100644 --- a/lib/StaticAnalyzer/Checkers/FixedAddressChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/FixedAddressChecker.cpp @@ -13,7 +13,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" diff --git a/lib/StaticAnalyzer/Checkers/GCDAntipatternChecker.cpp b/lib/StaticAnalyzer/Checkers/GCDAntipatternChecker.cpp index 5cb51b01f0..248b9c3f76 100644 --- a/lib/StaticAnalyzer/Checkers/GCDAntipatternChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/GCDAntipatternChecker.cpp @@ -29,7 +29,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" diff --git a/lib/StaticAnalyzer/Checkers/GTestChecker.cpp b/lib/StaticAnalyzer/Checkers/GTestChecker.cpp index 3ef95e673b..818716dd60 100644 --- a/lib/StaticAnalyzer/Checkers/GTestChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/GTestChecker.cpp @@ -13,7 +13,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/Expr.h" #include "clang/Basic/LangOptions.h" #include "clang/StaticAnalyzer/Core/Checker.h" diff --git a/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp b/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp index 899586745a..fbc8ff3512 100644 --- a/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp @@ -14,7 +14,7 @@ // aggressively, even if the involved symbols are under constrained. // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/Attr.h" #include "clang/Basic/Builtins.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" diff --git a/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp b/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp index f102ca96a5..4c2a229428 100644 --- a/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp @@ -16,7 +16,7 @@ /// //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/RecursiveASTVisitor.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" diff --git a/lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp b/lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp index b6c2ed549d..a4f47d727a 100644 --- a/lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp @@ -14,7 +14,7 @@ //===----------------------------------------------------------------------===// #include "AllocationState.h" -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "InterCheckerAPI.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h" diff --git a/lib/StaticAnalyzer/Checkers/IteratorChecker.cpp b/lib/StaticAnalyzer/Checkers/IteratorChecker.cpp index 0b8f677a4a..e719e19d68 100644 --- a/lib/StaticAnalyzer/Checkers/IteratorChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/IteratorChecker.cpp @@ -66,7 +66,7 @@ // making an assumption e.g. `S1 + n == S2 + m` we store `S1 - S2 == m - n` as // a constraint which we later retrieve when doing an actual comparison. -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/DeclTemplate.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" diff --git a/lib/StaticAnalyzer/Checkers/IvarInvalidationChecker.cpp b/lib/StaticAnalyzer/Checkers/IvarInvalidationChecker.cpp index 2fb627184e..aade62fd74 100644 --- a/lib/StaticAnalyzer/Checkers/IvarInvalidationChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/IvarInvalidationChecker.cpp @@ -28,7 +28,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/Attr.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/StmtVisitor.h" diff --git a/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp b/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp index 18618d0459..df238f2b2e 100644 --- a/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/StmtVisitor.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" diff --git a/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp b/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp index 103a33d39f..eda39efeca 100644 --- a/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp @@ -15,7 +15,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/Attr.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclObjC.h" diff --git a/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.cpp b/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.cpp index 3f89c33cde..28c6898f79 100644 --- a/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.cpp @@ -16,7 +16,7 @@ //===----------------------------------------------------------------------===// #include "MPIChecker.h" -#include "../ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" namespace clang { namespace ento { diff --git a/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp b/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp index f5c7d52f4e..06e27fc571 100644 --- a/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp @@ -12,7 +12,7 @@ // to be freed using a call to SecKeychainItemFreeContent. //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" diff --git a/lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp b/lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp index dfdec23d26..f5976d7da4 100644 --- a/lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp @@ -15,7 +15,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/Basic/TargetInfo.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" diff --git a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp index 8e88fadd37..ae1b1fc837 100644 --- a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "InterCheckerAPI.h" #include "clang/AST/Attr.h" #include "clang/AST/ParentMap.h" diff --git a/lib/StaticAnalyzer/Checkers/MallocOverflowSecurityChecker.cpp b/lib/StaticAnalyzer/Checkers/MallocOverflowSecurityChecker.cpp index 4e45a37fd8..d02ed48bce 100644 --- a/lib/StaticAnalyzer/Checkers/MallocOverflowSecurityChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/MallocOverflowSecurityChecker.cpp @@ -18,7 +18,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/EvaluatedExprVisitor.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" #include "clang/StaticAnalyzer/Core/Checker.h" diff --git a/lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp b/lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp index 80a3fbe1a4..bb245d82bc 100644 --- a/lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp @@ -13,7 +13,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/StmtVisitor.h" #include "clang/AST/TypeLoc.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" diff --git a/lib/StaticAnalyzer/Checkers/MmapWriteExecChecker.cpp b/lib/StaticAnalyzer/Checkers/MmapWriteExecChecker.cpp index 0d63cfe937..e3b24f20b0 100644 --- a/lib/StaticAnalyzer/Checkers/MmapWriteExecChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/MmapWriteExecChecker.cpp @@ -13,7 +13,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" diff --git a/lib/StaticAnalyzer/Checkers/MoveChecker.cpp b/lib/StaticAnalyzer/Checkers/MoveChecker.cpp index d387e0bea7..0eaa75d645 100644 --- a/lib/StaticAnalyzer/Checkers/MoveChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/MoveChecker.cpp @@ -13,8 +13,8 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" #include "clang/AST/ExprCXX.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" diff --git a/lib/StaticAnalyzer/Checkers/NSAutoreleasePoolChecker.cpp b/lib/StaticAnalyzer/Checkers/NSAutoreleasePoolChecker.cpp index 0e7894788c..4ed1b25cb0 100644 --- a/lib/StaticAnalyzer/Checkers/NSAutoreleasePoolChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/NSAutoreleasePoolChecker.cpp @@ -15,7 +15,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclObjC.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" diff --git a/lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp b/lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp index 2bd68b625c..06c43c6b94 100644 --- a/lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp @@ -15,7 +15,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclObjC.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" diff --git a/lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp b/lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp index 44674eb4d7..83d4b5b075 100644 --- a/lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/Attr.h" #include "clang/Analysis/SelectorExtras.h" #include "clang/StaticAnalyzer/Core/Checker.h" diff --git a/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp b/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp index a97eab4e82..3c4363b685 100644 --- a/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp @@ -15,7 +15,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/Attr.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" diff --git a/lib/StaticAnalyzer/Checkers/NonnullGlobalConstantsChecker.cpp b/lib/StaticAnalyzer/Checkers/NonnullGlobalConstantsChecker.cpp index 6f3180eb83..ce9e950aa9 100644 --- a/lib/StaticAnalyzer/Checkers/NonnullGlobalConstantsChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/NonnullGlobalConstantsChecker.cpp @@ -21,7 +21,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" diff --git a/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp b/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp index ce656d5201..e535d1ae27 100644 --- a/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp @@ -25,7 +25,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" diff --git a/lib/StaticAnalyzer/Checkers/NumberObjectConversionChecker.cpp b/lib/StaticAnalyzer/Checkers/NumberObjectConversionChecker.cpp index f808739347..4e3a7205f1 100644 --- a/lib/StaticAnalyzer/Checkers/NumberObjectConversionChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/NumberObjectConversionChecker.cpp @@ -26,7 +26,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" diff --git a/lib/StaticAnalyzer/Checkers/ObjCAtSyncChecker.cpp b/lib/StaticAnalyzer/Checkers/ObjCAtSyncChecker.cpp index f56a795636..185b57575c 100644 --- a/lib/StaticAnalyzer/Checkers/ObjCAtSyncChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/ObjCAtSyncChecker.cpp @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/StmtObjC.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" diff --git a/lib/StaticAnalyzer/Checkers/ObjCAutoreleaseWriteChecker.cpp b/lib/StaticAnalyzer/Checkers/ObjCAutoreleaseWriteChecker.cpp index 81bcda51b8..0424958f8e 100644 --- a/lib/StaticAnalyzer/Checkers/ObjCAutoreleaseWriteChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/ObjCAutoreleaseWriteChecker.cpp @@ -27,7 +27,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" diff --git a/lib/StaticAnalyzer/Checkers/ObjCContainersASTChecker.cpp b/lib/StaticAnalyzer/Checkers/ObjCContainersASTChecker.cpp index e4737fcee7..34ce47823d 100644 --- a/lib/StaticAnalyzer/Checkers/ObjCContainersASTChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/ObjCContainersASTChecker.cpp @@ -11,7 +11,7 @@ // 'CFDictionary', 'CFSet' APIs. // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/StmtVisitor.h" #include "clang/Analysis/AnalysisDeclContext.h" #include "clang/Basic/TargetInfo.h" diff --git a/lib/StaticAnalyzer/Checkers/ObjCContainersChecker.cpp b/lib/StaticAnalyzer/Checkers/ObjCContainersChecker.cpp index faaf2493d4..1c8c0d8ded 100644 --- a/lib/StaticAnalyzer/Checkers/ObjCContainersChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/ObjCContainersChecker.cpp @@ -16,7 +16,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/ParentMap.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" diff --git a/lib/StaticAnalyzer/Checkers/ObjCMissingSuperCallChecker.cpp b/lib/StaticAnalyzer/Checkers/ObjCMissingSuperCallChecker.cpp index d01c6ae6e0..d383302b27 100644 --- a/lib/StaticAnalyzer/Checkers/ObjCMissingSuperCallChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/ObjCMissingSuperCallChecker.cpp @@ -13,7 +13,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprObjC.h" diff --git a/lib/StaticAnalyzer/Checkers/ObjCPropertyChecker.cpp b/lib/StaticAnalyzer/Checkers/ObjCPropertyChecker.cpp index dfd2c9afe7..018d3fcfce 100644 --- a/lib/StaticAnalyzer/Checkers/ObjCPropertyChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/ObjCPropertyChecker.cpp @@ -15,7 +15,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" #include "clang/StaticAnalyzer/Core/Checker.h" diff --git a/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp b/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp index 6295204373..efa8042207 100644 --- a/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp @@ -36,7 +36,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/ParentMap.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" diff --git a/lib/StaticAnalyzer/Checkers/ObjCSuperDeallocChecker.cpp b/lib/StaticAnalyzer/Checkers/ObjCSuperDeallocChecker.cpp index f8c24245e3..9058784dd3 100644 --- a/lib/StaticAnalyzer/Checkers/ObjCSuperDeallocChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/ObjCSuperDeallocChecker.cpp @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" diff --git a/lib/StaticAnalyzer/Checkers/ObjCUnusedIVarsChecker.cpp b/lib/StaticAnalyzer/Checkers/ObjCUnusedIVarsChecker.cpp index 375b2cdfc7..7f7b453160 100644 --- a/lib/StaticAnalyzer/Checkers/ObjCUnusedIVarsChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/ObjCUnusedIVarsChecker.cpp @@ -13,7 +13,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/Attr.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/Expr.h" diff --git a/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp b/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp index dc361ad537..211db392bf 100644 --- a/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/CharUnits.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/RecordLayout.h" diff --git a/lib/StaticAnalyzer/Checkers/PointerArithChecker.cpp b/lib/StaticAnalyzer/Checkers/PointerArithChecker.cpp index af242845f0..de3a16ebc7 100644 --- a/lib/StaticAnalyzer/Checkers/PointerArithChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/PointerArithChecker.cpp @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/ExprCXX.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" diff --git a/lib/StaticAnalyzer/Checkers/PointerSubChecker.cpp b/lib/StaticAnalyzer/Checkers/PointerSubChecker.cpp index 9aa5348e4c..41490e45f2 100644 --- a/lib/StaticAnalyzer/Checkers/PointerSubChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/PointerSubChecker.cpp @@ -13,7 +13,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" diff --git a/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp b/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp index 10ab952e06..66cc372788 100644 --- a/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h index 0f43e8f5dd..151aa49ed4 100644 --- a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h +++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h @@ -15,7 +15,7 @@ #ifndef LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_RETAINCOUNTCHECKER_H #define LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_RETAINCOUNTCHECKER_H -#include "../ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "RetainCountDiagnostics.h" #include "clang/AST/Attr.h" #include "clang/AST/DeclCXX.h" diff --git a/lib/StaticAnalyzer/Checkers/ReturnPointerRangeChecker.cpp b/lib/StaticAnalyzer/Checkers/ReturnPointerRangeChecker.cpp index 1952715a9b..17ef395316 100644 --- a/lib/StaticAnalyzer/Checkers/ReturnPointerRangeChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/ReturnPointerRangeChecker.cpp @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" diff --git a/lib/StaticAnalyzer/Checkers/ReturnUndefChecker.cpp b/lib/StaticAnalyzer/Checkers/ReturnUndefChecker.cpp index e866f06ebb..3e0613e8ba 100644 --- a/lib/StaticAnalyzer/Checkers/ReturnUndefChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/ReturnUndefChecker.cpp @@ -13,7 +13,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" diff --git a/lib/StaticAnalyzer/Checkers/RunLoopAutoreleaseLeakChecker.cpp b/lib/StaticAnalyzer/Checkers/RunLoopAutoreleaseLeakChecker.cpp index 3f3477b928..cf03b3c211 100644 --- a/lib/StaticAnalyzer/Checkers/RunLoopAutoreleaseLeakChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/RunLoopAutoreleaseLeakChecker.cpp @@ -23,7 +23,7 @@ //===----------------------------------------------------------------------===// // -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclObjC.h" #include "clang/ASTMatchers/ASTMatchFinder.h" diff --git a/lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp b/lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp index ab4b4d3bd9..819d437e68 100644 --- a/lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp @@ -15,7 +15,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" diff --git a/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp b/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp index 5c5c6a163a..0f53d826a5 100644 --- a/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/ExprCXX.h" #include "clang/Basic/SourceManager.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" diff --git a/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp b/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp index 2f9f5d2d9c..6478128ce9 100644 --- a/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp @@ -51,7 +51,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" diff --git a/lib/StaticAnalyzer/Checkers/StreamChecker.cpp b/lib/StaticAnalyzer/Checkers/StreamChecker.cpp index b383411068..92647f0327 100644 --- a/lib/StaticAnalyzer/Checkers/StreamChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/StreamChecker.cpp @@ -11,7 +11,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" diff --git a/lib/StaticAnalyzer/Checkers/TaintTesterChecker.cpp b/lib/StaticAnalyzer/Checkers/TaintTesterChecker.cpp index 2e0529015c..3aa8e95d0a 100644 --- a/lib/StaticAnalyzer/Checkers/TaintTesterChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/TaintTesterChecker.cpp @@ -10,7 +10,7 @@ // This checker can be used for testing how taint data is propagated. // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" diff --git a/lib/StaticAnalyzer/Checkers/TestAfterDivZeroChecker.cpp b/lib/StaticAnalyzer/Checkers/TestAfterDivZeroChecker.cpp index 6429ea9413..527e371571 100644 --- a/lib/StaticAnalyzer/Checkers/TestAfterDivZeroChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/TestAfterDivZeroChecker.cpp @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" diff --git a/lib/StaticAnalyzer/Checkers/TraversalChecker.cpp b/lib/StaticAnalyzer/Checkers/TraversalChecker.cpp index f72fb9eaab..2f06469bb2 100644 --- a/lib/StaticAnalyzer/Checkers/TraversalChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/TraversalChecker.cpp @@ -11,7 +11,7 @@ // as it builds the ExplodedGraph. // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/ParentMap.h" #include "clang/AST/StmtObjC.h" #include "clang/StaticAnalyzer/Core/Checker.h" diff --git a/lib/StaticAnalyzer/Checkers/TrustNonnullChecker.cpp b/lib/StaticAnalyzer/Checkers/TrustNonnullChecker.cpp index 515c98cd11..5e777803af 100644 --- a/lib/StaticAnalyzer/Checkers/TrustNonnullChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/TrustNonnullChecker.cpp @@ -19,7 +19,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/Analysis/SelectorExtras.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" diff --git a/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp b/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp index 9e75bba5eb..d7fad4e475 100644 --- a/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" diff --git a/lib/StaticAnalyzer/Checkers/UndefCapturedBlockVarChecker.cpp b/lib/StaticAnalyzer/Checkers/UndefCapturedBlockVarChecker.cpp index 6a93c10c76..8a625227b8 100644 --- a/lib/StaticAnalyzer/Checkers/UndefCapturedBlockVarChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/UndefCapturedBlockVarChecker.cpp @@ -11,7 +11,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/Attr.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" diff --git a/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp b/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp index f30f32e959..624cff6048 100644 --- a/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" diff --git a/lib/StaticAnalyzer/Checkers/UndefinedArraySubscriptChecker.cpp b/lib/StaticAnalyzer/Checkers/UndefinedArraySubscriptChecker.cpp index 5a704eb41c..1d78d7cebd 100644 --- a/lib/StaticAnalyzer/Checkers/UndefinedArraySubscriptChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/UndefinedArraySubscriptChecker.cpp @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/DeclCXX.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" diff --git a/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp b/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp index a0bc857c49..8e10bfdd2f 100644 --- a/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" diff --git a/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp b/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp index 94f664ab93..208e303e82 100644 --- a/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp @@ -18,7 +18,7 @@ // //===----------------------------------------------------------------------===// -#include "../ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "UninitializedObject.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" diff --git a/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp b/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp index ae53f00b0b..aead59c7bf 100644 --- a/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp +++ b/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp @@ -15,7 +15,6 @@ // //===----------------------------------------------------------------------===// -#include "../ClangSACheckers.h" #include "UninitializedObject.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" diff --git a/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp b/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp index baf9aa0b57..bab0c12704 100644 --- a/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/Basic/TargetInfo.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" diff --git a/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp b/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp index f879891703..16b4d5e925 100644 --- a/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp @@ -13,7 +13,7 @@ // A similar flow-sensitive only check exists in Analysis/ReachableCode.cpp //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/ParentMap.h" #include "clang/Basic/Builtins.h" #include "clang/Basic/SourceManager.h" diff --git a/lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp b/lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp index 58ed463476..e458e0554e 100644 --- a/lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp @@ -14,7 +14,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/CharUnits.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" diff --git a/lib/StaticAnalyzer/Checkers/ValistChecker.cpp b/lib/StaticAnalyzer/Checkers/ValistChecker.cpp index 0812a1e3e5..748b226b7a 100644 --- a/lib/StaticAnalyzer/Checkers/ValistChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/ValistChecker.cpp @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" diff --git a/lib/StaticAnalyzer/Checkers/VforkChecker.cpp b/lib/StaticAnalyzer/Checkers/VforkChecker.cpp index 75aefc0e83..3ee9f1a07f 100644 --- a/lib/StaticAnalyzer/Checkers/VforkChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/VforkChecker.cpp @@ -25,7 +25,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h" diff --git a/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp b/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp index 902b325dec..5670631974 100644 --- a/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/DeclCXX.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" diff --git a/lib/StaticAnalyzer/Core/CMakeLists.txt b/lib/StaticAnalyzer/Core/CMakeLists.txt index 17334d841e..167f78af62 100644 --- a/lib/StaticAnalyzer/Core/CMakeLists.txt +++ b/lib/StaticAnalyzer/Core/CMakeLists.txt @@ -20,7 +20,6 @@ add_clang_library(clangStaticAnalyzerCore CheckerContext.cpp CheckerHelpers.cpp CheckerManager.cpp - CheckerRegistry.cpp CommonBugCategories.cpp ConstraintManager.cpp CoreEngine.cpp diff --git a/lib/StaticAnalyzer/Core/CheckerRegistry.cpp b/lib/StaticAnalyzer/Core/CheckerRegistry.cpp deleted file mode 100644 index 6a38e96efc..0000000000 --- a/lib/StaticAnalyzer/Core/CheckerRegistry.cpp +++ /dev/null @@ -1,193 +0,0 @@ -//===- CheckerRegistry.cpp - Maintains all available checkers -------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "clang/StaticAnalyzer/Core/CheckerRegistry.h" -#include "clang/Basic/Diagnostic.h" -#include "clang/Basic/LLVM.h" -#include "clang/StaticAnalyzer/Core/CheckerManager.h" -#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h" -#include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/SetVector.h" -#include "llvm/ADT/StringMap.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/Support/raw_ostream.h" -#include - -using namespace clang; -using namespace ento; - -static constexpr char PackageSeparator = '.'; - -static bool checkerNameLT(const CheckerRegistry::CheckerInfo &a, - const CheckerRegistry::CheckerInfo &b) { - return a.FullName < b.FullName; -} - -static bool isInPackage(const CheckerRegistry::CheckerInfo &checker, - StringRef packageName) { - // Does the checker's full name have the package as a prefix? - if (!checker.FullName.startswith(packageName)) - return false; - - // Is the package actually just the name of a specific checker? - if (checker.FullName.size() == packageName.size()) - return true; - - // Is the checker in the package (or a subpackage)? - if (checker.FullName[packageName.size()] == PackageSeparator) - return true; - - return false; -} - -CheckerRegistry::CheckerInfoSet CheckerRegistry::getEnabledCheckers( - const AnalyzerOptions &Opts, - DiagnosticsEngine &diags) const { - - assert(std::is_sorted(Checkers.begin(), Checkers.end(), checkerNameLT) && - "In order to efficiently gather checkers, this function expects them " - "to be already sorted!"); - - CheckerInfoSet enabledCheckers; - const auto end = Checkers.cend(); - - for (const std::pair &opt : Opts.CheckersControlList) { - // Use a binary search to find the possible start of the package. - CheckerRegistry::CheckerInfo packageInfo(nullptr, opt.first, ""); - auto firstRelatedChecker = - std::lower_bound(Checkers.cbegin(), end, packageInfo, checkerNameLT); - - if (firstRelatedChecker == end || - !isInPackage(*firstRelatedChecker, opt.first)) { - diags.Report(diag::err_unknown_analyzer_checker) << opt.first; - diags.Report(diag::note_suggest_disabling_all_checkers); - return {}; - } - - // See how large the package is. - // If the package doesn't exist, assume the option refers to a single - // checker. - size_t size = 1; - llvm::StringMap::const_iterator packageSize = - Packages.find(opt.first); - if (packageSize != Packages.end()) - size = packageSize->getValue(); - - // Step through all the checkers in the package. - for (auto lastRelatedChecker = firstRelatedChecker+size; - firstRelatedChecker != lastRelatedChecker; ++firstRelatedChecker) - if (opt.second) - enabledCheckers.insert(&*firstRelatedChecker); - else - enabledCheckers.remove(&*firstRelatedChecker); - } - - return enabledCheckers; -} - -void CheckerRegistry::addChecker(InitializationFunction fn, StringRef name, - StringRef desc) { - Checkers.push_back(CheckerInfo(fn, name, desc)); - - // Record the presence of the checker in its packages. - StringRef packageName, leafName; - std::tie(packageName, leafName) = name.rsplit(PackageSeparator); - while (!leafName.empty()) { - Packages[packageName] += 1; - std::tie(packageName, leafName) = packageName.rsplit(PackageSeparator); - } -} - -void CheckerRegistry::initializeManager(CheckerManager &checkerMgr, - const AnalyzerOptions &Opts, - DiagnosticsEngine &diags) const { - // Sort checkers for efficient collection. - llvm::sort(Checkers, checkerNameLT); - - // Collect checkers enabled by the options. - CheckerInfoSet enabledCheckers = getEnabledCheckers(Opts, diags); - - // Initialize the CheckerManager with all enabled checkers. - for (const auto *i : enabledCheckers) { - checkerMgr.setCurrentCheckName(CheckName(i->FullName)); - i->Initialize(checkerMgr); - } -} - -void CheckerRegistry::validateCheckerOptions(const AnalyzerOptions &opts, - DiagnosticsEngine &diags) const { - for (const auto &config : opts.Config) { - size_t pos = config.getKey().find(':'); - if (pos == StringRef::npos) - continue; - - bool hasChecker = false; - StringRef checkerName = config.getKey().substr(0, pos); - for (const auto &checker : Checkers) { - if (checker.FullName.startswith(checkerName) && - (checker.FullName.size() == pos || checker.FullName[pos] == '.')) { - hasChecker = true; - break; - } - } - if (!hasChecker) - diags.Report(diag::err_unknown_analyzer_checker) << checkerName; - } -} - -void CheckerRegistry::printHelp(raw_ostream &out, - size_t maxNameChars) const { - // FIXME: Alphabetical sort puts 'experimental' in the middle. - // Would it be better to name it '~experimental' or something else - // that's ASCIIbetically last? - llvm::sort(Checkers, checkerNameLT); - - // FIXME: Print available packages. - - out << "CHECKERS:\n"; - - // Find the maximum option length. - size_t optionFieldWidth = 0; - for (const auto &i : Checkers) { - // Limit the amount of padding we are willing to give up for alignment. - // Package.Name Description [Hidden] - size_t nameLength = i.FullName.size(); - if (nameLength <= maxNameChars) - optionFieldWidth = std::max(optionFieldWidth, nameLength); - } - - const size_t initialPad = 2; - for (const auto &i : Checkers) { - out.indent(initialPad) << i.FullName; - - int pad = optionFieldWidth - i.FullName.size(); - - // Break on long option names. - if (pad < 0) { - out << '\n'; - pad = optionFieldWidth + initialPad; - } - out.indent(pad + 2) << i.Desc; - - out << '\n'; - } -} - -void CheckerRegistry::printList(raw_ostream &out, - const AnalyzerOptions &opts, - DiagnosticsEngine &diags) const { - // Sort checkers for efficient collection. - llvm::sort(Checkers, checkerNameLT); - - // Collect checkers enabled by the options. - CheckerInfoSet enabledCheckers = getEnabledCheckers(opts, diags); - - for (const auto *i : enabledCheckers) - out << i->FullName << '\n'; -} diff --git a/lib/StaticAnalyzer/Frontend/CMakeLists.txt b/lib/StaticAnalyzer/Frontend/CMakeLists.txt index ff0a6e19fc..5e7dd8f18c 100644 --- a/lib/StaticAnalyzer/Frontend/CMakeLists.txt +++ b/lib/StaticAnalyzer/Frontend/CMakeLists.txt @@ -7,6 +7,7 @@ set(LLVM_LINK_COMPONENTS add_clang_library(clangStaticAnalyzerFrontend AnalysisConsumer.cpp CheckerRegistration.cpp + CheckerRegistry.cpp FrontendActions.cpp ModelConsumer.cpp ModelInjector.cpp diff --git a/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp b/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp index c82ed12cac..cc29613b50 100644 --- a/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp +++ b/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp @@ -14,10 +14,10 @@ #include "clang/StaticAnalyzer/Frontend/CheckerRegistration.h" #include "clang/Basic/Diagnostic.h" #include "clang/Frontend/FrontendDiagnostic.h" -#include "clang/StaticAnalyzer/Checkers/ClangCheckers.h" #include "clang/StaticAnalyzer/Core/AnalyzerOptions.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" -#include "clang/StaticAnalyzer/Core/CheckerRegistry.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" +#include "clang/StaticAnalyzer/Frontend/CheckerRegistry.h" #include "clang/StaticAnalyzer/Frontend/FrontendActions.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/DynamicLibrary.h" @@ -47,7 +47,12 @@ public: ClangCheckerRegistry::ClangCheckerRegistry(ArrayRef plugins, DiagnosticsEngine *diags) { - registerBuiltinCheckers(*this); +#define GET_CHECKERS +#define CHECKER(FULLNAME, CLASS, HELPTEXT) \ + addChecker(register##CLASS, FULLNAME, HELPTEXT); +#include "clang/StaticAnalyzer/Checkers/Checkers.inc" +#undef CHECKER +#undef GET_CHECKERS for (ArrayRef::iterator i = plugins.begin(), e = plugins.end(); i != e; ++i) { diff --git a/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp b/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp new file mode 100644 index 0000000000..d1931d3e6f --- /dev/null +++ b/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp @@ -0,0 +1,193 @@ +//===- CheckerRegistry.cpp - Maintains all available checkers -------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "clang/StaticAnalyzer/Frontend/CheckerRegistry.h" +#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/LLVM.h" +#include "clang/StaticAnalyzer/Core/CheckerManager.h" +#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SetVector.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/raw_ostream.h" +#include + +using namespace clang; +using namespace ento; + +static constexpr char PackageSeparator = '.'; + +static bool checkerNameLT(const CheckerRegistry::CheckerInfo &a, + const CheckerRegistry::CheckerInfo &b) { + return a.FullName < b.FullName; +} + +static bool isInPackage(const CheckerRegistry::CheckerInfo &checker, + StringRef packageName) { + // Does the checker's full name have the package as a prefix? + if (!checker.FullName.startswith(packageName)) + return false; + + // Is the package actually just the name of a specific checker? + if (checker.FullName.size() == packageName.size()) + return true; + + // Is the checker in the package (or a subpackage)? + if (checker.FullName[packageName.size()] == PackageSeparator) + return true; + + return false; +} + +CheckerRegistry::CheckerInfoSet CheckerRegistry::getEnabledCheckers( + const AnalyzerOptions &Opts, + DiagnosticsEngine &diags) const { + + assert(std::is_sorted(Checkers.begin(), Checkers.end(), checkerNameLT) && + "In order to efficiently gather checkers, this function expects them " + "to be already sorted!"); + + CheckerInfoSet enabledCheckers; + const auto end = Checkers.cend(); + + for (const std::pair &opt : Opts.CheckersControlList) { + // Use a binary search to find the possible start of the package. + CheckerRegistry::CheckerInfo packageInfo(nullptr, opt.first, ""); + auto firstRelatedChecker = + std::lower_bound(Checkers.cbegin(), end, packageInfo, checkerNameLT); + + if (firstRelatedChecker == end || + !isInPackage(*firstRelatedChecker, opt.first)) { + diags.Report(diag::err_unknown_analyzer_checker) << opt.first; + diags.Report(diag::note_suggest_disabling_all_checkers); + return {}; + } + + // See how large the package is. + // If the package doesn't exist, assume the option refers to a single + // checker. + size_t size = 1; + llvm::StringMap::const_iterator packageSize = + Packages.find(opt.first); + if (packageSize != Packages.end()) + size = packageSize->getValue(); + + // Step through all the checkers in the package. + for (auto lastRelatedChecker = firstRelatedChecker+size; + firstRelatedChecker != lastRelatedChecker; ++firstRelatedChecker) + if (opt.second) + enabledCheckers.insert(&*firstRelatedChecker); + else + enabledCheckers.remove(&*firstRelatedChecker); + } + + return enabledCheckers; +} + +void CheckerRegistry::addChecker(InitializationFunction fn, StringRef name, + StringRef desc) { + Checkers.push_back(CheckerInfo(fn, name, desc)); + + // Record the presence of the checker in its packages. + StringRef packageName, leafName; + std::tie(packageName, leafName) = name.rsplit(PackageSeparator); + while (!leafName.empty()) { + Packages[packageName] += 1; + std::tie(packageName, leafName) = packageName.rsplit(PackageSeparator); + } +} + +void CheckerRegistry::initializeManager(CheckerManager &checkerMgr, + const AnalyzerOptions &Opts, + DiagnosticsEngine &diags) const { + // Sort checkers for efficient collection. + llvm::sort(Checkers, checkerNameLT); + + // Collect checkers enabled by the options. + CheckerInfoSet enabledCheckers = getEnabledCheckers(Opts, diags); + + // Initialize the CheckerManager with all enabled checkers. + for (const auto *i : enabledCheckers) { + checkerMgr.setCurrentCheckName(CheckName(i->FullName)); + i->Initialize(checkerMgr); + } +} + +void CheckerRegistry::validateCheckerOptions(const AnalyzerOptions &opts, + DiagnosticsEngine &diags) const { + for (const auto &config : opts.Config) { + size_t pos = config.getKey().find(':'); + if (pos == StringRef::npos) + continue; + + bool hasChecker = false; + StringRef checkerName = config.getKey().substr(0, pos); + for (const auto &checker : Checkers) { + if (checker.FullName.startswith(checkerName) && + (checker.FullName.size() == pos || checker.FullName[pos] == '.')) { + hasChecker = true; + break; + } + } + if (!hasChecker) + diags.Report(diag::err_unknown_analyzer_checker) << checkerName; + } +} + +void CheckerRegistry::printHelp(raw_ostream &out, + size_t maxNameChars) const { + // FIXME: Alphabetical sort puts 'experimental' in the middle. + // Would it be better to name it '~experimental' or something else + // that's ASCIIbetically last? + llvm::sort(Checkers, checkerNameLT); + + // FIXME: Print available packages. + + out << "CHECKERS:\n"; + + // Find the maximum option length. + size_t optionFieldWidth = 0; + for (const auto &i : Checkers) { + // Limit the amount of padding we are willing to give up for alignment. + // Package.Name Description [Hidden] + size_t nameLength = i.FullName.size(); + if (nameLength <= maxNameChars) + optionFieldWidth = std::max(optionFieldWidth, nameLength); + } + + const size_t initialPad = 2; + for (const auto &i : Checkers) { + out.indent(initialPad) << i.FullName; + + int pad = optionFieldWidth - i.FullName.size(); + + // Break on long option names. + if (pad < 0) { + out << '\n'; + pad = optionFieldWidth + initialPad; + } + out.indent(pad + 2) << i.Desc; + + out << '\n'; + } +} + +void CheckerRegistry::printList(raw_ostream &out, + const AnalyzerOptions &opts, + DiagnosticsEngine &diags) const { + // Sort checkers for efficient collection. + llvm::sort(Checkers, checkerNameLT); + + // Collect checkers enabled by the options. + CheckerInfoSet enabledCheckers = getEnabledCheckers(opts, diags); + + for (const auto *i : enabledCheckers) + out << i->FullName << '\n'; +} diff --git a/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp b/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp index dcd115e596..c18121df17 100644 --- a/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp +++ b/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp @@ -11,9 +11,9 @@ #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" -#include "clang/StaticAnalyzer/Core/CheckerRegistry.h" #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h" #include "clang/StaticAnalyzer/Frontend/AnalysisConsumer.h" +#include "clang/StaticAnalyzer/Frontend/CheckerRegistry.h" #include "clang/Tooling/Tooling.h" #include "gtest/gtest.h" -- cgit v1.2.3 From 3092007b1ada865847ca8f64bc64370cada2b34b Mon Sep 17 00:00:00 2001 From: Kristof Umann Date: Sat, 15 Dec 2018 17:12:38 +0000 Subject: Fix a compilation error in examples/ git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349278 91177308-0d34-0410-b5e6-96231b3b80d8 --- examples/analyzer-plugin/MainCallChecker.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/analyzer-plugin/MainCallChecker.cpp b/examples/analyzer-plugin/MainCallChecker.cpp index 74fe663e98..adb4e7da30 100644 --- a/examples/analyzer-plugin/MainCallChecker.cpp +++ b/examples/analyzer-plugin/MainCallChecker.cpp @@ -1,6 +1,6 @@ #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" -#include "clang/StaticAnalyzer/Core/CheckerRegistry.h" +#include "clang/StaticAnalyzer/Frontend/CheckerRegistry.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" using namespace clang; -- cgit v1.2.3 From ca78a207dcf16c6c32f6f06841443e2d104467d9 Mon Sep 17 00:00:00 2001 From: Kristof Umann Date: Sat, 15 Dec 2018 18:03:15 +0000 Subject: Link examples/clang-interpreter against clangSerialization git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349279 91177308-0d34-0410-b5e6-96231b3b80d8 --- examples/clang-interpreter/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/clang-interpreter/CMakeLists.txt b/examples/clang-interpreter/CMakeLists.txt index 7b9657ec1a..b69a82e054 100644 --- a/examples/clang-interpreter/CMakeLists.txt +++ b/examples/clang-interpreter/CMakeLists.txt @@ -25,6 +25,7 @@ target_link_libraries(clang-interpreter clangCodeGen clangDriver clangFrontend + clangSerialization ) export_executable_symbols(clang-interpreter) -- cgit v1.2.3 From 40dd9f385190fd4c2f16add97ba6e64555f1d9fd Mon Sep 17 00:00:00 2001 From: Kristof Umann Date: Sat, 15 Dec 2018 18:11:49 +0000 Subject: [analyzer][NFC] Merge ClangCheckerRegistry to CheckerRegistry Now that CheckerRegistry lies in Frontend, we can finally eliminate ClangCheckerRegistry. Fortunately, this also provides us with a DiagnosticsEngine, so I went ahead and removed some parameters from it's methods. Differential Revision: https://reviews.llvm.org/D54437 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349280 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../StaticAnalyzer/Frontend/CheckerRegistry.h | 16 ++-- .../StaticAnalyzer/Frontend/FrontendActions.h | 3 +- lib/FrontendTool/ExecuteCompilerInvocation.cpp | 3 +- .../Frontend/CheckerRegistration.cpp | 93 ++-------------------- lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp | 80 ++++++++++++++++--- 5 files changed, 86 insertions(+), 109 deletions(-) diff --git a/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h b/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h index 589a258852..3599833d2c 100644 --- a/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h +++ b/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h @@ -81,6 +81,8 @@ namespace ento { /// "core.builtin", or the full name "core.builtin.NoReturnFunctionChecker". class CheckerRegistry { public: + CheckerRegistry(ArrayRef plugins, DiagnosticsEngine &diags); + /// Initialization functions perform any necessary setup for a checker. /// They should include a call to CheckerManager::registerChecker. using InitializationFunction = void (*)(CheckerManager &); @@ -122,25 +124,23 @@ public: /// all checkers specified by the given CheckerOptInfo list. The order of this /// list is significant; later options can be used to reverse earlier ones. /// This can be used to exclude certain checkers in an included package. - void initializeManager(CheckerManager &mgr, const AnalyzerOptions &Opts, - DiagnosticsEngine &diags) const; + void initializeManager(CheckerManager &mgr, + const AnalyzerOptions &Opts) const; /// Check if every option corresponds to a specific checker or package. - void validateCheckerOptions(const AnalyzerOptions &opts, - DiagnosticsEngine &diags) const; + void validateCheckerOptions(const AnalyzerOptions &opts) const; /// Prints the name and description of all checkers in this registry. /// This output is not intended to be machine-parseable. void printHelp(raw_ostream &out, size_t maxNameChars = 30) const; - void printList(raw_ostream &out, const AnalyzerOptions &opts, - DiagnosticsEngine &diags) const; + void printList(raw_ostream &out, const AnalyzerOptions &opts) const; private: - CheckerInfoSet getEnabledCheckers(const AnalyzerOptions &Opts, - DiagnosticsEngine &diags) const; + CheckerInfoSet getEnabledCheckers(const AnalyzerOptions &Opts) const; mutable CheckerInfoList Checkers; mutable llvm::StringMap Packages; + DiagnosticsEngine &Diags; }; } // namespace ento diff --git a/include/clang/StaticAnalyzer/Frontend/FrontendActions.h b/include/clang/StaticAnalyzer/Frontend/FrontendActions.h index 20b71ef69d..2e9d0502e6 100644 --- a/include/clang/StaticAnalyzer/Frontend/FrontendActions.h +++ b/include/clang/StaticAnalyzer/Frontend/FrontendActions.h @@ -52,7 +52,8 @@ private: llvm::StringMap &Bodies; }; -void printCheckerHelp(raw_ostream &OS, ArrayRef plugins); +void printCheckerHelp(raw_ostream &OS, ArrayRef plugins, + DiagnosticsEngine &diags); void printEnabledCheckerList(raw_ostream &OS, ArrayRef plugins, const AnalyzerOptions &opts, DiagnosticsEngine &diags); diff --git a/lib/FrontendTool/ExecuteCompilerInvocation.cpp b/lib/FrontendTool/ExecuteCompilerInvocation.cpp index 5239a7e6f8..7015772fa1 100644 --- a/lib/FrontendTool/ExecuteCompilerInvocation.cpp +++ b/lib/FrontendTool/ExecuteCompilerInvocation.cpp @@ -238,7 +238,8 @@ bool ExecuteCompilerInvocation(CompilerInstance *Clang) { // Honor -analyzer-checker-help. // This should happen AFTER plugins have been loaded! if (Clang->getAnalyzerOpts()->ShowCheckerHelp) { - ento::printCheckerHelp(llvm::outs(), Clang->getFrontendOpts().Plugins); + ento::printCheckerHelp(llvm::outs(), Clang->getFrontendOpts().Plugins, + Clang->getDiagnostics()); return true; } diff --git a/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp b/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp index cc29613b50..1c31c35b75 100644 --- a/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp +++ b/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp @@ -16,95 +16,15 @@ #include "clang/Frontend/FrontendDiagnostic.h" #include "clang/StaticAnalyzer/Core/AnalyzerOptions.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" -#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Frontend/CheckerRegistry.h" #include "clang/StaticAnalyzer/Frontend/FrontendActions.h" #include "llvm/ADT/SmallVector.h" -#include "llvm/Support/DynamicLibrary.h" #include "llvm/Support/FormattedStream.h" -#include "llvm/Support/Path.h" #include "llvm/Support/raw_ostream.h" #include using namespace clang; using namespace ento; -using llvm::sys::DynamicLibrary; - -namespace { -class ClangCheckerRegistry : public CheckerRegistry { - typedef void (*RegisterCheckersFn)(CheckerRegistry &); - - static bool isCompatibleAPIVersion(const char *versionString); - static void warnIncompatible(DiagnosticsEngine *diags, StringRef pluginPath, - const char *pluginAPIVersion); - -public: - ClangCheckerRegistry(ArrayRef plugins, - DiagnosticsEngine *diags = nullptr); -}; - -} // end anonymous namespace - -ClangCheckerRegistry::ClangCheckerRegistry(ArrayRef plugins, - DiagnosticsEngine *diags) { -#define GET_CHECKERS -#define CHECKER(FULLNAME, CLASS, HELPTEXT) \ - addChecker(register##CLASS, FULLNAME, HELPTEXT); -#include "clang/StaticAnalyzer/Checkers/Checkers.inc" -#undef CHECKER -#undef GET_CHECKERS - - for (ArrayRef::iterator i = plugins.begin(), e = plugins.end(); - i != e; ++i) { - // Get access to the plugin. - std::string err; - DynamicLibrary lib = DynamicLibrary::getPermanentLibrary(i->c_str(), &err); - if (!lib.isValid()) { - diags->Report(diag::err_fe_unable_to_load_plugin) << *i << err; - continue; - } - - // See if it's compatible with this build of clang. - const char *pluginAPIVersion = - (const char *) lib.getAddressOfSymbol("clang_analyzerAPIVersionString"); - if (!isCompatibleAPIVersion(pluginAPIVersion)) { - warnIncompatible(diags, *i, pluginAPIVersion); - continue; - } - - // Register its checkers. - RegisterCheckersFn registerPluginCheckers = - (RegisterCheckersFn) (intptr_t) lib.getAddressOfSymbol( - "clang_registerCheckers"); - if (registerPluginCheckers) - registerPluginCheckers(*this); - } -} - -bool ClangCheckerRegistry::isCompatibleAPIVersion(const char *versionString) { - // If the version string is null, it's not an analyzer plugin. - if (!versionString) - return false; - - // For now, none of the static analyzer API is considered stable. - // Versions must match exactly. - return strcmp(versionString, CLANG_ANALYZER_API_VERSION_STRING) == 0; -} - -void ClangCheckerRegistry::warnIncompatible(DiagnosticsEngine *diags, - StringRef pluginPath, - const char *pluginAPIVersion) { - if (!diags) - return; - if (!pluginAPIVersion) - return; - - diags->Report(diag::warn_incompatible_analyzer_plugin_api) - << llvm::sys::path::filename(pluginPath); - diags->Report(diag::note_incompatible_analyzer_plugin_api) - << CLANG_ANALYZER_API_VERSION_STRING - << pluginAPIVersion; -} std::unique_ptr ento::createCheckerManager( ASTContext &context, @@ -114,23 +34,24 @@ std::unique_ptr ento::createCheckerManager( DiagnosticsEngine &diags) { auto checkerMgr = llvm::make_unique(context, opts); - ClangCheckerRegistry allCheckers(plugins, &diags); + CheckerRegistry allCheckers(plugins, diags); for (const auto &Fn : checkerRegistrationFns) Fn(allCheckers); - allCheckers.initializeManager(*checkerMgr, opts, diags); - allCheckers.validateCheckerOptions(opts, diags); + allCheckers.initializeManager(*checkerMgr, opts); + allCheckers.validateCheckerOptions(opts); checkerMgr->finishedCheckerRegistration(); return checkerMgr; } -void ento::printCheckerHelp(raw_ostream &out, ArrayRef plugins) { +void ento::printCheckerHelp(raw_ostream &out, ArrayRef plugins, + DiagnosticsEngine &diags) { out << "OVERVIEW: Clang Static Analyzer Checkers List\n\n"; out << "USAGE: -analyzer-checker \n\n"; - ClangCheckerRegistry(plugins).printHelp(out); + CheckerRegistry(plugins, diags).printHelp(out); } void ento::printEnabledCheckerList(raw_ostream &out, @@ -139,7 +60,7 @@ void ento::printEnabledCheckerList(raw_ostream &out, DiagnosticsEngine &diags) { out << "OVERVIEW: Clang Static Analyzer Enabled Checkers List\n\n"; - ClangCheckerRegistry(plugins).printList(out, opts, diags); + CheckerRegistry(plugins, diags).printList(out, opts); } void ento::printAnalyzerConfigList(raw_ostream &out) { diff --git a/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp b/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp index d1931d3e6f..86cf62a163 100644 --- a/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp +++ b/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp @@ -10,17 +10,74 @@ #include "clang/StaticAnalyzer/Frontend/CheckerRegistry.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/LLVM.h" +#include "clang/Frontend/FrontendDiagnostic.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" #include "clang/StaticAnalyzer/Core/AnalyzerOptions.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SetVector.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/DynamicLibrary.h" +#include "llvm/Support/Path.h" #include "llvm/Support/raw_ostream.h" #include using namespace clang; using namespace ento; +using llvm::sys::DynamicLibrary; + +using RegisterCheckersFn = void (*)(CheckerRegistry &); + +static bool isCompatibleAPIVersion(const char *versionString) { + // If the version string is null, it's not an analyzer plugin. + if (!versionString) + return false; + + // For now, none of the static analyzer API is considered stable. + // Versions must match exactly. + return strcmp(versionString, CLANG_ANALYZER_API_VERSION_STRING) == 0; +} + +CheckerRegistry::CheckerRegistry(ArrayRef plugins, + DiagnosticsEngine &diags) : Diags(diags) { +#define GET_CHECKERS +#define CHECKER(FULLNAME, CLASS, HELPTEXT) \ + addChecker(register##CLASS, FULLNAME, HELPTEXT); +#include "clang/StaticAnalyzer/Checkers/Checkers.inc" +#undef CHECKER +#undef GET_CHECKERS + + for (ArrayRef::iterator i = plugins.begin(), e = plugins.end(); + i != e; ++i) { + // Get access to the plugin. + std::string err; + DynamicLibrary lib = DynamicLibrary::getPermanentLibrary(i->c_str(), &err); + if (!lib.isValid()) { + diags.Report(diag::err_fe_unable_to_load_plugin) << *i << err; + continue; + } + + // See if it's compatible with this build of clang. + const char *pluginAPIVersion = + (const char *) lib.getAddressOfSymbol("clang_analyzerAPIVersionString"); + if (!isCompatibleAPIVersion(pluginAPIVersion)) { + Diags.Report(diag::warn_incompatible_analyzer_plugin_api) + << llvm::sys::path::filename(*i); + Diags.Report(diag::note_incompatible_analyzer_plugin_api) + << CLANG_ANALYZER_API_VERSION_STRING + << pluginAPIVersion; + continue; + } + + // Register its checkers. + RegisterCheckersFn registerPluginCheckers = + (RegisterCheckersFn) (intptr_t) lib.getAddressOfSymbol( + "clang_registerCheckers"); + if (registerPluginCheckers) + registerPluginCheckers(*this); + } +} static constexpr char PackageSeparator = '.'; @@ -47,8 +104,7 @@ static bool isInPackage(const CheckerRegistry::CheckerInfo &checker, } CheckerRegistry::CheckerInfoSet CheckerRegistry::getEnabledCheckers( - const AnalyzerOptions &Opts, - DiagnosticsEngine &diags) const { + const AnalyzerOptions &Opts) const { assert(std::is_sorted(Checkers.begin(), Checkers.end(), checkerNameLT) && "In order to efficiently gather checkers, this function expects them " @@ -65,8 +121,8 @@ CheckerRegistry::CheckerInfoSet CheckerRegistry::getEnabledCheckers( if (firstRelatedChecker == end || !isInPackage(*firstRelatedChecker, opt.first)) { - diags.Report(diag::err_unknown_analyzer_checker) << opt.first; - diags.Report(diag::note_suggest_disabling_all_checkers); + Diags.Report(diag::err_unknown_analyzer_checker) << opt.first; + Diags.Report(diag::note_suggest_disabling_all_checkers); return {}; } @@ -105,13 +161,12 @@ void CheckerRegistry::addChecker(InitializationFunction fn, StringRef name, } void CheckerRegistry::initializeManager(CheckerManager &checkerMgr, - const AnalyzerOptions &Opts, - DiagnosticsEngine &diags) const { + const AnalyzerOptions &Opts) const { // Sort checkers for efficient collection. llvm::sort(Checkers, checkerNameLT); // Collect checkers enabled by the options. - CheckerInfoSet enabledCheckers = getEnabledCheckers(Opts, diags); + CheckerInfoSet enabledCheckers = getEnabledCheckers(Opts); // Initialize the CheckerManager with all enabled checkers. for (const auto *i : enabledCheckers) { @@ -120,8 +175,8 @@ void CheckerRegistry::initializeManager(CheckerManager &checkerMgr, } } -void CheckerRegistry::validateCheckerOptions(const AnalyzerOptions &opts, - DiagnosticsEngine &diags) const { +void CheckerRegistry::validateCheckerOptions( + const AnalyzerOptions &opts) const { for (const auto &config : opts.Config) { size_t pos = config.getKey().find(':'); if (pos == StringRef::npos) @@ -137,7 +192,7 @@ void CheckerRegistry::validateCheckerOptions(const AnalyzerOptions &opts, } } if (!hasChecker) - diags.Report(diag::err_unknown_analyzer_checker) << checkerName; + Diags.Report(diag::err_unknown_analyzer_checker) << checkerName; } } @@ -180,13 +235,12 @@ void CheckerRegistry::printHelp(raw_ostream &out, } void CheckerRegistry::printList(raw_ostream &out, - const AnalyzerOptions &opts, - DiagnosticsEngine &diags) const { + const AnalyzerOptions &opts) const { // Sort checkers for efficient collection. llvm::sort(Checkers, checkerNameLT); // Collect checkers enabled by the options. - CheckerInfoSet enabledCheckers = getEnabledCheckers(opts, diags); + CheckerInfoSet enabledCheckers = getEnabledCheckers(opts); for (const auto *i : enabledCheckers) out << i->FullName << '\n'; -- cgit v1.2.3 From 97361a20a727ffe1e8d3102ce94c83ccdf2eb1bb Mon Sep 17 00:00:00 2001 From: Kristof Umann Date: Sat, 15 Dec 2018 18:34:00 +0000 Subject: [analyzer][MallocChecker][NFC] Document and reorganize some functions This patch merely reorganizes some things, and features no functional change. In detail: * Provided documentation, or moved existing documentation in more obvious places. * Added dividers. (the //===----------===// thing). * Moved getAllocationFamily, printAllocDeallocName, printExpectedAllocName and printExpectedDeallocName in the global namespace on top of the file where AllocationFamily is declared, as they are very strongly related. * Moved isReleased and MallocUpdateRefState near RefState's definition for the same reason. * Realloc modeling was very poor in terms of variable and structure naming, as well as documentation, so I renamed some of them and added much needed docs. * Moved function IdentifierInfos to a separate struct, and moved isMemFunction, isCMemFunction adn isStandardNewDelete inside it. This makes the patch affect quite a lot of lines, should I extract it to a separate one? * Moved MallocBugVisitor out of MallocChecker. * Preferred switches to long else-if branches in some places. * Neatly organized some RUN: lines. Differential Revision: https://reviews.llvm.org/D54823 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349281 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/StaticAnalyzer/Checkers/MallocChecker.cpp | 1136 ++++++++++++++++--------- test/Analysis/malloc-annotations.c | 6 +- test/Analysis/malloc.c | 7 +- 3 files changed, 725 insertions(+), 424 deletions(-) diff --git a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp index ae1b1fc837..a5b774fe24 100644 --- a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp @@ -7,8 +7,41 @@ // //===----------------------------------------------------------------------===// // -// This file defines malloc/free checker, which checks for potential memory -// leaks, double free, and use-after-free problems. +// This file defines a variety of memory management related checkers, such as +// leak, double free, and use-after-free. +// +// The following checkers are defined here: +// +// * MallocChecker +// Despite its name, it models all sorts of memory allocations and +// de- or reallocation, including but not limited to malloc, free, +// relloc, new, delete. It also reports on a variety of memory misuse +// errors. +// Many other checkers interact very closely with this checker, in fact, +// most are merely options to this one. Other checkers may register +// MallocChecker, but do not enable MallocChecker's reports (more details +// to follow around its field, ChecksEnabled). +// It also has a boolean "Optimistic" checker option, which if set to true +// will cause the checker to model user defined memory management related +// functions annotated via the attribute ownership_takes, ownership_holds +// and ownership_returns. +// +// * NewDeleteChecker +// Enables the modeling of new, new[], delete, delete[] in MallocChecker, +// and checks for related double-free and use-after-free errors. +// +// * NewDeleteLeaksChecker +// Checks for leaks related to new, new[], delete, delete[]. +// Depends on NewDeleteChecker. +// +// * MismatchedDeallocatorChecker +// Enables checking whether memory is deallocated with the correspending +// allocation function in MallocChecker, such as malloc() allocated +// regions are only freed by free(), new by delete, new[] by delete[]. +// +// InnerPointerChecker interacts very closely with MallocChecker, but unlike +// the above checkers, it has it's own file, hence the many InnerPointerChecker +// related headers and non-static functions. // //===----------------------------------------------------------------------===// @@ -37,6 +70,10 @@ using namespace clang; using namespace ento; +//===----------------------------------------------------------------------===// +// The types of allocation we're modeling. +//===----------------------------------------------------------------------===// + namespace { // Used to check correspondence between allocators and deallocators. @@ -50,28 +87,59 @@ enum AllocationFamily { AF_InnerBuffer }; +struct MemFunctionInfoTy; + +} // end of anonymous namespace + +/// Determine family of a deallocation expression. +static AllocationFamily getAllocationFamily( + const MemFunctionInfoTy &MemFunctionInfo, CheckerContext &C, const Stmt *S); + +/// Print names of allocators and deallocators. +/// +/// \returns true on success. +static bool printAllocDeallocName(raw_ostream &os, CheckerContext &C, + const Expr *E); + +/// Print expected name of an allocator based on the deallocator's +/// family derived from the DeallocExpr. +static void printExpectedAllocName(raw_ostream &os, + const MemFunctionInfoTy &MemFunctionInfo, + CheckerContext &C, const Expr *E); + +/// Print expected name of a deallocator based on the allocator's +/// family. +static void printExpectedDeallocName(raw_ostream &os, AllocationFamily Family); + +//===----------------------------------------------------------------------===// +// The state of a symbol, in terms of memory management. +//===----------------------------------------------------------------------===// + +namespace { + class RefState { - enum Kind { // Reference to allocated memory. - Allocated, - // Reference to zero-allocated memory. - AllocatedOfSizeZero, - // Reference to released/freed memory. - Released, - // The responsibility for freeing resources has transferred from - // this reference. A relinquished symbol should not be freed. - Relinquished, - // We are no longer guaranteed to have observed all manipulations - // of this pointer/memory. For example, it could have been - // passed as a parameter to an opaque function. - Escaped + enum Kind { + // Reference to allocated memory. + Allocated, + // Reference to zero-allocated memory. + AllocatedOfSizeZero, + // Reference to released/freed memory. + Released, + // The responsibility for freeing resources has transferred from + // this reference. A relinquished symbol should not be freed. + Relinquished, + // We are no longer guaranteed to have observed all manipulations + // of this pointer/memory. For example, it could have been + // passed as a parameter to an opaque function. + Escaped }; const Stmt *S; - unsigned K : 3; // Kind enum, but stored as a bitfield. - unsigned Family : 29; // Rest of 32-bit word, currently just an allocation - // family. - RefState(Kind k, const Stmt *s, unsigned family) + Kind K : 3; + AllocationFamily Family : 3; + + RefState(Kind k, const Stmt *s, AllocationFamily family) : S(s), K(k), Family(family) { assert(family != AF_None); } @@ -82,7 +150,7 @@ public: bool isRelinquished() const { return K == Relinquished; } bool isEscaped() const { return K == Escaped; } AllocationFamily getAllocationFamily() const { - return (AllocationFamily)Family; + return Family; } const Stmt *getStmt() const { return S; } @@ -90,17 +158,17 @@ public: return K == X.K && S == X.S && Family == X.Family; } - static RefState getAllocated(unsigned family, const Stmt *s) { + static RefState getAllocated(AllocationFamily family, const Stmt *s) { return RefState(Allocated, s, family); } static RefState getAllocatedOfSizeZero(const RefState *RS) { return RefState(AllocatedOfSizeZero, RS->getStmt(), RS->getAllocationFamily()); } - static RefState getReleased(unsigned family, const Stmt *s) { + static RefState getReleased(AllocationFamily family, const Stmt *s) { return RefState(Released, s, family); } - static RefState getRelinquished(unsigned family, const Stmt *s) { + static RefState getRelinquished(AllocationFamily family, const Stmt *s) { return RefState(Relinquished, s, family); } static RefState getEscaped(const RefState *RS) { @@ -113,8 +181,8 @@ public: ID.AddInteger(Family); } - void dump(raw_ostream &OS) const { - switch (static_cast(K)) { + LLVM_DUMP_METHOD void dump(raw_ostream &OS) const { + switch (K) { #define CASE(ID) case ID: OS << #ID; break; CASE(Allocated) CASE(AllocatedOfSizeZero) @@ -127,23 +195,61 @@ public: LLVM_DUMP_METHOD void dump() const { dump(llvm::errs()); } }; -enum ReallocPairKind { - RPToBeFreedAfterFailure, - // The symbol has been freed when reallocation failed. - RPIsFreeOnFailure, - // The symbol does not need to be freed after reallocation fails. - RPDoNotTrackAfterFailure +} // end of anonymous namespace + +REGISTER_MAP_WITH_PROGRAMSTATE(RegionState, SymbolRef, RefState) + +/// Check if the memory associated with this symbol was released. +static bool isReleased(SymbolRef Sym, CheckerContext &C); + +/// Update the RefState to reflect the new memory allocation. +/// The optional \p RetVal parameter specifies the newly allocated pointer +/// value; if unspecified, the value of expression \p E is used. +static ProgramStateRef +MallocUpdateRefState(CheckerContext &C, const Expr *E, ProgramStateRef State, + AllocationFamily Family = AF_Malloc, + Optional RetVal = None); + +//===----------------------------------------------------------------------===// +// The modeling of memory reallocation. +// +// The terminology 'toPtr' and 'fromPtr' will be used: +// toPtr = realloc(fromPtr, 20); +//===----------------------------------------------------------------------===// + +REGISTER_SET_WITH_PROGRAMSTATE(ReallocSizeZeroSymbols, SymbolRef) + +namespace { + +/// The state of 'fromPtr' after reallocation is known to have failed. +enum OwnershipAfterReallocKind { + // The symbol needs to be freed (e.g.: realloc) + OAR_ToBeFreedAfterFailure, + // The symbol has been freed (e.g.: reallocf) + OAR_FreeOnFailure, + // The symbol doesn't have to freed (e.g.: we aren't sure if, how and where + // 'fromPtr' was allocated: + // void Haha(int *ptr) { + // ptr = realloc(ptr, 67); + // // ... + // } + // ). + OAR_DoNotTrackAfterFailure }; -/// \class ReallocPair -/// Stores information about the symbol being reallocated by a call to -/// 'realloc' to allow modeling failed reallocation later in the path. +/// Stores information about the 'fromPtr' symbol after reallocation. +/// +/// This is important because realloc may fail, and that needs special modeling. +/// Whether reallocation failed or not will not be known until later, so we'll +/// store whether upon failure 'fromPtr' will be freed, or needs to be freed +/// later, etc. struct ReallocPair { - // The symbol which realloc reallocated. + + // The 'fromPtr'. SymbolRef ReallocatedSym; - ReallocPairKind Kind; + OwnershipAfterReallocKind Kind; - ReallocPair(SymbolRef S, ReallocPairKind K) : + ReallocPair(SymbolRef S, OwnershipAfterReallocKind K) : ReallocatedSym(S), Kind(K) {} void Profile(llvm::FoldingSetNodeID &ID) const { ID.AddInteger(Kind); @@ -155,7 +261,75 @@ struct ReallocPair { } }; -typedef std::pair LeakInfo; +} // end of anonymous namespace + +REGISTER_MAP_WITH_PROGRAMSTATE(ReallocPairs, SymbolRef, ReallocPair) + +//===----------------------------------------------------------------------===// +// Kinds of memory operations, information about resource managing functions. +//===----------------------------------------------------------------------===// + +namespace { + +enum class MemoryOperationKind { + MOK_Allocate, + MOK_Free, + MOK_Any +}; + +struct MemFunctionInfoTy { + /// The value of the MallocChecker:Optimistic is stored in this variable. + /// + /// In pessimistic mode, the checker assumes that it does not know which + /// functions might free the memory. + /// In optimistic mode, the checker assumes that all user-defined functions + /// which might free a pointer are annotated. + DefaultBool ShouldIncludeOwnershipAnnotatedFunctions; + + // TODO: Change these to CallDescription, and get rid of lazy initialization. + mutable IdentifierInfo *II_alloca = nullptr, *II_win_alloca = nullptr, + *II_malloc = nullptr, *II_free = nullptr, + *II_realloc = nullptr, *II_calloc = nullptr, + *II_valloc = nullptr, *II_reallocf = nullptr, + *II_strndup = nullptr, *II_strdup = nullptr, + *II_win_strdup = nullptr, *II_kmalloc = nullptr, + *II_if_nameindex = nullptr, + *II_if_freenameindex = nullptr, *II_wcsdup = nullptr, + *II_win_wcsdup = nullptr, *II_g_malloc = nullptr, + *II_g_malloc0 = nullptr, *II_g_realloc = nullptr, + *II_g_try_malloc = nullptr, + *II_g_try_malloc0 = nullptr, + *II_g_try_realloc = nullptr, *II_g_free = nullptr, + *II_g_memdup = nullptr, *II_g_malloc_n = nullptr, + *II_g_malloc0_n = nullptr, *II_g_realloc_n = nullptr, + *II_g_try_malloc_n = nullptr, + *II_g_try_malloc0_n = nullptr, + *II_g_try_realloc_n = nullptr; + + void initIdentifierInfo(ASTContext &C) const; + + ///@{ + /// Check if this is one of the functions which can allocate/reallocate + /// memory pointed to by one of its arguments. + bool isMemFunction(const FunctionDecl *FD, ASTContext &C) const; + bool isCMemFunction(const FunctionDecl *FD, + ASTContext &C, + AllocationFamily Family, + MemoryOperationKind MemKind) const; + + /// Tells if the callee is one of the builtin new/delete operators, including + /// placement operators and other standard overloads. + bool isStandardNewDelete(const FunctionDecl *FD, ASTContext &C) const; + ///@} +}; + +} // end of anonymous namespace + +//===----------------------------------------------------------------------===// +// Definition of the MallocChecker class. +//===----------------------------------------------------------------------===// + +namespace { class MallocChecker : public Checker, check::PostObjCMessage, check::Location, - eval::Assume> -{ + eval::Assume> { public: - MallocChecker() - : II_alloca(nullptr), II_win_alloca(nullptr), II_malloc(nullptr), - II_free(nullptr), II_realloc(nullptr), II_calloc(nullptr), - II_valloc(nullptr), II_reallocf(nullptr), II_strndup(nullptr), - II_strdup(nullptr), II_win_strdup(nullptr), II_kmalloc(nullptr), - II_if_nameindex(nullptr), II_if_freenameindex(nullptr), - II_wcsdup(nullptr), II_win_wcsdup(nullptr), II_g_malloc(nullptr), - II_g_malloc0(nullptr), II_g_realloc(nullptr), II_g_try_malloc(nullptr), - II_g_try_malloc0(nullptr), II_g_try_realloc(nullptr), - II_g_free(nullptr), II_g_memdup(nullptr), II_g_malloc_n(nullptr), - II_g_malloc0_n(nullptr), II_g_realloc_n(nullptr), - II_g_try_malloc_n(nullptr), II_g_try_malloc0_n(nullptr), - II_g_try_realloc_n(nullptr) {} + MemFunctionInfoTy MemFunctionInfo; - /// In pessimistic mode, the checker assumes that it does not know which - /// functions might free the memory. + /// Many checkers are essentially built into this one, so enabling them will + /// make MallocChecker perform additional modeling and reporting. enum CheckKind { + /// When a subchecker is enabled but MallocChecker isn't, model memory + /// management but do not emit warnings emitted with MallocChecker only + /// enabled. CK_MallocChecker, CK_NewDeleteChecker, CK_NewDeleteLeaksChecker, @@ -198,13 +362,7 @@ public: CK_NumCheckKinds }; - enum class MemoryOperationKind { - MOK_Allocate, - MOK_Free, - MOK_Any - }; - - DefaultBool IsOptimistic; + using LeakInfo = std::pair; DefaultBool ChecksEnabled[CK_NumCheckKinds]; CheckName CheckNames[CK_NumCheckKinds]; @@ -247,47 +405,9 @@ private: mutable std::unique_ptr BT_MismatchedDealloc; mutable std::unique_ptr BT_OffsetFree[CK_NumCheckKinds]; mutable std::unique_ptr BT_UseZerroAllocated[CK_NumCheckKinds]; - mutable IdentifierInfo *II_alloca, *II_win_alloca, *II_malloc, *II_free, - *II_realloc, *II_calloc, *II_valloc, *II_reallocf, - *II_strndup, *II_strdup, *II_win_strdup, *II_kmalloc, - *II_if_nameindex, *II_if_freenameindex, *II_wcsdup, - *II_win_wcsdup, *II_g_malloc, *II_g_malloc0, - *II_g_realloc, *II_g_try_malloc, *II_g_try_malloc0, - *II_g_try_realloc, *II_g_free, *II_g_memdup, - *II_g_malloc_n, *II_g_malloc0_n, *II_g_realloc_n, - *II_g_try_malloc_n, *II_g_try_malloc0_n, - *II_g_try_realloc_n; - mutable Optional KernelZeroFlagVal; - - void initIdentifierInfo(ASTContext &C) const; - - /// Determine family of a deallocation expression. - AllocationFamily getAllocationFamily(CheckerContext &C, const Stmt *S) const; - /// Print names of allocators and deallocators. - /// - /// \returns true on success. - bool printAllocDeallocName(raw_ostream &os, CheckerContext &C, - const Expr *E) const; - - /// Print expected name of an allocator based on the deallocator's - /// family derived from the DeallocExpr. - void printExpectedAllocName(raw_ostream &os, CheckerContext &C, - const Expr *DeallocExpr) const; - /// Print expected name of a deallocator based on the allocator's - /// family. - void printExpectedDeallocName(raw_ostream &os, AllocationFamily Family) const; - - ///@{ - /// Check if this is one of the functions which can allocate/reallocate memory - /// pointed to by one of its arguments. - bool isMemFunction(const FunctionDecl *FD, ASTContext &C) const; - bool isCMemFunction(const FunctionDecl *FD, - ASTContext &C, - AllocationFamily Family, - MemoryOperationKind MemKind) const; - bool isStandardNewDelete(const FunctionDecl *FD, ASTContext &C) const; - ///@} + // TODO: Remove mutable by moving the initializtaion to the registry function. + mutable Optional KernelZeroFlagVal; /// Process C++ operator new()'s allocation, which is the part of C++ /// new-expression that goes before the constructor. @@ -295,23 +415,64 @@ private: SVal Target) const; /// Perform a zero-allocation check. - /// The optional \p RetVal parameter specifies the newly allocated pointer - /// value; if unspecified, the value of expression \p E is used. - ProgramStateRef ProcessZeroAllocation(CheckerContext &C, const Expr *E, - const unsigned AllocationSizeArg, - ProgramStateRef State, - Optional RetVal = None) const; - + /// + /// \param [in] E The expression that allocates memory. + /// \param [in] IndexOfSizeArg Index of the argument that specifies the size + /// of the memory that needs to be allocated. E.g. for malloc, this would be + /// 0. + /// \param [in] RetVal Specifies the newly allocated pointer value; + /// if unspecified, the value of expression \p E is used. + static ProgramStateRef ProcessZeroAllocCheck(CheckerContext &C, const Expr *E, + const unsigned IndexOfSizeArg, + ProgramStateRef State, + Optional RetVal = None); + + /// Model functions with the ownership_returns attribute. + /// + /// User-defined function may have the ownership_returns attribute, which + /// annotates that the function returns with an object that was allocated on + /// the heap, and passes the ownertship to the callee. + /// + /// void __attribute((ownership_returns(malloc, 1))) *my_malloc(size_t); + /// + /// It has two parameters: + /// - first: name of the resource (e.g. 'malloc') + /// - (OPTIONAL) second: size of the allocated region + /// + /// \param [in] CE The expression that allocates memory. + /// \param [in] Att The ownership_returns attribute. + /// \param [in] State The \c ProgramState right before allocation. + /// \returns The ProgramState right after allocation. ProgramStateRef MallocMemReturnsAttr(CheckerContext &C, const CallExpr *CE, const OwnershipAttr* Att, ProgramStateRef State) const; + + /// Models memory allocation. + /// + /// \param [in] CE The expression that allocates memory. + /// \param [in] SizeEx Size of the memory that needs to be allocated. + /// \param [in] Init The value the allocated memory needs to be initialized. + /// with. For example, \c calloc initializes the allocated memory to 0, + /// malloc leaves it undefined. + /// \param [in] State The \c ProgramState right before allocation. + /// \returns The ProgramState right after allocation. static ProgramStateRef MallocMemAux(CheckerContext &C, const CallExpr *CE, const Expr *SizeEx, SVal Init, ProgramStateRef State, AllocationFamily Family = AF_Malloc); + + /// Models memory allocation. + /// + /// \param [in] CE The expression that allocates memory. + /// \param [in] Size Size of the memory that needs to be allocated. + /// \param [in] Init The value the allocated memory needs to be initialized. + /// with. For example, \c calloc initializes the allocated memory to 0, + /// malloc leaves it undefined. + /// \param [in] State The \c ProgramState right before allocation. + /// \returns The ProgramState right after allocation. static ProgramStateRef MallocMemAux(CheckerContext &C, const CallExpr *CE, - SVal SizeEx, SVal Init, + SVal Size, SVal Init, ProgramStateRef State, AllocationFamily Family = AF_Malloc); @@ -324,49 +485,124 @@ private: performKernelMalloc(const CallExpr *CE, CheckerContext &C, const ProgramStateRef &State) const; - /// Update the RefState to reflect the new memory allocation. - /// The optional \p RetVal parameter specifies the newly allocated pointer - /// value; if unspecified, the value of expression \p E is used. - static ProgramStateRef - MallocUpdateRefState(CheckerContext &C, const Expr *E, ProgramStateRef State, - AllocationFamily Family = AF_Malloc, - Optional RetVal = None); - + /// Model functions with the ownership_takes and ownership_holds attributes. + /// + /// User-defined function may have the ownership_takes and/or ownership_holds + /// attributes, which annotates that the function frees the memory passed as a + /// parameter. + /// + /// void __attribute((ownership_takes(malloc, 1))) my_free(void *); + /// void __attribute((ownership_holds(malloc, 1))) my_hold(void *); + /// + /// They have two parameters: + /// - first: name of the resource (e.g. 'malloc') + /// - second: index of the parameter the attribute applies to + /// + /// \param [in] CE The expression that frees memory. + /// \param [in] Att The ownership_takes or ownership_holds attribute. + /// \param [in] State The \c ProgramState right before allocation. + /// \returns The ProgramState right after deallocation. ProgramStateRef FreeMemAttr(CheckerContext &C, const CallExpr *CE, const OwnershipAttr* Att, ProgramStateRef State) const; + + /// Models memory deallocation. + /// + /// \param [in] CE The expression that frees memory. + /// \param [in] State The \c ProgramState right before allocation. + /// \param [in] Num Index of the argument that needs to be freed. This is + /// normally 0, but for custom free functions it may be different. + /// \param [in] Hold Whether the parameter at \p Index has the ownership_holds + /// attribute. + /// \param [out] IsKnownToBeAllocated Whether the memory to be freed is known + /// to have been allocated, or in other words, the symbol to be freed was + /// registered as allocated by this checker. In the following case, \c ptr + /// isn't known to be allocated. + /// void Haha(int *ptr) { + /// ptr = realloc(ptr, 67); + /// // ... + /// } + /// \param [in] ReturnsNullOnFailure Whether the memory deallocation function + /// we're modeling returns with Null on failure. + /// \returns The ProgramState right after deallocation. ProgramStateRef FreeMemAux(CheckerContext &C, const CallExpr *CE, - ProgramStateRef state, unsigned Num, + ProgramStateRef State, unsigned Num, bool Hold, - bool &ReleasedAllocated, + bool &IsKnownToBeAllocated, bool ReturnsNullOnFailure = false) const; - ProgramStateRef FreeMemAux(CheckerContext &C, const Expr *Arg, + + /// Models memory deallocation. + /// + /// \param [in] ArgExpr The variable who's pointee needs to be freed. + /// \param [in] ParentExpr The expression that frees the memory. + /// \param [in] State The \c ProgramState right before allocation. + /// normally 0, but for custom free functions it may be different. + /// \param [in] Hold Whether the parameter at \p Index has the ownership_holds + /// attribute. + /// \param [out] IsKnownToBeAllocated Whether the memory to be freed is known + /// to have been allocated, or in other words, the symbol to be freed was + /// registered as allocated by this checker. In the following case, \c ptr + /// isn't known to be allocated. + /// void Haha(int *ptr) { + /// ptr = realloc(ptr, 67); + /// // ... + /// } + /// \param [in] ReturnsNullOnFailure Whether the memory deallocation function + /// we're modeling returns with Null on failure. + /// \returns The ProgramState right after deallocation. + ProgramStateRef FreeMemAux(CheckerContext &C, const Expr *ArgExpr, const Expr *ParentExpr, ProgramStateRef State, bool Hold, - bool &ReleasedAllocated, + bool &IsKnownToBeAllocated, bool ReturnsNullOnFailure = false) const; + // TODO: Needs some refactoring, as all other deallocation modeling + // functions are suffering from out parameters and messy code due to how + // realloc is handled. + // + /// Models memory reallocation. + /// + /// \param [in] CE The expression that reallocated memory + /// \param [in] FreesMemOnFailure Whether if reallocation fails, the supplied + /// memory should be freed. + /// \param [in] State The \c ProgramState right before reallocation. + /// \param [in] SuffixWithN Whether the reallocation function we're modeling + /// has an '_n' suffix, such as g_realloc_n. + /// \returns The ProgramState right after reallocation. ProgramStateRef ReallocMemAux(CheckerContext &C, const CallExpr *CE, - bool FreesMemOnFailure, + bool ShouldFreeOnFail, ProgramStateRef State, bool SuffixWithN = false) const; + + /// Evaluates the buffer size that needs to be allocated. + /// + /// \param [in] Blocks The amount of blocks that needs to be allocated. + /// \param [in] BlockBytes The size of a block. + /// \returns The symbolic value of \p Blocks * \p BlockBytes. static SVal evalMulForBufferSize(CheckerContext &C, const Expr *Blocks, const Expr *BlockBytes); + + /// Models zero initialized array allocation. + /// + /// \param [in] CE The expression that reallocated memory + /// \param [in] State The \c ProgramState right before reallocation. + /// \returns The ProgramState right after allocation. static ProgramStateRef CallocMem(CheckerContext &C, const CallExpr *CE, ProgramStateRef State); - /// Check if the memory associated with this symbol was released. - bool isReleased(SymbolRef Sym, CheckerContext &C) const; - + /// If in \p S \p Sym is used, check whether \p Sym was already freed. bool checkUseAfterFree(SymbolRef Sym, CheckerContext &C, const Stmt *S) const; + /// If in \p S \p Sym is used, check whether \p Sym was allocated as a zero + /// sized memory region. void checkUseZeroAllocated(SymbolRef Sym, CheckerContext &C, const Stmt *S) const; + /// If in \p S \p Sym is being freed, check whether \p Sym was already freed. bool checkDoubleDelete(SymbolRef Sym, CheckerContext &C) const; - /// Check if the function is known free memory, or if it is + /// Check if the function is known to free memory, or if it is /// "interesting" and should be modeled explicitly. /// /// \param [out] EscapingSymbol A function might not free memory in general, @@ -380,12 +616,12 @@ private: ProgramStateRef State, SymbolRef &EscapingSymbol) const; - // Implementation of the checkPointerEscape callbacks. + /// Implementation of the checkPointerEscape callbacks. ProgramStateRef checkPointerEscapeAux(ProgramStateRef State, - const InvalidatedSymbols &Escaped, - const CallEvent *Call, - PointerEscapeKind Kind, - bool(*CheckRefState)(const RefState*)) const; + const InvalidatedSymbols &Escaped, + const CallEvent *Call, + PointerEscapeKind Kind, + bool IsConstPointerEscape) const; // Implementation of the checkPreStmt and checkEndFunction callbacks. void checkEscapeOnReturn(const ReturnStmt *S, CheckerContext &C) const; @@ -404,6 +640,7 @@ private: ///@} static bool SummarizeValue(raw_ostream &os, SVal V); static bool SummarizeRegion(raw_ostream &os, const MemRegion *MR); + void ReportBadFree(CheckerContext &C, SVal ArgVal, SourceRange Range, const Expr *DeallocExpr) const; void ReportFreeAlloca(CheckerContext &C, SVal ArgVal, @@ -429,143 +666,149 @@ private: /// Find the location of the allocation for Sym on the path leading to the /// exploded node N. - LeakInfo getAllocationSite(const ExplodedNode *N, SymbolRef Sym, - CheckerContext &C) const; + static LeakInfo getAllocationSite(const ExplodedNode *N, SymbolRef Sym, + CheckerContext &C); - void reportLeak(SymbolRef Sym, ExplodedNode *N, CheckerContext &C) const; - /// The bug visitor which allows us to print extra diagnostics along the - /// BugReport path. For example, showing the allocation site of the leaked - /// region. - class MallocBugVisitor final : public BugReporterVisitor { - protected: - enum NotificationMode { - Normal, - ReallocationFailed - }; + void reportLeak(SymbolRef Sym, ExplodedNode *N, CheckerContext &C) const; +}; - // The allocated region symbol tracked by the main analysis. - SymbolRef Sym; +} // end anonymous namespace - // The mode we are in, i.e. what kind of diagnostics will be emitted. - NotificationMode Mode; +//===----------------------------------------------------------------------===// +// Definition of MallocBugVisitor. +//===----------------------------------------------------------------------===// - // A symbol from when the primary region should have been reallocated. - SymbolRef FailedReallocSymbol; +/// The bug visitor which allows us to print extra diagnostics along the +/// BugReport path. For example, showing the allocation site of the leaked +/// region. +class MallocBugVisitor final : public BugReporterVisitor { +protected: + enum NotificationMode { + Normal, + ReallocationFailed + }; - // A C++ destructor stack frame in which memory was released. Used for - // miscellaneous false positive suppression. - const StackFrameContext *ReleaseDestructorLC; + // The allocated region symbol tracked by the main analysis. + SymbolRef Sym; - bool IsLeak; + // The mode we are in, i.e. what kind of diagnostics will be emitted. + NotificationMode Mode; - public: - MallocBugVisitor(SymbolRef S, bool isLeak = false) - : Sym(S), Mode(Normal), FailedReallocSymbol(nullptr), - ReleaseDestructorLC(nullptr), IsLeak(isLeak) {} + // A symbol from when the primary region should have been reallocated. + SymbolRef FailedReallocSymbol; - static void *getTag() { - static int Tag = 0; - return &Tag; - } + // A C++ destructor stack frame in which memory was released. Used for + // miscellaneous false positive suppression. + const StackFrameContext *ReleaseDestructorLC; - void Profile(llvm::FoldingSetNodeID &ID) const override { - ID.AddPointer(getTag()); - ID.AddPointer(Sym); - } + bool IsLeak; - inline bool isAllocated(const RefState *S, const RefState *SPrev, - const Stmt *Stmt) { - // Did not track -> allocated. Other state (released) -> allocated. - return (Stmt && (isa(Stmt) || isa(Stmt)) && - (S && (S->isAllocated() || S->isAllocatedOfSizeZero())) && - (!SPrev || !(SPrev->isAllocated() || - SPrev->isAllocatedOfSizeZero()))); - } +public: + MallocBugVisitor(SymbolRef S, bool isLeak = false) + : Sym(S), Mode(Normal), FailedReallocSymbol(nullptr), + ReleaseDestructorLC(nullptr), IsLeak(isLeak) {} + + static void *getTag() { + static int Tag = 0; + return &Tag; + } + + void Profile(llvm::FoldingSetNodeID &ID) const override { + ID.AddPointer(getTag()); + ID.AddPointer(Sym); + } + + /// Did not track -> allocated. Other state (released) -> allocated. + static inline bool isAllocated(const RefState *RSCurr, const RefState *RSPrev, + const Stmt *Stmt) { + return (Stmt && (isa(Stmt) || isa(Stmt)) && + (RSCurr && (RSCurr->isAllocated() || + RSCurr->isAllocatedOfSizeZero())) && + (!RSPrev || !(RSPrev->isAllocated() || + RSPrev->isAllocatedOfSizeZero()))); + } + + /// Did not track -> released. Other state (allocated) -> released. + /// The statement associated with the release might be missing. + static inline bool isReleased(const RefState *RSCurr, const RefState *RSPrev, + const Stmt *Stmt) { + bool IsReleased = (RSCurr && RSCurr->isReleased()) && + (!RSPrev || !RSPrev->isReleased()); + assert(!IsReleased || + (Stmt && (isa(Stmt) || isa(Stmt))) || + (!Stmt && RSCurr->getAllocationFamily() == AF_InnerBuffer)); + return IsReleased; + } + + /// Did not track -> relinquished. Other state (allocated) -> relinquished. + static inline bool isRelinquished(const RefState *RSCurr, + const RefState *RSPrev, + const Stmt *Stmt) { + return (Stmt && (isa(Stmt) || isa(Stmt) || + isa(Stmt)) && + (RSCurr && RSCurr->isRelinquished()) && + (!RSPrev || !RSPrev->isRelinquished())); + } + + /// If the expression is not a call, and the state change is + /// released -> allocated, it must be the realloc return value + /// check. If we have to handle more cases here, it might be cleaner just + /// to track this extra bit in the state itself. + static inline bool hasReallocFailed(const RefState *RSCurr, + const RefState *RSPrev, + const Stmt *Stmt) { + return ((!Stmt || !isa(Stmt)) && + (RSCurr && (RSCurr->isAllocated() || + RSCurr->isAllocatedOfSizeZero())) && + (RSPrev && !(RSPrev->isAllocated() || + RSPrev->isAllocatedOfSizeZero()))); + } + + std::shared_ptr VisitNode(const ExplodedNode *N, + BugReporterContext &BRC, + BugReport &BR) override; + + std::shared_ptr + getEndPath(BugReporterContext &BRC, const ExplodedNode *EndPathNode, + BugReport &BR) override { + if (!IsLeak) + return nullptr; - inline bool isReleased(const RefState *S, const RefState *SPrev, - const Stmt *Stmt) { - // Did not track -> released. Other state (allocated) -> released. - // The statement associated with the release might be missing. - bool IsReleased = (S && S->isReleased()) && - (!SPrev || !SPrev->isReleased()); - assert(!IsReleased || - (Stmt && (isa(Stmt) || isa(Stmt))) || - (!Stmt && S->getAllocationFamily() == AF_InnerBuffer)); - return IsReleased; - } + PathDiagnosticLocation L = + PathDiagnosticLocation::createEndOfPath(EndPathNode, + BRC.getSourceManager()); + // Do not add the statement itself as a range in case of leak. + return std::make_shared(L, BR.getDescription(), + false); + } - inline bool isRelinquished(const RefState *S, const RefState *SPrev, - const Stmt *Stmt) { - // Did not track -> relinquished. Other state (allocated) -> relinquished. - return (Stmt && (isa(Stmt) || isa(Stmt) || - isa(Stmt)) && - (S && S->isRelinquished()) && - (!SPrev || !SPrev->isRelinquished())); - } +private: + class StackHintGeneratorForReallocationFailed + : public StackHintGeneratorForSymbol { + public: + StackHintGeneratorForReallocationFailed(SymbolRef S, StringRef M) + : StackHintGeneratorForSymbol(S, M) {} - inline bool isReallocFailedCheck(const RefState *S, const RefState *SPrev, - const Stmt *Stmt) { - // If the expression is not a call, and the state change is - // released -> allocated, it must be the realloc return value - // check. If we have to handle more cases here, it might be cleaner just - // to track this extra bit in the state itself. - return ((!Stmt || !isa(Stmt)) && - (S && (S->isAllocated() || S->isAllocatedOfSizeZero())) && - (SPrev && !(SPrev->isAllocated() || - SPrev->isAllocatedOfSizeZero()))); - } + std::string getMessageForArg(const Expr *ArgE, + unsigned ArgIndex) override { + // Printed parameters start at 1, not 0. + ++ArgIndex; - std::shared_ptr VisitNode(const ExplodedNode *N, - BugReporterContext &BRC, - BugReport &BR) override; + SmallString<200> buf; + llvm::raw_svector_ostream os(buf); - std::shared_ptr - getEndPath(BugReporterContext &BRC, const ExplodedNode *EndPathNode, - BugReport &BR) override { - if (!IsLeak) - return nullptr; + os << "Reallocation of " << ArgIndex << llvm::getOrdinalSuffix(ArgIndex) + << " parameter failed"; - PathDiagnosticLocation L = - PathDiagnosticLocation::createEndOfPath(EndPathNode, - BRC.getSourceManager()); - // Do not add the statement itself as a range in case of leak. - return std::make_shared(L, BR.getDescription(), - false); + return os.str(); } - private: - class StackHintGeneratorForReallocationFailed - : public StackHintGeneratorForSymbol { - public: - StackHintGeneratorForReallocationFailed(SymbolRef S, StringRef M) - : StackHintGeneratorForSymbol(S, M) {} - - std::string getMessageForArg(const Expr *ArgE, - unsigned ArgIndex) override { - // Printed parameters start at 1, not 0. - ++ArgIndex; - - SmallString<200> buf; - llvm::raw_svector_ostream os(buf); - - os << "Reallocation of " << ArgIndex << llvm::getOrdinalSuffix(ArgIndex) - << " parameter failed"; - - return os.str(); - } - - std::string getMessageForReturn(const CallExpr *CallExpr) override { - return "Reallocation of returned value failed"; - } - }; + std::string getMessageForReturn(const CallExpr *CallExpr) override { + return "Reallocation of returned value failed"; + } }; }; -} // end anonymous namespace - -REGISTER_MAP_WITH_PROGRAMSTATE(RegionState, SymbolRef, RefState) -REGISTER_MAP_WITH_PROGRAMSTATE(ReallocPairs, SymbolRef, ReallocPair) -REGISTER_SET_WITH_PROGRAMSTATE(ReallocSizeZeroSymbols, SymbolRef) // A map from the freed symbol to the symbol representing the return value of // the free function. @@ -585,7 +828,11 @@ public: }; } // end anonymous namespace -void MallocChecker::initIdentifierInfo(ASTContext &Ctx) const { +//===----------------------------------------------------------------------===// +// Methods of MemFunctionInfoTy. +//===----------------------------------------------------------------------===// + +void MemFunctionInfoTy::initIdentifierInfo(ASTContext &Ctx) const { if (II_malloc) return; II_alloca = &Ctx.Idents.get("alloca"); @@ -624,7 +871,8 @@ void MallocChecker::initIdentifierInfo(ASTContext &Ctx) const { II_g_try_realloc_n = &Ctx.Idents.get("g_try_realloc_n"); } -bool MallocChecker::isMemFunction(const FunctionDecl *FD, ASTContext &C) const { +bool MemFunctionInfoTy::isMemFunction(const FunctionDecl *FD, + ASTContext &C) const { if (isCMemFunction(FD, C, AF_Malloc, MemoryOperationKind::MOK_Any)) return true; @@ -640,10 +888,10 @@ bool MallocChecker::isMemFunction(const FunctionDecl *FD, ASTContext &C) const { return false; } -bool MallocChecker::isCMemFunction(const FunctionDecl *FD, - ASTContext &C, - AllocationFamily Family, - MemoryOperationKind MemKind) const { +bool MemFunctionInfoTy::isCMemFunction(const FunctionDecl *FD, + ASTContext &C, + AllocationFamily Family, + MemoryOperationKind MemKind) const { if (!FD) return false; @@ -696,7 +944,7 @@ bool MallocChecker::isCMemFunction(const FunctionDecl *FD, if (Family != AF_Malloc) return false; - if (IsOptimistic && FD->hasAttrs()) { + if (ShouldIncludeOwnershipAnnotatedFunctions && FD->hasAttrs()) { for (const auto *I : FD->specific_attrs()) { OwnershipAttr::OwnershipKind OwnKind = I->getOwnKind(); if(OwnKind == OwnershipAttr::Takes || OwnKind == OwnershipAttr::Holds) { @@ -711,10 +959,7 @@ bool MallocChecker::isCMemFunction(const FunctionDecl *FD, return false; } - -// Tells if the callee is one of the builtin new/delete operators, including -// placement operators and other standard overloads. -bool MallocChecker::isStandardNewDelete(const FunctionDecl *FD, +bool MemFunctionInfoTy::isStandardNewDelete(const FunctionDecl *FD, ASTContext &C) const { if (!FD) return false; @@ -731,6 +976,10 @@ bool MallocChecker::isStandardNewDelete(const FunctionDecl *FD, return !L.isValid() || C.getSourceManager().isInSystemHeader(L); } +//===----------------------------------------------------------------------===// +// Methods of MallocChecker and MallocBugVisitor. +//===----------------------------------------------------------------------===// + llvm::Optional MallocChecker::performKernelMalloc( const CallExpr *CE, CheckerContext &C, const ProgramStateRef &State) const { // 3-argument malloc(), as commonly used in {Free,Net,Open}BSD Kernels: @@ -829,28 +1078,35 @@ void MallocChecker::checkPostStmt(const CallExpr *CE, CheckerContext &C) const { return; ProgramStateRef State = C.getState(); - bool ReleasedAllocatedMemory = false; + bool IsKnownToBeAllocatedMemory = false; if (FD->getKind() == Decl::Function) { - initIdentifierInfo(C.getASTContext()); + MemFunctionInfo.initIdentifierInfo(C.getASTContext()); IdentifierInfo *FunI = FD->getIdentifier(); - if (FunI == II_malloc || FunI == II_g_malloc || FunI == II_g_try_malloc) { - if (CE->getNumArgs() < 1) + if (FunI == MemFunctionInfo.II_malloc || + FunI == MemFunctionInfo.II_g_malloc || + FunI == MemFunctionInfo.II_g_try_malloc) { + switch(CE->getNumArgs()) { + default: return; - if (CE->getNumArgs() < 3) { + case 1: + State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State); + State = ProcessZeroAllocCheck(C, CE, 0, State); + break; + case 2: State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State); - if (CE->getNumArgs() == 1) - State = ProcessZeroAllocation(C, CE, 0, State); - } else if (CE->getNumArgs() == 3) { + break; + case 3: llvm::Optional MaybeState = performKernelMalloc(CE, C, State); if (MaybeState.hasValue()) State = MaybeState.getValue(); else State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State); + break; } - } else if (FunI == II_kmalloc) { + } else if (FunI == MemFunctionInfo.II_kmalloc) { if (CE->getNumArgs() < 1) return; llvm::Optional MaybeState = @@ -859,97 +1115,112 @@ void MallocChecker::checkPostStmt(const CallExpr *CE, CheckerContext &C) const { State = MaybeState.getValue(); else State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State); - } else if (FunI == II_valloc) { + } else if (FunI == MemFunctionInfo.II_valloc) { if (CE->getNumArgs() < 1) return; State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State); - State = ProcessZeroAllocation(C, CE, 0, State); - } else if (FunI == II_realloc || FunI == II_g_realloc || - FunI == II_g_try_realloc) { - State = ReallocMemAux(C, CE, false, State); - State = ProcessZeroAllocation(C, CE, 1, State); - } else if (FunI == II_reallocf) { - State = ReallocMemAux(C, CE, true, State); - State = ProcessZeroAllocation(C, CE, 1, State); - } else if (FunI == II_calloc) { + State = ProcessZeroAllocCheck(C, CE, 0, State); + } else if (FunI == MemFunctionInfo.II_realloc || + FunI == MemFunctionInfo.II_g_realloc || + FunI == MemFunctionInfo.II_g_try_realloc) { + State = ReallocMemAux(C, CE, /*ShouldFreeOnFail*/false, State); + State = ProcessZeroAllocCheck(C, CE, 1, State); + } else if (FunI == MemFunctionInfo.II_reallocf) { + State = ReallocMemAux(C, CE, /*ShouldFreeOnFail*/true, State); + State = ProcessZeroAllocCheck(C, CE, 1, State); + } else if (FunI == MemFunctionInfo.II_calloc) { State = CallocMem(C, CE, State); - State = ProcessZeroAllocation(C, CE, 0, State); - State = ProcessZeroAllocation(C, CE, 1, State); - } else if (FunI == II_free || FunI == II_g_free) { - State = FreeMemAux(C, CE, State, 0, false, ReleasedAllocatedMemory); - } else if (FunI == II_strdup || FunI == II_win_strdup || - FunI == II_wcsdup || FunI == II_win_wcsdup) { + State = ProcessZeroAllocCheck(C, CE, 0, State); + State = ProcessZeroAllocCheck(C, CE, 1, State); + } else if (FunI == MemFunctionInfo.II_free || + FunI == MemFunctionInfo.II_g_free) { + State = FreeMemAux(C, CE, State, 0, false, IsKnownToBeAllocatedMemory); + } else if (FunI == MemFunctionInfo.II_strdup || + FunI == MemFunctionInfo.II_win_strdup || + FunI == MemFunctionInfo.II_wcsdup || + FunI == MemFunctionInfo.II_win_wcsdup) { State = MallocUpdateRefState(C, CE, State); - } else if (FunI == II_strndup) { + } else if (FunI == MemFunctionInfo.II_strndup) { State = MallocUpdateRefState(C, CE, State); - } else if (FunI == II_alloca || FunI == II_win_alloca) { + } else if (FunI == MemFunctionInfo.II_alloca || + FunI == MemFunctionInfo.II_win_alloca) { if (CE->getNumArgs() < 1) return; State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State, AF_Alloca); - State = ProcessZeroAllocation(C, CE, 0, State); - } else if (isStandardNewDelete(FD, C.getASTContext())) { + State = ProcessZeroAllocCheck(C, CE, 0, State); + } else if (MemFunctionInfo.isStandardNewDelete(FD, C.getASTContext())) { // Process direct calls to operator new/new[]/delete/delete[] functions // as distinct from new/new[]/delete/delete[] expressions that are // processed by the checkPostStmt callbacks for CXXNewExpr and // CXXDeleteExpr. - OverloadedOperatorKind K = FD->getOverloadedOperator(); - if (K == OO_New) { + switch(FD->getOverloadedOperator()) { + case OO_New: State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State, AF_CXXNew); - State = ProcessZeroAllocation(C, CE, 0, State); - } - else if (K == OO_Array_New) { + State = ProcessZeroAllocCheck(C, CE, 0, State); + break; + case OO_Array_New: State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State, AF_CXXNewArray); - State = ProcessZeroAllocation(C, CE, 0, State); - } - else if (K == OO_Delete || K == OO_Array_Delete) - State = FreeMemAux(C, CE, State, 0, false, ReleasedAllocatedMemory); - else + State = ProcessZeroAllocCheck(C, CE, 0, State); + break; + case OO_Delete: + case OO_Array_Delete: + State = FreeMemAux(C, CE, State, 0, false, IsKnownToBeAllocatedMemory); + break; + default: llvm_unreachable("not a new/delete operator"); - } else if (FunI == II_if_nameindex) { + } + } else if (FunI == MemFunctionInfo.II_if_nameindex) { // Should we model this differently? We can allocate a fixed number of // elements with zeros in the last one. State = MallocMemAux(C, CE, UnknownVal(), UnknownVal(), State, AF_IfNameIndex); - } else if (FunI == II_if_freenameindex) { - State = FreeMemAux(C, CE, State, 0, false, ReleasedAllocatedMemory); - } else if (FunI == II_g_malloc0 || FunI == II_g_try_malloc0) { + } else if (FunI == MemFunctionInfo.II_if_freenameindex) { + State = FreeMemAux(C, CE, State, 0, false, IsKnownToBeAllocatedMemory); + } else if (FunI == MemFunctionInfo.II_g_malloc0 || + FunI == MemFunctionInfo.II_g_try_malloc0) { if (CE->getNumArgs() < 1) return; SValBuilder &svalBuilder = C.getSValBuilder(); SVal zeroVal = svalBuilder.makeZeroVal(svalBuilder.getContext().CharTy); State = MallocMemAux(C, CE, CE->getArg(0), zeroVal, State); - State = ProcessZeroAllocation(C, CE, 0, State); - } else if (FunI == II_g_memdup) { + State = ProcessZeroAllocCheck(C, CE, 0, State); + } else if (FunI == MemFunctionInfo.II_g_memdup) { if (CE->getNumArgs() < 2) return; State = MallocMemAux(C, CE, CE->getArg(1), UndefinedVal(), State); - State = ProcessZeroAllocation(C, CE, 1, State); - } else if (FunI == II_g_malloc_n || FunI == II_g_try_malloc_n || - FunI == II_g_malloc0_n || FunI == II_g_try_malloc0_n) { + State = ProcessZeroAllocCheck(C, CE, 1, State); + } else if (FunI == MemFunctionInfo.II_g_malloc_n || + FunI == MemFunctionInfo.II_g_try_malloc_n || + FunI == MemFunctionInfo.II_g_malloc0_n || + FunI == MemFunctionInfo.II_g_try_malloc0_n) { if (CE->getNumArgs() < 2) return; SVal Init = UndefinedVal(); - if (FunI == II_g_malloc0_n || FunI == II_g_try_malloc0_n) { + if (FunI == MemFunctionInfo.II_g_malloc0_n || + FunI == MemFunctionInfo.II_g_try_malloc0_n) { SValBuilder &SB = C.getSValBuilder(); Init = SB.makeZeroVal(SB.getContext().CharTy); } SVal TotalSize = evalMulForBufferSize(C, CE->getArg(0), CE->getArg(1)); State = MallocMemAux(C, CE, TotalSize, Init, State); - State = ProcessZeroAllocation(C, CE, 0, State); - State = ProcessZeroAllocation(C, CE, 1, State); - } else if (FunI == II_g_realloc_n || FunI == II_g_try_realloc_n) { + State = ProcessZeroAllocCheck(C, CE, 0, State); + State = ProcessZeroAllocCheck(C, CE, 1, State); + } else if (FunI == MemFunctionInfo.II_g_realloc_n || + FunI == MemFunctionInfo.II_g_try_realloc_n) { if (CE->getNumArgs() < 3) return; - State = ReallocMemAux(C, CE, false, State, true); - State = ProcessZeroAllocation(C, CE, 1, State); - State = ProcessZeroAllocation(C, CE, 2, State); + State = ReallocMemAux(C, CE, /*ShouldFreeOnFail*/false, State, + /*SuffixWithN*/true); + State = ProcessZeroAllocCheck(C, CE, 1, State); + State = ProcessZeroAllocCheck(C, CE, 2, State); } } - if (IsOptimistic || ChecksEnabled[CK_MismatchedDeallocatorChecker]) { + if (MemFunctionInfo.ShouldIncludeOwnershipAnnotatedFunctions || + ChecksEnabled[CK_MismatchedDeallocatorChecker]) { // Check all the attributes, if there are any. // There can be multiple of these attributes. if (FD->hasAttrs()) @@ -969,9 +1240,9 @@ void MallocChecker::checkPostStmt(const CallExpr *CE, CheckerContext &C) const { } // Performs a 0-sized allocations check. -ProgramStateRef MallocChecker::ProcessZeroAllocation( - CheckerContext &C, const Expr *E, const unsigned AllocationSizeArg, - ProgramStateRef State, Optional RetVal) const { +ProgramStateRef MallocChecker::ProcessZeroAllocCheck( + CheckerContext &C, const Expr *E, const unsigned IndexOfSizeArg, + ProgramStateRef State, Optional RetVal) { if (!State) return nullptr; @@ -981,7 +1252,7 @@ ProgramStateRef MallocChecker::ProcessZeroAllocation( const Expr *Arg = nullptr; if (const CallExpr *CE = dyn_cast(E)) { - Arg = CE->getArg(AllocationSizeArg); + Arg = CE->getArg(IndexOfSizeArg); } else if (const CXXNewExpr *NE = dyn_cast(E)) { if (NE->isArray()) @@ -1043,7 +1314,9 @@ static QualType getDeepPointeeType(QualType T) { return Result; } -static bool treatUnusedNewEscaped(const CXXNewExpr *NE) { +/// \returns true if the constructor invoked by \p NE has an argument of a +/// pointer/reference to a record type. +static bool hasNonTrivialConstructorCall(const CXXNewExpr *NE) { const CXXConstructExpr *ConstructE = NE->getConstructExpr(); if (!ConstructE) @@ -1073,11 +1346,17 @@ static bool treatUnusedNewEscaped(const CXXNewExpr *NE) { void MallocChecker::processNewAllocation(const CXXNewExpr *NE, CheckerContext &C, SVal Target) const { - if (!isStandardNewDelete(NE->getOperatorNew(), C.getASTContext())) + if (!MemFunctionInfo.isStandardNewDelete(NE->getOperatorNew(), + C.getASTContext())) return; ParentMap &PM = C.getLocationContext()->getParentMap(); - if (!PM.isConsumedExpr(NE) && treatUnusedNewEscaped(NE)) + + // Non-trivial constructors have a chance to escape 'this', but marking all + // invocations of trivial constructors as escaped would cause too great of + // reduction of true positives, so let's just do that for constructors that + // have an argument of a pointer-to-record type. + if (!PM.isConsumedExpr(NE) && hasNonTrivialConstructorCall(NE)) return; ProgramStateRef State = C.getState(); @@ -1088,7 +1367,7 @@ void MallocChecker::processNewAllocation(const CXXNewExpr *NE, State = MallocUpdateRefState(C, NE, State, NE->isArray() ? AF_CXXNewArray : AF_CXXNew, Target); State = addExtentSize(C, NE, State, Target); - State = ProcessZeroAllocation(C, NE, 0, State, Target); + State = ProcessZeroAllocCheck(C, NE, 0, State, Target); C.addTransition(State); } @@ -1157,13 +1436,14 @@ void MallocChecker::checkPreStmt(const CXXDeleteExpr *DE, if (SymbolRef Sym = C.getSVal(DE->getArgument()).getAsSymbol()) checkUseAfterFree(Sym, C, DE->getArgument()); - if (!isStandardNewDelete(DE->getOperatorDelete(), C.getASTContext())) + if (!MemFunctionInfo.isStandardNewDelete(DE->getOperatorDelete(), + C.getASTContext())) return; ProgramStateRef State = C.getState(); - bool ReleasedAllocated; + bool IsKnownToBeAllocated; State = FreeMemAux(C, DE->getArgument(), DE, State, - /*Hold*/false, ReleasedAllocated); + /*Hold*/false, IsKnownToBeAllocated); C.addTransition(State); } @@ -1203,10 +1483,10 @@ void MallocChecker::checkPostObjCMessage(const ObjCMethodCall &Call, if (!*FreeWhenDone) return; - bool ReleasedAllocatedMemory; + bool IsKnownToBeAllocatedMemory; ProgramStateRef State = FreeMemAux(C, Call.getArgExpr(0), Call.getOriginExpr(), C.getState(), - /*Hold=*/true, ReleasedAllocatedMemory, + /*Hold=*/true, IsKnownToBeAllocatedMemory, /*RetNullOnFailure=*/true); C.addTransition(State); @@ -1219,7 +1499,7 @@ MallocChecker::MallocMemReturnsAttr(CheckerContext &C, const CallExpr *CE, if (!State) return nullptr; - if (Att->getModule() != II_malloc) + if (Att->getModule() != MemFunctionInfo.II_malloc) return nullptr; OwnershipAttr::args_iterator I = Att->args_begin(), E = Att->args_end(); @@ -1285,11 +1565,9 @@ ProgramStateRef MallocChecker::MallocMemAux(CheckerContext &C, return MallocUpdateRefState(C, CE, State, Family); } -ProgramStateRef MallocChecker::MallocUpdateRefState(CheckerContext &C, - const Expr *E, - ProgramStateRef State, - AllocationFamily Family, - Optional RetVal) { +static ProgramStateRef +MallocUpdateRefState(CheckerContext &C, const Expr *E, ProgramStateRef State, + AllocationFamily Family, Optional RetVal) { if (!State) return nullptr; @@ -1317,15 +1595,15 @@ ProgramStateRef MallocChecker::FreeMemAttr(CheckerContext &C, if (!State) return nullptr; - if (Att->getModule() != II_malloc) + if (Att->getModule() != MemFunctionInfo.II_malloc) return nullptr; - bool ReleasedAllocated = false; + bool IsKnownToBeAllocated = false; for (const auto &Arg : Att->args()) { ProgramStateRef StateI = FreeMemAux( C, CE, State, Arg.getASTIndex(), - Att->getOwnKind() == OwnershipAttr::Holds, ReleasedAllocated); + Att->getOwnKind() == OwnershipAttr::Holds, IsKnownToBeAllocated); if (StateI) State = StateI; } @@ -1337,7 +1615,7 @@ ProgramStateRef MallocChecker::FreeMemAux(CheckerContext &C, ProgramStateRef State, unsigned Num, bool Hold, - bool &ReleasedAllocated, + bool &IsKnownToBeAllocated, bool ReturnsNullOnFailure) const { if (!State) return nullptr; @@ -1346,7 +1624,7 @@ ProgramStateRef MallocChecker::FreeMemAux(CheckerContext &C, return nullptr; return FreeMemAux(C, CE->getArg(Num), CE, State, Hold, - ReleasedAllocated, ReturnsNullOnFailure); + IsKnownToBeAllocated, ReturnsNullOnFailure); } /// Checks if the previous call to free on the given symbol failed - if free @@ -1364,8 +1642,9 @@ static bool didPreviousFreeFail(ProgramStateRef State, return false; } -AllocationFamily MallocChecker::getAllocationFamily(CheckerContext &C, - const Stmt *S) const { +static AllocationFamily getAllocationFamily( + const MemFunctionInfoTy &MemFunctionInfo, CheckerContext &C, const Stmt *S) { + if (!S) return AF_None; @@ -1377,10 +1656,10 @@ AllocationFamily MallocChecker::getAllocationFamily(CheckerContext &C, ASTContext &Ctx = C.getASTContext(); - if (isCMemFunction(FD, Ctx, AF_Malloc, MemoryOperationKind::MOK_Any)) + if (MemFunctionInfo.isCMemFunction(FD, Ctx, AF_Malloc, MemoryOperationKind::MOK_Any)) return AF_Malloc; - if (isStandardNewDelete(FD, Ctx)) { + if (MemFunctionInfo.isStandardNewDelete(FD, Ctx)) { OverloadedOperatorKind Kind = FD->getOverloadedOperator(); if (Kind == OO_New || Kind == OO_Delete) return AF_CXXNew; @@ -1388,10 +1667,12 @@ AllocationFamily MallocChecker::getAllocationFamily(CheckerContext &C, return AF_CXXNewArray; } - if (isCMemFunction(FD, Ctx, AF_IfNameIndex, MemoryOperationKind::MOK_Any)) + if (MemFunctionInfo.isCMemFunction(FD, Ctx, AF_IfNameIndex, + MemoryOperationKind::MOK_Any)) return AF_IfNameIndex; - if (isCMemFunction(FD, Ctx, AF_Alloca, MemoryOperationKind::MOK_Any)) + if (MemFunctionInfo.isCMemFunction(FD, Ctx, AF_Alloca, + MemoryOperationKind::MOK_Any)) return AF_Alloca; return AF_None; @@ -1409,8 +1690,8 @@ AllocationFamily MallocChecker::getAllocationFamily(CheckerContext &C, return AF_None; } -bool MallocChecker::printAllocDeallocName(raw_ostream &os, CheckerContext &C, - const Expr *E) const { +static bool printAllocDeallocName(raw_ostream &os, CheckerContext &C, + const Expr *E) { if (const CallExpr *CE = dyn_cast(E)) { // FIXME: This doesn't handle indirect calls. const FunctionDecl *FD = CE->getDirectCallee(); @@ -1449,9 +1730,10 @@ bool MallocChecker::printAllocDeallocName(raw_ostream &os, CheckerContext &C, return false; } -void MallocChecker::printExpectedAllocName(raw_ostream &os, CheckerContext &C, - const Expr *E) const { - AllocationFamily Family = getAllocationFamily(C, E); +static void printExpectedAllocName(raw_ostream &os, + const MemFunctionInfoTy &MemFunctionInfo, + CheckerContext &C, const Expr *E) { + AllocationFamily Family = getAllocationFamily(MemFunctionInfo, C, E); switch(Family) { case AF_Malloc: os << "malloc()"; return; @@ -1464,8 +1746,7 @@ void MallocChecker::printExpectedAllocName(raw_ostream &os, CheckerContext &C, } } -void MallocChecker::printExpectedDeallocName(raw_ostream &os, - AllocationFamily Family) const { +static void printExpectedDeallocName(raw_ostream &os, AllocationFamily Family) { switch(Family) { case AF_Malloc: os << "free()"; return; case AF_CXXNew: os << "'delete'"; return; @@ -1482,7 +1763,7 @@ ProgramStateRef MallocChecker::FreeMemAux(CheckerContext &C, const Expr *ParentExpr, ProgramStateRef State, bool Hold, - bool &ReleasedAllocated, + bool &IsKnownToBeAllocated, bool ReturnsNullOnFailure) const { if (!State) @@ -1556,6 +1837,9 @@ ProgramStateRef MallocChecker::FreeMemAux(CheckerContext &C, const RefState *RsBase = State->get(SymBase); SymbolRef PreviousRetStatusSymbol = nullptr; + IsKnownToBeAllocated = RsBase && (RsBase->isAllocated() || + RsBase->isAllocatedOfSizeZero()); + if (RsBase) { // Memory returned by alloca() shouldn't be freed. @@ -1578,7 +1862,8 @@ ProgramStateRef MallocChecker::FreeMemAux(CheckerContext &C, // Check if an expected deallocation function matches the real one. bool DeallocMatchesAlloc = - RsBase->getAllocationFamily() == getAllocationFamily(C, ParentExpr); + RsBase->getAllocationFamily() == + getAllocationFamily(MemFunctionInfo, C, ParentExpr); if (!DeallocMatchesAlloc) { ReportMismatchedDealloc(C, ArgExpr->getSourceRange(), ParentExpr, RsBase, SymBase, Hold); @@ -1604,9 +1889,6 @@ ProgramStateRef MallocChecker::FreeMemAux(CheckerContext &C, return nullptr; } - ReleasedAllocated = (RsBase != nullptr) && (RsBase->isAllocated() || - RsBase->isAllocatedOfSizeZero()); - // Clean out the info on previous call to free return info. State = State->remove(SymBase); @@ -1622,7 +1904,7 @@ ProgramStateRef MallocChecker::FreeMemAux(CheckerContext &C, } AllocationFamily Family = RsBase ? RsBase->getAllocationFamily() - : getAllocationFamily(C, ParentExpr); + : getAllocationFamily(MemFunctionInfo, C, ParentExpr); // Normal free. if (Hold) return State->set(SymBase, @@ -1672,8 +1954,8 @@ Optional MallocChecker::getCheckIfTracked(CheckerContext &C, const Stmt *AllocDeallocStmt, bool IsALeakCheck) const { - return getCheckIfTracked(getAllocationFamily(C, AllocDeallocStmt), - IsALeakCheck); + return getCheckIfTracked( + getAllocationFamily(MemFunctionInfo, C, AllocDeallocStmt), IsALeakCheck); } Optional @@ -1811,7 +2093,7 @@ void MallocChecker::ReportBadFree(CheckerContext &C, SVal ArgVal, else os << "not memory allocated by "; - printExpectedAllocName(os, C, DeallocExpr); + printExpectedAllocName(os, MemFunctionInfo, C, DeallocExpr); auto R = llvm::make_unique(*BT_BadFree[*CheckKind], os.str(), N); R->markInteresting(MR); @@ -2118,7 +2400,7 @@ void MallocChecker::ReportFunctionPointerFree(CheckerContext &C, SVal ArgVal, ProgramStateRef MallocChecker::ReallocMemAux(CheckerContext &C, const CallExpr *CE, - bool FreesOnFail, + bool ShouldFreeOnFail, ProgramStateRef State, bool SuffixWithN) const { if (!State) @@ -2183,33 +2465,32 @@ ProgramStateRef MallocChecker::ReallocMemAux(CheckerContext &C, if (!FromPtr || !ToPtr) return nullptr; - bool ReleasedAllocated = false; + bool IsKnownToBeAllocated = false; // If the size is 0, free the memory. if (SizeIsZero) + // The semantics of the return value are: + // If size was equal to 0, either NULL or a pointer suitable to be passed + // to free() is returned. We just free the input pointer and do not add + // any constrains on the output pointer. if (ProgramStateRef stateFree = FreeMemAux(C, CE, StateSizeIsZero, 0, - false, ReleasedAllocated)){ - // The semantics of the return value are: - // If size was equal to 0, either NULL or a pointer suitable to be passed - // to free() is returned. We just free the input pointer and do not add - // any constrains on the output pointer. + false, IsKnownToBeAllocated)) return stateFree; - } // Default behavior. if (ProgramStateRef stateFree = - FreeMemAux(C, CE, State, 0, false, ReleasedAllocated)) { + FreeMemAux(C, CE, State, 0, false, IsKnownToBeAllocated)) { ProgramStateRef stateRealloc = MallocMemAux(C, CE, TotalSize, UnknownVal(), stateFree); if (!stateRealloc) return nullptr; - ReallocPairKind Kind = RPToBeFreedAfterFailure; - if (FreesOnFail) - Kind = RPIsFreeOnFailure; - else if (!ReleasedAllocated) - Kind = RPDoNotTrackAfterFailure; + OwnershipAfterReallocKind Kind = OAR_ToBeFreedAfterFailure; + if (ShouldFreeOnFail) + Kind = OAR_FreeOnFailure; + else if (!IsKnownToBeAllocated) + Kind = OAR_DoNotTrackAfterFailure; // Record the info about the reallocated symbol so that we could properly // process failed reallocation. @@ -2237,9 +2518,9 @@ ProgramStateRef MallocChecker::CallocMem(CheckerContext &C, const CallExpr *CE, return MallocMemAux(C, CE, TotalSize, zeroVal, State); } -LeakInfo +MallocChecker::LeakInfo MallocChecker::getAllocationSite(const ExplodedNode *N, SymbolRef Sym, - CheckerContext &C) const { + CheckerContext &C) { const LocationContext *LeakContext = N->getLocationContext(); // Walk the ExplodedGraph backwards and find the first node that referred to // the tracked symbol. @@ -2420,9 +2701,10 @@ void MallocChecker::checkPreCall(const CallEvent &Call, ASTContext &Ctx = C.getASTContext(); if (ChecksEnabled[CK_MallocChecker] && - (isCMemFunction(FD, Ctx, AF_Malloc, MemoryOperationKind::MOK_Free) || - isCMemFunction(FD, Ctx, AF_IfNameIndex, - MemoryOperationKind::MOK_Free))) + (MemFunctionInfo.isCMemFunction(FD, Ctx, AF_Malloc, + MemoryOperationKind::MOK_Free) || + MemFunctionInfo.isCMemFunction(FD, Ctx, AF_IfNameIndex, + MemoryOperationKind::MOK_Free))) return; } @@ -2525,7 +2807,7 @@ void MallocChecker::checkPostStmt(const BlockExpr *BE, C.addTransition(state); } -bool MallocChecker::isReleased(SymbolRef Sym, CheckerContext &C) const { +static bool isReleased(SymbolRef Sym, CheckerContext &C) { assert(Sym); const RefState *RS = C.getState()->get(Sym); return (RS && RS->isReleased()); @@ -2601,13 +2883,17 @@ ProgramStateRef MallocChecker::evalAssume(ProgramStateRef state, SymbolRef ReallocSym = I.getData().ReallocatedSym; if (const RefState *RS = state->get(ReallocSym)) { if (RS->isReleased()) { - if (I.getData().Kind == RPToBeFreedAfterFailure) + switch(I.getData().Kind) { + case OAR_ToBeFreedAfterFailure: state = state->set(ReallocSym, RefState::getAllocated(RS->getAllocationFamily(), RS->getStmt())); - else if (I.getData().Kind == RPDoNotTrackAfterFailure) + break; + case OAR_DoNotTrackAfterFailure: state = state->remove(ReallocSym); - else - assert(I.getData().Kind == RPIsFreeOnFailure); + break; + default: + assert(I.getData().Kind == OAR_FreeOnFailure); + } } } state = state->remove(I.getKey()); @@ -2690,7 +2976,7 @@ bool MallocChecker::mayFreeAnyEscapedMemoryOrIsModeledExplicitly( // If it's one of the allocation functions we can reason about, we model // its behavior explicitly. - if (isMemFunction(FD, ASTC)) + if (MemFunctionInfo.isMemFunction(FD, ASTC)) return false; // If it's not a system call, assume it frees memory. @@ -2782,10 +3068,6 @@ bool MallocChecker::mayFreeAnyEscapedMemoryOrIsModeledExplicitly( return false; } -static bool retTrue(const RefState *RS) { - return true; -} - static bool checkIfNewOrNewArrayFamily(const RefState *RS) { return (RS->getAllocationFamily() == AF_CXXNewArray || RS->getAllocationFamily() == AF_CXXNew); @@ -2795,22 +3077,25 @@ ProgramStateRef MallocChecker::checkPointerEscape(ProgramStateRef State, const InvalidatedSymbols &Escaped, const CallEvent *Call, PointerEscapeKind Kind) const { - return checkPointerEscapeAux(State, Escaped, Call, Kind, &retTrue); + return checkPointerEscapeAux(State, Escaped, Call, Kind, + /*IsConstPointerEscape*/ false); } ProgramStateRef MallocChecker::checkConstPointerEscape(ProgramStateRef State, const InvalidatedSymbols &Escaped, const CallEvent *Call, PointerEscapeKind Kind) const { + // If a const pointer escapes, it may not be freed(), but it could be deleted. return checkPointerEscapeAux(State, Escaped, Call, Kind, - &checkIfNewOrNewArrayFamily); + /*IsConstPointerEscape*/ true); } -ProgramStateRef MallocChecker::checkPointerEscapeAux(ProgramStateRef State, +ProgramStateRef MallocChecker::checkPointerEscapeAux( + ProgramStateRef State, const InvalidatedSymbols &Escaped, const CallEvent *Call, PointerEscapeKind Kind, - bool(*CheckRefState)(const RefState*)) const { + bool IsConstPointerEscape) const { // If we know that the call does not free memory, or we want to process the // call later, keep tracking the top level arguments. SymbolRef EscapingSymbol = nullptr; @@ -2830,10 +3115,11 @@ ProgramStateRef MallocChecker::checkPointerEscapeAux(ProgramStateRef State, continue; if (const RefState *RS = State->get(sym)) { - if ((RS->isAllocated() || RS->isAllocatedOfSizeZero()) && - CheckRefState(RS)) { - State = State->remove(sym); - State = State->set(sym, RefState::getEscaped(RS)); + if ((RS->isAllocated() || RS->isAllocatedOfSizeZero())) { + if (!IsConstPointerEscape || checkIfNewOrNewArrayFamily(RS)) { + State = State->remove(sym); + State = State->set(sym, RefState::getEscaped(RS)); + } } } } @@ -2845,9 +3131,8 @@ static SymbolRef findFailedReallocSymbol(ProgramStateRef currState, ReallocPairsTy currMap = currState->get(); ReallocPairsTy prevMap = prevState->get(); - for (ReallocPairsTy::iterator I = prevMap.begin(), E = prevMap.end(); - I != E; ++I) { - SymbolRef sym = I.getKey(); + for (const ReallocPairsTy::value_type &Pair : prevMap) { + SymbolRef sym = Pair.first; if (!currMap.lookup(sym)) return sym; } @@ -2868,19 +3153,19 @@ static bool isReferenceCountingPointerDestructor(const CXXDestructorDecl *DD) { return false; } -std::shared_ptr MallocChecker::MallocBugVisitor::VisitNode( +std::shared_ptr MallocBugVisitor::VisitNode( const ExplodedNode *N, BugReporterContext &BRC, BugReport &BR) { ProgramStateRef state = N->getState(); ProgramStateRef statePrev = N->getFirstPred()->getState(); - const RefState *RS = state->get(Sym); + const RefState *RSCurr = state->get(Sym); const RefState *RSPrev = statePrev->get(Sym); const Stmt *S = PathDiagnosticLocation::getStmt(N); // When dealing with containers, we sometimes want to give a note // even if the statement is missing. - if (!S && (!RS || RS->getAllocationFamily() != AF_InnerBuffer)) + if (!S && (!RSCurr || RSCurr->getAllocationFamily() != AF_InnerBuffer)) return nullptr; const LocationContext *CurrentLC = N->getLocationContext(); @@ -2915,12 +3200,12 @@ std::shared_ptr MallocChecker::MallocBugVisitor::VisitNode( llvm::raw_svector_ostream OS(Buf); if (Mode == Normal) { - if (isAllocated(RS, RSPrev, S)) { + if (isAllocated(RSCurr, RSPrev, S)) { Msg = "Memory is allocated"; StackHint = new StackHintGeneratorForSymbol(Sym, "Returned allocated memory"); - } else if (isReleased(RS, RSPrev, S)) { - const auto Family = RS->getAllocationFamily(); + } else if (isReleased(RSCurr, RSPrev, S)) { + const auto Family = RSCurr->getAllocationFamily(); switch (Family) { case AF_Alloca: case AF_Malloc: @@ -2944,7 +3229,7 @@ std::shared_ptr MallocChecker::MallocBugVisitor::VisitNode( "Returning; inner buffer was deallocated"); } else { OS << "reallocated by call to '"; - const Stmt *S = RS->getStmt(); + const Stmt *S = RSCurr->getStmt(); if (const auto *MemCallE = dyn_cast(S)) { OS << MemCallE->getMethodDecl()->getNameAsString(); } else if (const auto *OpCallE = dyn_cast(S)) { @@ -2995,10 +3280,10 @@ std::shared_ptr MallocChecker::MallocBugVisitor::VisitNode( } } } - } else if (isRelinquished(RS, RSPrev, S)) { + } else if (isRelinquished(RSCurr, RSPrev, S)) { Msg = "Memory ownership is transferred"; StackHint = new StackHintGeneratorForSymbol(Sym, ""); - } else if (isReallocFailedCheck(RS, RSPrev, S)) { + } else if (hasReallocFailed(RSCurr, RSPrev, S)) { Mode = ReallocationFailed; Msg = "Reallocation failed"; StackHint = new StackHintGeneratorForReallocationFailed(Sym, @@ -3035,7 +3320,7 @@ std::shared_ptr MallocChecker::MallocBugVisitor::VisitNode( // Generate the extra diagnostic. PathDiagnosticLocation Pos; if (!S) { - assert(RS->getAllocationFamily() == AF_InnerBuffer); + assert(RSCurr->getAllocationFamily() == AF_InnerBuffer); auto PostImplCall = N->getLocation().getAs(); if (!PostImplCall) return nullptr; @@ -3090,8 +3375,11 @@ markReleased(ProgramStateRef State, SymbolRef Sym, const Expr *Origin) { void ento::registerNewDeleteLeaksChecker(CheckerManager &mgr) { registerCStringCheckerBasic(mgr); MallocChecker *checker = mgr.registerChecker(); - checker->IsOptimistic = mgr.getAnalyzerOptions().getCheckerBooleanOption( - "Optimistic", false, checker); + + checker->MemFunctionInfo.ShouldIncludeOwnershipAnnotatedFunctions = + mgr.getAnalyzerOptions().getCheckerBooleanOption( + "Optimistic", false, checker); + checker->ChecksEnabled[MallocChecker::CK_NewDeleteLeaksChecker] = true; checker->CheckNames[MallocChecker::CK_NewDeleteLeaksChecker] = mgr.getCurrentCheckName(); @@ -3109,21 +3397,25 @@ void ento::registerNewDeleteLeaksChecker(CheckerManager &mgr) { // Intended to be used in InnerPointerChecker to register the part of // MallocChecker connected to it. void ento::registerInnerPointerCheckerAux(CheckerManager &mgr) { - registerCStringCheckerBasic(mgr); - MallocChecker *checker = mgr.registerChecker(); - checker->IsOptimistic = mgr.getAnalyzerOptions().getCheckerBooleanOption( - "Optimistic", false, checker); - checker->ChecksEnabled[MallocChecker::CK_InnerPointerChecker] = true; - checker->CheckNames[MallocChecker::CK_InnerPointerChecker] = - mgr.getCurrentCheckName(); + registerCStringCheckerBasic(mgr); + MallocChecker *checker = mgr.registerChecker(); + + checker->MemFunctionInfo.ShouldIncludeOwnershipAnnotatedFunctions = + mgr.getAnalyzerOptions().getCheckerBooleanOption( + "Optimistic", false, checker); + + checker->ChecksEnabled[MallocChecker::CK_InnerPointerChecker] = true; + checker->CheckNames[MallocChecker::CK_InnerPointerChecker] = + mgr.getCurrentCheckName(); } #define REGISTER_CHECKER(name) \ void ento::register##name(CheckerManager &mgr) { \ registerCStringCheckerBasic(mgr); \ MallocChecker *checker = mgr.registerChecker(); \ - checker->IsOptimistic = mgr.getAnalyzerOptions().getCheckerBooleanOption( \ - "Optimistic", false, checker); \ + checker->MemFunctionInfo.ShouldIncludeOwnershipAnnotatedFunctions = \ + mgr.getAnalyzerOptions().getCheckerBooleanOption( \ + "Optimistic", false, checker);\ checker->ChecksEnabled[MallocChecker::CK_##name] = true; \ checker->CheckNames[MallocChecker::CK_##name] = mgr.getCurrentCheckName(); \ } diff --git a/test/Analysis/malloc-annotations.c b/test/Analysis/malloc-annotations.c index 21eaab72b7..50a18c5b96 100644 --- a/test/Analysis/malloc-annotations.c +++ b/test/Analysis/malloc-annotations.c @@ -1,4 +1,8 @@ -// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.deadcode.UnreachableCode,alpha.core.CastSize,unix.Malloc -analyzer-store=region -verify -analyzer-config unix.Malloc:Optimistic=true %s +// RUN: %clang_analyze_cc1 -analyzer-store=region -verify %s \ +// RUN: -analyzer-checker=core \ +// RUN: -analyzer-checker=alpha.deadcode.UnreachableCode \ +// RUN: -analyzer-checker=alpha.core.CastSize,unix.Malloc \ +// RUN: -analyzer-config unix.Malloc:Optimistic=true typedef __typeof(sizeof(int)) size_t; void *malloc(size_t); void free(void *); diff --git a/test/Analysis/malloc.c b/test/Analysis/malloc.c index 3e86c29a55..8e0f5c04ca 100644 --- a/test/Analysis/malloc.c +++ b/test/Analysis/malloc.c @@ -1,4 +1,9 @@ -// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.deadcode.UnreachableCode,alpha.core.CastSize,unix.Malloc,debug.ExprInspection -analyzer-store=region -verify %s +// RUN: %clang_analyze_cc1 -analyzer-store=region -verify %s \ +// RUN: -analyzer-checker=core \ +// RUN: -analyzer-checker=alpha.deadcode.UnreachableCode \ +// RUN: -analyzer-checker=alpha.core.CastSize \ +// RUN: -analyzer-checker=unix.Malloc \ +// RUN: -analyzer-checker=debug.ExprInspection #include "Inputs/system-header-simulator.h" -- cgit v1.2.3 From 6ca50489452e99b9bd64e691d2488162b42be4d8 Mon Sep 17 00:00:00 2001 From: Kristof Umann Date: Sat, 15 Dec 2018 18:41:37 +0000 Subject: [analyzer][MallocChecker] Improve warning messages on double-delete errors Differential Revision: https://reviews.llvm.org/D54834 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349283 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/StaticAnalyzer/Checkers/MallocChecker.cpp | 12 ++++++++++-- .../expected-plists/NewDelete-path-notes.cpp.plist | 20 ++++++++++---------- .../Malloc+MismatchedDeallocator+NewDelete.cpp | 2 +- test/Analysis/NewDelete-checker-test.cpp | 2 +- test/Analysis/NewDelete-path-notes.cpp | 8 ++++---- test/Analysis/dtor.cpp | 2 +- 6 files changed, 27 insertions(+), 19 deletions(-) diff --git a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp index a5b774fe24..fb770eb9ee 100644 --- a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp @@ -1431,7 +1431,8 @@ ProgramStateRef MallocChecker::addExtentSize(CheckerContext &C, void MallocChecker::checkPreStmt(const CXXDeleteExpr *DE, CheckerContext &C) const { - + // This will regard deleting freed() regions as a use-after-free, rather then + // a double-free or double-delete error. if (!ChecksEnabled[CK_NewDeleteChecker]) if (SymbolRef Sym = C.getSVal(DE->getArgument()).getAsSymbol()) checkUseAfterFree(Sym, C, DE->getArgument()); @@ -1628,7 +1629,8 @@ ProgramStateRef MallocChecker::FreeMemAux(CheckerContext &C, } /// Checks if the previous call to free on the given symbol failed - if free -/// failed, returns true. Also, returns the corresponding return value symbol. +/// failed, returns true. Also, stores the corresponding return value symbol in +/// \p RetStatusSymbol. static bool didPreviousFreeFail(ProgramStateRef State, SymbolRef Sym, SymbolRef &RetStatusSymbol) { const SymbolRef *Ret = State->get(Sym); @@ -2289,6 +2291,12 @@ void MallocChecker::ReportDoubleFree(CheckerContext &C, SourceRange Range, if (!CheckKind.hasValue()) return; + // If this is a double delete error, print the appropiate warning message. + if (CheckKind == CK_NewDeleteChecker) { + ReportDoubleDelete(C, Sym); + return; + } + if (ExplodedNode *N = C.generateErrorNode()) { if (!BT_DoubleFree[*CheckKind]) BT_DoubleFree[*CheckKind].reset(new BugType( diff --git a/test/Analysis/Inputs/expected-plists/NewDelete-path-notes.cpp.plist b/test/Analysis/Inputs/expected-plists/NewDelete-path-notes.cpp.plist index d74d9fc7c6..6a3a3d30c4 100644 --- a/test/Analysis/Inputs/expected-plists/NewDelete-path-notes.cpp.plist +++ b/test/Analysis/Inputs/expected-plists/NewDelete-path-notes.cpp.plist @@ -194,17 +194,17 @@ depth0 extended_message - Attempt to free released memory + Attempt to delete released memory message - Attempt to free released memory + Attempt to delete released memory - descriptionAttempt to free released memory + descriptionAttempt to delete released memory categoryMemory error - typeDouble free + typeDouble delete check_namecplusplus.NewDelete - issue_hash_content_of_line_in_contextbd8e324d09c70b9e2be6f824a4942e5a + issue_hash_content_of_line_in_context593b185245106bed5175ccf2753039b2 issue_context_kindfunction issue_contexttest issue_hash_function_offset8 @@ -423,17 +423,17 @@ depth0 extended_message - Attempt to free released memory + Attempt to delete released memory message - Attempt to free released memory + Attempt to delete released memory - descriptionAttempt to free released memory + descriptionAttempt to delete released memory categoryMemory error - typeDouble free + typeDouble delete check_namecplusplus.NewDelete - issue_hash_content_of_line_in_context8bf1a5b9fdae9d86780aa6c4cdce2605 + issue_hash_content_of_line_in_context6484e9b006ede7362edef2187ba6eb37 issue_context_kindfunction issue_contexttest issue_hash_function_offset3 diff --git a/test/Analysis/Malloc+MismatchedDeallocator+NewDelete.cpp b/test/Analysis/Malloc+MismatchedDeallocator+NewDelete.cpp index b5e47b3355..e5176eb50f 100644 --- a/test/Analysis/Malloc+MismatchedDeallocator+NewDelete.cpp +++ b/test/Analysis/Malloc+MismatchedDeallocator+NewDelete.cpp @@ -46,7 +46,7 @@ void testMismatchedDeallocator() { void testNewDoubleFree() { int *p = new int; delete p; - delete p; // expected-warning{{Attempt to free released memory}} + delete p; // expected-warning{{Attempt to delete released memory}} } void testNewLeak() { diff --git a/test/Analysis/NewDelete-checker-test.cpp b/test/Analysis/NewDelete-checker-test.cpp index 620237cd6e..fcbe2c7402 100644 --- a/test/Analysis/NewDelete-checker-test.cpp +++ b/test/Analysis/NewDelete-checker-test.cpp @@ -182,7 +182,7 @@ void testUseThisAfterDelete() { void testDoubleDelete() { int *p = new int; delete p; - delete p; // expected-warning{{Attempt to free released memory}} + delete p; // expected-warning{{Attempt to delete released memory}} } void testExprDeleteArg() { diff --git a/test/Analysis/NewDelete-path-notes.cpp b/test/Analysis/NewDelete-path-notes.cpp index d9fe1976b8..94658360fb 100644 --- a/test/Analysis/NewDelete-path-notes.cpp +++ b/test/Analysis/NewDelete-path-notes.cpp @@ -11,8 +11,8 @@ void test() { delete p; // expected-note@-1 {{Memory is released}} - delete p; // expected-warning {{Attempt to free released memory}} - // expected-note@-1 {{Attempt to free released memory}} + delete p; // expected-warning {{Attempt to delete released memory}} + // expected-note@-1 {{Attempt to delete released memory}} } struct Odd { @@ -24,7 +24,7 @@ struct Odd { void test(Odd *odd) { odd->kill(); // expected-note{{Calling 'Odd::kill'}} // expected-note@-1 {{Returning; memory was released}} - delete odd; // expected-warning {{Attempt to free released memory}} - // expected-note@-1 {{Attempt to free released memory}} + delete odd; // expected-warning {{Attempt to delete released memory}} + // expected-note@-1 {{Attempt to delete released memory}} } diff --git a/test/Analysis/dtor.cpp b/test/Analysis/dtor.cpp index d843f03aad..2ea38e95c8 100644 --- a/test/Analysis/dtor.cpp +++ b/test/Analysis/dtor.cpp @@ -528,7 +528,7 @@ struct NonTrivial { return *this; } ~NonTrivial() { - delete[] p; // expected-warning {{free released memory}} + delete[] p; // expected-warning {{delete released memory}} } }; -- cgit v1.2.3 From 26546ec349da3daee235046a0e55bd4f82112cba Mon Sep 17 00:00:00 2001 From: Aaron Puchert Date: Sun, 16 Dec 2018 14:15:30 +0000 Subject: Thread safety analysis: Allow scoped releasing of capabilities Summary: The pattern is problematic with C++ exceptions, and not as widespread as scoped locks, but it's still used by some, for example Chromium. We are a bit stricter here at join points, patterns that are allowed for scoped locks aren't allowed here. That could still be changed in the future, but I'd argue we should only relax this if people ask for it. Fixes PR36162. Reviewers: aaron.ballman, delesley, pwnall Reviewed By: delesley, pwnall Subscribers: pwnall, cfe-commits Differential Revision: https://reviews.llvm.org/D52578 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349300 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Analysis/ThreadSafety.cpp | 112 +++++++++++++++++---------- test/SemaCXX/warn-thread-safety-analysis.cpp | 104 +++++++++++++++++++++++++ 2 files changed, 177 insertions(+), 39 deletions(-) diff --git a/lib/Analysis/ThreadSafety.cpp b/lib/Analysis/ThreadSafety.cpp index f83b0e0cab..ca146a83c6 100644 --- a/lib/Analysis/ThreadSafety.cpp +++ b/lib/Analysis/ThreadSafety.cpp @@ -42,6 +42,7 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/ImmutableMap.h" #include "llvm/ADT/Optional.h" +#include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" @@ -890,28 +891,46 @@ public: class ScopedLockableFactEntry : public FactEntry { private: - SmallVector UnderlyingMutexes; + enum UnderlyingCapabilityKind { + UCK_Acquired, ///< Any kind of acquired capability. + UCK_ReleasedShared, ///< Shared capability that was released. + UCK_ReleasedExclusive, ///< Exclusive capability that was released. + }; + + using UnderlyingCapability = + llvm::PointerIntPair; + + SmallVector UnderlyingMutexes; public: ScopedLockableFactEntry(const CapabilityExpr &CE, SourceLocation Loc, - const CapExprSet &Excl, const CapExprSet &Shrd) + const CapExprSet &Excl, const CapExprSet &Shrd, + const CapExprSet &ExclRel, const CapExprSet &ShrdRel) : FactEntry(CE, LK_Exclusive, Loc, false) { for (const auto &M : Excl) - UnderlyingMutexes.push_back(M.sexpr()); + UnderlyingMutexes.emplace_back(M.sexpr(), UCK_Acquired); for (const auto &M : Shrd) - UnderlyingMutexes.push_back(M.sexpr()); + UnderlyingMutexes.emplace_back(M.sexpr(), UCK_Acquired); + for (const auto &M : ExclRel) + UnderlyingMutexes.emplace_back(M.sexpr(), UCK_ReleasedExclusive); + for (const auto &M : ShrdRel) + UnderlyingMutexes.emplace_back(M.sexpr(), UCK_ReleasedShared); } void handleRemovalFromIntersection(const FactSet &FSet, FactManager &FactMan, SourceLocation JoinLoc, LockErrorKind LEK, ThreadSafetyHandler &Handler) const override { - for (const auto *UnderlyingMutex : UnderlyingMutexes) { - if (FSet.findLock(FactMan, CapabilityExpr(UnderlyingMutex, false))) { + for (const auto &UnderlyingMutex : UnderlyingMutexes) { + const auto *Entry = FSet.findLock( + FactMan, CapabilityExpr(UnderlyingMutex.getPointer(), false)); + if ((UnderlyingMutex.getInt() == UCK_Acquired && Entry) || + (UnderlyingMutex.getInt() != UCK_Acquired && !Entry)) { // If this scoped lock manages another mutex, and if the underlying - // mutex is still held, then warn about the underlying mutex. + // mutex is still/not held, then warn about the underlying mutex. Handler.handleMutexHeldEndOfScope( - "mutex", sx::toString(UnderlyingMutex), loc(), JoinLoc, LEK); + "mutex", sx::toString(UnderlyingMutex.getPointer()), loc(), JoinLoc, + LEK); } } } @@ -919,17 +938,14 @@ public: void handleLock(FactSet &FSet, FactManager &FactMan, const FactEntry &entry, ThreadSafetyHandler &Handler, StringRef DiagKind) const override { - for (const auto *UnderlyingMutex : UnderlyingMutexes) { - CapabilityExpr UnderCp(UnderlyingMutex, false); + for (const auto &UnderlyingMutex : UnderlyingMutexes) { + CapabilityExpr UnderCp(UnderlyingMutex.getPointer(), false); - // We're relocking the underlying mutexes. Warn on double locking. - if (FSet.findLock(FactMan, UnderCp)) { - Handler.handleDoubleLock(DiagKind, UnderCp.toString(), entry.loc()); - } else { - FSet.removeLock(FactMan, !UnderCp); - FSet.addLock(FactMan, llvm::make_unique( - UnderCp, entry.kind(), entry.loc())); - } + if (UnderlyingMutex.getInt() == UCK_Acquired) + lock(FSet, FactMan, UnderCp, entry.kind(), entry.loc(), &Handler, + DiagKind); + else + unlock(FSet, FactMan, UnderCp, entry.loc(), &Handler, DiagKind); } } @@ -938,32 +954,49 @@ public: bool FullyRemove, ThreadSafetyHandler &Handler, StringRef DiagKind) const override { assert(!Cp.negative() && "Managing object cannot be negative."); - for (const auto *UnderlyingMutex : UnderlyingMutexes) { - CapabilityExpr UnderCp(UnderlyingMutex, false); - auto UnderEntry = llvm::make_unique( - !UnderCp, LK_Exclusive, UnlockLoc); - - if (FullyRemove) { - // We're destroying the managing object. - // Remove the underlying mutex if it exists; but don't warn. - if (FSet.findLock(FactMan, UnderCp)) { - FSet.removeLock(FactMan, UnderCp); - FSet.addLock(FactMan, std::move(UnderEntry)); - } + for (const auto &UnderlyingMutex : UnderlyingMutexes) { + CapabilityExpr UnderCp(UnderlyingMutex.getPointer(), false); + + // Remove/lock the underlying mutex if it exists/is still unlocked; warn + // on double unlocking/locking if we're not destroying the scoped object. + ThreadSafetyHandler *TSHandler = FullyRemove ? nullptr : &Handler; + if (UnderlyingMutex.getInt() == UCK_Acquired) { + unlock(FSet, FactMan, UnderCp, UnlockLoc, TSHandler, DiagKind); } else { - // We're releasing the underlying mutex, but not destroying the - // managing object. Warn on dual release. - if (!FSet.findLock(FactMan, UnderCp)) { - Handler.handleUnmatchedUnlock(DiagKind, UnderCp.toString(), - UnlockLoc); - } - FSet.removeLock(FactMan, UnderCp); - FSet.addLock(FactMan, std::move(UnderEntry)); + LockKind kind = UnderlyingMutex.getInt() == UCK_ReleasedShared + ? LK_Shared + : LK_Exclusive; + lock(FSet, FactMan, UnderCp, kind, UnlockLoc, TSHandler, DiagKind); } } if (FullyRemove) FSet.removeLock(FactMan, Cp); } + +private: + void lock(FactSet &FSet, FactManager &FactMan, const CapabilityExpr &Cp, + LockKind kind, SourceLocation loc, ThreadSafetyHandler *Handler, + StringRef DiagKind) const { + if (!FSet.findLock(FactMan, Cp)) { + FSet.removeLock(FactMan, !Cp); + FSet.addLock(FactMan, + llvm::make_unique(Cp, kind, loc)); + } else if (Handler) { + Handler->handleDoubleLock(DiagKind, Cp.toString(), loc); + } + } + + void unlock(FactSet &FSet, FactManager &FactMan, const CapabilityExpr &Cp, + SourceLocation loc, ThreadSafetyHandler *Handler, + StringRef DiagKind) const { + if (FSet.findLock(FactMan, Cp)) { + FSet.removeLock(FactMan, Cp); + FSet.addLock(FactMan, llvm::make_unique( + !Cp, LK_Exclusive, loc)); + } else if (Handler) { + Handler->handleUnmatchedUnlock(DiagKind, Cp.toString(), loc); + } + } }; /// Class which implements the core thread safety analysis routines. @@ -1911,7 +1944,8 @@ void BuildLockset::handleCall(const Expr *Exp, const NamedDecl *D, std::back_inserter(SharedLocksToAdd)); Analyzer->addLock(FSet, llvm::make_unique( - Scp, MLoc, ExclusiveLocksToAdd, SharedLocksToAdd), + Scp, MLoc, ExclusiveLocksToAdd, SharedLocksToAdd, + ExclusiveLocksToRemove, SharedLocksToRemove), CapDiagKind); } } diff --git a/test/SemaCXX/warn-thread-safety-analysis.cpp b/test/SemaCXX/warn-thread-safety-analysis.cpp index 54e3369f4d..f959beb622 100644 --- a/test/SemaCXX/warn-thread-safety-analysis.cpp +++ b/test/SemaCXX/warn-thread-safety-analysis.cpp @@ -2787,6 +2787,110 @@ void relockWeird() { } // end namespace RelockableScopedLock +namespace ScopedUnlock { + +class SCOPED_LOCKABLE MutexUnlock { +public: + MutexUnlock(Mutex *mu) EXCLUSIVE_UNLOCK_FUNCTION(mu); + ~MutexUnlock() EXCLUSIVE_UNLOCK_FUNCTION(); + + void Lock() EXCLUSIVE_UNLOCK_FUNCTION(); + void Unlock() EXCLUSIVE_LOCK_FUNCTION(); +}; + +class SCOPED_LOCKABLE ReaderMutexUnlock { +public: + ReaderMutexUnlock(Mutex *mu) SHARED_UNLOCK_FUNCTION(mu); + ~ReaderMutexUnlock() EXCLUSIVE_UNLOCK_FUNCTION(); + + void Lock() EXCLUSIVE_UNLOCK_FUNCTION(); + void Unlock() EXCLUSIVE_LOCK_FUNCTION(); +}; + +Mutex mu; +int x GUARDED_BY(mu); +bool c; +void print(int); + +void simple() EXCLUSIVE_LOCKS_REQUIRED(mu) { + x = 1; + MutexUnlock scope(&mu); + x = 2; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}} +} + +void simpleShared() SHARED_LOCKS_REQUIRED(mu) { + print(x); + ReaderMutexUnlock scope(&mu); + print(x); // expected-warning {{reading variable 'x' requires holding mutex 'mu'}} +} + +void innerUnlock() { + MutexLock outer(&mu); + if (x == 0) { + MutexUnlock inner(&mu); + x = 1; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}} + } + x = 2; +} + +void innerUnlockShared() { + ReaderMutexLock outer(&mu); + if (x == 0) { + ReaderMutexUnlock inner(&mu); + print(x); // expected-warning {{reading variable 'x' requires holding mutex 'mu'}} + } + print(x); +} + +void manual() EXCLUSIVE_LOCKS_REQUIRED(mu) { + MutexUnlock scope(&mu); + scope.Lock(); + x = 2; + scope.Unlock(); + x = 3; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}} +} + +void join() EXCLUSIVE_LOCKS_REQUIRED(mu) { + MutexUnlock scope(&mu); + if (c) { + scope.Lock(); // expected-note{{mutex acquired here}} + } + // expected-warning@+1{{mutex 'mu' is not held on every path through here}} + scope.Lock(); +} + +void doubleLock() EXCLUSIVE_LOCKS_REQUIRED(mu) { + MutexUnlock scope(&mu); + scope.Lock(); + scope.Lock(); // expected-warning {{acquiring mutex 'mu' that is already held}} +} + +void doubleUnlock() EXCLUSIVE_LOCKS_REQUIRED(mu) { + MutexUnlock scope(&mu); + scope.Unlock(); // expected-warning {{releasing mutex 'mu' that was not held}} +} + +class SCOPED_LOCKABLE MutexLockUnlock { +public: + MutexLockUnlock(Mutex *mu1, Mutex *mu2) EXCLUSIVE_UNLOCK_FUNCTION(mu1) EXCLUSIVE_LOCK_FUNCTION(mu2); + ~MutexLockUnlock() EXCLUSIVE_UNLOCK_FUNCTION(); + + void Release() EXCLUSIVE_UNLOCK_FUNCTION(); + void Acquire() EXCLUSIVE_LOCK_FUNCTION(); +}; + +Mutex other; +void fn() EXCLUSIVE_LOCKS_REQUIRED(other); + +void lockUnlock() EXCLUSIVE_LOCKS_REQUIRED(mu) { + MutexLockUnlock scope(&mu, &other); + fn(); + x = 1; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}} +} + +} // end namespace ScopedUnlock + + namespace TrylockFunctionTest { class Foo { -- cgit v1.2.3 From a6b9739069763243020f4ea6fe586bc135fde1f9 Mon Sep 17 00:00:00 2001 From: Aaron Puchert Date: Sun, 16 Dec 2018 16:19:11 +0000 Subject: Thread safety analysis: Avoid intermediate copies [NFC] The main reason is to reduce the number of constructor arguments though, especially since many of them had the same type. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349308 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Analysis/ThreadSafety.cpp | 52 ++++++++++++++++++++++++++----------------- 1 file changed, 31 insertions(+), 21 deletions(-) diff --git a/lib/Analysis/ThreadSafety.cpp b/lib/Analysis/ThreadSafety.cpp index ca146a83c6..fe6d3a23a8 100644 --- a/lib/Analysis/ThreadSafety.cpp +++ b/lib/Analysis/ThreadSafety.cpp @@ -903,18 +903,23 @@ private: SmallVector UnderlyingMutexes; public: - ScopedLockableFactEntry(const CapabilityExpr &CE, SourceLocation Loc, - const CapExprSet &Excl, const CapExprSet &Shrd, - const CapExprSet &ExclRel, const CapExprSet &ShrdRel) - : FactEntry(CE, LK_Exclusive, Loc, false) { - for (const auto &M : Excl) - UnderlyingMutexes.emplace_back(M.sexpr(), UCK_Acquired); - for (const auto &M : Shrd) - UnderlyingMutexes.emplace_back(M.sexpr(), UCK_Acquired); - for (const auto &M : ExclRel) - UnderlyingMutexes.emplace_back(M.sexpr(), UCK_ReleasedExclusive); - for (const auto &M : ShrdRel) - UnderlyingMutexes.emplace_back(M.sexpr(), UCK_ReleasedShared); + ScopedLockableFactEntry(const CapabilityExpr &CE, SourceLocation Loc) + : FactEntry(CE, LK_Exclusive, Loc, false) {} + + void addExclusiveLock(const CapabilityExpr &M) { + UnderlyingMutexes.emplace_back(M.sexpr(), UCK_Acquired); + } + + void addSharedLock(const CapabilityExpr &M) { + UnderlyingMutexes.emplace_back(M.sexpr(), UCK_Acquired); + } + + void addExclusiveUnlock(const CapabilityExpr &M) { + UnderlyingMutexes.emplace_back(M.sexpr(), UCK_ReleasedExclusive); + } + + void addSharedUnlock(const CapabilityExpr &M) { + UnderlyingMutexes.emplace_back(M.sexpr(), UCK_ReleasedShared); } void @@ -1938,15 +1943,20 @@ void BuildLockset::handleCall(const Expr *Exp, const NamedDecl *D, // FIXME: does this store a pointer to DRE? CapabilityExpr Scp = Analyzer->SxBuilder.translateAttrExpr(&DRE, nullptr); - std::copy(ScopedExclusiveReqs.begin(), ScopedExclusiveReqs.end(), - std::back_inserter(ExclusiveLocksToAdd)); - std::copy(ScopedSharedReqs.begin(), ScopedSharedReqs.end(), - std::back_inserter(SharedLocksToAdd)); - Analyzer->addLock(FSet, - llvm::make_unique( - Scp, MLoc, ExclusiveLocksToAdd, SharedLocksToAdd, - ExclusiveLocksToRemove, SharedLocksToRemove), - CapDiagKind); + auto ScopedEntry = llvm::make_unique(Scp, MLoc); + for (const auto &M : ExclusiveLocksToAdd) + ScopedEntry->addExclusiveLock(M); + for (const auto &M : ScopedExclusiveReqs) + ScopedEntry->addExclusiveLock(M); + for (const auto &M : SharedLocksToAdd) + ScopedEntry->addSharedLock(M); + for (const auto &M : ScopedSharedReqs) + ScopedEntry->addSharedLock(M); + for (const auto &M : ExclusiveLocksToRemove) + ScopedEntry->addExclusiveUnlock(M); + for (const auto &M : SharedLocksToRemove) + ScopedEntry->addSharedUnlock(M); + Analyzer->addLock(FSet, std::move(ScopedEntry), CapDiagKind); } } -- cgit v1.2.3 From ba218efee57f415dc415aa0fd31d64d23ba3d987 Mon Sep 17 00:00:00 2001 From: Artem Dergachev Date: Sun, 16 Dec 2018 23:44:06 +0000 Subject: [analyzer] Fix some expressions staying live too long. Add a debug checker. StaticAnalyzer uses the CFG-based RelaxedLiveVariables analysis in order to, in particular, figure out values of which expressions are still needed. When the expression becomes "dead", it is garbage-collected during the dead binding scan. Expressions that constitute branches/bodies of control flow statements, eg. `E1' in `if (C1) E1;' but not `E2' in `if (C2) { E2; }', were kept alive for too long. This caused false positives in MoveChecker because it relies on cleaning up loop-local variables when they go out of scope, but some of those live-for-too-long expressions were keeping a reference to those variables. Fix liveness analysis to correctly mark these expressions as dead. Add a debug checker, debug.DumpLiveStmts, in order to test expressions liveness. Differential Revision: https://reviews.llvm.org/D55566 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349320 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/analyzer/DebugChecks.rst | 5 +- include/clang/Analysis/Analyses/LiveVariables.h | 8 +- include/clang/StaticAnalyzer/Checkers/Checkers.td | 3 + lib/Analysis/LiveVariables.cpp | 48 +++++++ lib/StaticAnalyzer/Checkers/DebugCheckers.cpp | 19 +++ test/Analysis/live-stmts.cpp | 167 ++++++++++++++++++++++ test/Analysis/use-after-move.cpp | 39 +++++ 7 files changed, 286 insertions(+), 3 deletions(-) create mode 100644 test/Analysis/live-stmts.cpp diff --git a/docs/analyzer/DebugChecks.rst b/docs/analyzer/DebugChecks.rst index 7b192f6522..bb2f37f339 100644 --- a/docs/analyzer/DebugChecks.rst +++ b/docs/analyzer/DebugChecks.rst @@ -30,9 +30,12 @@ using a 'dot' format viewer (such as Graphviz on OS X) instead. - debug.DumpLiveVars: Show the results of live variable analysis for each top-level function being analyzed. +- debug.DumpLiveStmts: Show the results of live statement analysis for each + top-level function being analyzed. + - debug.ViewExplodedGraph: Show the Exploded Graphs generated for the analysis of different functions in the input translation unit. When there - are several functions analyzed, display one graph per function. Beware + are several functions analyzed, display one graph per function. Beware that these graphs may grow very large, even for small functions. Path Tracking diff --git a/include/clang/Analysis/Analyses/LiveVariables.h b/include/clang/Analysis/Analyses/LiveVariables.h index 0cb500fffb..114597661a 100644 --- a/include/clang/Analysis/Analyses/LiveVariables.h +++ b/include/clang/Analysis/Analyses/LiveVariables.h @@ -88,9 +88,13 @@ public: /// before the given block-level expression (see runOnAllBlocks). bool isLive(const Stmt *Loc, const Stmt *StmtVal); - /// Print to stderr the liveness information associated with + /// Print to stderr the variable liveness information associated with /// each basic block. - void dumpBlockLiveness(const SourceManager& M); + void dumpBlockLiveness(const SourceManager &M); + + /// Print to stderr the statement liveness information associated with + /// each basic block. + void dumpStmtLiveness(const SourceManager &M); void runOnAllBlocks(Observer &obs); diff --git a/include/clang/StaticAnalyzer/Checkers/Checkers.td b/include/clang/StaticAnalyzer/Checkers/Checkers.td index 9feb5a8766..5280ad70e9 100644 --- a/include/clang/StaticAnalyzer/Checkers/Checkers.td +++ b/include/clang/StaticAnalyzer/Checkers/Checkers.td @@ -707,6 +707,9 @@ def DominatorsTreeDumper : Checker<"DumpDominators">, def LiveVariablesDumper : Checker<"DumpLiveVars">, HelpText<"Print results of live variable analysis">; +def LiveStatementsDumper : Checker<"DumpLiveStmts">, + HelpText<"Print results of live statement analysis">; + def CFGViewer : Checker<"ViewCFG">, HelpText<"View Control-Flow Graphs using GraphViz">; diff --git a/lib/Analysis/LiveVariables.cpp b/lib/Analysis/LiveVariables.cpp index 4f22ccc55a..afe2d26490 100644 --- a/lib/Analysis/LiveVariables.cpp +++ b/lib/Analysis/LiveVariables.cpp @@ -93,6 +93,7 @@ public: LiveVariables::Observer *obs = nullptr); void dumpBlockLiveness(const SourceManager& M); + void dumpStmtLiveness(const SourceManager& M); LiveVariablesImpl(AnalysisDeclContext &ac, bool KillAtAssign) : analysisContext(ac), @@ -327,6 +328,35 @@ void TransferFunctions::Visit(Stmt *S) { // No need to unconditionally visit subexpressions. return; } + case Stmt::IfStmtClass: { + // If one of the branches is an expression rather than a compound + // statement, it will be bad if we mark it as live at the terminator + // of the if-statement (i.e., immediately after the condition expression). + AddLiveStmt(val.liveStmts, LV.SSetFact, cast(S)->getCond()); + return; + } + case Stmt::WhileStmtClass: { + // If the loop body is an expression rather than a compound statement, + // it will be bad if we mark it as live at the terminator of the loop + // (i.e., immediately after the condition expression). + AddLiveStmt(val.liveStmts, LV.SSetFact, cast(S)->getCond()); + return; + } + case Stmt::DoStmtClass: { + // If the loop body is an expression rather than a compound statement, + // it will be bad if we mark it as live at the terminator of the loop + // (i.e., immediately after the condition expression). + AddLiveStmt(val.liveStmts, LV.SSetFact, cast(S)->getCond()); + return; + } + case Stmt::ForStmtClass: { + // If the loop body is an expression rather than a compound statement, + // it will be bad if we mark it as live at the terminator of the loop + // (i.e., immediately after the condition expression). + AddLiveStmt(val.liveStmts, LV.SSetFact, cast(S)->getCond()); + return; + } + } for (Stmt *Child : S->children()) { @@ -632,5 +662,23 @@ void LiveVariablesImpl::dumpBlockLiveness(const SourceManager &M) { llvm::errs() << "\n"; } +void LiveVariables::dumpStmtLiveness(const SourceManager &M) { + getImpl(impl).dumpStmtLiveness(M); +} + +void LiveVariablesImpl::dumpStmtLiveness(const SourceManager &M) { + // Don't iterate over blockEndsToLiveness directly because it's not sorted. + for (auto I : *analysisContext.getCFG()) { + + llvm::errs() << "\n[ B" << I->getBlockID() + << " (live statements at block exit) ]\n"; + for (auto S : blocksEndToLiveness[I].liveStmts) { + llvm::errs() << "\n"; + S->dump(); + } + llvm::errs() << "\n"; + } +} + const void *LiveVariables::getTag() { static int x; return &x; } const void *RelaxedLiveVariables::getTag() { static int x; return &x; } diff --git a/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp b/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp index 5840ee7913..90b1111aff 100644 --- a/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp +++ b/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp @@ -68,6 +68,25 @@ void ento::registerLiveVariablesDumper(CheckerManager &mgr) { mgr.registerChecker(); } +//===----------------------------------------------------------------------===// +// LiveStatementsDumper +//===----------------------------------------------------------------------===// + +namespace { +class LiveStatementsDumper : public Checker { +public: + void checkASTCodeBody(const Decl *D, AnalysisManager& Mgr, + BugReporter &BR) const { + if (LiveVariables *L = Mgr.getAnalysis(D)) + L->dumpStmtLiveness(Mgr.getSourceManager()); + } +}; +} + +void ento::registerLiveStatementsDumper(CheckerManager &mgr) { + mgr.registerChecker(); +} + //===----------------------------------------------------------------------===// // CFGViewer //===----------------------------------------------------------------------===// diff --git a/test/Analysis/live-stmts.cpp b/test/Analysis/live-stmts.cpp new file mode 100644 index 0000000000..1b8a750c5e --- /dev/null +++ b/test/Analysis/live-stmts.cpp @@ -0,0 +1,167 @@ +// RUN: %clang_analyze_cc1 -w -analyzer-checker=debug.DumpLiveStmts %s 2>&1\ +// RUN: | FileCheck %s + +int coin(); + + +int testThatDumperWorks(int x, int y, int z) { + return x ? y : z; +} +// CHECK: [ B0 (live statements at block exit) ] +// CHECK-EMPTY: +// CHECK-EMPTY: +// CHECK: [ B1 (live statements at block exit) ] +// CHECK-EMPTY: +// CHECK-EMPTY: +// CHECK: [ B2 (live statements at block exit) ] +// CHECK-EMPTY: +// CHECK-NEXT: DeclRefExpr {{.*}} 'y' 'int' +// CHECK-EMPTY: +// CHECK-NEXT: DeclRefExpr {{.*}} 'z' 'int' +// CHECK-EMPTY: +// CHECK-NEXT: ImplicitCastExpr {{.*}} +// CHECK-NEXT: `-ImplicitCastExpr {{.*}} +// CHECK-NEXT: `-DeclRefExpr {{.*}} 'x' 'int' +// CHECK-EMPTY: +// CHECK-EMPTY: +// CHECK: [ B3 (live statements at block exit) ] +// CHECK-EMPTY: +// CHECK-NEXT: DeclRefExpr {{.*}} 'y' 'int' +// CHECK-EMPTY: +// CHECK-NEXT: DeclRefExpr {{.*}} 'z' 'int' +// CHECK-EMPTY: +// CHECK-NEXT: ImplicitCastExpr {{.*}} +// CHECK-NEXT: `-ImplicitCastExpr {{.*}} +// CHECK-NEXT: `-DeclRefExpr {{.*}} 'x' 'int' +// CHECK: [ B4 (live statements at block exit) ] +// CHECK-EMPTY: +// CHECK-NEXT: DeclRefExpr {{.*}} 'y' 'int' +// CHECK-EMPTY: +// CHECK-NEXT: DeclRefExpr {{.*}} 'z' 'int' +// CHECK-EMPTY: +// CHECK-NEXT: ImplicitCastExpr {{.*}} +// CHECK-NEXT: `-ImplicitCastExpr {{.*}} +// CHECK-NEXT: `-DeclRefExpr {{.*}} 'x' 'int' +// CHECK-EMPTY: +// CHECK-EMPTY: +// CHECK: [ B5 (live statements at block exit) ] +// CHECK-EMPTY: +// CHECK-NEXT: DeclRefExpr {{.*}} 'y' 'int' +// CHECK-EMPTY: +// CHECK-NEXT: DeclRefExpr {{.*}} 'z' 'int' +// CHECK-EMPTY: +// CHECK-EMPTY: + + +void testIfBranchExpression(bool flag) { + // No expressions should be carried over from one block to another here. + while (flag) { + int e = 1; + if (true) + e; + } +} +// CHECK: [ B0 (live statements at block exit) ] +// CHECK-EMPTY: +// CHECK-EMPTY: +// CHECK: [ B1 (live statements at block exit) ] +// CHECK-EMPTY: +// CHECK-EMPTY: +// CHECK: [ B2 (live statements at block exit) ] +// CHECK-EMPTY: +// CHECK-EMPTY: +// CHECK: [ B3 (live statements at block exit) ] +// CHECK-EMPTY: +// CHECK-EMPTY: +// CHECK: [ B4 (live statements at block exit) ] +// CHECK-EMPTY: +// CHECK-EMPTY: +// CHECK: [ B5 (live statements at block exit) ] +// CHECK-EMPTY: +// CHECK-EMPTY: + + +void testWhileBodyExpression(bool flag) { + // No expressions should be carried over from one block to another here. + while (flag) { + int e = 1; + while (coin()) + e; + } +} +// CHECK: [ B0 (live statements at block exit) ] +// CHECK-EMPTY: +// CHECK-EMPTY: +// CHECK: [ B1 (live statements at block exit) ] +// CHECK-EMPTY: +// CHECK-EMPTY: +// CHECK: [ B2 (live statements at block exit) ] +// CHECK-EMPTY: +// CHECK-EMPTY: +// CHECK: [ B3 (live statements at block exit) ] +// CHECK-EMPTY: +// CHECK-EMPTY: +// CHECK: [ B4 (live statements at block exit) ] +// CHECK-EMPTY: +// CHECK-EMPTY: +// CHECK: [ B5 (live statements at block exit) ] +// CHECK-EMPTY: +// CHECK-EMPTY: + + +void testDoWhileBodyExpression(bool flag) { + // No expressions should be carried over from one block to another here. + while (flag) { + int e = 1; + do + e; + while (coin()); + } +} +// CHECK: [ B0 (live statements at block exit) ] +// CHECK-EMPTY: +// CHECK-EMPTY: +// CHECK: [ B1 (live statements at block exit) ] +// CHECK-EMPTY: +// CHECK-EMPTY: +// CHECK: [ B2 (live statements at block exit) ] +// CHECK-EMPTY: +// CHECK-EMPTY: +// CHECK: [ B3 (live statements at block exit) ] +// CHECK-EMPTY: +// CHECK-EMPTY: +// CHECK: [ B4 (live statements at block exit) ] +// CHECK-EMPTY: +// CHECK-EMPTY: +// CHECK: [ B5 (live statements at block exit) ] +// CHECK-EMPTY: +// CHECK-EMPTY: + + +void testForBodyExpression(bool flag) { + // No expressions should be carried over from one block to another here. + while (flag) { + int e = 1; + for (; coin();) + e; + } +} +// CHECK: [ B0 (live statements at block exit) ] +// CHECK-EMPTY: +// CHECK-EMPTY: +// CHECK: [ B1 (live statements at block exit) ] +// CHECK-EMPTY: +// CHECK-EMPTY: +// CHECK: [ B2 (live statements at block exit) ] +// CHECK-EMPTY: +// CHECK-EMPTY: +// CHECK: [ B3 (live statements at block exit) ] +// CHECK-EMPTY: +// CHECK-EMPTY: +// CHECK: [ B4 (live statements at block exit) ] +// CHECK-EMPTY: +// CHECK-EMPTY: +// CHECK: [ B5 (live statements at block exit) ] +// CHECK-EMPTY: +// CHECK-EMPTY: + diff --git a/test/Analysis/use-after-move.cpp b/test/Analysis/use-after-move.cpp index 18e1b3da6a..3bb52f164b 100644 --- a/test/Analysis/use-after-move.cpp +++ b/test/Analysis/use-after-move.cpp @@ -778,6 +778,45 @@ void checkLoopZombies() { } } +void checkMoreLoopZombies1(bool flag) { + while (flag) { + Empty e{}; + if (true) + e; // expected-warning {{expression result unused}} + Empty f = std::move(e); // no-warning + } +} + +bool coin(); + +void checkMoreLoopZombies2(bool flag) { + while (flag) { + Empty e{}; + while (coin()) + e; // expected-warning {{expression result unused}} + Empty f = std::move(e); // no-warning + } +} + +void checkMoreLoopZombies3(bool flag) { + while (flag) { + Empty e{}; + do + e; // expected-warning {{expression result unused}} + while (coin()); + Empty f = std::move(e); // no-warning + } +} + +void checkMoreLoopZombies4(bool flag) { + while (flag) { + Empty e{}; + for (; coin();) + e; // expected-warning {{expression result unused}} + Empty f = std::move(e); // no-warning + } +} + struct MoveOnlyWithDestructor { MoveOnlyWithDestructor(); ~MoveOnlyWithDestructor(); -- cgit v1.2.3 From c1ae04023a00cfe3f3b50aeca648e9e0b1c4db13 Mon Sep 17 00:00:00 2001 From: Artem Dergachev Date: Mon, 17 Dec 2018 05:25:23 +0000 Subject: Speculatively re-apply "[analyzer] MoveChecker: Add checks for dereferencing..." This re-applies commit r349226 that was reverted in r349233 due to failures on clang-x64-windows-msvc. Specify enum type as unsigned for use in bit field. Otherwise overflows may cause UB. Differential Revision: https://reviews.llvm.org/D55388 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349326 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/StaticAnalyzer/Checkers/MoveChecker.cpp | 200 +++++++++++++++++++++------- test/Analysis/use-after-move.cpp | 34 ++++- 2 files changed, 178 insertions(+), 56 deletions(-) diff --git a/lib/StaticAnalyzer/Checkers/MoveChecker.cpp b/lib/StaticAnalyzer/Checkers/MoveChecker.cpp index 0eaa75d645..68a6554942 100644 --- a/lib/StaticAnalyzer/Checkers/MoveChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/MoveChecker.cpp @@ -61,19 +61,35 @@ public: const char *NL, const char *Sep) const override; private: - enum MisuseKind { MK_FunCall, MK_Copy, MK_Move }; + enum MisuseKind { MK_FunCall, MK_Copy, MK_Move, MK_Dereference }; + enum StdObjectKind : unsigned { SK_NonStd, SK_Unsafe, SK_Safe, SK_SmartPtr }; + + static bool misuseCausesCrash(MisuseKind MK) { + return MK == MK_Dereference; + } struct ObjectKind { - bool Local : 1; // Is this a local variable or a local rvalue reference? - bool STL : 1; // Is this an object of a standard type? + // Is this a local variable or a local rvalue reference? + bool IsLocal : 1; + // Is this an STL object? If so, of what kind? + StdObjectKind StdKind : 2; + }; + + // STL smart pointers are automatically re-initialized to null when moved + // from. So we can't warn on many methods, but we can warn when it is + // dereferenced, which is UB even if the resulting lvalue never gets read. + const llvm::StringSet<> StdSmartPtrClasses = { + "shared_ptr", + "unique_ptr", + "weak_ptr", }; // Not all of these are entirely move-safe, but they do provide *some* // guarantees, and it means that somebody is using them after move // in a valid manner. - // TODO: We can still try to identify *unsafe* use after move, such as - // dereference of a moved-from smart pointer (which is guaranteed to be null). - const llvm::StringSet<> StandardMoveSafeClasses = { + // TODO: We can still try to identify *unsafe* use after move, + // like we did with smart pointers. + const llvm::StringSet<> StdSafeClasses = { "basic_filebuf", "basic_ios", "future", @@ -82,11 +98,8 @@ private: "promise", "shared_future", "shared_lock", - "shared_ptr", "thread", - "unique_ptr", "unique_lock", - "weak_ptr", }; // Should we bother tracking the state of the object? @@ -97,10 +110,25 @@ private: // their user to re-use the storage. The latter is possible because STL // objects are known to end up in a valid but unspecified state after the // move and their state-reset methods are also known, which allows us to - // predict precisely when use-after-move is invalid. In aggressive mode, - // warn on any use-after-move because the user has intentionally asked us - // to completely eliminate use-after-move in his code. - return IsAggressive || OK.Local || OK.STL; + // predict precisely when use-after-move is invalid. + // Some STL objects are known to conform to additional contracts after move, + // so they are not tracked. However, smart pointers specifically are tracked + // because we can perform extra checking over them. + // In aggressive mode, warn on any use-after-move because the user has + // intentionally asked us to completely eliminate use-after-move + // in his code. + return IsAggressive || OK.IsLocal + || OK.StdKind == SK_Unsafe || OK.StdKind == SK_SmartPtr; + } + + // Some objects only suffer from some kinds of misuses, but we need to track + // them anyway because we cannot know in advance what misuse will we find. + bool shouldWarnAbout(ObjectKind OK, MisuseKind MK) const { + // Additionally, only warn on smart pointers when they are dereferenced (or + // local or we are aggressive). + return shouldBeTracked(OK) && + (IsAggressive || OK.IsLocal + || OK.StdKind != SK_SmartPtr || MK == MK_Dereference); } // Obtains ObjectKind of an object. Because class declaration cannot always @@ -108,17 +136,17 @@ private: ObjectKind classifyObject(const MemRegion *MR, const CXXRecordDecl *RD) const; // Classifies the object and dumps a user-friendly description string to - // the stream. Return value is equivalent to classifyObject. - ObjectKind explainObject(llvm::raw_ostream &OS, - const MemRegion *MR, const CXXRecordDecl *RD) const; + // the stream. + void explainObject(llvm::raw_ostream &OS, const MemRegion *MR, + const CXXRecordDecl *RD, MisuseKind MK) const; - bool isStandardMoveSafeClass(const CXXRecordDecl *RD) const; + bool belongsTo(const CXXRecordDecl *RD, const llvm::StringSet<> &Set) const; class MovedBugVisitor : public BugReporterVisitor { public: - MovedBugVisitor(const MoveChecker &Chk, - const MemRegion *R, const CXXRecordDecl *RD) - : Chk(Chk), Region(R), RD(RD), Found(false) {} + MovedBugVisitor(const MoveChecker &Chk, const MemRegion *R, + const CXXRecordDecl *RD, MisuseKind MK) + : Chk(Chk), Region(R), RD(RD), MK(MK), Found(false) {} void Profile(llvm::FoldingSetNodeID &ID) const override { static int X = 0; @@ -140,6 +168,8 @@ private: const MemRegion *Region; // The class of the tracked object. const CXXRecordDecl *RD; + // How exactly the object was misused. + const MisuseKind MK; bool Found; }; @@ -232,18 +262,37 @@ MoveChecker::MovedBugVisitor::VisitNode(const ExplodedNode *N, SmallString<128> Str; llvm::raw_svector_ostream OS(Str); - OS << "Object"; - ObjectKind OK = Chk.explainObject(OS, Region, RD); - if (OK.STL) - OS << " is left in a valid but unspecified state after move"; - else - OS << " is moved"; + ObjectKind OK = Chk.classifyObject(Region, RD); + switch (OK.StdKind) { + case SK_SmartPtr: + if (MK == MK_Dereference) { + OS << "Smart pointer"; + Chk.explainObject(OS, Region, RD, MK); + OS << " is reset to null when moved from"; + break; + } + + // If it's not a dereference, we don't care if it was reset to null + // or that it is even a smart pointer. + LLVM_FALLTHROUGH; + case SK_NonStd: + case SK_Safe: + OS << "Object"; + Chk.explainObject(OS, Region, RD, MK); + OS << " is moved"; + break; + case SK_Unsafe: + OS << "Object"; + Chk.explainObject(OS, Region, RD, MK); + OS << " is left in a valid but unspecified state after move"; + break; + } // Generate the extra diagnostic. PathDiagnosticLocation Pos(S, BRC.getSourceManager(), N->getLocationContext()); return std::make_shared(Pos, OS.str(), true); - } +} const ExplodedNode *MoveChecker::getMoveLocation(const ExplodedNode *N, const MemRegion *Region, @@ -267,25 +316,48 @@ void MoveChecker::modelUse(ProgramStateRef State, const MemRegion *Region, CheckerContext &C) const { assert(!C.isDifferent() && "No transitions should have been made by now"); const RegionState *RS = State->get(Region); + ObjectKind OK = classifyObject(Region, RD); + + // Just in case: if it's not a smart pointer but it does have operator *, + // we shouldn't call the bug a dereference. + if (MK == MK_Dereference && OK.StdKind != SK_SmartPtr) + MK = MK_FunCall; - if (!RS || isAnyBaseRegionReported(State, Region) + if (!RS || !shouldWarnAbout(OK, MK) || isInMoveSafeContext(C.getLocationContext())) { // Finalize changes made by the caller. C.addTransition(State); return; } + // Don't report it in case if any base region is already reported. + // But still generate a sink in case of UB. + // And still finalize changes made by the caller. + if (isAnyBaseRegionReported(State, Region)) { + if (misuseCausesCrash(MK)) { + C.generateSink(State, C.getPredecessor()); + } else { + C.addTransition(State); + } + return; + } + ExplodedNode *N = reportBug(Region, RD, C, MK); + // If the program has already crashed on this path, don't bother. + if (N->isSink()) + return; + State = State->set(Region, RegionState::getReported()); C.addTransition(State, N); } ExplodedNode *MoveChecker::reportBug(const MemRegion *Region, - const CXXRecordDecl *RD, - CheckerContext &C, + const CXXRecordDecl *RD, CheckerContext &C, MisuseKind MK) const { - if (ExplodedNode *N = C.generateNonFatalErrorNode()) { + if (ExplodedNode *N = misuseCausesCrash(MK) ? C.generateErrorNode() + : C.generateNonFatalErrorNode()) { + if (!BT) BT.reset(new BugType(this, "Use-after-move", "C++ move semantics")); @@ -304,24 +376,28 @@ ExplodedNode *MoveChecker::reportBug(const MemRegion *Region, switch(MK) { case MK_FunCall: OS << "Method called on moved-from object"; - explainObject(OS, Region, RD); + explainObject(OS, Region, RD, MK); break; case MK_Copy: OS << "Moved-from object"; - explainObject(OS, Region, RD); + explainObject(OS, Region, RD, MK); OS << " is copied"; break; case MK_Move: OS << "Moved-from object"; - explainObject(OS, Region, RD); + explainObject(OS, Region, RD, MK); OS << " is moved"; break; + case MK_Dereference: + OS << "Dereference of null smart pointer"; + explainObject(OS, Region, RD, MK); + break; } auto R = llvm::make_unique(*BT, OS.str(), N, LocUsedForUniqueing, MoveNode->getLocationContext()->getDecl()); - R->addVisitor(llvm::make_unique(*this, Region, RD)); + R->addVisitor(llvm::make_unique(*this, Region, RD, MK)); C.emitReport(std::move(R)); return N; } @@ -433,9 +509,10 @@ bool MoveChecker::isInMoveSafeContext(const LocationContext *LC) const { return false; } -bool MoveChecker::isStandardMoveSafeClass(const CXXRecordDecl *RD) const { +bool MoveChecker::belongsTo(const CXXRecordDecl *RD, + const llvm::StringSet<> &Set) const { const IdentifierInfo *II = RD->getIdentifier(); - return II && StandardMoveSafeClasses.count(II->getName()); + return II && Set.count(II->getName()); } MoveChecker::ObjectKind @@ -445,18 +522,23 @@ MoveChecker::classifyObject(const MemRegion *MR, // For the purposes of this checker, we classify move-safe STL types // as not-"STL" types, because that's how the checker treats them. MR = unwrapRValueReferenceIndirection(MR); - return { - /*Local=*/ - MR && isa(MR) && isa(MR->getMemorySpace()), - /*STL=*/ - RD && RD->getDeclContext()->isStdNamespace() && - !isStandardMoveSafeClass(RD) - }; + bool IsLocal = + MR && isa(MR) && isa(MR->getMemorySpace()); + + if (!RD || !RD->getDeclContext()->isStdNamespace()) + return { IsLocal, SK_NonStd }; + + if (belongsTo(RD, StdSmartPtrClasses)) + return { IsLocal, SK_SmartPtr }; + + if (belongsTo(RD, StdSafeClasses)) + return { IsLocal, SK_Safe }; + + return { IsLocal, SK_Unsafe }; } -MoveChecker::ObjectKind -MoveChecker::explainObject(llvm::raw_ostream &OS, const MemRegion *MR, - const CXXRecordDecl *RD) const { +void MoveChecker::explainObject(llvm::raw_ostream &OS, const MemRegion *MR, + const CXXRecordDecl *RD, MisuseKind MK) const { // We may need a leading space every time we actually explain anything, // and we never know if we are to explain anything until we try. if (const auto DR = @@ -464,11 +546,22 @@ MoveChecker::explainObject(llvm::raw_ostream &OS, const MemRegion *MR, const auto *RegionDecl = cast(DR->getDecl()); OS << " '" << RegionDecl->getNameAsString() << "'"; } + ObjectKind OK = classifyObject(MR, RD); - if (OK.STL) { - OS << " of type '" << RD->getQualifiedNameAsString() << "'"; - } - return OK; + switch (OK.StdKind) { + case SK_NonStd: + case SK_Safe: + break; + case SK_SmartPtr: + if (MK != MK_Dereference) + break; + + // We only care about the type if it's a dereference. + LLVM_FALLTHROUGH; + case SK_Unsafe: + OS << " of type '" << RD->getQualifiedNameAsString() << "'"; + break; + }; } void MoveChecker::checkPreCall(const CallEvent &Call, CheckerContext &C) const { @@ -543,6 +636,11 @@ void MoveChecker::checkPreCall(const CallEvent &Call, CheckerContext &C) const { C.addTransition(State); return; } + + if (OOK == OO_Star || OOK == OO_Arrow) { + modelUse(State, ThisRegion, RD, MK_Dereference, C); + return; + } } modelUse(State, ThisRegion, RD, MK_FunCall, C); diff --git a/test/Analysis/use-after-move.cpp b/test/Analysis/use-after-move.cpp index 3bb52f164b..d60f07f095 100644 --- a/test/Analysis/use-after-move.cpp +++ b/test/Analysis/use-after-move.cpp @@ -1,20 +1,26 @@ // RUN: %clang_analyze_cc1 -analyzer-checker=alpha.cplusplus.Move -verify %s\ // RUN: -std=c++11 -analyzer-output=text -analyzer-config eagerly-assume=false\ -// RUN: -analyzer-config exploration_strategy=unexplored_first_queue +// RUN: -analyzer-config exploration_strategy=unexplored_first_queue\ +// RUN: -analyzer-checker debug.ExprInspection // RUN: %clang_analyze_cc1 -analyzer-checker=alpha.cplusplus.Move -verify %s\ // RUN: -std=c++11 -analyzer-output=text -analyzer-config eagerly-assume=false\ -// RUN: -analyzer-config exploration_strategy=dfs -DDFS=1 +// RUN: -analyzer-config exploration_strategy=dfs -DDFS=1\ +// RUN: -analyzer-checker debug.ExprInspection // RUN: %clang_analyze_cc1 -analyzer-checker=alpha.cplusplus.Move -verify %s\ // RUN: -std=c++11 -analyzer-output=text -analyzer-config eagerly-assume=false\ // RUN: -analyzer-config exploration_strategy=unexplored_first_queue\ -// RUN: -analyzer-config alpha.cplusplus.Move:Aggressive=true -DAGGRESSIVE +// RUN: -analyzer-config alpha.cplusplus.Move:Aggressive=true -DAGGRESSIVE\ +// RUN: -analyzer-checker debug.ExprInspection // RUN: %clang_analyze_cc1 -analyzer-checker=alpha.cplusplus.Move -verify %s\ // RUN: -std=c++11 -analyzer-output=text -analyzer-config eagerly-assume=false\ // RUN: -analyzer-config exploration_strategy=dfs -DDFS=1\ -// RUN: -analyzer-config alpha.cplusplus.Move:Aggressive=true -DAGGRESSIVE +// RUN: -analyzer-config alpha.cplusplus.Move:Aggressive=true -DAGGRESSIVE\ +// RUN: -analyzer-checker debug.ExprInspection #include "Inputs/system-header-simulator-cxx.h" +void clang_analyzer_warnIfReached(); + class B { public: B() = default; @@ -849,7 +855,19 @@ class HasSTLField { // expected-note@-4{{Object 'P' is moved}} // expected-note@-4{{Method called on moved-from object 'P'}} #endif - *P += 1; // FIXME: Should warn that the pointer is null. + + // Because that well-defined state is null, dereference is still UB. + // Note that in aggressive mode we already warned about 'P', + // so no extra warning is generated. + *P += 1; +#ifndef AGGRESSIVE + // expected-warning@-2{{Dereference of null smart pointer 'P' of type 'std::unique_ptr'}} + // expected-note@-14{{Smart pointer 'P' of type 'std::unique_ptr' is reset to null when moved from}} + // expected-note@-4{{Dereference of null smart pointer 'P' of type 'std::unique_ptr'}} +#endif + + // The program should have crashed by now. + clang_analyzer_warnIfReached(); // no-warning } }; @@ -866,3 +884,9 @@ void localUniquePtr(std::unique_ptr P) { P.get(); // expected-warning{{Method called on moved-from object 'P'}} // expected-note@-1{{Method called on moved-from object 'P'}} } + +void localUniquePtrWithArrow(std::unique_ptr P) { + std::unique_ptr Q = std::move(P); // expected-note{{Smart pointer 'P' of type 'std::unique_ptr' is reset to null when moved from}} + P->foo(); // expected-warning{{Dereference of null smart pointer 'P' of type 'std::unique_ptr'}} + // expected-note@-1{{Dereference of null smart pointer 'P' of type 'std::unique_ptr'}} +} -- cgit v1.2.3 From 77e91cadfc10664326513f489ca605f6618bd570 Mon Sep 17 00:00:00 2001 From: Artem Dergachev Date: Mon, 17 Dec 2018 06:19:32 +0000 Subject: [analyzer] MoveChecker: Add an option to suppress warnings on locals. Re-using a moved-from local variable is most likely a bug because there's rarely a good motivation for not introducing a separate variable instead. We plan to keep emitting such warnings by default. Introduce a flag that allows disabling warnings on local variables that are not of a known move-unsafe type. If it doesn't work out as we expected, we'll just flip the flag. We still warn on move-unsafe objects and unsafe operations on known move-safe objects. Differential Revision: https://reviews.llvm.org/D55730 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349327 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/StaticAnalyzer/Checkers/MoveChecker.cpp | 38 ++- test/Analysis/use-after-move.cpp | 463 +++++++++++++++++++++------- 2 files changed, 384 insertions(+), 117 deletions(-) diff --git a/lib/StaticAnalyzer/Checkers/MoveChecker.cpp b/lib/StaticAnalyzer/Checkers/MoveChecker.cpp index 68a6554942..6436a6c6cb 100644 --- a/lib/StaticAnalyzer/Checkers/MoveChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/MoveChecker.cpp @@ -26,7 +26,6 @@ using namespace clang; using namespace ento; namespace { - struct RegionState { private: enum Kind { Moved, Reported } K; @@ -42,7 +41,9 @@ public: bool operator==(const RegionState &X) const { return K == X.K; } void Profile(llvm::FoldingSetNodeID &ID) const { ID.AddInteger(K); } }; +} // end of anonymous namespace +namespace { class MoveChecker : public Checker { @@ -62,8 +63,18 @@ public: private: enum MisuseKind { MK_FunCall, MK_Copy, MK_Move, MK_Dereference }; + // This needs to be unsigned in order to avoid undefined behavior + // when putting it into a tight bitfield. enum StdObjectKind : unsigned { SK_NonStd, SK_Unsafe, SK_Safe, SK_SmartPtr }; + enum AggressivenessKind { // In any case, don't warn after a reset. + AK_Invalid = -1, + AK_KnownsOnly = 0, // Warn only about known move-unsafe classes. + AK_KnownsAndLocals = 1, // Also warn about all local objects. + AK_All = 2, // Warn on any use-after-move. + AK_NumKinds = AK_All + }; + static bool misuseCausesCrash(MisuseKind MK) { return MK == MK_Dereference; } @@ -117,8 +128,9 @@ private: // In aggressive mode, warn on any use-after-move because the user has // intentionally asked us to completely eliminate use-after-move // in his code. - return IsAggressive || OK.IsLocal - || OK.StdKind == SK_Unsafe || OK.StdKind == SK_SmartPtr; + return (Aggressiveness == AK_All) || + (Aggressiveness >= AK_KnownsAndLocals && OK.IsLocal) || + OK.StdKind == SK_Unsafe || OK.StdKind == SK_SmartPtr; } // Some objects only suffer from some kinds of misuses, but we need to track @@ -127,8 +139,9 @@ private: // Additionally, only warn on smart pointers when they are dereferenced (or // local or we are aggressive). return shouldBeTracked(OK) && - (IsAggressive || OK.IsLocal - || OK.StdKind != SK_SmartPtr || MK == MK_Dereference); + ((Aggressiveness == AK_All) || + (Aggressiveness >= AK_KnownsAndLocals && OK.IsLocal) || + OK.StdKind != SK_SmartPtr || MK == MK_Dereference); } // Obtains ObjectKind of an object. Because class declaration cannot always @@ -173,10 +186,17 @@ private: bool Found; }; - bool IsAggressive = false; + AggressivenessKind Aggressiveness; public: - void setAggressiveness(bool Aggressive) { IsAggressive = Aggressive; } + void setAggressiveness(StringRef Str) { + Aggressiveness = + llvm::StringSwitch(Str) + .Case("KnownsOnly", AK_KnownsOnly) + .Case("KnownsAndLocals", AK_KnownsAndLocals) + .Case("All", AK_All) + .Default(AK_KnownsAndLocals); // A sane default. + }; private: mutable std::unique_ptr BT; @@ -717,6 +737,6 @@ void MoveChecker::printState(raw_ostream &Out, ProgramStateRef State, } void ento::registerMoveChecker(CheckerManager &mgr) { MoveChecker *chk = mgr.registerChecker(); - chk->setAggressiveness(mgr.getAnalyzerOptions().getCheckerBooleanOption( - "Aggressive", false, chk)); + chk->setAggressiveness( + mgr.getAnalyzerOptions().getCheckerStringOption("WarnOn", "", chk)); } diff --git a/test/Analysis/use-after-move.cpp b/test/Analysis/use-after-move.cpp index d60f07f095..652f08f45c 100644 --- a/test/Analysis/use-after-move.cpp +++ b/test/Analysis/use-after-move.cpp @@ -9,12 +9,22 @@ // RUN: %clang_analyze_cc1 -analyzer-checker=alpha.cplusplus.Move -verify %s\ // RUN: -std=c++11 -analyzer-output=text -analyzer-config eagerly-assume=false\ // RUN: -analyzer-config exploration_strategy=unexplored_first_queue\ -// RUN: -analyzer-config alpha.cplusplus.Move:Aggressive=true -DAGGRESSIVE\ +// RUN: -analyzer-config alpha.cplusplus.Move:WarnOn=KnownsOnly -DPEACEFUL\ // RUN: -analyzer-checker debug.ExprInspection // RUN: %clang_analyze_cc1 -analyzer-checker=alpha.cplusplus.Move -verify %s\ // RUN: -std=c++11 -analyzer-output=text -analyzer-config eagerly-assume=false\ // RUN: -analyzer-config exploration_strategy=dfs -DDFS=1\ -// RUN: -analyzer-config alpha.cplusplus.Move:Aggressive=true -DAGGRESSIVE\ +// RUN: -analyzer-config alpha.cplusplus.Move:WarnOn=KnownsOnly -DPEACEFUL\ +// RUN: -analyzer-checker debug.ExprInspection +// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.cplusplus.Move -verify %s\ +// RUN: -std=c++11 -analyzer-output=text -analyzer-config eagerly-assume=false\ +// RUN: -analyzer-config exploration_strategy=unexplored_first_queue\ +// RUN: -analyzer-config alpha.cplusplus.Move:WarnOn=All -DAGGRESSIVE\ +// RUN: -analyzer-checker debug.ExprInspection +// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.cplusplus.Move -verify %s\ +// RUN: -std=c++11 -analyzer-output=text -analyzer-config eagerly-assume=false\ +// RUN: -analyzer-config exploration_strategy=dfs -DDFS=1\ +// RUN: -analyzer-config alpha.cplusplus.Move:WarnOn=All -DAGGRESSIVE\ // RUN: -analyzer-checker debug.ExprInspection #include "Inputs/system-header-simulator-cxx.h" @@ -119,18 +129,33 @@ void copyOrMoveCall(A a) { void simpleMoveCtorTest() { { A a; - A b = std::move(a); // expected-note {{Object 'a' is moved}} - a.foo(); // expected-warning {{Method called on moved-from object 'a'}} expected-note {{Method called on moved-from object 'a'}} + A b = std::move(a); + a.foo(); +#ifndef PEACEFUL + // expected-note@-3 {{Object 'a' is moved}} + // expected-warning@-3 {{Method called on moved-from object 'a'}} + // expected-note@-4 {{Method called on moved-from object 'a'}} +#endif } { A a; - A b = std::move(a); // expected-note {{Object 'a' is moved}} - b = a; // expected-warning {{Moved-from object 'a' is copied}} expected-note {{Moved-from object 'a' is copied}} + A b = std::move(a); + b = a; +#ifndef PEACEFUL + // expected-note@-3 {{Object 'a' is moved}} + // expected-warning@-3 {{Moved-from object 'a' is copied}} + // expected-note@-4 {{Moved-from object 'a' is copied}} +#endif } { A a; - A b = std::move(a); // expected-note {{Object 'a' is moved}} - b = std::move(a); // expected-warning {{Moved-from object 'a' is moved}} expected-note {{Moved-from object 'a' is moved}} + A b = std::move(a); + b = std::move(a); +#ifndef PEACEFUL + // expected-note@-3 {{Object 'a' is moved}} + // expected-warning@-3 {{Moved-from object 'a' is moved}} + // expected-note@-4 {{Moved-from object 'a' is moved}} +#endif } } @@ -138,20 +163,35 @@ void simpleMoveAssignementTest() { { A a; A b; - b = std::move(a); // expected-note {{Object 'a' is moved}} - a.foo(); // expected-warning {{Method called on moved-from object 'a'}} expected-note {{Method called on moved-from object 'a'}} + b = std::move(a); + a.foo(); +#ifndef PEACEFUL + // expected-note@-3 {{Object 'a' is moved}} + // expected-warning@-3 {{Method called on moved-from object 'a'}} + // expected-note@-4 {{Method called on moved-from object 'a'}} +#endif } { A a; A b; - b = std::move(a); // expected-note {{Object 'a' is moved}} - A c(a); // expected-warning {{Moved-from object 'a' is copied}} expected-note {{Moved-from object 'a' is copied}} + b = std::move(a); + A c(a); +#ifndef PEACEFUL + // expected-note@-3 {{Object 'a' is moved}} + // expected-warning@-3 {{Moved-from object 'a' is copied}} + // expected-note@-4 {{Moved-from object 'a' is copied}} +#endif } { A a; A b; - b = std::move(a); // expected-note {{Object 'a' is moved}} - A c(std::move(a)); // expected-warning {{Moved-from object 'a' is moved}} expected-note {{Moved-from object 'a' is moved}} + b = std::move(a); + A c(std::move(a)); +#ifndef PEACEFUL + // expected-note@-3 {{Object 'a' is moved}} + // expected-warning@-3 {{Moved-from object 'a' is moved}} + // expected-note@-4 {{Moved-from object 'a' is moved}} +#endif } } @@ -160,8 +200,13 @@ void moveInInitListTest() { A a; }; A a; - S s{std::move(a)}; // expected-note {{Object 'a' is moved}} - a.foo(); // expected-warning {{Method called on moved-from object 'a'}} expected-note {{Method called on moved-from object 'a'}} + S s{std::move(a)}; + a.foo(); +#ifndef PEACEFUL + // expected-note@-3 {{Object 'a' is moved}} + // expected-warning@-3 {{Method called on moved-from object 'a'}} + // expected-note@-4 {{Method called on moved-from object 'a'}} +#endif } // Don't report a bug if the variable was assigned to in the meantime. @@ -175,23 +220,43 @@ void reinitializationTest(int i) { } { A a; - if (i == 1) { // expected-note {{Assuming 'i' is not equal to 1}} expected-note {{Taking false branch}} - // expected-note@-1 {{Assuming 'i' is not equal to 1}} expected-note@-1 {{Taking false branch}} + if (i == 1) { +#ifndef PEACEFUL + // expected-note@-2 {{Assuming 'i' is not equal to 1}} + // expected-note@-3 {{Taking false branch}} + // And the other report: + // expected-note@-5 {{Assuming 'i' is not equal to 1}} + // expected-note@-6 {{Taking false branch}} +#endif A b; b = std::move(a); a = A(); } - if (i == 2) { // expected-note {{Assuming 'i' is not equal to 2}} expected-note {{Taking false branch}} - //expected-note@-1 {{Assuming 'i' is not equal to 2}} expected-note@-1 {{Taking false branch}} + if (i == 2) { +#ifndef PEACEFUL + // expected-note@-2 {{Assuming 'i' is not equal to 2}} + // expected-note@-3 {{Taking false branch}} + // And the other report: + // expected-note@-5 {{Assuming 'i' is not equal to 2}} + // expected-note@-6 {{Taking false branch}} +#endif a.foo(); // no-warning } } { A a; - if (i == 1) { // expected-note {{Taking false branch}} expected-note {{Taking false branch}} + if (i == 1) { +#ifndef PEACEFUL + // expected-note@-2 {{Taking false branch}} + // expected-note@-3 {{Taking false branch}} +#endif std::move(a); } - if (i == 2) { // expected-note {{Taking false branch}} expected-note {{Taking false branch}} + if (i == 2) { +#ifndef PEACEFUL + // expected-note@-2 {{Taking false branch}} + // expected-note@-3 {{Taking false branch}} +#endif a = A(); a.foo(); } @@ -209,19 +274,36 @@ void reinitializationTest(int i) { A b; b = std::move(a); a = A(); - b = std::move(a); // expected-note {{Object 'a' is moved}} - a.foo(); // expected-warning {{Method called on moved-from object 'a'}} expected-note {{Method called on moved-from object 'a'}} + b = std::move(a); + a.foo(); +#ifndef PEACEFUL + // expected-note@-3 {{Object 'a' is moved}} + // expected-warning@-3 {{Method called on moved-from object 'a'}} + // expected-note@-4 {{Method called on moved-from object 'a'}} +#endif } // If a path exist where we not reinitialize the variable we report a bug. { A a; A b; - b = std::move(a); // expected-note {{Object 'a' is moved}} - if (i < 10) { // expected-note {{Assuming 'i' is >= 10}} expected-note {{Taking false branch}} + b = std::move(a); +#ifndef PEACEFUL + // expected-note@-2 {{Object 'a' is moved}} +#endif + if (i < 10) { +#ifndef PEACEFUL + // expected-note@-2 {{Assuming 'i' is >= 10}} + // expected-note@-3 {{Taking false branch}} +#endif a = A(); } - if (i > 5) { // expected-note {{Taking true branch}} - a.foo(); // expected-warning {{Method called on moved-from object 'a'}} expected-note {{Method called on moved-from object 'a'}} + if (i > 5) { + a.foo(); +#ifndef PEACEFUL + // expected-note@-3 {{Taking true branch}} + // expected-warning@-3 {{Method called on moved-from object 'a'}} + // expected-note@-4 {{Method called on moved-from object 'a'}} +#endif } } } @@ -236,79 +318,117 @@ void decltypeIsNotUseTest() { void loopTest() { { A a; - for (int i = 0; i < bignum(); i++) { // expected-note {{Loop condition is false. Execution jumps to the end of the function}} + for (int i = 0; i < bignum(); i++) { +#ifndef PEACEFUL + // expected-note@-2 {{Loop condition is false. Execution jumps to the end of the function}} +#endif rightRefCall(std::move(a)); // no-warning } } { A a; - for (int i = 0; i < 2; i++) { // expected-note {{Loop condition is true. Entering loop body}} - //expected-note@-1 {{Loop condition is true. Entering loop body}} - //expected-note@-2 {{Loop condition is false. Execution jumps to the end of the function}} + for (int i = 0; i < 2; i++) { +#ifndef PEACEFUL + // expected-note@-2 {{Loop condition is true. Entering loop body}} + // expected-note@-3 {{Loop condition is true. Entering loop body}} + // expected-note@-4 {{Loop condition is false. Execution jumps to the end of the function}} +#endif rightRefCall(std::move(a)); // no-warning } } { A a; - for (int i = 0; i < bignum(); i++) { // expected-note {{Loop condition is false. Execution jumps to the end of the function}} + for (int i = 0; i < bignum(); i++) { +#ifndef PEACEFUL + // expected-note@-2 {{Loop condition is false. Execution jumps to the end of the function}} +#endif leftRefCall(a); // no-warning } } { A a; - for (int i = 0; i < 2; i++) { // expected-note {{Loop condition is true. Entering loop body}} - //expected-note@-1 {{Loop condition is true. Entering loop body}} - //expected-note@-2 {{Loop condition is false. Execution jumps to the end of the function}} + for (int i = 0; i < 2; i++) { +#ifndef PEACEFUL + // expected-note@-2 {{Loop condition is true. Entering loop body}} + // expected-note@-3 {{Loop condition is true. Entering loop body}} + // expected-note@-4 {{Loop condition is false. Execution jumps to the end of the function}} +#endif leftRefCall(a); // no-warning } } { A a; - for (int i = 0; i < bignum(); i++) { // expected-note {{Loop condition is false. Execution jumps to the end of the function}} + for (int i = 0; i < bignum(); i++) { +#ifndef PEACEFUL + // expected-note@-2 {{Loop condition is false. Execution jumps to the end of the function}} +#endif constCopyOrMoveCall(a); // no-warning } } { A a; - for (int i = 0; i < 2; i++) { // expected-note {{Loop condition is true. Entering loop body}} - //expected-note@-1 {{Loop condition is true. Entering loop body}} - //expected-note@-2 {{Loop condition is false. Execution jumps to the end of the function}} + for (int i = 0; i < 2; i++) { +#ifndef PEACEFUL + // expected-note@-2 {{Loop condition is true. Entering loop body}} + // expected-note@-3 {{Loop condition is true. Entering loop body}} + // expected-note@-4 {{Loop condition is false. Execution jumps to the end of the function}} +#endif constCopyOrMoveCall(a); // no-warning } } { A a; - for (int i = 0; i < bignum(); i++) { // expected-note {{Loop condition is false. Execution jumps to the end of the function}} + for (int i = 0; i < bignum(); i++) { +#ifndef PEACEFUL + // expected-note@-2 {{Loop condition is false. Execution jumps to the end of the function}} +#endif moveInsideFunctionCall(a); // no-warning } } { A a; - for (int i = 0; i < 2; i++) { // expected-note {{Loop condition is true. Entering loop body}} - //expected-note@-1 {{Loop condition is true. Entering loop body}} - //expected-note@-2 {{Loop condition is false. Execution jumps to the end of the function}} + for (int i = 0; i < 2; i++) { +#ifndef PEACEFUL + // expected-note@-2 {{Loop condition is true. Entering loop body}} + // expected-note@-3 {{Loop condition is true. Entering loop body}} + // expected-note@-4 {{Loop condition is false. Execution jumps to the end of the function}} +#endif moveInsideFunctionCall(a); // no-warning } } { A a; - for (int i = 0; i < bignum(); i++) { // expected-note {{Loop condition is false. Execution jumps to the end of the function}} + for (int i = 0; i < bignum(); i++) { +#ifndef PEACEFUL + // expected-note@-2 {{Loop condition is false. Execution jumps to the end of the function}} +#endif copyOrMoveCall(a); // no-warning } } { A a; - for (int i = 0; i < 2; i++) { // expected-note {{Loop condition is true.}} - //expected-note@-1 {{Loop condition is true. Entering loop body}} - //expected-note@-2 {{Loop condition is false. Execution jumps to the end of the function}} + for (int i = 0; i < 2; i++) { +#ifndef PEACEFUL + // expected-note@-2 {{Loop condition is true. Entering loop body}} + // expected-note@-3 {{Loop condition is true. Entering loop body}} + // expected-note@-4 {{Loop condition is false. Execution jumps to the end of the function}} +#endif copyOrMoveCall(a); // no-warning } } { A a; - for (int i = 0; i < bignum(); i++) { // expected-note {{Loop condition is true. Entering loop body}} expected-note {{Loop condition is true. Entering loop body}} - constCopyOrMoveCall(std::move(a)); // expected-warning {{Moved-from object 'a' is moved}} expected-note {{Moved-from object 'a' is moved}} - // expected-note@-1 {{Object 'a' is moved}} + for (int i = 0; i < bignum(); i++) { +#ifndef PEACEFUL + // expected-note@-2 {{Loop condition is true. Entering loop body}} + // expected-note@-3 {{Loop condition is true. Entering loop body}} +#endif + constCopyOrMoveCall(std::move(a)); +#ifndef PEACEFUL + // expected-note@-2 {{Object 'a' is moved}} + // expected-warning@-3 {{Moved-from object 'a' is moved}} + // expected-note@-4 {{Moved-from object 'a' is moved}} +#endif } } @@ -326,14 +446,21 @@ void loopTest() { } } -//report a usage of a moved-from object only at the first use +// Report a usage of a moved-from object only at the first use. void uniqueTest(bool cond) { A a(42, 42.0); A b; - b = std::move(a); // expected-note {{Object 'a' is moved}} + b = std::move(a); - if (cond) { // expected-note {{Assuming 'cond' is not equal to 0}} expected-note {{Taking true branch}} - a.foo(); // expected-warning {{Method called on moved-from object 'a'}} expected-note {{Method called on moved-from object 'a'}} + if (cond) { + a.foo(); +#ifndef PEACEFUL + // expected-note@-5 {{Object 'a' is moved}} + // expected-note@-4 {{Assuming 'cond' is not equal to 0}} + // expected-note@-5 {{Taking true branch}} + // expected-warning@-5 {{Method called on moved-from object 'a'}} + // expected-note@-6 {{Method called on moved-from object 'a'}} +#endif } if (cond) { a.bar(); // no-warning @@ -344,8 +471,13 @@ void uniqueTest(bool cond) { void uniqueTest2() { A a; - A a1 = std::move(a); // expected-note {{Object 'a' is moved}} - a.foo(); // expected-warning {{Method called on moved-from object 'a'}} expected-note {{Method called on moved-from object 'a'}} + A a1 = std::move(a); + a.foo(); +#ifndef PEACEFUL + // expected-note@-3 {{Object 'a' is moved}} + // expected-warning@-3 {{Method called on moved-from object 'a'}} + // expected-note@-4 {{Method called on moved-from object 'a'}} +#endif A a2 = std::move(a); // no-warning a.foo(); // no-warning @@ -355,12 +487,19 @@ void uniqueTest2() { //even on moved-from objects. void moveSafeFunctionsTest() { A a; - A b = std::move(a); // expected-note {{Object 'a' is moved}} + A b = std::move(a); +#ifndef PEACEFUL + // expected-note@-2 {{Object 'a' is moved}} +#endif a.empty(); // no-warning a.isEmpty(); // no-warning (void)a; // no-warning (bool)a; // expected-warning {{expression result unused}} - a.foo(); // expected-warning {{Method called on moved-from object 'a'}} expected-note {{Method called on moved-from object 'a'}} + a.foo(); +#ifndef PEACEFUL + // expected-warning@-2 {{Method called on moved-from object 'a'}} + // expected-note@-3 {{Method called on moved-from object 'a'}} +#endif } void moveStateResetFunctionsTest() { @@ -496,7 +635,11 @@ void differentBranchesTest(int i) { // Don't warn if the use is in a different branch from the move. { A a; - if (i > 0) { // expected-note {{Assuming 'i' is > 0}} expected-note {{Taking true branch}} + if (i > 0) { +#ifndef PEACEFUL + // expected-note@-2 {{Assuming 'i' is > 0}} + // expected-note@-3 {{Taking true branch}} +#endif A b; b = std::move(a); } else { @@ -506,24 +649,40 @@ void differentBranchesTest(int i) { // Same thing, but with a ternary operator. { A a, b; - i > 0 ? (void)(b = std::move(a)) : a.bar(); // no-warning // expected-note {{'?' condition is true}} + i > 0 ? (void)(b = std::move(a)) : a.bar(); // no-warning +#ifndef PEACEFUL + // expected-note@-2 {{'?' condition is true}} +#endif } // A variation on the theme above. { A a; + a.foo() > 0 ? a.foo() : A(std::move(a)).foo(); #ifdef DFS - a.foo() > 0 ? a.foo() : A(std::move(a)).foo(); // expected-note {{Assuming the condition is false}} expected-note {{'?' condition is false}} + #ifndef PEACEFUL + // expected-note@-3 {{Assuming the condition is false}} + // expected-note@-4 {{'?' condition is false}} + #endif #else - a.foo() > 0 ? a.foo() : A(std::move(a)).foo(); // expected-note {{Assuming the condition is true}} expected-note {{'?' condition is true}} + #ifndef PEACEFUL + // expected-note@-8 {{Assuming the condition is true}} + // expected-note@-9 {{'?' condition is true}} + #endif #endif } // Same thing, but with a switch statement. { A a, b; - switch (i) { // expected-note {{Control jumps to 'case 1:'}} + switch (i) { +#ifndef PEACEFUL + // expected-note@-2 {{Control jumps to 'case 1:'}} +#endif case 1: b = std::move(a); // no-warning - break; // expected-note {{Execution jumps to the end of the function}} + break; +#ifndef PEACEFUL + // expected-note@-2 {{Execution jumps to the end of the function}} +#endif case 2: a.foo(); // no-warning break; @@ -532,11 +691,21 @@ void differentBranchesTest(int i) { // However, if there's a fallthrough, we do warn. { A a, b; - switch (i) { // expected-note {{Control jumps to 'case 1:'}} + switch (i) { +#ifndef PEACEFUL + // expected-note@-2 {{Control jumps to 'case 1:'}} +#endif case 1: - b = std::move(a); // expected-note {{Object 'a' is moved}} + b = std::move(a); +#ifndef PEACEFUL + // expected-note@-2 {{Object 'a' is moved}} +#endif case 2: - a.foo(); // expected-warning {{Method called on moved-from object}} expected-note {{Method called on moved-from object 'a'}} + a.foo(); +#ifndef PEACEFUL + // expected-warning@-2 {{Method called on moved-from object}} + // expected-note@-3 {{Method called on moved-from object 'a'}} +#endif break; } } @@ -551,14 +720,22 @@ void tempTest() { } void interFunTest1(A &a) { - a.bar(); // expected-warning {{Method called on moved-from object 'a'}} expected-note {{Method called on moved-from object 'a'}} + a.bar(); +#ifndef PEACEFUL + // expected-warning@-2 {{Method called on moved-from object 'a'}} + // expected-note@-3 {{Method called on moved-from object 'a'}} +#endif } void interFunTest2() { A a; A b; - b = std::move(a); // expected-note {{Object 'a' is moved}} - interFunTest1(a); // expected-note {{Calling 'interFunTest1'}} + b = std::move(a); + interFunTest1(a); +#ifndef PEACEFUL + // expected-note@-3 {{Object 'a' is moved}} + // expected-note@-3 {{Calling 'interFunTest1'}} +#endif } void foobar(A a, int i); @@ -566,8 +743,12 @@ void foobar(int i, A a); void paramEvaluateOrderTest() { A a; - foobar(std::move(a), a.getI()); // expected-warning {{Method called on moved-from object 'a'}} expected-note {{Method called on moved-from object 'a'}} - // expected-note@-1 {{Object 'a' is moved}} + foobar(std::move(a), a.getI()); +#ifndef PEACEFUL + // expected-note@-2 {{Object 'a' is moved}} + // expected-warning@-3 {{Method called on moved-from object 'a'}} + // expected-note@-4 {{Method called on moved-from object 'a'}} +#endif //FALSE NEGATIVE since parameters evaluate order is undefined foobar(a.getI(), std::move(a)); //no-warning @@ -590,10 +771,14 @@ void regionAndPointerEscapeTest() { { A a; A b; - b = std::move(a); // expected-note{{Object 'a' is moved}} + b = std::move(a); not_known_pass_by_const_ref(a); - a.foo(); // expected-warning{{Method called on moved-from object 'a'}} - // expected-note@-1{{Method called on moved-from object 'a'}} + a.foo(); +#ifndef PEACEFUL + // expected-note@-4{{Object 'a' is moved}} + // expected-warning@-3{{Method called on moved-from object 'a'}} + // expected-note@-4 {{Method called on moved-from object 'a'}} +#endif } { A a; @@ -612,10 +797,14 @@ void regionAndPointerEscapeTest() { { A a; A b; - b = std::move(a); // expected-note{{Object 'a' is moved}} + b = std::move(a); not_known_pass_by_const_ptr(&a); - a.foo(); // expected-warning{{Method called on moved-from object 'a'}} - // expected-note@-1{{Method called on moved-from object 'a'}} + a.foo(); +#ifndef PEACEFUL + // expected-note@-4{{Object 'a' is moved}} + // expected-warning@-3{{Method called on moved-from object 'a'}} + // expected-note@-4 {{Method called on moved-from object 'a'}} +#endif } } @@ -628,8 +817,12 @@ void declarationSequenceTest() { } { A a; - A a1 = std::move(a), a2 = a; // expected-warning {{Moved-from object 'a' is copied}} expected-note {{Moved-from object 'a' is copied}} - // expected-note@-1 {{Object 'a' is moved}} + A a1 = std::move(a), a2 = a; +#ifndef PEACEFUL + // expected-note@-2 {{Object 'a' is moved}} + // expected-warning@-3 {{Moved-from object 'a' is copied}} + // expected-note@-4 {{Moved-from object 'a' is copied}} +#endif } } @@ -637,43 +830,74 @@ void declarationSequenceTest() { void logicalOperatorsSequenceTest() { { A a; - if (a.foo() > 0 && A(std::move(a)).foo() > 0) { // expected-note {{Assuming the condition is false}} expected-note {{Assuming the condition is false}} - // expected-note@-1 {{Left side of '&&' is false}} expected-note@-1 {{Left side of '&&' is false}} - //expected-note@-2 {{Taking false branch}} expected-note@-2 {{Taking false branch}} + if (a.foo() > 0 && A(std::move(a)).foo() > 0) { +#ifndef PEACEFUL + // expected-note@-2 {{Assuming the condition is false}} + // expected-note@-3 {{Left side of '&&' is false}} + // expected-note@-4 {{Taking false branch}} + // And the other report: + // expected-note@-6 {{Assuming the condition is false}} + // expected-note@-7 {{Left side of '&&' is false}} + // expected-note@-8 {{Taking false branch}} A().bar(); +#endif } } // A variation: Negate the result of the && (which pushes the && further down // into the AST). { A a; - if (!(a.foo() > 0 && A(std::move(a)).foo() > 0)) { // expected-note {{Assuming the condition is false}} expected-note {{Assuming the condition is false}} - // expected-note@-1 {{Left side of '&&' is false}} expected-note@-1 {{Left side of '&&' is false}} - // expected-note@-2 {{Taking true branch}} expected-note@-2 {{Taking true branch}} + if (!(a.foo() > 0 && A(std::move(a)).foo() > 0)) { +#ifndef PEACEFUL + // expected-note@-2 {{Assuming the condition is false}} + // expected-note@-3 {{Left side of '&&' is false}} + // expected-note@-4 {{Taking true branch}} + // And the other report: + // expected-note@-6 {{Assuming the condition is false}} + // expected-note@-7 {{Left side of '&&' is false}} + // expected-note@-8 {{Taking true branch}} +#endif A().bar(); } } { A a; - if (A(std::move(a)).foo() > 0 && a.foo() > 0) { // expected-warning {{Method called on moved-from object 'a'}} expected-note {{Method called on moved-from object 'a'}} - // expected-note@-1 {{Object 'a' is moved}} expected-note@-1 {{Assuming the condition is true}} expected-note@-1 {{Assuming the condition is false}} - // expected-note@-2 {{Left side of '&&' is false}} expected-note@-2 {{Left side of '&&' is true}} - // expected-note@-3 {{Taking false branch}} + if (A(std::move(a)).foo() > 0 && a.foo() > 0) { +#ifndef PEACEFUL + // expected-note@-2 {{Object 'a' is moved}} + // expected-note@-3 {{Assuming the condition is true}} + // expected-note@-4 {{Left side of '&&' is true}} + // expected-warning@-5 {{Method called on moved-from object 'a'}} + // expected-note@-6 {{Method called on moved-from object 'a'}} + // And the other report: + // expected-note@-8 {{Assuming the condition is false}} + // expected-note@-9 {{Left side of '&&' is false}} + // expected-note@-10{{Taking false branch}} +#endif A().bar(); } } { A a; - if (a.foo() > 0 || A(std::move(a)).foo() > 0) { // expected-note {{Assuming the condition is true}} - //expected-note@-1 {{Left side of '||' is true}} - //expected-note@-2 {{Taking true branch}} + if (a.foo() > 0 || A(std::move(a)).foo() > 0) { +#ifndef PEACEFUL + // expected-note@-2 {{Assuming the condition is true}} + // expected-note@-3 {{Left side of '||' is true}} + // expected-note@-4 {{Taking true branch}} +#endif A().bar(); } } { A a; - if (A(std::move(a)).foo() > 0 || a.foo() > 0) { // expected-warning {{Method called on moved-from object 'a'}} expected-note {{Method called on moved-from object 'a'}} - // expected-note@-1 {{Object 'a' is moved}} expected-note@-1 {{Assuming the condition is false}} expected-note@-1 {{Left side of '||' is false}} + if (A(std::move(a)).foo() > 0 || a.foo() > 0) { +#ifndef PEACEFUL + // expected-note@-2 {{Object 'a' is moved}} + // expected-note@-3 {{Assuming the condition is false}} + // expected-note@-4 {{Left side of '||' is false}} + // expected-warning@-5 {{Method called on moved-from object 'a'}} + // expected-note@-6 {{Method called on moved-from object 'a'}} +#endif A().bar(); } } @@ -729,14 +953,24 @@ void subRegionMoveTest() { // Don't report a misuse if any SuperRegion is already reported. { A a; - A a1 = std::move(a); // expected-note {{Object 'a' is moved}} - a.foo(); // expected-warning {{Method called on moved-from object 'a'}} expected-note {{Method called on moved-from object 'a'}} + A a1 = std::move(a); + a.foo(); +#ifndef PEACEFUL + // expected-note@-3 {{Object 'a' is moved}} + // expected-warning@-3 {{Method called on moved-from object 'a'}} + // expected-note@-4 {{Method called on moved-from object 'a'}} +#endif a.b.foo(); // no-warning } { C c; - C c1 = std::move(c); // expected-note {{Object 'c' is moved}} - c.foo(); // expected-warning {{Method called on moved-from object 'c'}} expected-note {{Method called on moved-from object 'c'}} + C c1 = std::move(c); + c.foo(); +#ifndef PEACEFUL + // expected-note@-3 {{Object 'c' is moved}} + // expected-warning@-3 {{Method called on moved-from object 'c'}} + // expected-note@-4 {{Method called on moved-from object 'c'}} +#endif c.b.foo(); // no-warning } } @@ -757,8 +991,13 @@ void resetSuperClass2() { void reportSuperClass() { C c; - C c1 = std::move(c); // expected-note {{Object 'c' is moved}} - c.foo(); // expected-warning {{Method called on moved-from object 'c'}} expected-note {{Method called on moved-from object 'c'}} + C c1 = std::move(c); + c.foo(); +#ifndef PEACEFUL + // expected-note@-3 {{Object 'c' is moved}} + // expected-warning@-3 {{Method called on moved-from object 'c'}} + // expected-note@-4 {{Method called on moved-from object 'c'}} +#endif C c2 = c; // no-warning } @@ -872,17 +1111,25 @@ class HasSTLField { }; void localRValueMove(A &&a) { - A b = std::move(a); // expected-note{{Object 'a' is moved}} - a.foo(); // expected-warning{{Method called on moved-from object 'a'}} - // expected-note@-1{{Method called on moved-from object 'a'}} + A b = std::move(a); + a.foo(); +#ifndef PEACEFUL + // expected-note@-3 {{Object 'a' is moved}} + // expected-warning@-3 {{Method called on moved-from object 'a'}} + // expected-note@-4 {{Method called on moved-from object 'a'}} +#endif } void localUniquePtr(std::unique_ptr P) { // Even though unique_ptr is safe to use after move, // reusing a local variable this way usually indicates a bug. - std::unique_ptr Q = std::move(P); // expected-note{{Object 'P' is moved}} - P.get(); // expected-warning{{Method called on moved-from object 'P'}} - // expected-note@-1{{Method called on moved-from object 'P'}} + std::unique_ptr Q = std::move(P); + P.get(); +#ifndef PEACEFUL + // expected-note@-3 {{Object 'P' is moved}} + // expected-warning@-3 {{Method called on moved-from object 'P'}} + // expected-note@-4 {{Method called on moved-from object 'P'}} +#endif } void localUniquePtrWithArrow(std::unique_ptr P) { -- cgit v1.2.3 From 9cc18140e73769c5980338eb0f65d5d40553718a Mon Sep 17 00:00:00 2001 From: Artem Dergachev Date: Mon, 17 Dec 2018 06:30:39 +0000 Subject: [analyzer] MoveChecker: Enable by default as cplusplus.Move. This checker warns you when you re-use an object after moving it. Mostly developed by Peter Szecsi! Differential Revision: https://reviews.llvm.org/D38675 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349328 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/StaticAnalyzer/Checkers/Checkers.td | 6 +++--- test/Analysis/mismatched-iterator.cpp | 5 ++++- test/Analysis/use-after-move.cpp | 20 ++++++++++---------- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/include/clang/StaticAnalyzer/Checkers/Checkers.td b/include/clang/StaticAnalyzer/Checkers/Checkers.td index 5280ad70e9..0d16de1ccc 100644 --- a/include/clang/StaticAnalyzer/Checkers/Checkers.td +++ b/include/clang/StaticAnalyzer/Checkers/Checkers.td @@ -275,6 +275,9 @@ def NewDeleteLeaksChecker : Checker<"NewDeleteLeaks">, def CXXSelfAssignmentChecker : Checker<"SelfAssignment">, HelpText<"Checks C++ copy and move assignment operators for self assignment">; +def MoveChecker: Checker<"Move">, + HelpText<"Find use-after-move bugs in C++">; + } // end: "cplusplus" let ParentPackage = CplusplusOptIn in { @@ -303,9 +306,6 @@ def MismatchedIteratorChecker : Checker<"MismatchedIterator">, HelpText<"Check for use of iterators of different containers where iterators " "of the same container are expected">; -def MoveChecker: Checker<"Move">, - HelpText<"Find use-after-move bugs in C++">; - def UninitializedObjectChecker: Checker<"UninitializedObject">, HelpText<"Reports uninitialized fields after object construction">; diff --git a/test/Analysis/mismatched-iterator.cpp b/test/Analysis/mismatched-iterator.cpp index 23f54d3f79..756d095443 100644 --- a/test/Analysis/mismatched-iterator.cpp +++ b/test/Analysis/mismatched-iterator.cpp @@ -100,7 +100,7 @@ void good_move_find2(std::vector &v1, std::vector &v2, int n) { void good_move_find3(std::vector &v1, std::vector &v2, int n) { auto i0 = v2.cend(); v1 = std::move(v2); - v2.push_back(n); + v2.push_back(n); // expected-warning{{Method called on moved-from object of type 'std::vector'}} std::find(v2.cbegin(), i0, n); // no-warning } @@ -125,6 +125,7 @@ void bad_move_find1(std::vector &v1, std::vector &v2, int n) { auto i0 = v2.cbegin(); v1 = std::move(v2); std::find(i0, v2.cend(), n); // expected-warning{{Iterators of different containers used where the same container is expected}} + // expected-warning@-1{{Method called on moved-from object of type 'std::vector'}} } void bad_insert_find(std::vector &v1, std::vector &v2, int n, int m) { @@ -167,12 +168,14 @@ void bad_move(std::vector &v1, std::vector &v2) { const auto i0 = ++v2.cbegin(); v1 = std::move(v2); v2.erase(i0); // expected-warning{{Container accessed using foreign iterator argument}} + // expected-warning@-1{{Method called on moved-from object of type 'std::vector'}} } void bad_move_find2(std::vector &v1, std::vector &v2, int n) { auto i0 = --v2.cend(); v1 = std::move(v2); std::find(i0, v2.cend(), n); // expected-warning{{Iterators of different containers used where the same container is expected}} + // expected-warning@-1{{Method called on moved-from object of type 'std::vector'}} } void bad_move_find3(std::vector &v1, std::vector &v2, int n) { diff --git a/test/Analysis/use-after-move.cpp b/test/Analysis/use-after-move.cpp index 652f08f45c..280724512f 100644 --- a/test/Analysis/use-after-move.cpp +++ b/test/Analysis/use-after-move.cpp @@ -1,30 +1,30 @@ -// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.cplusplus.Move -verify %s\ +// RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus.Move -verify %s\ // RUN: -std=c++11 -analyzer-output=text -analyzer-config eagerly-assume=false\ // RUN: -analyzer-config exploration_strategy=unexplored_first_queue\ // RUN: -analyzer-checker debug.ExprInspection -// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.cplusplus.Move -verify %s\ +// RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus.Move -verify %s\ // RUN: -std=c++11 -analyzer-output=text -analyzer-config eagerly-assume=false\ // RUN: -analyzer-config exploration_strategy=dfs -DDFS=1\ // RUN: -analyzer-checker debug.ExprInspection -// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.cplusplus.Move -verify %s\ +// RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus.Move -verify %s\ // RUN: -std=c++11 -analyzer-output=text -analyzer-config eagerly-assume=false\ // RUN: -analyzer-config exploration_strategy=unexplored_first_queue\ -// RUN: -analyzer-config alpha.cplusplus.Move:WarnOn=KnownsOnly -DPEACEFUL\ +// RUN: -analyzer-config cplusplus.Move:WarnOn=KnownsOnly -DPEACEFUL\ // RUN: -analyzer-checker debug.ExprInspection -// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.cplusplus.Move -verify %s\ +// RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus.Move -verify %s\ // RUN: -std=c++11 -analyzer-output=text -analyzer-config eagerly-assume=false\ // RUN: -analyzer-config exploration_strategy=dfs -DDFS=1\ -// RUN: -analyzer-config alpha.cplusplus.Move:WarnOn=KnownsOnly -DPEACEFUL\ +// RUN: -analyzer-config cplusplus.Move:WarnOn=KnownsOnly -DPEACEFUL\ // RUN: -analyzer-checker debug.ExprInspection -// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.cplusplus.Move -verify %s\ +// RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus.Move -verify %s\ // RUN: -std=c++11 -analyzer-output=text -analyzer-config eagerly-assume=false\ // RUN: -analyzer-config exploration_strategy=unexplored_first_queue\ -// RUN: -analyzer-config alpha.cplusplus.Move:WarnOn=All -DAGGRESSIVE\ +// RUN: -analyzer-config cplusplus.Move:WarnOn=All -DAGGRESSIVE\ // RUN: -analyzer-checker debug.ExprInspection -// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.cplusplus.Move -verify %s\ +// RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus.Move -verify %s\ // RUN: -std=c++11 -analyzer-output=text -analyzer-config eagerly-assume=false\ // RUN: -analyzer-config exploration_strategy=dfs -DDFS=1\ -// RUN: -analyzer-config alpha.cplusplus.Move:WarnOn=All -DAGGRESSIVE\ +// RUN: -analyzer-config cplusplus.Move:WarnOn=All -DAGGRESSIVE\ // RUN: -analyzer-checker debug.ExprInspection #include "Inputs/system-header-simulator-cxx.h" -- cgit v1.2.3 From 6ee9b9291f15391989fa14b029bf60e9cf7215ca Mon Sep 17 00:00:00 2001 From: Carey Williams Date: Mon, 17 Dec 2018 10:11:35 +0000 Subject: [Docs] Expand -fstack-protector and -fstack-protector-all Improve the description of these command line options by providing specific heuristic information, as outlined for the ssp function attribute(s) in LLVM's documentation. Also rewords -fstack-protector-all for affinity. Differential Revision: https://reviews.llvm.org/D55428 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349335 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Driver/Options.td | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td index acf82c5ab2..50aa0833e1 100644 --- a/include/clang/Driver/Options.td +++ b/include/clang/Driver/Options.td @@ -1639,11 +1639,18 @@ def fno_signed_char : Flag<["-"], "fno-signed-char">, Group, Flags<[CC1Option]>, HelpText<"Char is unsigned">; def fsplit_stack : Flag<["-"], "fsplit-stack">, Group; def fstack_protector_all : Flag<["-"], "fstack-protector-all">, Group, - HelpText<"Force the usage of stack protectors for all functions">; + HelpText<"Enable stack protectors for all functions">; def fstack_protector_strong : Flag<["-"], "fstack-protector-strong">, Group, - HelpText<"Use a strong heuristic to apply stack protectors to functions">; + HelpText<"Enable stack protectors for some functions vulnerable to stack smashing. " + "Compared to -fstack-protector, this uses a stronger heuristic " + "that includes functions containing arrays of any size (and any type), " + "as well as any calls to alloca or the taking of an address from a local variable">; def fstack_protector : Flag<["-"], "fstack-protector">, Group, - HelpText<"Enable stack protectors for functions potentially vulnerable to stack smashing">; + HelpText<"Enable stack protectors for some functions vulnerable to stack smashing. " + "This uses a loose heuristic which considers functions vulnerable " + "if they contain a char (or 8bit integer) array or constant sized calls to " + "alloca, which are of greater size than ssp-buffer-size (default: 8 bytes). " + "All variable sized calls to alloca are considered vulnerable">; def fstandalone_debug : Flag<["-"], "fstandalone-debug">, Group, Flags<[CoreOption]>, HelpText<"Emit full debug info for all types used by the program">; def fno_standalone_debug : Flag<["-"], "fno-standalone-debug">, Group, Flags<[CoreOption]>, -- cgit v1.2.3 From 5f610d030dfd76b4df01f08fec8893357145d352 Mon Sep 17 00:00:00 2001 From: Kristof Umann Date: Mon, 17 Dec 2018 10:31:35 +0000 Subject: Reverting bitfield size to attempt to fix a windows buildbot git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349336 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/StaticAnalyzer/Checkers/MallocChecker.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp index fb770eb9ee..b56c55d666 100644 --- a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp @@ -137,7 +137,7 @@ class RefState { const Stmt *S; Kind K : 3; - AllocationFamily Family : 3; + AllocationFamily Family : 29; RefState(Kind k, const Stmt *s, AllocationFamily family) : S(s), K(k), Family(family) { -- cgit v1.2.3 From 2fc54d06aa00bb86417851258a2583742e68b8fe Mon Sep 17 00:00:00 2001 From: Kristof Umann Date: Mon, 17 Dec 2018 12:07:57 +0000 Subject: Revert rC349281 '[analyzer][MallocChecker][NFC] Document and reorganize some functions' git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349340 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/StaticAnalyzer/Checkers/MallocChecker.cpp | 14 +++----------- .../expected-plists/NewDelete-path-notes.cpp.plist | 20 ++++++++++---------- .../Malloc+MismatchedDeallocator+NewDelete.cpp | 2 +- test/Analysis/NewDelete-checker-test.cpp | 2 +- test/Analysis/NewDelete-path-notes.cpp | 8 ++++---- test/Analysis/dtor.cpp | 2 +- 6 files changed, 20 insertions(+), 28 deletions(-) diff --git a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp index b56c55d666..a5b774fe24 100644 --- a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp @@ -137,7 +137,7 @@ class RefState { const Stmt *S; Kind K : 3; - AllocationFamily Family : 29; + AllocationFamily Family : 3; RefState(Kind k, const Stmt *s, AllocationFamily family) : S(s), K(k), Family(family) { @@ -1431,8 +1431,7 @@ ProgramStateRef MallocChecker::addExtentSize(CheckerContext &C, void MallocChecker::checkPreStmt(const CXXDeleteExpr *DE, CheckerContext &C) const { - // This will regard deleting freed() regions as a use-after-free, rather then - // a double-free or double-delete error. + if (!ChecksEnabled[CK_NewDeleteChecker]) if (SymbolRef Sym = C.getSVal(DE->getArgument()).getAsSymbol()) checkUseAfterFree(Sym, C, DE->getArgument()); @@ -1629,8 +1628,7 @@ ProgramStateRef MallocChecker::FreeMemAux(CheckerContext &C, } /// Checks if the previous call to free on the given symbol failed - if free -/// failed, returns true. Also, stores the corresponding return value symbol in -/// \p RetStatusSymbol. +/// failed, returns true. Also, returns the corresponding return value symbol. static bool didPreviousFreeFail(ProgramStateRef State, SymbolRef Sym, SymbolRef &RetStatusSymbol) { const SymbolRef *Ret = State->get(Sym); @@ -2291,12 +2289,6 @@ void MallocChecker::ReportDoubleFree(CheckerContext &C, SourceRange Range, if (!CheckKind.hasValue()) return; - // If this is a double delete error, print the appropiate warning message. - if (CheckKind == CK_NewDeleteChecker) { - ReportDoubleDelete(C, Sym); - return; - } - if (ExplodedNode *N = C.generateErrorNode()) { if (!BT_DoubleFree[*CheckKind]) BT_DoubleFree[*CheckKind].reset(new BugType( diff --git a/test/Analysis/Inputs/expected-plists/NewDelete-path-notes.cpp.plist b/test/Analysis/Inputs/expected-plists/NewDelete-path-notes.cpp.plist index 6a3a3d30c4..d74d9fc7c6 100644 --- a/test/Analysis/Inputs/expected-plists/NewDelete-path-notes.cpp.plist +++ b/test/Analysis/Inputs/expected-plists/NewDelete-path-notes.cpp.plist @@ -194,17 +194,17 @@ depth0 extended_message - Attempt to delete released memory + Attempt to free released memory message - Attempt to delete released memory + Attempt to free released memory - descriptionAttempt to delete released memory + descriptionAttempt to free released memory categoryMemory error - typeDouble delete + typeDouble free check_namecplusplus.NewDelete - issue_hash_content_of_line_in_context593b185245106bed5175ccf2753039b2 + issue_hash_content_of_line_in_contextbd8e324d09c70b9e2be6f824a4942e5a issue_context_kindfunction issue_contexttest issue_hash_function_offset8 @@ -423,17 +423,17 @@ depth0 extended_message - Attempt to delete released memory + Attempt to free released memory message - Attempt to delete released memory + Attempt to free released memory - descriptionAttempt to delete released memory + descriptionAttempt to free released memory categoryMemory error - typeDouble delete + typeDouble free check_namecplusplus.NewDelete - issue_hash_content_of_line_in_context6484e9b006ede7362edef2187ba6eb37 + issue_hash_content_of_line_in_context8bf1a5b9fdae9d86780aa6c4cdce2605 issue_context_kindfunction issue_contexttest issue_hash_function_offset3 diff --git a/test/Analysis/Malloc+MismatchedDeallocator+NewDelete.cpp b/test/Analysis/Malloc+MismatchedDeallocator+NewDelete.cpp index e5176eb50f..b5e47b3355 100644 --- a/test/Analysis/Malloc+MismatchedDeallocator+NewDelete.cpp +++ b/test/Analysis/Malloc+MismatchedDeallocator+NewDelete.cpp @@ -46,7 +46,7 @@ void testMismatchedDeallocator() { void testNewDoubleFree() { int *p = new int; delete p; - delete p; // expected-warning{{Attempt to delete released memory}} + delete p; // expected-warning{{Attempt to free released memory}} } void testNewLeak() { diff --git a/test/Analysis/NewDelete-checker-test.cpp b/test/Analysis/NewDelete-checker-test.cpp index fcbe2c7402..620237cd6e 100644 --- a/test/Analysis/NewDelete-checker-test.cpp +++ b/test/Analysis/NewDelete-checker-test.cpp @@ -182,7 +182,7 @@ void testUseThisAfterDelete() { void testDoubleDelete() { int *p = new int; delete p; - delete p; // expected-warning{{Attempt to delete released memory}} + delete p; // expected-warning{{Attempt to free released memory}} } void testExprDeleteArg() { diff --git a/test/Analysis/NewDelete-path-notes.cpp b/test/Analysis/NewDelete-path-notes.cpp index 94658360fb..d9fe1976b8 100644 --- a/test/Analysis/NewDelete-path-notes.cpp +++ b/test/Analysis/NewDelete-path-notes.cpp @@ -11,8 +11,8 @@ void test() { delete p; // expected-note@-1 {{Memory is released}} - delete p; // expected-warning {{Attempt to delete released memory}} - // expected-note@-1 {{Attempt to delete released memory}} + delete p; // expected-warning {{Attempt to free released memory}} + // expected-note@-1 {{Attempt to free released memory}} } struct Odd { @@ -24,7 +24,7 @@ struct Odd { void test(Odd *odd) { odd->kill(); // expected-note{{Calling 'Odd::kill'}} // expected-note@-1 {{Returning; memory was released}} - delete odd; // expected-warning {{Attempt to delete released memory}} - // expected-note@-1 {{Attempt to delete released memory}} + delete odd; // expected-warning {{Attempt to free released memory}} + // expected-note@-1 {{Attempt to free released memory}} } diff --git a/test/Analysis/dtor.cpp b/test/Analysis/dtor.cpp index 2ea38e95c8..d843f03aad 100644 --- a/test/Analysis/dtor.cpp +++ b/test/Analysis/dtor.cpp @@ -528,7 +528,7 @@ struct NonTrivial { return *this; } ~NonTrivial() { - delete[] p; // expected-warning {{delete released memory}} + delete[] p; // expected-warning {{free released memory}} } }; -- cgit v1.2.3 From c9e5cf1d03a7814cadb8e7ca0336bf1a017df642 Mon Sep 17 00:00:00 2001 From: Simon Pilgrim Date: Mon, 17 Dec 2018 12:17:37 +0000 Subject: Fix "enumeral mismatch in conditional expression" gcc7 warnings. NFCI. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349342 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaDeclAttr.cpp | 7 ++++--- lib/Sema/SemaDeclCXX.cpp | 34 +++++++++++++++++----------------- 2 files changed, 21 insertions(+), 20 deletions(-) diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index 78374b8089..ba041a8786 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -6103,9 +6103,10 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, // though they were unknown attributes. if (AL.getKind() == ParsedAttr::UnknownAttribute || !AL.existsInTarget(S.Context.getTargetInfo())) { - S.Diag(AL.getLoc(), AL.isDeclspecAttribute() - ? diag::warn_unhandled_ms_attribute_ignored - : diag::warn_unknown_attribute_ignored) + S.Diag(AL.getLoc(), + AL.isDeclspecAttribute() + ? (unsigned)diag::warn_unhandled_ms_attribute_ignored + : (unsigned)diag::warn_unknown_attribute_ignored) << AL; return; } diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index d56c880311..d46aa23c27 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -2347,8 +2347,8 @@ Sema::ActOnBaseSpecifier(Decl *classdecl, SourceRange SpecifierRange, if (AL.isInvalid() || AL.getKind() == ParsedAttr::IgnoredAttribute) continue; Diag(AL.getLoc(), AL.getKind() == ParsedAttr::UnknownAttribute - ? diag::warn_unknown_attribute_ignored - : diag::err_base_specifier_attribute) + ? (unsigned)diag::warn_unknown_attribute_ignored + : (unsigned)diag::err_base_specifier_attribute) << AL.getName(); } @@ -2867,14 +2867,14 @@ static const ParsedAttr *getMSPropertyAttr(const ParsedAttributesView &list) { return nullptr; } -// Check if there is a field shadowing. -void Sema::CheckShadowInheritedFields(const SourceLocation &Loc, - DeclarationName FieldName, - const CXXRecordDecl *RD, - bool DeclIsField) { - if (Diags.isIgnored(diag::warn_shadow_field, Loc)) - return; - +// Check if there is a field shadowing. +void Sema::CheckShadowInheritedFields(const SourceLocation &Loc, + DeclarationName FieldName, + const CXXRecordDecl *RD, + bool DeclIsField) { + if (Diags.isIgnored(diag::warn_shadow_field, Loc)) + return; + // To record a shadowed field in a base std::map Bases; auto FieldShadowed = [&](const CXXBaseSpecifier *Specifier, @@ -2908,13 +2908,13 @@ void Sema::CheckShadowInheritedFields(const SourceLocation &Loc, continue; auto BaseField = It->second; assert(BaseField->getAccess() != AS_private); - if (AS_none != - CXXRecordDecl::MergeAccess(P.Access, BaseField->getAccess())) { - Diag(Loc, diag::warn_shadow_field) - << FieldName << RD << Base << DeclIsField; - Diag(BaseField->getLocation(), diag::note_shadow_field); - Bases.erase(It); - } + if (AS_none != + CXXRecordDecl::MergeAccess(P.Access, BaseField->getAccess())) { + Diag(Loc, diag::warn_shadow_field) + << FieldName << RD << Base << DeclIsField; + Diag(BaseField->getLocation(), diag::note_shadow_field); + Bases.erase(It); + } } } -- cgit v1.2.3 From 8a7e164bd5adfbc3956cda016984a1bfc0078802 Mon Sep 17 00:00:00 2001 From: Simon Pilgrim Date: Mon, 17 Dec 2018 12:25:42 +0000 Subject: Fix "enumeral mismatch in conditional expression" gcc7 warning. NFCI. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349343 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaStmtAttr.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/Sema/SemaStmtAttr.cpp b/lib/Sema/SemaStmtAttr.cpp index 353cd60c4a..91f7997166 100644 --- a/lib/Sema/SemaStmtAttr.cpp +++ b/lib/Sema/SemaStmtAttr.cpp @@ -316,9 +316,10 @@ static Attr *ProcessStmtAttribute(Sema &S, Stmt *St, const ParsedAttr &A, SourceRange Range) { switch (A.getKind()) { case ParsedAttr::UnknownAttribute: - S.Diag(A.getLoc(), A.isDeclspecAttribute() ? - diag::warn_unhandled_ms_attribute_ignored : - diag::warn_unknown_attribute_ignored) << A.getName(); + S.Diag(A.getLoc(), A.isDeclspecAttribute() + ? (unsigned)diag::warn_unhandled_ms_attribute_ignored + : (unsigned)diag::warn_unknown_attribute_ignored) + << A.getName(); return nullptr; case ParsedAttr::AT_FallThrough: return handleFallThroughAttr(S, St, A, Range); -- cgit v1.2.3 From 67d5e1ae731d8f9992a01a92cd3c47d745315af9 Mon Sep 17 00:00:00 2001 From: Kristof Umann Date: Mon, 17 Dec 2018 12:25:48 +0000 Subject: Revert rC349281 '[analyzer][MallocChecker][NFC] Document and reorganize some functions' Accidentally commited earlier with the same commit title, but really it should've been "Revert rC349283 '[analyzer][MallocChecker] Improve warning messages on double-delete errors'" git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349344 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/StaticAnalyzer/Checkers/MallocChecker.cpp | 1136 +++++++++---------------- 1 file changed, 422 insertions(+), 714 deletions(-) diff --git a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp index a5b774fe24..ae1b1fc837 100644 --- a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp @@ -7,41 +7,8 @@ // //===----------------------------------------------------------------------===// // -// This file defines a variety of memory management related checkers, such as -// leak, double free, and use-after-free. -// -// The following checkers are defined here: -// -// * MallocChecker -// Despite its name, it models all sorts of memory allocations and -// de- or reallocation, including but not limited to malloc, free, -// relloc, new, delete. It also reports on a variety of memory misuse -// errors. -// Many other checkers interact very closely with this checker, in fact, -// most are merely options to this one. Other checkers may register -// MallocChecker, but do not enable MallocChecker's reports (more details -// to follow around its field, ChecksEnabled). -// It also has a boolean "Optimistic" checker option, which if set to true -// will cause the checker to model user defined memory management related -// functions annotated via the attribute ownership_takes, ownership_holds -// and ownership_returns. -// -// * NewDeleteChecker -// Enables the modeling of new, new[], delete, delete[] in MallocChecker, -// and checks for related double-free and use-after-free errors. -// -// * NewDeleteLeaksChecker -// Checks for leaks related to new, new[], delete, delete[]. -// Depends on NewDeleteChecker. -// -// * MismatchedDeallocatorChecker -// Enables checking whether memory is deallocated with the correspending -// allocation function in MallocChecker, such as malloc() allocated -// regions are only freed by free(), new by delete, new[] by delete[]. -// -// InnerPointerChecker interacts very closely with MallocChecker, but unlike -// the above checkers, it has it's own file, hence the many InnerPointerChecker -// related headers and non-static functions. +// This file defines malloc/free checker, which checks for potential memory +// leaks, double free, and use-after-free problems. // //===----------------------------------------------------------------------===// @@ -70,10 +37,6 @@ using namespace clang; using namespace ento; -//===----------------------------------------------------------------------===// -// The types of allocation we're modeling. -//===----------------------------------------------------------------------===// - namespace { // Used to check correspondence between allocators and deallocators. @@ -87,59 +50,28 @@ enum AllocationFamily { AF_InnerBuffer }; -struct MemFunctionInfoTy; - -} // end of anonymous namespace - -/// Determine family of a deallocation expression. -static AllocationFamily getAllocationFamily( - const MemFunctionInfoTy &MemFunctionInfo, CheckerContext &C, const Stmt *S); - -/// Print names of allocators and deallocators. -/// -/// \returns true on success. -static bool printAllocDeallocName(raw_ostream &os, CheckerContext &C, - const Expr *E); - -/// Print expected name of an allocator based on the deallocator's -/// family derived from the DeallocExpr. -static void printExpectedAllocName(raw_ostream &os, - const MemFunctionInfoTy &MemFunctionInfo, - CheckerContext &C, const Expr *E); - -/// Print expected name of a deallocator based on the allocator's -/// family. -static void printExpectedDeallocName(raw_ostream &os, AllocationFamily Family); - -//===----------------------------------------------------------------------===// -// The state of a symbol, in terms of memory management. -//===----------------------------------------------------------------------===// - -namespace { - class RefState { - enum Kind { - // Reference to allocated memory. - Allocated, - // Reference to zero-allocated memory. - AllocatedOfSizeZero, - // Reference to released/freed memory. - Released, - // The responsibility for freeing resources has transferred from - // this reference. A relinquished symbol should not be freed. - Relinquished, - // We are no longer guaranteed to have observed all manipulations - // of this pointer/memory. For example, it could have been - // passed as a parameter to an opaque function. - Escaped + enum Kind { // Reference to allocated memory. + Allocated, + // Reference to zero-allocated memory. + AllocatedOfSizeZero, + // Reference to released/freed memory. + Released, + // The responsibility for freeing resources has transferred from + // this reference. A relinquished symbol should not be freed. + Relinquished, + // We are no longer guaranteed to have observed all manipulations + // of this pointer/memory. For example, it could have been + // passed as a parameter to an opaque function. + Escaped }; const Stmt *S; + unsigned K : 3; // Kind enum, but stored as a bitfield. + unsigned Family : 29; // Rest of 32-bit word, currently just an allocation + // family. - Kind K : 3; - AllocationFamily Family : 3; - - RefState(Kind k, const Stmt *s, AllocationFamily family) + RefState(Kind k, const Stmt *s, unsigned family) : S(s), K(k), Family(family) { assert(family != AF_None); } @@ -150,7 +82,7 @@ public: bool isRelinquished() const { return K == Relinquished; } bool isEscaped() const { return K == Escaped; } AllocationFamily getAllocationFamily() const { - return Family; + return (AllocationFamily)Family; } const Stmt *getStmt() const { return S; } @@ -158,17 +90,17 @@ public: return K == X.K && S == X.S && Family == X.Family; } - static RefState getAllocated(AllocationFamily family, const Stmt *s) { + static RefState getAllocated(unsigned family, const Stmt *s) { return RefState(Allocated, s, family); } static RefState getAllocatedOfSizeZero(const RefState *RS) { return RefState(AllocatedOfSizeZero, RS->getStmt(), RS->getAllocationFamily()); } - static RefState getReleased(AllocationFamily family, const Stmt *s) { + static RefState getReleased(unsigned family, const Stmt *s) { return RefState(Released, s, family); } - static RefState getRelinquished(AllocationFamily family, const Stmt *s) { + static RefState getRelinquished(unsigned family, const Stmt *s) { return RefState(Relinquished, s, family); } static RefState getEscaped(const RefState *RS) { @@ -181,8 +113,8 @@ public: ID.AddInteger(Family); } - LLVM_DUMP_METHOD void dump(raw_ostream &OS) const { - switch (K) { + void dump(raw_ostream &OS) const { + switch (static_cast(K)) { #define CASE(ID) case ID: OS << #ID; break; CASE(Allocated) CASE(AllocatedOfSizeZero) @@ -195,61 +127,23 @@ public: LLVM_DUMP_METHOD void dump() const { dump(llvm::errs()); } }; -} // end of anonymous namespace - -REGISTER_MAP_WITH_PROGRAMSTATE(RegionState, SymbolRef, RefState) - -/// Check if the memory associated with this symbol was released. -static bool isReleased(SymbolRef Sym, CheckerContext &C); - -/// Update the RefState to reflect the new memory allocation. -/// The optional \p RetVal parameter specifies the newly allocated pointer -/// value; if unspecified, the value of expression \p E is used. -static ProgramStateRef -MallocUpdateRefState(CheckerContext &C, const Expr *E, ProgramStateRef State, - AllocationFamily Family = AF_Malloc, - Optional RetVal = None); - -//===----------------------------------------------------------------------===// -// The modeling of memory reallocation. -// -// The terminology 'toPtr' and 'fromPtr' will be used: -// toPtr = realloc(fromPtr, 20); -//===----------------------------------------------------------------------===// - -REGISTER_SET_WITH_PROGRAMSTATE(ReallocSizeZeroSymbols, SymbolRef) - -namespace { - -/// The state of 'fromPtr' after reallocation is known to have failed. -enum OwnershipAfterReallocKind { - // The symbol needs to be freed (e.g.: realloc) - OAR_ToBeFreedAfterFailure, - // The symbol has been freed (e.g.: reallocf) - OAR_FreeOnFailure, - // The symbol doesn't have to freed (e.g.: we aren't sure if, how and where - // 'fromPtr' was allocated: - // void Haha(int *ptr) { - // ptr = realloc(ptr, 67); - // // ... - // } - // ). - OAR_DoNotTrackAfterFailure +enum ReallocPairKind { + RPToBeFreedAfterFailure, + // The symbol has been freed when reallocation failed. + RPIsFreeOnFailure, + // The symbol does not need to be freed after reallocation fails. + RPDoNotTrackAfterFailure }; -/// Stores information about the 'fromPtr' symbol after reallocation. -/// -/// This is important because realloc may fail, and that needs special modeling. -/// Whether reallocation failed or not will not be known until later, so we'll -/// store whether upon failure 'fromPtr' will be freed, or needs to be freed -/// later, etc. +/// \class ReallocPair +/// Stores information about the symbol being reallocated by a call to +/// 'realloc' to allow modeling failed reallocation later in the path. struct ReallocPair { - - // The 'fromPtr'. + // The symbol which realloc reallocated. SymbolRef ReallocatedSym; - OwnershipAfterReallocKind Kind; + ReallocPairKind Kind; - ReallocPair(SymbolRef S, OwnershipAfterReallocKind K) : + ReallocPair(SymbolRef S, ReallocPairKind K) : ReallocatedSym(S), Kind(K) {} void Profile(llvm::FoldingSetNodeID &ID) const { ID.AddInteger(Kind); @@ -261,75 +155,7 @@ struct ReallocPair { } }; -} // end of anonymous namespace - -REGISTER_MAP_WITH_PROGRAMSTATE(ReallocPairs, SymbolRef, ReallocPair) - -//===----------------------------------------------------------------------===// -// Kinds of memory operations, information about resource managing functions. -//===----------------------------------------------------------------------===// - -namespace { - -enum class MemoryOperationKind { - MOK_Allocate, - MOK_Free, - MOK_Any -}; - -struct MemFunctionInfoTy { - /// The value of the MallocChecker:Optimistic is stored in this variable. - /// - /// In pessimistic mode, the checker assumes that it does not know which - /// functions might free the memory. - /// In optimistic mode, the checker assumes that all user-defined functions - /// which might free a pointer are annotated. - DefaultBool ShouldIncludeOwnershipAnnotatedFunctions; - - // TODO: Change these to CallDescription, and get rid of lazy initialization. - mutable IdentifierInfo *II_alloca = nullptr, *II_win_alloca = nullptr, - *II_malloc = nullptr, *II_free = nullptr, - *II_realloc = nullptr, *II_calloc = nullptr, - *II_valloc = nullptr, *II_reallocf = nullptr, - *II_strndup = nullptr, *II_strdup = nullptr, - *II_win_strdup = nullptr, *II_kmalloc = nullptr, - *II_if_nameindex = nullptr, - *II_if_freenameindex = nullptr, *II_wcsdup = nullptr, - *II_win_wcsdup = nullptr, *II_g_malloc = nullptr, - *II_g_malloc0 = nullptr, *II_g_realloc = nullptr, - *II_g_try_malloc = nullptr, - *II_g_try_malloc0 = nullptr, - *II_g_try_realloc = nullptr, *II_g_free = nullptr, - *II_g_memdup = nullptr, *II_g_malloc_n = nullptr, - *II_g_malloc0_n = nullptr, *II_g_realloc_n = nullptr, - *II_g_try_malloc_n = nullptr, - *II_g_try_malloc0_n = nullptr, - *II_g_try_realloc_n = nullptr; - - void initIdentifierInfo(ASTContext &C) const; - - ///@{ - /// Check if this is one of the functions which can allocate/reallocate - /// memory pointed to by one of its arguments. - bool isMemFunction(const FunctionDecl *FD, ASTContext &C) const; - bool isCMemFunction(const FunctionDecl *FD, - ASTContext &C, - AllocationFamily Family, - MemoryOperationKind MemKind) const; - - /// Tells if the callee is one of the builtin new/delete operators, including - /// placement operators and other standard overloads. - bool isStandardNewDelete(const FunctionDecl *FD, ASTContext &C) const; - ///@} -}; - -} // end of anonymous namespace - -//===----------------------------------------------------------------------===// -// Definition of the MallocChecker class. -//===----------------------------------------------------------------------===// - -namespace { +typedef std::pair LeakInfo; class MallocChecker : public Checker, check::PostObjCMessage, check::Location, - eval::Assume> { + eval::Assume> +{ public: - MemFunctionInfoTy MemFunctionInfo; + MallocChecker() + : II_alloca(nullptr), II_win_alloca(nullptr), II_malloc(nullptr), + II_free(nullptr), II_realloc(nullptr), II_calloc(nullptr), + II_valloc(nullptr), II_reallocf(nullptr), II_strndup(nullptr), + II_strdup(nullptr), II_win_strdup(nullptr), II_kmalloc(nullptr), + II_if_nameindex(nullptr), II_if_freenameindex(nullptr), + II_wcsdup(nullptr), II_win_wcsdup(nullptr), II_g_malloc(nullptr), + II_g_malloc0(nullptr), II_g_realloc(nullptr), II_g_try_malloc(nullptr), + II_g_try_malloc0(nullptr), II_g_try_realloc(nullptr), + II_g_free(nullptr), II_g_memdup(nullptr), II_g_malloc_n(nullptr), + II_g_malloc0_n(nullptr), II_g_realloc_n(nullptr), + II_g_try_malloc_n(nullptr), II_g_try_malloc0_n(nullptr), + II_g_try_realloc_n(nullptr) {} - /// Many checkers are essentially built into this one, so enabling them will - /// make MallocChecker perform additional modeling and reporting. + /// In pessimistic mode, the checker assumes that it does not know which + /// functions might free the memory. enum CheckKind { - /// When a subchecker is enabled but MallocChecker isn't, model memory - /// management but do not emit warnings emitted with MallocChecker only - /// enabled. CK_MallocChecker, CK_NewDeleteChecker, CK_NewDeleteLeaksChecker, @@ -362,7 +198,13 @@ public: CK_NumCheckKinds }; - using LeakInfo = std::pair; + enum class MemoryOperationKind { + MOK_Allocate, + MOK_Free, + MOK_Any + }; + + DefaultBool IsOptimistic; DefaultBool ChecksEnabled[CK_NumCheckKinds]; CheckName CheckNames[CK_NumCheckKinds]; @@ -405,74 +247,71 @@ private: mutable std::unique_ptr BT_MismatchedDealloc; mutable std::unique_ptr BT_OffsetFree[CK_NumCheckKinds]; mutable std::unique_ptr BT_UseZerroAllocated[CK_NumCheckKinds]; - - // TODO: Remove mutable by moving the initializtaion to the registry function. + mutable IdentifierInfo *II_alloca, *II_win_alloca, *II_malloc, *II_free, + *II_realloc, *II_calloc, *II_valloc, *II_reallocf, + *II_strndup, *II_strdup, *II_win_strdup, *II_kmalloc, + *II_if_nameindex, *II_if_freenameindex, *II_wcsdup, + *II_win_wcsdup, *II_g_malloc, *II_g_malloc0, + *II_g_realloc, *II_g_try_malloc, *II_g_try_malloc0, + *II_g_try_realloc, *II_g_free, *II_g_memdup, + *II_g_malloc_n, *II_g_malloc0_n, *II_g_realloc_n, + *II_g_try_malloc_n, *II_g_try_malloc0_n, + *II_g_try_realloc_n; mutable Optional KernelZeroFlagVal; + void initIdentifierInfo(ASTContext &C) const; + + /// Determine family of a deallocation expression. + AllocationFamily getAllocationFamily(CheckerContext &C, const Stmt *S) const; + + /// Print names of allocators and deallocators. + /// + /// \returns true on success. + bool printAllocDeallocName(raw_ostream &os, CheckerContext &C, + const Expr *E) const; + + /// Print expected name of an allocator based on the deallocator's + /// family derived from the DeallocExpr. + void printExpectedAllocName(raw_ostream &os, CheckerContext &C, + const Expr *DeallocExpr) const; + /// Print expected name of a deallocator based on the allocator's + /// family. + void printExpectedDeallocName(raw_ostream &os, AllocationFamily Family) const; + + ///@{ + /// Check if this is one of the functions which can allocate/reallocate memory + /// pointed to by one of its arguments. + bool isMemFunction(const FunctionDecl *FD, ASTContext &C) const; + bool isCMemFunction(const FunctionDecl *FD, + ASTContext &C, + AllocationFamily Family, + MemoryOperationKind MemKind) const; + bool isStandardNewDelete(const FunctionDecl *FD, ASTContext &C) const; + ///@} + /// Process C++ operator new()'s allocation, which is the part of C++ /// new-expression that goes before the constructor. void processNewAllocation(const CXXNewExpr *NE, CheckerContext &C, SVal Target) const; /// Perform a zero-allocation check. - /// - /// \param [in] E The expression that allocates memory. - /// \param [in] IndexOfSizeArg Index of the argument that specifies the size - /// of the memory that needs to be allocated. E.g. for malloc, this would be - /// 0. - /// \param [in] RetVal Specifies the newly allocated pointer value; - /// if unspecified, the value of expression \p E is used. - static ProgramStateRef ProcessZeroAllocCheck(CheckerContext &C, const Expr *E, - const unsigned IndexOfSizeArg, - ProgramStateRef State, - Optional RetVal = None); - - /// Model functions with the ownership_returns attribute. - /// - /// User-defined function may have the ownership_returns attribute, which - /// annotates that the function returns with an object that was allocated on - /// the heap, and passes the ownertship to the callee. - /// - /// void __attribute((ownership_returns(malloc, 1))) *my_malloc(size_t); - /// - /// It has two parameters: - /// - first: name of the resource (e.g. 'malloc') - /// - (OPTIONAL) second: size of the allocated region - /// - /// \param [in] CE The expression that allocates memory. - /// \param [in] Att The ownership_returns attribute. - /// \param [in] State The \c ProgramState right before allocation. - /// \returns The ProgramState right after allocation. + /// The optional \p RetVal parameter specifies the newly allocated pointer + /// value; if unspecified, the value of expression \p E is used. + ProgramStateRef ProcessZeroAllocation(CheckerContext &C, const Expr *E, + const unsigned AllocationSizeArg, + ProgramStateRef State, + Optional RetVal = None) const; + ProgramStateRef MallocMemReturnsAttr(CheckerContext &C, const CallExpr *CE, const OwnershipAttr* Att, ProgramStateRef State) const; - - /// Models memory allocation. - /// - /// \param [in] CE The expression that allocates memory. - /// \param [in] SizeEx Size of the memory that needs to be allocated. - /// \param [in] Init The value the allocated memory needs to be initialized. - /// with. For example, \c calloc initializes the allocated memory to 0, - /// malloc leaves it undefined. - /// \param [in] State The \c ProgramState right before allocation. - /// \returns The ProgramState right after allocation. static ProgramStateRef MallocMemAux(CheckerContext &C, const CallExpr *CE, const Expr *SizeEx, SVal Init, ProgramStateRef State, AllocationFamily Family = AF_Malloc); - - /// Models memory allocation. - /// - /// \param [in] CE The expression that allocates memory. - /// \param [in] Size Size of the memory that needs to be allocated. - /// \param [in] Init The value the allocated memory needs to be initialized. - /// with. For example, \c calloc initializes the allocated memory to 0, - /// malloc leaves it undefined. - /// \param [in] State The \c ProgramState right before allocation. - /// \returns The ProgramState right after allocation. static ProgramStateRef MallocMemAux(CheckerContext &C, const CallExpr *CE, - SVal Size, SVal Init, + SVal SizeEx, SVal Init, ProgramStateRef State, AllocationFamily Family = AF_Malloc); @@ -485,124 +324,49 @@ private: performKernelMalloc(const CallExpr *CE, CheckerContext &C, const ProgramStateRef &State) const; - /// Model functions with the ownership_takes and ownership_holds attributes. - /// - /// User-defined function may have the ownership_takes and/or ownership_holds - /// attributes, which annotates that the function frees the memory passed as a - /// parameter. - /// - /// void __attribute((ownership_takes(malloc, 1))) my_free(void *); - /// void __attribute((ownership_holds(malloc, 1))) my_hold(void *); - /// - /// They have two parameters: - /// - first: name of the resource (e.g. 'malloc') - /// - second: index of the parameter the attribute applies to - /// - /// \param [in] CE The expression that frees memory. - /// \param [in] Att The ownership_takes or ownership_holds attribute. - /// \param [in] State The \c ProgramState right before allocation. - /// \returns The ProgramState right after deallocation. + /// Update the RefState to reflect the new memory allocation. + /// The optional \p RetVal parameter specifies the newly allocated pointer + /// value; if unspecified, the value of expression \p E is used. + static ProgramStateRef + MallocUpdateRefState(CheckerContext &C, const Expr *E, ProgramStateRef State, + AllocationFamily Family = AF_Malloc, + Optional RetVal = None); + ProgramStateRef FreeMemAttr(CheckerContext &C, const CallExpr *CE, const OwnershipAttr* Att, ProgramStateRef State) const; - - /// Models memory deallocation. - /// - /// \param [in] CE The expression that frees memory. - /// \param [in] State The \c ProgramState right before allocation. - /// \param [in] Num Index of the argument that needs to be freed. This is - /// normally 0, but for custom free functions it may be different. - /// \param [in] Hold Whether the parameter at \p Index has the ownership_holds - /// attribute. - /// \param [out] IsKnownToBeAllocated Whether the memory to be freed is known - /// to have been allocated, or in other words, the symbol to be freed was - /// registered as allocated by this checker. In the following case, \c ptr - /// isn't known to be allocated. - /// void Haha(int *ptr) { - /// ptr = realloc(ptr, 67); - /// // ... - /// } - /// \param [in] ReturnsNullOnFailure Whether the memory deallocation function - /// we're modeling returns with Null on failure. - /// \returns The ProgramState right after deallocation. ProgramStateRef FreeMemAux(CheckerContext &C, const CallExpr *CE, - ProgramStateRef State, unsigned Num, + ProgramStateRef state, unsigned Num, bool Hold, - bool &IsKnownToBeAllocated, + bool &ReleasedAllocated, bool ReturnsNullOnFailure = false) const; - - /// Models memory deallocation. - /// - /// \param [in] ArgExpr The variable who's pointee needs to be freed. - /// \param [in] ParentExpr The expression that frees the memory. - /// \param [in] State The \c ProgramState right before allocation. - /// normally 0, but for custom free functions it may be different. - /// \param [in] Hold Whether the parameter at \p Index has the ownership_holds - /// attribute. - /// \param [out] IsKnownToBeAllocated Whether the memory to be freed is known - /// to have been allocated, or in other words, the symbol to be freed was - /// registered as allocated by this checker. In the following case, \c ptr - /// isn't known to be allocated. - /// void Haha(int *ptr) { - /// ptr = realloc(ptr, 67); - /// // ... - /// } - /// \param [in] ReturnsNullOnFailure Whether the memory deallocation function - /// we're modeling returns with Null on failure. - /// \returns The ProgramState right after deallocation. - ProgramStateRef FreeMemAux(CheckerContext &C, const Expr *ArgExpr, + ProgramStateRef FreeMemAux(CheckerContext &C, const Expr *Arg, const Expr *ParentExpr, ProgramStateRef State, bool Hold, - bool &IsKnownToBeAllocated, + bool &ReleasedAllocated, bool ReturnsNullOnFailure = false) const; - // TODO: Needs some refactoring, as all other deallocation modeling - // functions are suffering from out parameters and messy code due to how - // realloc is handled. - // - /// Models memory reallocation. - /// - /// \param [in] CE The expression that reallocated memory - /// \param [in] FreesMemOnFailure Whether if reallocation fails, the supplied - /// memory should be freed. - /// \param [in] State The \c ProgramState right before reallocation. - /// \param [in] SuffixWithN Whether the reallocation function we're modeling - /// has an '_n' suffix, such as g_realloc_n. - /// \returns The ProgramState right after reallocation. ProgramStateRef ReallocMemAux(CheckerContext &C, const CallExpr *CE, - bool ShouldFreeOnFail, + bool FreesMemOnFailure, ProgramStateRef State, bool SuffixWithN = false) const; - - /// Evaluates the buffer size that needs to be allocated. - /// - /// \param [in] Blocks The amount of blocks that needs to be allocated. - /// \param [in] BlockBytes The size of a block. - /// \returns The symbolic value of \p Blocks * \p BlockBytes. static SVal evalMulForBufferSize(CheckerContext &C, const Expr *Blocks, const Expr *BlockBytes); - - /// Models zero initialized array allocation. - /// - /// \param [in] CE The expression that reallocated memory - /// \param [in] State The \c ProgramState right before reallocation. - /// \returns The ProgramState right after allocation. static ProgramStateRef CallocMem(CheckerContext &C, const CallExpr *CE, ProgramStateRef State); - /// If in \p S \p Sym is used, check whether \p Sym was already freed. + /// Check if the memory associated with this symbol was released. + bool isReleased(SymbolRef Sym, CheckerContext &C) const; + bool checkUseAfterFree(SymbolRef Sym, CheckerContext &C, const Stmt *S) const; - /// If in \p S \p Sym is used, check whether \p Sym was allocated as a zero - /// sized memory region. void checkUseZeroAllocated(SymbolRef Sym, CheckerContext &C, const Stmt *S) const; - /// If in \p S \p Sym is being freed, check whether \p Sym was already freed. bool checkDoubleDelete(SymbolRef Sym, CheckerContext &C) const; - /// Check if the function is known to free memory, or if it is + /// Check if the function is known free memory, or if it is /// "interesting" and should be modeled explicitly. /// /// \param [out] EscapingSymbol A function might not free memory in general, @@ -616,12 +380,12 @@ private: ProgramStateRef State, SymbolRef &EscapingSymbol) const; - /// Implementation of the checkPointerEscape callbacks. + // Implementation of the checkPointerEscape callbacks. ProgramStateRef checkPointerEscapeAux(ProgramStateRef State, - const InvalidatedSymbols &Escaped, - const CallEvent *Call, - PointerEscapeKind Kind, - bool IsConstPointerEscape) const; + const InvalidatedSymbols &Escaped, + const CallEvent *Call, + PointerEscapeKind Kind, + bool(*CheckRefState)(const RefState*)) const; // Implementation of the checkPreStmt and checkEndFunction callbacks. void checkEscapeOnReturn(const ReturnStmt *S, CheckerContext &C) const; @@ -640,7 +404,6 @@ private: ///@} static bool SummarizeValue(raw_ostream &os, SVal V); static bool SummarizeRegion(raw_ostream &os, const MemRegion *MR); - void ReportBadFree(CheckerContext &C, SVal ArgVal, SourceRange Range, const Expr *DeallocExpr) const; void ReportFreeAlloca(CheckerContext &C, SVal ArgVal, @@ -666,149 +429,143 @@ private: /// Find the location of the allocation for Sym on the path leading to the /// exploded node N. - static LeakInfo getAllocationSite(const ExplodedNode *N, SymbolRef Sym, - CheckerContext &C); - + LeakInfo getAllocationSite(const ExplodedNode *N, SymbolRef Sym, + CheckerContext &C) const; void reportLeak(SymbolRef Sym, ExplodedNode *N, CheckerContext &C) const; -}; -} // end anonymous namespace + /// The bug visitor which allows us to print extra diagnostics along the + /// BugReport path. For example, showing the allocation site of the leaked + /// region. + class MallocBugVisitor final : public BugReporterVisitor { + protected: + enum NotificationMode { + Normal, + ReallocationFailed + }; -//===----------------------------------------------------------------------===// -// Definition of MallocBugVisitor. -//===----------------------------------------------------------------------===// + // The allocated region symbol tracked by the main analysis. + SymbolRef Sym; -/// The bug visitor which allows us to print extra diagnostics along the -/// BugReport path. For example, showing the allocation site of the leaked -/// region. -class MallocBugVisitor final : public BugReporterVisitor { -protected: - enum NotificationMode { - Normal, - ReallocationFailed - }; + // The mode we are in, i.e. what kind of diagnostics will be emitted. + NotificationMode Mode; - // The allocated region symbol tracked by the main analysis. - SymbolRef Sym; + // A symbol from when the primary region should have been reallocated. + SymbolRef FailedReallocSymbol; - // The mode we are in, i.e. what kind of diagnostics will be emitted. - NotificationMode Mode; + // A C++ destructor stack frame in which memory was released. Used for + // miscellaneous false positive suppression. + const StackFrameContext *ReleaseDestructorLC; - // A symbol from when the primary region should have been reallocated. - SymbolRef FailedReallocSymbol; + bool IsLeak; - // A C++ destructor stack frame in which memory was released. Used for - // miscellaneous false positive suppression. - const StackFrameContext *ReleaseDestructorLC; + public: + MallocBugVisitor(SymbolRef S, bool isLeak = false) + : Sym(S), Mode(Normal), FailedReallocSymbol(nullptr), + ReleaseDestructorLC(nullptr), IsLeak(isLeak) {} - bool IsLeak; + static void *getTag() { + static int Tag = 0; + return &Tag; + } -public: - MallocBugVisitor(SymbolRef S, bool isLeak = false) - : Sym(S), Mode(Normal), FailedReallocSymbol(nullptr), - ReleaseDestructorLC(nullptr), IsLeak(isLeak) {} - - static void *getTag() { - static int Tag = 0; - return &Tag; - } - - void Profile(llvm::FoldingSetNodeID &ID) const override { - ID.AddPointer(getTag()); - ID.AddPointer(Sym); - } - - /// Did not track -> allocated. Other state (released) -> allocated. - static inline bool isAllocated(const RefState *RSCurr, const RefState *RSPrev, - const Stmt *Stmt) { - return (Stmt && (isa(Stmt) || isa(Stmt)) && - (RSCurr && (RSCurr->isAllocated() || - RSCurr->isAllocatedOfSizeZero())) && - (!RSPrev || !(RSPrev->isAllocated() || - RSPrev->isAllocatedOfSizeZero()))); - } - - /// Did not track -> released. Other state (allocated) -> released. - /// The statement associated with the release might be missing. - static inline bool isReleased(const RefState *RSCurr, const RefState *RSPrev, - const Stmt *Stmt) { - bool IsReleased = (RSCurr && RSCurr->isReleased()) && - (!RSPrev || !RSPrev->isReleased()); - assert(!IsReleased || - (Stmt && (isa(Stmt) || isa(Stmt))) || - (!Stmt && RSCurr->getAllocationFamily() == AF_InnerBuffer)); - return IsReleased; - } - - /// Did not track -> relinquished. Other state (allocated) -> relinquished. - static inline bool isRelinquished(const RefState *RSCurr, - const RefState *RSPrev, - const Stmt *Stmt) { - return (Stmt && (isa(Stmt) || isa(Stmt) || - isa(Stmt)) && - (RSCurr && RSCurr->isRelinquished()) && - (!RSPrev || !RSPrev->isRelinquished())); - } - - /// If the expression is not a call, and the state change is - /// released -> allocated, it must be the realloc return value - /// check. If we have to handle more cases here, it might be cleaner just - /// to track this extra bit in the state itself. - static inline bool hasReallocFailed(const RefState *RSCurr, - const RefState *RSPrev, - const Stmt *Stmt) { - return ((!Stmt || !isa(Stmt)) && - (RSCurr && (RSCurr->isAllocated() || - RSCurr->isAllocatedOfSizeZero())) && - (RSPrev && !(RSPrev->isAllocated() || - RSPrev->isAllocatedOfSizeZero()))); - } - - std::shared_ptr VisitNode(const ExplodedNode *N, - BugReporterContext &BRC, - BugReport &BR) override; - - std::shared_ptr - getEndPath(BugReporterContext &BRC, const ExplodedNode *EndPathNode, - BugReport &BR) override { - if (!IsLeak) - return nullptr; + void Profile(llvm::FoldingSetNodeID &ID) const override { + ID.AddPointer(getTag()); + ID.AddPointer(Sym); + } - PathDiagnosticLocation L = - PathDiagnosticLocation::createEndOfPath(EndPathNode, - BRC.getSourceManager()); - // Do not add the statement itself as a range in case of leak. - return std::make_shared(L, BR.getDescription(), - false); - } + inline bool isAllocated(const RefState *S, const RefState *SPrev, + const Stmt *Stmt) { + // Did not track -> allocated. Other state (released) -> allocated. + return (Stmt && (isa(Stmt) || isa(Stmt)) && + (S && (S->isAllocated() || S->isAllocatedOfSizeZero())) && + (!SPrev || !(SPrev->isAllocated() || + SPrev->isAllocatedOfSizeZero()))); + } -private: - class StackHintGeneratorForReallocationFailed - : public StackHintGeneratorForSymbol { - public: - StackHintGeneratorForReallocationFailed(SymbolRef S, StringRef M) - : StackHintGeneratorForSymbol(S, M) {} + inline bool isReleased(const RefState *S, const RefState *SPrev, + const Stmt *Stmt) { + // Did not track -> released. Other state (allocated) -> released. + // The statement associated with the release might be missing. + bool IsReleased = (S && S->isReleased()) && + (!SPrev || !SPrev->isReleased()); + assert(!IsReleased || + (Stmt && (isa(Stmt) || isa(Stmt))) || + (!Stmt && S->getAllocationFamily() == AF_InnerBuffer)); + return IsReleased; + } - std::string getMessageForArg(const Expr *ArgE, - unsigned ArgIndex) override { - // Printed parameters start at 1, not 0. - ++ArgIndex; + inline bool isRelinquished(const RefState *S, const RefState *SPrev, + const Stmt *Stmt) { + // Did not track -> relinquished. Other state (allocated) -> relinquished. + return (Stmt && (isa(Stmt) || isa(Stmt) || + isa(Stmt)) && + (S && S->isRelinquished()) && + (!SPrev || !SPrev->isRelinquished())); + } - SmallString<200> buf; - llvm::raw_svector_ostream os(buf); + inline bool isReallocFailedCheck(const RefState *S, const RefState *SPrev, + const Stmt *Stmt) { + // If the expression is not a call, and the state change is + // released -> allocated, it must be the realloc return value + // check. If we have to handle more cases here, it might be cleaner just + // to track this extra bit in the state itself. + return ((!Stmt || !isa(Stmt)) && + (S && (S->isAllocated() || S->isAllocatedOfSizeZero())) && + (SPrev && !(SPrev->isAllocated() || + SPrev->isAllocatedOfSizeZero()))); + } - os << "Reallocation of " << ArgIndex << llvm::getOrdinalSuffix(ArgIndex) - << " parameter failed"; + std::shared_ptr VisitNode(const ExplodedNode *N, + BugReporterContext &BRC, + BugReport &BR) override; - return os.str(); - } + std::shared_ptr + getEndPath(BugReporterContext &BRC, const ExplodedNode *EndPathNode, + BugReport &BR) override { + if (!IsLeak) + return nullptr; - std::string getMessageForReturn(const CallExpr *CallExpr) override { - return "Reallocation of returned value failed"; + PathDiagnosticLocation L = + PathDiagnosticLocation::createEndOfPath(EndPathNode, + BRC.getSourceManager()); + // Do not add the statement itself as a range in case of leak. + return std::make_shared(L, BR.getDescription(), + false); } + + private: + class StackHintGeneratorForReallocationFailed + : public StackHintGeneratorForSymbol { + public: + StackHintGeneratorForReallocationFailed(SymbolRef S, StringRef M) + : StackHintGeneratorForSymbol(S, M) {} + + std::string getMessageForArg(const Expr *ArgE, + unsigned ArgIndex) override { + // Printed parameters start at 1, not 0. + ++ArgIndex; + + SmallString<200> buf; + llvm::raw_svector_ostream os(buf); + + os << "Reallocation of " << ArgIndex << llvm::getOrdinalSuffix(ArgIndex) + << " parameter failed"; + + return os.str(); + } + + std::string getMessageForReturn(const CallExpr *CallExpr) override { + return "Reallocation of returned value failed"; + } + }; }; }; +} // end anonymous namespace + +REGISTER_MAP_WITH_PROGRAMSTATE(RegionState, SymbolRef, RefState) +REGISTER_MAP_WITH_PROGRAMSTATE(ReallocPairs, SymbolRef, ReallocPair) +REGISTER_SET_WITH_PROGRAMSTATE(ReallocSizeZeroSymbols, SymbolRef) // A map from the freed symbol to the symbol representing the return value of // the free function. @@ -828,11 +585,7 @@ public: }; } // end anonymous namespace -//===----------------------------------------------------------------------===// -// Methods of MemFunctionInfoTy. -//===----------------------------------------------------------------------===// - -void MemFunctionInfoTy::initIdentifierInfo(ASTContext &Ctx) const { +void MallocChecker::initIdentifierInfo(ASTContext &Ctx) const { if (II_malloc) return; II_alloca = &Ctx.Idents.get("alloca"); @@ -871,8 +624,7 @@ void MemFunctionInfoTy::initIdentifierInfo(ASTContext &Ctx) const { II_g_try_realloc_n = &Ctx.Idents.get("g_try_realloc_n"); } -bool MemFunctionInfoTy::isMemFunction(const FunctionDecl *FD, - ASTContext &C) const { +bool MallocChecker::isMemFunction(const FunctionDecl *FD, ASTContext &C) const { if (isCMemFunction(FD, C, AF_Malloc, MemoryOperationKind::MOK_Any)) return true; @@ -888,10 +640,10 @@ bool MemFunctionInfoTy::isMemFunction(const FunctionDecl *FD, return false; } -bool MemFunctionInfoTy::isCMemFunction(const FunctionDecl *FD, - ASTContext &C, - AllocationFamily Family, - MemoryOperationKind MemKind) const { +bool MallocChecker::isCMemFunction(const FunctionDecl *FD, + ASTContext &C, + AllocationFamily Family, + MemoryOperationKind MemKind) const { if (!FD) return false; @@ -944,7 +696,7 @@ bool MemFunctionInfoTy::isCMemFunction(const FunctionDecl *FD, if (Family != AF_Malloc) return false; - if (ShouldIncludeOwnershipAnnotatedFunctions && FD->hasAttrs()) { + if (IsOptimistic && FD->hasAttrs()) { for (const auto *I : FD->specific_attrs()) { OwnershipAttr::OwnershipKind OwnKind = I->getOwnKind(); if(OwnKind == OwnershipAttr::Takes || OwnKind == OwnershipAttr::Holds) { @@ -959,7 +711,10 @@ bool MemFunctionInfoTy::isCMemFunction(const FunctionDecl *FD, return false; } -bool MemFunctionInfoTy::isStandardNewDelete(const FunctionDecl *FD, + +// Tells if the callee is one of the builtin new/delete operators, including +// placement operators and other standard overloads. +bool MallocChecker::isStandardNewDelete(const FunctionDecl *FD, ASTContext &C) const { if (!FD) return false; @@ -976,10 +731,6 @@ bool MemFunctionInfoTy::isStandardNewDelete(const FunctionDecl *FD, return !L.isValid() || C.getSourceManager().isInSystemHeader(L); } -//===----------------------------------------------------------------------===// -// Methods of MallocChecker and MallocBugVisitor. -//===----------------------------------------------------------------------===// - llvm::Optional MallocChecker::performKernelMalloc( const CallExpr *CE, CheckerContext &C, const ProgramStateRef &State) const { // 3-argument malloc(), as commonly used in {Free,Net,Open}BSD Kernels: @@ -1078,35 +829,28 @@ void MallocChecker::checkPostStmt(const CallExpr *CE, CheckerContext &C) const { return; ProgramStateRef State = C.getState(); - bool IsKnownToBeAllocatedMemory = false; + bool ReleasedAllocatedMemory = false; if (FD->getKind() == Decl::Function) { - MemFunctionInfo.initIdentifierInfo(C.getASTContext()); + initIdentifierInfo(C.getASTContext()); IdentifierInfo *FunI = FD->getIdentifier(); - if (FunI == MemFunctionInfo.II_malloc || - FunI == MemFunctionInfo.II_g_malloc || - FunI == MemFunctionInfo.II_g_try_malloc) { - switch(CE->getNumArgs()) { - default: + if (FunI == II_malloc || FunI == II_g_malloc || FunI == II_g_try_malloc) { + if (CE->getNumArgs() < 1) return; - case 1: - State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State); - State = ProcessZeroAllocCheck(C, CE, 0, State); - break; - case 2: + if (CE->getNumArgs() < 3) { State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State); - break; - case 3: + if (CE->getNumArgs() == 1) + State = ProcessZeroAllocation(C, CE, 0, State); + } else if (CE->getNumArgs() == 3) { llvm::Optional MaybeState = performKernelMalloc(CE, C, State); if (MaybeState.hasValue()) State = MaybeState.getValue(); else State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State); - break; } - } else if (FunI == MemFunctionInfo.II_kmalloc) { + } else if (FunI == II_kmalloc) { if (CE->getNumArgs() < 1) return; llvm::Optional MaybeState = @@ -1115,112 +859,97 @@ void MallocChecker::checkPostStmt(const CallExpr *CE, CheckerContext &C) const { State = MaybeState.getValue(); else State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State); - } else if (FunI == MemFunctionInfo.II_valloc) { + } else if (FunI == II_valloc) { if (CE->getNumArgs() < 1) return; State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State); - State = ProcessZeroAllocCheck(C, CE, 0, State); - } else if (FunI == MemFunctionInfo.II_realloc || - FunI == MemFunctionInfo.II_g_realloc || - FunI == MemFunctionInfo.II_g_try_realloc) { - State = ReallocMemAux(C, CE, /*ShouldFreeOnFail*/false, State); - State = ProcessZeroAllocCheck(C, CE, 1, State); - } else if (FunI == MemFunctionInfo.II_reallocf) { - State = ReallocMemAux(C, CE, /*ShouldFreeOnFail*/true, State); - State = ProcessZeroAllocCheck(C, CE, 1, State); - } else if (FunI == MemFunctionInfo.II_calloc) { + State = ProcessZeroAllocation(C, CE, 0, State); + } else if (FunI == II_realloc || FunI == II_g_realloc || + FunI == II_g_try_realloc) { + State = ReallocMemAux(C, CE, false, State); + State = ProcessZeroAllocation(C, CE, 1, State); + } else if (FunI == II_reallocf) { + State = ReallocMemAux(C, CE, true, State); + State = ProcessZeroAllocation(C, CE, 1, State); + } else if (FunI == II_calloc) { State = CallocMem(C, CE, State); - State = ProcessZeroAllocCheck(C, CE, 0, State); - State = ProcessZeroAllocCheck(C, CE, 1, State); - } else if (FunI == MemFunctionInfo.II_free || - FunI == MemFunctionInfo.II_g_free) { - State = FreeMemAux(C, CE, State, 0, false, IsKnownToBeAllocatedMemory); - } else if (FunI == MemFunctionInfo.II_strdup || - FunI == MemFunctionInfo.II_win_strdup || - FunI == MemFunctionInfo.II_wcsdup || - FunI == MemFunctionInfo.II_win_wcsdup) { + State = ProcessZeroAllocation(C, CE, 0, State); + State = ProcessZeroAllocation(C, CE, 1, State); + } else if (FunI == II_free || FunI == II_g_free) { + State = FreeMemAux(C, CE, State, 0, false, ReleasedAllocatedMemory); + } else if (FunI == II_strdup || FunI == II_win_strdup || + FunI == II_wcsdup || FunI == II_win_wcsdup) { State = MallocUpdateRefState(C, CE, State); - } else if (FunI == MemFunctionInfo.II_strndup) { + } else if (FunI == II_strndup) { State = MallocUpdateRefState(C, CE, State); - } else if (FunI == MemFunctionInfo.II_alloca || - FunI == MemFunctionInfo.II_win_alloca) { + } else if (FunI == II_alloca || FunI == II_win_alloca) { if (CE->getNumArgs() < 1) return; State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State, AF_Alloca); - State = ProcessZeroAllocCheck(C, CE, 0, State); - } else if (MemFunctionInfo.isStandardNewDelete(FD, C.getASTContext())) { + State = ProcessZeroAllocation(C, CE, 0, State); + } else if (isStandardNewDelete(FD, C.getASTContext())) { // Process direct calls to operator new/new[]/delete/delete[] functions // as distinct from new/new[]/delete/delete[] expressions that are // processed by the checkPostStmt callbacks for CXXNewExpr and // CXXDeleteExpr. - switch(FD->getOverloadedOperator()) { - case OO_New: + OverloadedOperatorKind K = FD->getOverloadedOperator(); + if (K == OO_New) { State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State, AF_CXXNew); - State = ProcessZeroAllocCheck(C, CE, 0, State); - break; - case OO_Array_New: + State = ProcessZeroAllocation(C, CE, 0, State); + } + else if (K == OO_Array_New) { State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State, AF_CXXNewArray); - State = ProcessZeroAllocCheck(C, CE, 0, State); - break; - case OO_Delete: - case OO_Array_Delete: - State = FreeMemAux(C, CE, State, 0, false, IsKnownToBeAllocatedMemory); - break; - default: - llvm_unreachable("not a new/delete operator"); + State = ProcessZeroAllocation(C, CE, 0, State); } - } else if (FunI == MemFunctionInfo.II_if_nameindex) { + else if (K == OO_Delete || K == OO_Array_Delete) + State = FreeMemAux(C, CE, State, 0, false, ReleasedAllocatedMemory); + else + llvm_unreachable("not a new/delete operator"); + } else if (FunI == II_if_nameindex) { // Should we model this differently? We can allocate a fixed number of // elements with zeros in the last one. State = MallocMemAux(C, CE, UnknownVal(), UnknownVal(), State, AF_IfNameIndex); - } else if (FunI == MemFunctionInfo.II_if_freenameindex) { - State = FreeMemAux(C, CE, State, 0, false, IsKnownToBeAllocatedMemory); - } else if (FunI == MemFunctionInfo.II_g_malloc0 || - FunI == MemFunctionInfo.II_g_try_malloc0) { + } else if (FunI == II_if_freenameindex) { + State = FreeMemAux(C, CE, State, 0, false, ReleasedAllocatedMemory); + } else if (FunI == II_g_malloc0 || FunI == II_g_try_malloc0) { if (CE->getNumArgs() < 1) return; SValBuilder &svalBuilder = C.getSValBuilder(); SVal zeroVal = svalBuilder.makeZeroVal(svalBuilder.getContext().CharTy); State = MallocMemAux(C, CE, CE->getArg(0), zeroVal, State); - State = ProcessZeroAllocCheck(C, CE, 0, State); - } else if (FunI == MemFunctionInfo.II_g_memdup) { + State = ProcessZeroAllocation(C, CE, 0, State); + } else if (FunI == II_g_memdup) { if (CE->getNumArgs() < 2) return; State = MallocMemAux(C, CE, CE->getArg(1), UndefinedVal(), State); - State = ProcessZeroAllocCheck(C, CE, 1, State); - } else if (FunI == MemFunctionInfo.II_g_malloc_n || - FunI == MemFunctionInfo.II_g_try_malloc_n || - FunI == MemFunctionInfo.II_g_malloc0_n || - FunI == MemFunctionInfo.II_g_try_malloc0_n) { + State = ProcessZeroAllocation(C, CE, 1, State); + } else if (FunI == II_g_malloc_n || FunI == II_g_try_malloc_n || + FunI == II_g_malloc0_n || FunI == II_g_try_malloc0_n) { if (CE->getNumArgs() < 2) return; SVal Init = UndefinedVal(); - if (FunI == MemFunctionInfo.II_g_malloc0_n || - FunI == MemFunctionInfo.II_g_try_malloc0_n) { + if (FunI == II_g_malloc0_n || FunI == II_g_try_malloc0_n) { SValBuilder &SB = C.getSValBuilder(); Init = SB.makeZeroVal(SB.getContext().CharTy); } SVal TotalSize = evalMulForBufferSize(C, CE->getArg(0), CE->getArg(1)); State = MallocMemAux(C, CE, TotalSize, Init, State); - State = ProcessZeroAllocCheck(C, CE, 0, State); - State = ProcessZeroAllocCheck(C, CE, 1, State); - } else if (FunI == MemFunctionInfo.II_g_realloc_n || - FunI == MemFunctionInfo.II_g_try_realloc_n) { + State = ProcessZeroAllocation(C, CE, 0, State); + State = ProcessZeroAllocation(C, CE, 1, State); + } else if (FunI == II_g_realloc_n || FunI == II_g_try_realloc_n) { if (CE->getNumArgs() < 3) return; - State = ReallocMemAux(C, CE, /*ShouldFreeOnFail*/false, State, - /*SuffixWithN*/true); - State = ProcessZeroAllocCheck(C, CE, 1, State); - State = ProcessZeroAllocCheck(C, CE, 2, State); + State = ReallocMemAux(C, CE, false, State, true); + State = ProcessZeroAllocation(C, CE, 1, State); + State = ProcessZeroAllocation(C, CE, 2, State); } } - if (MemFunctionInfo.ShouldIncludeOwnershipAnnotatedFunctions || - ChecksEnabled[CK_MismatchedDeallocatorChecker]) { + if (IsOptimistic || ChecksEnabled[CK_MismatchedDeallocatorChecker]) { // Check all the attributes, if there are any. // There can be multiple of these attributes. if (FD->hasAttrs()) @@ -1240,9 +969,9 @@ void MallocChecker::checkPostStmt(const CallExpr *CE, CheckerContext &C) const { } // Performs a 0-sized allocations check. -ProgramStateRef MallocChecker::ProcessZeroAllocCheck( - CheckerContext &C, const Expr *E, const unsigned IndexOfSizeArg, - ProgramStateRef State, Optional RetVal) { +ProgramStateRef MallocChecker::ProcessZeroAllocation( + CheckerContext &C, const Expr *E, const unsigned AllocationSizeArg, + ProgramStateRef State, Optional RetVal) const { if (!State) return nullptr; @@ -1252,7 +981,7 @@ ProgramStateRef MallocChecker::ProcessZeroAllocCheck( const Expr *Arg = nullptr; if (const CallExpr *CE = dyn_cast(E)) { - Arg = CE->getArg(IndexOfSizeArg); + Arg = CE->getArg(AllocationSizeArg); } else if (const CXXNewExpr *NE = dyn_cast(E)) { if (NE->isArray()) @@ -1314,9 +1043,7 @@ static QualType getDeepPointeeType(QualType T) { return Result; } -/// \returns true if the constructor invoked by \p NE has an argument of a -/// pointer/reference to a record type. -static bool hasNonTrivialConstructorCall(const CXXNewExpr *NE) { +static bool treatUnusedNewEscaped(const CXXNewExpr *NE) { const CXXConstructExpr *ConstructE = NE->getConstructExpr(); if (!ConstructE) @@ -1346,17 +1073,11 @@ static bool hasNonTrivialConstructorCall(const CXXNewExpr *NE) { void MallocChecker::processNewAllocation(const CXXNewExpr *NE, CheckerContext &C, SVal Target) const { - if (!MemFunctionInfo.isStandardNewDelete(NE->getOperatorNew(), - C.getASTContext())) + if (!isStandardNewDelete(NE->getOperatorNew(), C.getASTContext())) return; ParentMap &PM = C.getLocationContext()->getParentMap(); - - // Non-trivial constructors have a chance to escape 'this', but marking all - // invocations of trivial constructors as escaped would cause too great of - // reduction of true positives, so let's just do that for constructors that - // have an argument of a pointer-to-record type. - if (!PM.isConsumedExpr(NE) && hasNonTrivialConstructorCall(NE)) + if (!PM.isConsumedExpr(NE) && treatUnusedNewEscaped(NE)) return; ProgramStateRef State = C.getState(); @@ -1367,7 +1088,7 @@ void MallocChecker::processNewAllocation(const CXXNewExpr *NE, State = MallocUpdateRefState(C, NE, State, NE->isArray() ? AF_CXXNewArray : AF_CXXNew, Target); State = addExtentSize(C, NE, State, Target); - State = ProcessZeroAllocCheck(C, NE, 0, State, Target); + State = ProcessZeroAllocation(C, NE, 0, State, Target); C.addTransition(State); } @@ -1436,14 +1157,13 @@ void MallocChecker::checkPreStmt(const CXXDeleteExpr *DE, if (SymbolRef Sym = C.getSVal(DE->getArgument()).getAsSymbol()) checkUseAfterFree(Sym, C, DE->getArgument()); - if (!MemFunctionInfo.isStandardNewDelete(DE->getOperatorDelete(), - C.getASTContext())) + if (!isStandardNewDelete(DE->getOperatorDelete(), C.getASTContext())) return; ProgramStateRef State = C.getState(); - bool IsKnownToBeAllocated; + bool ReleasedAllocated; State = FreeMemAux(C, DE->getArgument(), DE, State, - /*Hold*/false, IsKnownToBeAllocated); + /*Hold*/false, ReleasedAllocated); C.addTransition(State); } @@ -1483,10 +1203,10 @@ void MallocChecker::checkPostObjCMessage(const ObjCMethodCall &Call, if (!*FreeWhenDone) return; - bool IsKnownToBeAllocatedMemory; + bool ReleasedAllocatedMemory; ProgramStateRef State = FreeMemAux(C, Call.getArgExpr(0), Call.getOriginExpr(), C.getState(), - /*Hold=*/true, IsKnownToBeAllocatedMemory, + /*Hold=*/true, ReleasedAllocatedMemory, /*RetNullOnFailure=*/true); C.addTransition(State); @@ -1499,7 +1219,7 @@ MallocChecker::MallocMemReturnsAttr(CheckerContext &C, const CallExpr *CE, if (!State) return nullptr; - if (Att->getModule() != MemFunctionInfo.II_malloc) + if (Att->getModule() != II_malloc) return nullptr; OwnershipAttr::args_iterator I = Att->args_begin(), E = Att->args_end(); @@ -1565,9 +1285,11 @@ ProgramStateRef MallocChecker::MallocMemAux(CheckerContext &C, return MallocUpdateRefState(C, CE, State, Family); } -static ProgramStateRef -MallocUpdateRefState(CheckerContext &C, const Expr *E, ProgramStateRef State, - AllocationFamily Family, Optional RetVal) { +ProgramStateRef MallocChecker::MallocUpdateRefState(CheckerContext &C, + const Expr *E, + ProgramStateRef State, + AllocationFamily Family, + Optional RetVal) { if (!State) return nullptr; @@ -1595,15 +1317,15 @@ ProgramStateRef MallocChecker::FreeMemAttr(CheckerContext &C, if (!State) return nullptr; - if (Att->getModule() != MemFunctionInfo.II_malloc) + if (Att->getModule() != II_malloc) return nullptr; - bool IsKnownToBeAllocated = false; + bool ReleasedAllocated = false; for (const auto &Arg : Att->args()) { ProgramStateRef StateI = FreeMemAux( C, CE, State, Arg.getASTIndex(), - Att->getOwnKind() == OwnershipAttr::Holds, IsKnownToBeAllocated); + Att->getOwnKind() == OwnershipAttr::Holds, ReleasedAllocated); if (StateI) State = StateI; } @@ -1615,7 +1337,7 @@ ProgramStateRef MallocChecker::FreeMemAux(CheckerContext &C, ProgramStateRef State, unsigned Num, bool Hold, - bool &IsKnownToBeAllocated, + bool &ReleasedAllocated, bool ReturnsNullOnFailure) const { if (!State) return nullptr; @@ -1624,7 +1346,7 @@ ProgramStateRef MallocChecker::FreeMemAux(CheckerContext &C, return nullptr; return FreeMemAux(C, CE->getArg(Num), CE, State, Hold, - IsKnownToBeAllocated, ReturnsNullOnFailure); + ReleasedAllocated, ReturnsNullOnFailure); } /// Checks if the previous call to free on the given symbol failed - if free @@ -1642,9 +1364,8 @@ static bool didPreviousFreeFail(ProgramStateRef State, return false; } -static AllocationFamily getAllocationFamily( - const MemFunctionInfoTy &MemFunctionInfo, CheckerContext &C, const Stmt *S) { - +AllocationFamily MallocChecker::getAllocationFamily(CheckerContext &C, + const Stmt *S) const { if (!S) return AF_None; @@ -1656,10 +1377,10 @@ static AllocationFamily getAllocationFamily( ASTContext &Ctx = C.getASTContext(); - if (MemFunctionInfo.isCMemFunction(FD, Ctx, AF_Malloc, MemoryOperationKind::MOK_Any)) + if (isCMemFunction(FD, Ctx, AF_Malloc, MemoryOperationKind::MOK_Any)) return AF_Malloc; - if (MemFunctionInfo.isStandardNewDelete(FD, Ctx)) { + if (isStandardNewDelete(FD, Ctx)) { OverloadedOperatorKind Kind = FD->getOverloadedOperator(); if (Kind == OO_New || Kind == OO_Delete) return AF_CXXNew; @@ -1667,12 +1388,10 @@ static AllocationFamily getAllocationFamily( return AF_CXXNewArray; } - if (MemFunctionInfo.isCMemFunction(FD, Ctx, AF_IfNameIndex, - MemoryOperationKind::MOK_Any)) + if (isCMemFunction(FD, Ctx, AF_IfNameIndex, MemoryOperationKind::MOK_Any)) return AF_IfNameIndex; - if (MemFunctionInfo.isCMemFunction(FD, Ctx, AF_Alloca, - MemoryOperationKind::MOK_Any)) + if (isCMemFunction(FD, Ctx, AF_Alloca, MemoryOperationKind::MOK_Any)) return AF_Alloca; return AF_None; @@ -1690,8 +1409,8 @@ static AllocationFamily getAllocationFamily( return AF_None; } -static bool printAllocDeallocName(raw_ostream &os, CheckerContext &C, - const Expr *E) { +bool MallocChecker::printAllocDeallocName(raw_ostream &os, CheckerContext &C, + const Expr *E) const { if (const CallExpr *CE = dyn_cast(E)) { // FIXME: This doesn't handle indirect calls. const FunctionDecl *FD = CE->getDirectCallee(); @@ -1730,10 +1449,9 @@ static bool printAllocDeallocName(raw_ostream &os, CheckerContext &C, return false; } -static void printExpectedAllocName(raw_ostream &os, - const MemFunctionInfoTy &MemFunctionInfo, - CheckerContext &C, const Expr *E) { - AllocationFamily Family = getAllocationFamily(MemFunctionInfo, C, E); +void MallocChecker::printExpectedAllocName(raw_ostream &os, CheckerContext &C, + const Expr *E) const { + AllocationFamily Family = getAllocationFamily(C, E); switch(Family) { case AF_Malloc: os << "malloc()"; return; @@ -1746,7 +1464,8 @@ static void printExpectedAllocName(raw_ostream &os, } } -static void printExpectedDeallocName(raw_ostream &os, AllocationFamily Family) { +void MallocChecker::printExpectedDeallocName(raw_ostream &os, + AllocationFamily Family) const { switch(Family) { case AF_Malloc: os << "free()"; return; case AF_CXXNew: os << "'delete'"; return; @@ -1763,7 +1482,7 @@ ProgramStateRef MallocChecker::FreeMemAux(CheckerContext &C, const Expr *ParentExpr, ProgramStateRef State, bool Hold, - bool &IsKnownToBeAllocated, + bool &ReleasedAllocated, bool ReturnsNullOnFailure) const { if (!State) @@ -1837,9 +1556,6 @@ ProgramStateRef MallocChecker::FreeMemAux(CheckerContext &C, const RefState *RsBase = State->get(SymBase); SymbolRef PreviousRetStatusSymbol = nullptr; - IsKnownToBeAllocated = RsBase && (RsBase->isAllocated() || - RsBase->isAllocatedOfSizeZero()); - if (RsBase) { // Memory returned by alloca() shouldn't be freed. @@ -1862,8 +1578,7 @@ ProgramStateRef MallocChecker::FreeMemAux(CheckerContext &C, // Check if an expected deallocation function matches the real one. bool DeallocMatchesAlloc = - RsBase->getAllocationFamily() == - getAllocationFamily(MemFunctionInfo, C, ParentExpr); + RsBase->getAllocationFamily() == getAllocationFamily(C, ParentExpr); if (!DeallocMatchesAlloc) { ReportMismatchedDealloc(C, ArgExpr->getSourceRange(), ParentExpr, RsBase, SymBase, Hold); @@ -1889,6 +1604,9 @@ ProgramStateRef MallocChecker::FreeMemAux(CheckerContext &C, return nullptr; } + ReleasedAllocated = (RsBase != nullptr) && (RsBase->isAllocated() || + RsBase->isAllocatedOfSizeZero()); + // Clean out the info on previous call to free return info. State = State->remove(SymBase); @@ -1904,7 +1622,7 @@ ProgramStateRef MallocChecker::FreeMemAux(CheckerContext &C, } AllocationFamily Family = RsBase ? RsBase->getAllocationFamily() - : getAllocationFamily(MemFunctionInfo, C, ParentExpr); + : getAllocationFamily(C, ParentExpr); // Normal free. if (Hold) return State->set(SymBase, @@ -1954,8 +1672,8 @@ Optional MallocChecker::getCheckIfTracked(CheckerContext &C, const Stmt *AllocDeallocStmt, bool IsALeakCheck) const { - return getCheckIfTracked( - getAllocationFamily(MemFunctionInfo, C, AllocDeallocStmt), IsALeakCheck); + return getCheckIfTracked(getAllocationFamily(C, AllocDeallocStmt), + IsALeakCheck); } Optional @@ -2093,7 +1811,7 @@ void MallocChecker::ReportBadFree(CheckerContext &C, SVal ArgVal, else os << "not memory allocated by "; - printExpectedAllocName(os, MemFunctionInfo, C, DeallocExpr); + printExpectedAllocName(os, C, DeallocExpr); auto R = llvm::make_unique(*BT_BadFree[*CheckKind], os.str(), N); R->markInteresting(MR); @@ -2400,7 +2118,7 @@ void MallocChecker::ReportFunctionPointerFree(CheckerContext &C, SVal ArgVal, ProgramStateRef MallocChecker::ReallocMemAux(CheckerContext &C, const CallExpr *CE, - bool ShouldFreeOnFail, + bool FreesOnFail, ProgramStateRef State, bool SuffixWithN) const { if (!State) @@ -2465,32 +2183,33 @@ ProgramStateRef MallocChecker::ReallocMemAux(CheckerContext &C, if (!FromPtr || !ToPtr) return nullptr; - bool IsKnownToBeAllocated = false; + bool ReleasedAllocated = false; // If the size is 0, free the memory. if (SizeIsZero) - // The semantics of the return value are: - // If size was equal to 0, either NULL or a pointer suitable to be passed - // to free() is returned. We just free the input pointer and do not add - // any constrains on the output pointer. if (ProgramStateRef stateFree = FreeMemAux(C, CE, StateSizeIsZero, 0, - false, IsKnownToBeAllocated)) + false, ReleasedAllocated)){ + // The semantics of the return value are: + // If size was equal to 0, either NULL or a pointer suitable to be passed + // to free() is returned. We just free the input pointer and do not add + // any constrains on the output pointer. return stateFree; + } // Default behavior. if (ProgramStateRef stateFree = - FreeMemAux(C, CE, State, 0, false, IsKnownToBeAllocated)) { + FreeMemAux(C, CE, State, 0, false, ReleasedAllocated)) { ProgramStateRef stateRealloc = MallocMemAux(C, CE, TotalSize, UnknownVal(), stateFree); if (!stateRealloc) return nullptr; - OwnershipAfterReallocKind Kind = OAR_ToBeFreedAfterFailure; - if (ShouldFreeOnFail) - Kind = OAR_FreeOnFailure; - else if (!IsKnownToBeAllocated) - Kind = OAR_DoNotTrackAfterFailure; + ReallocPairKind Kind = RPToBeFreedAfterFailure; + if (FreesOnFail) + Kind = RPIsFreeOnFailure; + else if (!ReleasedAllocated) + Kind = RPDoNotTrackAfterFailure; // Record the info about the reallocated symbol so that we could properly // process failed reallocation. @@ -2518,9 +2237,9 @@ ProgramStateRef MallocChecker::CallocMem(CheckerContext &C, const CallExpr *CE, return MallocMemAux(C, CE, TotalSize, zeroVal, State); } -MallocChecker::LeakInfo +LeakInfo MallocChecker::getAllocationSite(const ExplodedNode *N, SymbolRef Sym, - CheckerContext &C) { + CheckerContext &C) const { const LocationContext *LeakContext = N->getLocationContext(); // Walk the ExplodedGraph backwards and find the first node that referred to // the tracked symbol. @@ -2701,10 +2420,9 @@ void MallocChecker::checkPreCall(const CallEvent &Call, ASTContext &Ctx = C.getASTContext(); if (ChecksEnabled[CK_MallocChecker] && - (MemFunctionInfo.isCMemFunction(FD, Ctx, AF_Malloc, - MemoryOperationKind::MOK_Free) || - MemFunctionInfo.isCMemFunction(FD, Ctx, AF_IfNameIndex, - MemoryOperationKind::MOK_Free))) + (isCMemFunction(FD, Ctx, AF_Malloc, MemoryOperationKind::MOK_Free) || + isCMemFunction(FD, Ctx, AF_IfNameIndex, + MemoryOperationKind::MOK_Free))) return; } @@ -2807,7 +2525,7 @@ void MallocChecker::checkPostStmt(const BlockExpr *BE, C.addTransition(state); } -static bool isReleased(SymbolRef Sym, CheckerContext &C) { +bool MallocChecker::isReleased(SymbolRef Sym, CheckerContext &C) const { assert(Sym); const RefState *RS = C.getState()->get(Sym); return (RS && RS->isReleased()); @@ -2883,17 +2601,13 @@ ProgramStateRef MallocChecker::evalAssume(ProgramStateRef state, SymbolRef ReallocSym = I.getData().ReallocatedSym; if (const RefState *RS = state->get(ReallocSym)) { if (RS->isReleased()) { - switch(I.getData().Kind) { - case OAR_ToBeFreedAfterFailure: + if (I.getData().Kind == RPToBeFreedAfterFailure) state = state->set(ReallocSym, RefState::getAllocated(RS->getAllocationFamily(), RS->getStmt())); - break; - case OAR_DoNotTrackAfterFailure: + else if (I.getData().Kind == RPDoNotTrackAfterFailure) state = state->remove(ReallocSym); - break; - default: - assert(I.getData().Kind == OAR_FreeOnFailure); - } + else + assert(I.getData().Kind == RPIsFreeOnFailure); } } state = state->remove(I.getKey()); @@ -2976,7 +2690,7 @@ bool MallocChecker::mayFreeAnyEscapedMemoryOrIsModeledExplicitly( // If it's one of the allocation functions we can reason about, we model // its behavior explicitly. - if (MemFunctionInfo.isMemFunction(FD, ASTC)) + if (isMemFunction(FD, ASTC)) return false; // If it's not a system call, assume it frees memory. @@ -3068,6 +2782,10 @@ bool MallocChecker::mayFreeAnyEscapedMemoryOrIsModeledExplicitly( return false; } +static bool retTrue(const RefState *RS) { + return true; +} + static bool checkIfNewOrNewArrayFamily(const RefState *RS) { return (RS->getAllocationFamily() == AF_CXXNewArray || RS->getAllocationFamily() == AF_CXXNew); @@ -3077,25 +2795,22 @@ ProgramStateRef MallocChecker::checkPointerEscape(ProgramStateRef State, const InvalidatedSymbols &Escaped, const CallEvent *Call, PointerEscapeKind Kind) const { - return checkPointerEscapeAux(State, Escaped, Call, Kind, - /*IsConstPointerEscape*/ false); + return checkPointerEscapeAux(State, Escaped, Call, Kind, &retTrue); } ProgramStateRef MallocChecker::checkConstPointerEscape(ProgramStateRef State, const InvalidatedSymbols &Escaped, const CallEvent *Call, PointerEscapeKind Kind) const { - // If a const pointer escapes, it may not be freed(), but it could be deleted. return checkPointerEscapeAux(State, Escaped, Call, Kind, - /*IsConstPointerEscape*/ true); + &checkIfNewOrNewArrayFamily); } -ProgramStateRef MallocChecker::checkPointerEscapeAux( - ProgramStateRef State, +ProgramStateRef MallocChecker::checkPointerEscapeAux(ProgramStateRef State, const InvalidatedSymbols &Escaped, const CallEvent *Call, PointerEscapeKind Kind, - bool IsConstPointerEscape) const { + bool(*CheckRefState)(const RefState*)) const { // If we know that the call does not free memory, or we want to process the // call later, keep tracking the top level arguments. SymbolRef EscapingSymbol = nullptr; @@ -3115,11 +2830,10 @@ ProgramStateRef MallocChecker::checkPointerEscapeAux( continue; if (const RefState *RS = State->get(sym)) { - if ((RS->isAllocated() || RS->isAllocatedOfSizeZero())) { - if (!IsConstPointerEscape || checkIfNewOrNewArrayFamily(RS)) { - State = State->remove(sym); - State = State->set(sym, RefState::getEscaped(RS)); - } + if ((RS->isAllocated() || RS->isAllocatedOfSizeZero()) && + CheckRefState(RS)) { + State = State->remove(sym); + State = State->set(sym, RefState::getEscaped(RS)); } } } @@ -3131,8 +2845,9 @@ static SymbolRef findFailedReallocSymbol(ProgramStateRef currState, ReallocPairsTy currMap = currState->get(); ReallocPairsTy prevMap = prevState->get(); - for (const ReallocPairsTy::value_type &Pair : prevMap) { - SymbolRef sym = Pair.first; + for (ReallocPairsTy::iterator I = prevMap.begin(), E = prevMap.end(); + I != E; ++I) { + SymbolRef sym = I.getKey(); if (!currMap.lookup(sym)) return sym; } @@ -3153,19 +2868,19 @@ static bool isReferenceCountingPointerDestructor(const CXXDestructorDecl *DD) { return false; } -std::shared_ptr MallocBugVisitor::VisitNode( +std::shared_ptr MallocChecker::MallocBugVisitor::VisitNode( const ExplodedNode *N, BugReporterContext &BRC, BugReport &BR) { ProgramStateRef state = N->getState(); ProgramStateRef statePrev = N->getFirstPred()->getState(); - const RefState *RSCurr = state->get(Sym); + const RefState *RS = state->get(Sym); const RefState *RSPrev = statePrev->get(Sym); const Stmt *S = PathDiagnosticLocation::getStmt(N); // When dealing with containers, we sometimes want to give a note // even if the statement is missing. - if (!S && (!RSCurr || RSCurr->getAllocationFamily() != AF_InnerBuffer)) + if (!S && (!RS || RS->getAllocationFamily() != AF_InnerBuffer)) return nullptr; const LocationContext *CurrentLC = N->getLocationContext(); @@ -3200,12 +2915,12 @@ std::shared_ptr MallocBugVisitor::VisitNode( llvm::raw_svector_ostream OS(Buf); if (Mode == Normal) { - if (isAllocated(RSCurr, RSPrev, S)) { + if (isAllocated(RS, RSPrev, S)) { Msg = "Memory is allocated"; StackHint = new StackHintGeneratorForSymbol(Sym, "Returned allocated memory"); - } else if (isReleased(RSCurr, RSPrev, S)) { - const auto Family = RSCurr->getAllocationFamily(); + } else if (isReleased(RS, RSPrev, S)) { + const auto Family = RS->getAllocationFamily(); switch (Family) { case AF_Alloca: case AF_Malloc: @@ -3229,7 +2944,7 @@ std::shared_ptr MallocBugVisitor::VisitNode( "Returning; inner buffer was deallocated"); } else { OS << "reallocated by call to '"; - const Stmt *S = RSCurr->getStmt(); + const Stmt *S = RS->getStmt(); if (const auto *MemCallE = dyn_cast(S)) { OS << MemCallE->getMethodDecl()->getNameAsString(); } else if (const auto *OpCallE = dyn_cast(S)) { @@ -3280,10 +2995,10 @@ std::shared_ptr MallocBugVisitor::VisitNode( } } } - } else if (isRelinquished(RSCurr, RSPrev, S)) { + } else if (isRelinquished(RS, RSPrev, S)) { Msg = "Memory ownership is transferred"; StackHint = new StackHintGeneratorForSymbol(Sym, ""); - } else if (hasReallocFailed(RSCurr, RSPrev, S)) { + } else if (isReallocFailedCheck(RS, RSPrev, S)) { Mode = ReallocationFailed; Msg = "Reallocation failed"; StackHint = new StackHintGeneratorForReallocationFailed(Sym, @@ -3320,7 +3035,7 @@ std::shared_ptr MallocBugVisitor::VisitNode( // Generate the extra diagnostic. PathDiagnosticLocation Pos; if (!S) { - assert(RSCurr->getAllocationFamily() == AF_InnerBuffer); + assert(RS->getAllocationFamily() == AF_InnerBuffer); auto PostImplCall = N->getLocation().getAs(); if (!PostImplCall) return nullptr; @@ -3375,11 +3090,8 @@ markReleased(ProgramStateRef State, SymbolRef Sym, const Expr *Origin) { void ento::registerNewDeleteLeaksChecker(CheckerManager &mgr) { registerCStringCheckerBasic(mgr); MallocChecker *checker = mgr.registerChecker(); - - checker->MemFunctionInfo.ShouldIncludeOwnershipAnnotatedFunctions = - mgr.getAnalyzerOptions().getCheckerBooleanOption( - "Optimistic", false, checker); - + checker->IsOptimistic = mgr.getAnalyzerOptions().getCheckerBooleanOption( + "Optimistic", false, checker); checker->ChecksEnabled[MallocChecker::CK_NewDeleteLeaksChecker] = true; checker->CheckNames[MallocChecker::CK_NewDeleteLeaksChecker] = mgr.getCurrentCheckName(); @@ -3397,25 +3109,21 @@ void ento::registerNewDeleteLeaksChecker(CheckerManager &mgr) { // Intended to be used in InnerPointerChecker to register the part of // MallocChecker connected to it. void ento::registerInnerPointerCheckerAux(CheckerManager &mgr) { - registerCStringCheckerBasic(mgr); - MallocChecker *checker = mgr.registerChecker(); - - checker->MemFunctionInfo.ShouldIncludeOwnershipAnnotatedFunctions = - mgr.getAnalyzerOptions().getCheckerBooleanOption( - "Optimistic", false, checker); - - checker->ChecksEnabled[MallocChecker::CK_InnerPointerChecker] = true; - checker->CheckNames[MallocChecker::CK_InnerPointerChecker] = - mgr.getCurrentCheckName(); + registerCStringCheckerBasic(mgr); + MallocChecker *checker = mgr.registerChecker(); + checker->IsOptimistic = mgr.getAnalyzerOptions().getCheckerBooleanOption( + "Optimistic", false, checker); + checker->ChecksEnabled[MallocChecker::CK_InnerPointerChecker] = true; + checker->CheckNames[MallocChecker::CK_InnerPointerChecker] = + mgr.getCurrentCheckName(); } #define REGISTER_CHECKER(name) \ void ento::register##name(CheckerManager &mgr) { \ registerCStringCheckerBasic(mgr); \ MallocChecker *checker = mgr.registerChecker(); \ - checker->MemFunctionInfo.ShouldIncludeOwnershipAnnotatedFunctions = \ - mgr.getAnalyzerOptions().getCheckerBooleanOption( \ - "Optimistic", false, checker);\ + checker->IsOptimistic = mgr.getAnalyzerOptions().getCheckerBooleanOption( \ + "Optimistic", false, checker); \ checker->ChecksEnabled[MallocChecker::CK_##name] = true; \ checker->CheckNames[MallocChecker::CK_##name] = mgr.getCurrentCheckName(); \ } -- cgit v1.2.3 From b533efb62cddf6fa272689b548fb1ab7f518bfe7 Mon Sep 17 00:00:00 2001 From: Gabor Marton Date: Mon, 17 Dec 2018 12:42:12 +0000 Subject: [ASTImporter] Fix redecl chain of classes and class templates Summary: The crux of the issue that is being fixed is that lookup could not find previous decls of a friend class. The solution involves making the friend declarations visible in their decl context (i.e. adding them to the lookup table). Also, we simplify `VisitRecordDecl` greatly. This fix involves two other repairs (without these the unittests fail): (1) We could not handle the addition of injected class types properly when a redecl chain was involved, now this is fixed. (2) DeclContext::removeDecl failed if the lookup table in Vector form did not contain the to be removed element. This caused troubles in ASTImporter::ImportDeclContext. This is also fixed. Reviewers: a_sidorin, balazske, a.sidorin Subscribers: rnkovacs, dkrupp, Szelethus, cfe-commits Differential Revision: https://reviews.llvm.org/D53655 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349349 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/LibASTMatchersReference.html | 10 + include/clang/ASTMatchers/ASTMatchers.h | 11 + lib/AST/ASTImporter.cpp | 333 ++++++------- lib/AST/DeclBase.cpp | 4 +- lib/ASTMatchers/ASTMatchersInternal.cpp | 2 + lib/ASTMatchers/Dynamic/Registry.cpp | 1 + unittests/AST/ASTImporterTest.cpp | 728 ++++++++++++++++++++++++---- unittests/AST/StructuralEquivalenceTest.cpp | 71 +++ 8 files changed, 899 insertions(+), 261 deletions(-) diff --git a/docs/LibASTMatchersReference.html b/docs/LibASTMatchersReference.html index 28017cab39..27cb00b6bd 100644 --- a/docs/LibASTMatchersReference.html +++ b/docs/LibASTMatchersReference.html @@ -300,6 +300,16 @@ Example matches f +Matcher<Decl>indirectFieldDeclMatcher<IndirectFieldDecl>... +
Matches indirect field declarations.
+
+Given
+  struct X { struct { int a; }; };
+indirectFieldDecl()
+  matches 'a'.
+
+ + Matcher<Decl>labelDeclMatcher<LabelDecl>...
Matches a declaration of label.
 
diff --git a/include/clang/ASTMatchers/ASTMatchers.h b/include/clang/ASTMatchers/ASTMatchers.h
index b913e54b37..7e35f0667a 100644
--- a/include/clang/ASTMatchers/ASTMatchers.h
+++ b/include/clang/ASTMatchers/ASTMatchers.h
@@ -1158,6 +1158,17 @@ extern const internal::VariadicDynCastAllOfMatcher varDecl;
 ///   matches 'm'.
 extern const internal::VariadicDynCastAllOfMatcher fieldDecl;
 
+/// Matches indirect field declarations.
+///
+/// Given
+/// \code
+///   struct X { struct { int a; }; };
+/// \endcode
+/// indirectFieldDecl()
+///   matches 'a'.
+extern const internal::VariadicDynCastAllOfMatcher
+    indirectFieldDecl;
+
 /// Matches function declarations.
 ///
 /// Example matches f
diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp
index 6ba80cdaa7..c67990cfcf 100644
--- a/lib/AST/ASTImporter.cpp
+++ b/lib/AST/ASTImporter.cpp
@@ -122,6 +122,8 @@ namespace clang {
       return getCanonicalForwardRedeclChain(FD);
     if (auto *VD = dyn_cast(D))
       return getCanonicalForwardRedeclChain(VD);
+    if (auto *TD = dyn_cast(D))
+      return getCanonicalForwardRedeclChain(TD);
     llvm_unreachable("Bad declaration kind");
   }
 
@@ -2607,10 +2609,9 @@ ExpectedDecl ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
       return std::move(Err);
     IDNS = Decl::IDNS_Ordinary;
   } else if (Importer.getToContext().getLangOpts().CPlusPlus)
-    IDNS |= Decl::IDNS_Ordinary;
+    IDNS |= Decl::IDNS_Ordinary | Decl::IDNS_TagFriend;
 
   // We may already have a record of the same name; try to find and match it.
-  RecordDecl *AdoptDecl = nullptr;
   RecordDecl *PrevDecl = nullptr;
   if (!DC->isFunctionOrMethod()) {
     SmallVector ConflictingDecls;
@@ -2643,26 +2644,22 @@ ExpectedDecl ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
       }
 
       if (auto *FoundRecord = dyn_cast(Found)) {
-        if (!SearchName) {
+        // Do not emit false positive diagnostic in case of unnamed
+        // struct/union and in case of anonymous structs.  Would be false
+        // because there may be several anonymous/unnamed structs in a class.
+        // E.g. these are both valid:
+        //  struct A { // unnamed structs
+        //    struct { struct A *next; } entry0;
+        //    struct { struct A *next; } entry1;
+        //  };
+        //  struct X { struct { int a; }; struct { int b; }; }; // anon structs
+        if (!SearchName)
           if (!IsStructuralMatch(D, FoundRecord, false))
             continue;
-        } else {
-          if (!IsStructuralMatch(D, FoundRecord)) {
-            ConflictingDecls.push_back(FoundDecl);
-            continue;
-          }
-        }
 
-        PrevDecl = FoundRecord;
-
-        if (RecordDecl *FoundDef = FoundRecord->getDefinition()) {
-          if ((SearchName && !D->isCompleteDefinition() && !IsFriendTemplate)
-              || (D->isCompleteDefinition() &&
-                  D->isAnonymousStructOrUnion()
-                    == FoundDef->isAnonymousStructOrUnion())) {
-            // The record types structurally match, or the "from" translation
-            // unit only had a forward declaration anyway; call it the same
-            // function.
+        if (IsStructuralMatch(D, FoundRecord)) {
+          RecordDecl *FoundDef = FoundRecord->getDefinition();
+          if (D->isThisDeclarationADefinition() && FoundDef) {
             // FIXME: Structural equivalence check should check for same
             // user-defined methods.
             Importer.MapImported(D, FoundDef);
@@ -2670,46 +2667,20 @@ ExpectedDecl ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
               auto *FoundCXX = dyn_cast(FoundDef);
               assert(FoundCXX && "Record type mismatch");
 
-              if (D->isCompleteDefinition() && !Importer.isMinimalImport())
+              if (!Importer.isMinimalImport())
                 // FoundDef may not have every implicit method that D has
                 // because implicit methods are created only if they are used.
                 if (Error Err = ImportImplicitMethods(DCXX, FoundCXX))
                   return std::move(Err);
             }
-            return FoundDef;
           }
-          if (IsFriendTemplate)
-            continue;
-        } else if (!D->isCompleteDefinition()) {
-          // We have a forward declaration of this type, so adopt that forward
-          // declaration rather than building a new one.
-
-          // If one or both can be completed from external storage then try one
-          // last time to complete and compare them before doing this.
-
-          if (FoundRecord->hasExternalLexicalStorage() &&
-              !FoundRecord->isCompleteDefinition())
-            FoundRecord->getASTContext().getExternalSource()->CompleteType(FoundRecord);
-          if (D->hasExternalLexicalStorage())
-            D->getASTContext().getExternalSource()->CompleteType(D);
-
-          if (FoundRecord->isCompleteDefinition() &&
-              D->isCompleteDefinition() &&
-              !IsStructuralMatch(D, FoundRecord)) {
-            ConflictingDecls.push_back(FoundDecl);
-            continue;
-          }
-
-          AdoptDecl = FoundRecord;
-          continue;
+          PrevDecl = FoundRecord->getMostRecentDecl();
+          break;
         }
-
-        continue;
-      } else if (isa(Found))
-        continue;
+      }
 
       ConflictingDecls.push_back(FoundDecl);
-    }
+    } // for
 
     if (!ConflictingDecls.empty() && SearchName) {
       Name = Importer.HandleNameConflict(Name, DC, IDNS,
@@ -2725,79 +2696,90 @@ ExpectedDecl ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
     return BeginLocOrErr.takeError();
 
   // Create the record declaration.
-  RecordDecl *D2 = AdoptDecl;
-  if (!D2) {
-    CXXRecordDecl *D2CXX = nullptr;
-    if (auto *DCXX = dyn_cast(D)) {
-      if (DCXX->isLambda()) {
-        auto TInfoOrErr = import(DCXX->getLambdaTypeInfo());
-        if (!TInfoOrErr)
-          return TInfoOrErr.takeError();
-        if (GetImportedOrCreateSpecialDecl(
-                D2CXX, CXXRecordDecl::CreateLambda, D, Importer.getToContext(),
-                DC, *TInfoOrErr, Loc, DCXX->isDependentLambda(),
-                DCXX->isGenericLambda(), DCXX->getLambdaCaptureDefault()))
-          return D2CXX;
-        ExpectedDecl CDeclOrErr = import(DCXX->getLambdaContextDecl());
-        if (!CDeclOrErr)
-          return CDeclOrErr.takeError();
-        D2CXX->setLambdaMangling(DCXX->getLambdaManglingNumber(), *CDeclOrErr);
-      } else if (DCXX->isInjectedClassName()) {
-        // We have to be careful to do a similar dance to the one in
-        // Sema::ActOnStartCXXMemberDeclarations
-        CXXRecordDecl *const PrevDecl = nullptr;
-        const bool DelayTypeCreation = true;
-        if (GetImportedOrCreateDecl(D2CXX, D, Importer.getToContext(),
-                                    D->getTagKind(), DC, *BeginLocOrErr, Loc,
-                                    Name.getAsIdentifierInfo(), PrevDecl,
-                                    DelayTypeCreation))
-          return D2CXX;
-        Importer.getToContext().getTypeDeclType(
-            D2CXX, dyn_cast(DC));
-      } else {
-        if (GetImportedOrCreateDecl(D2CXX, D, Importer.getToContext(),
-                                    D->getTagKind(), DC, *BeginLocOrErr, Loc,
-                                    Name.getAsIdentifierInfo(),
-                                    cast_or_null(PrevDecl)))
-          return D2CXX;
-      }
+  RecordDecl *D2 = nullptr;
+  CXXRecordDecl *D2CXX = nullptr;
+  if (auto *DCXX = dyn_cast(D)) {
+    if (DCXX->isLambda()) {
+      auto TInfoOrErr = import(DCXX->getLambdaTypeInfo());
+      if (!TInfoOrErr)
+        return TInfoOrErr.takeError();
+      if (GetImportedOrCreateSpecialDecl(
+              D2CXX, CXXRecordDecl::CreateLambda, D, Importer.getToContext(),
+              DC, *TInfoOrErr, Loc, DCXX->isDependentLambda(),
+              DCXX->isGenericLambda(), DCXX->getLambdaCaptureDefault()))
+        return D2CXX;
+      ExpectedDecl CDeclOrErr = import(DCXX->getLambdaContextDecl());
+      if (!CDeclOrErr)
+        return CDeclOrErr.takeError();
+      D2CXX->setLambdaMangling(DCXX->getLambdaManglingNumber(), *CDeclOrErr);
+    } else if (DCXX->isInjectedClassName()) {
+      // We have to be careful to do a similar dance to the one in
+      // Sema::ActOnStartCXXMemberDeclarations
+      const bool DelayTypeCreation = true;
+      if (GetImportedOrCreateDecl(
+              D2CXX, D, Importer.getToContext(), D->getTagKind(), DC,
+              *BeginLocOrErr, Loc, Name.getAsIdentifierInfo(),
+              cast_or_null(PrevDecl), DelayTypeCreation))
+        return D2CXX;
+      Importer.getToContext().getTypeDeclType(
+          D2CXX, dyn_cast(DC));
+    } else {
+      if (GetImportedOrCreateDecl(D2CXX, D, Importer.getToContext(),
+                                  D->getTagKind(), DC, *BeginLocOrErr, Loc,
+                                  Name.getAsIdentifierInfo(),
+                                  cast_or_null(PrevDecl)))
+        return D2CXX;
+    }
 
-      D2 = D2CXX;
-      D2->setAccess(D->getAccess());
-      D2->setLexicalDeclContext(LexicalDC);
-      if (!DCXX->getDescribedClassTemplate() || DCXX->isImplicit())
-        LexicalDC->addDeclInternal(D2);
-
-      if (ClassTemplateDecl *FromDescribed =
-          DCXX->getDescribedClassTemplate()) {
-        ClassTemplateDecl *ToDescribed;
-        if (Error Err = importInto(ToDescribed, FromDescribed))
-          return std::move(Err);
-        D2CXX->setDescribedClassTemplate(ToDescribed);
-        if (!DCXX->isInjectedClassName() && !IsFriendTemplate) {
-          // In a record describing a template the type should be an
-          // InjectedClassNameType (see Sema::CheckClassTemplate). Update the
-          // previously set type to the correct value here (ToDescribed is not
-          // available at record create).
-          // FIXME: The previous type is cleared but not removed from
-          // ASTContext's internal storage.
-          CXXRecordDecl *Injected = nullptr;
-          for (NamedDecl *Found : D2CXX->noload_lookup(Name)) {
-            auto *Record = dyn_cast(Found);
-            if (Record && Record->isInjectedClassName()) {
-              Injected = Record;
-              break;
-            }
-          }
-          D2CXX->setTypeForDecl(nullptr);
-          Importer.getToContext().getInjectedClassNameType(D2CXX,
-              ToDescribed->getInjectedClassNameSpecialization());
-          if (Injected) {
-            Injected->setTypeForDecl(nullptr);
-            Importer.getToContext().getTypeDeclType(Injected, D2CXX);
+    D2 = D2CXX;
+    D2->setAccess(D->getAccess());
+    D2->setLexicalDeclContext(LexicalDC);
+    if (!DCXX->getDescribedClassTemplate() || DCXX->isImplicit())
+      LexicalDC->addDeclInternal(D2);
+
+    if (LexicalDC != DC && D->isInIdentifierNamespace(Decl::IDNS_TagFriend))
+      DC->makeDeclVisibleInContext(D2);
+
+    if (ClassTemplateDecl *FromDescribed =
+        DCXX->getDescribedClassTemplate()) {
+      ClassTemplateDecl *ToDescribed;
+      if (Error Err = importInto(ToDescribed, FromDescribed))
+        return std::move(Err);
+      D2CXX->setDescribedClassTemplate(ToDescribed);
+      if (!DCXX->isInjectedClassName() && !IsFriendTemplate) {
+        // In a record describing a template the type should be an
+        // InjectedClassNameType (see Sema::CheckClassTemplate). Update the
+        // previously set type to the correct value here (ToDescribed is not
+        // available at record create).
+        // FIXME: The previous type is cleared but not removed from
+        // ASTContext's internal storage.
+        CXXRecordDecl *Injected = nullptr;
+        for (NamedDecl *Found : D2CXX->noload_lookup(Name)) {
+          auto *Record = dyn_cast(Found);
+          if (Record && Record->isInjectedClassName()) {
+            Injected = Record;
+            break;
           }
         }
-      } else if (MemberSpecializationInfo *MemberInfo =
+        // Create an injected type for the whole redecl chain.
+        SmallVector Redecls =
+            getCanonicalForwardRedeclChain(D2CXX);
+        for (auto *R : Redecls) {
+          auto *RI = cast(R);
+          RI->setTypeForDecl(nullptr);
+          // Below we create a new injected type and assign that to the
+          // canonical decl, subsequent declarations in the chain will reuse
+          // that type.
+          Importer.getToContext().getInjectedClassNameType(
+              RI, ToDescribed->getInjectedClassNameSpecialization());
+        }
+        // Set the new type for the previous injected decl too.
+        if (Injected) {
+          Injected->setTypeForDecl(nullptr);
+          Importer.getToContext().getTypeDeclType(Injected, D2CXX);
+        }
+      }
+    } else if (MemberSpecializationInfo *MemberInfo =
                    DCXX->getMemberSpecializationInfo()) {
         TemplateSpecializationKind SK =
             MemberInfo->getTemplateSpecializationKind();
@@ -2814,27 +2796,24 @@ ExpectedDecl ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
             *POIOrErr);
         else
           return POIOrErr.takeError();
-      }
-
-    } else {
-      if (GetImportedOrCreateDecl(D2, D, Importer.getToContext(),
-                                  D->getTagKind(), DC, *BeginLocOrErr, Loc,
-                                  Name.getAsIdentifierInfo(), PrevDecl))
-        return D2;
-      D2->setLexicalDeclContext(LexicalDC);
-      LexicalDC->addDeclInternal(D2);
     }
 
-    if (auto QualifierLocOrErr = import(D->getQualifierLoc()))
-      D2->setQualifierInfo(*QualifierLocOrErr);
-    else
-      return QualifierLocOrErr.takeError();
-
-    if (D->isAnonymousStructOrUnion())
-      D2->setAnonymousStructOrUnion(true);
+  } else {
+    if (GetImportedOrCreateDecl(D2, D, Importer.getToContext(),
+                                D->getTagKind(), DC, *BeginLocOrErr, Loc,
+                                Name.getAsIdentifierInfo(), PrevDecl))
+      return D2;
+    D2->setLexicalDeclContext(LexicalDC);
+    LexicalDC->addDeclInternal(D2);
   }
 
-  Importer.MapImported(D, D2);
+  if (auto QualifierLocOrErr = import(D->getQualifierLoc()))
+    D2->setQualifierInfo(*QualifierLocOrErr);
+  else
+    return QualifierLocOrErr.takeError();
+
+  if (D->isAnonymousStructOrUnion())
+    D2->setAnonymousStructOrUnion(true);
 
   if (D->isCompleteDefinition())
     if (Error Err = ImportDefinition(D, D2, IDK_Default))
@@ -4990,14 +4969,12 @@ static ClassTemplateDecl *getDefinition(ClassTemplateDecl *D) {
 ExpectedDecl ASTNodeImporter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
   bool IsFriend = D->getFriendObjectKind() != Decl::FOK_None;
 
-  // If this record has a definition in the translation unit we're coming from,
-  // but this particular declaration is not that definition, import the
+  // If this template has a definition in the translation unit we're coming
+  // from, but this particular declaration is not that definition, import the
   // definition and map to that.
-  auto *Definition =
-      cast_or_null(D->getTemplatedDecl()->getDefinition());
-  if (Definition && Definition != D->getTemplatedDecl() && !IsFriend) {
-    if (ExpectedDecl ImportedDefOrErr = import(
-        Definition->getDescribedClassTemplate()))
+  ClassTemplateDecl *Definition = getDefinition(D);
+  if (Definition && Definition != D && !IsFriend) {
+    if (ExpectedDecl ImportedDefOrErr = import(Definition))
       return Importer.MapImported(D, *ImportedDefOrErr);
     else
       return ImportedDefOrErr.takeError();
@@ -5013,38 +4990,29 @@ ExpectedDecl ASTNodeImporter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
   if (ToD)
     return ToD;
 
+  ClassTemplateDecl *FoundByLookup = nullptr;
+
   // We may already have a template of the same name; try to find and match it.
   if (!DC->isFunctionOrMethod()) {
     SmallVector ConflictingDecls;
     SmallVector FoundDecls;
     DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
     for (auto *FoundDecl : FoundDecls) {
-      if (!FoundDecl->isInIdentifierNamespace(Decl::IDNS_Ordinary))
+      if (!FoundDecl->isInIdentifierNamespace(Decl::IDNS_Ordinary |
+                                              Decl::IDNS_TagFriend))
         continue;
 
       Decl *Found = FoundDecl;
-      if (auto *FoundTemplate = dyn_cast(Found)) {
-
-        // The class to be imported is a definition.
-        if (D->isThisDeclarationADefinition()) {
-          // Lookup will find the fwd decl only if that is more recent than the
-          // definition. So, try to get the definition if that is available in
-          // the redecl chain.
-          ClassTemplateDecl *TemplateWithDef = getDefinition(FoundTemplate);
-          if (TemplateWithDef)
-            FoundTemplate = TemplateWithDef;
-          else
-            continue;
-        }
+      auto *FoundTemplate = dyn_cast(Found);
+      if (FoundTemplate) {
 
         if (IsStructuralMatch(D, FoundTemplate)) {
-          if (!IsFriend) {
-            Importer.MapImported(D->getTemplatedDecl(),
-                                 FoundTemplate->getTemplatedDecl());
-            return Importer.MapImported(D, FoundTemplate);
+          ClassTemplateDecl *TemplateWithDef = getDefinition(FoundTemplate);
+          if (D->isThisDeclarationADefinition() && TemplateWithDef) {
+            return Importer.MapImported(D, TemplateWithDef);
           }
-
-          continue;
+          FoundByLookup = FoundTemplate;
+          break;
         }
       }
 
@@ -5081,18 +5049,39 @@ ExpectedDecl ASTNodeImporter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
 
   ToTemplated->setDescribedClassTemplate(D2);
 
-  if (ToTemplated->getPreviousDecl()) {
-    assert(
-        ToTemplated->getPreviousDecl()->getDescribedClassTemplate() &&
-        "Missing described template");
-    D2->setPreviousDecl(
-        ToTemplated->getPreviousDecl()->getDescribedClassTemplate());
-  }
   D2->setAccess(D->getAccess());
   D2->setLexicalDeclContext(LexicalDC);
-  if (!IsFriend)
+
+  if (D->getDeclContext()->containsDeclAndLoad(D))
+    DC->addDeclInternal(D2);
+  if (DC != LexicalDC && D->getLexicalDeclContext()->containsDeclAndLoad(D))
     LexicalDC->addDeclInternal(D2);
 
+  if (FoundByLookup) {
+    auto *Recent =
+        const_cast(FoundByLookup->getMostRecentDecl());
+
+    // It is possible that during the import of the class template definition
+    // we start the import of a fwd friend decl of the very same class template
+    // and we add the fwd friend decl to the lookup table. But the ToTemplated
+    // had been created earlier and by that time the lookup could not find
+    // anything existing, so it has no previous decl. Later, (still during the
+    // import of the fwd friend decl) we start to import the definition again
+    // and this time the lookup finds the previous fwd friend class template.
+    // In this case we must set up the previous decl for the templated decl.
+    if (!ToTemplated->getPreviousDecl()) {
+      CXXRecordDecl *PrevTemplated =
+          FoundByLookup->getTemplatedDecl()->getMostRecentDecl();
+      if (ToTemplated != PrevTemplated)
+        ToTemplated->setPreviousDecl(PrevTemplated);
+    }
+
+    D2->setPreviousDecl(Recent);
+  }
+
+  if (LexicalDC != DC && IsFriend)
+    DC->makeDeclVisibleInContext(D2);
+
   if (FromTemplated->isCompleteDefinition() &&
       !ToTemplated->isCompleteDefinition()) {
     // FIXME: Import definition!
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp
index 95babf7917..66dfa53314 100644
--- a/lib/AST/DeclBase.cpp
+++ b/lib/AST/DeclBase.cpp
@@ -1463,7 +1463,9 @@ void DeclContext::removeDecl(Decl *D) {
       if (Map) {
         StoredDeclsMap::iterator Pos = Map->find(ND->getDeclName());
         assert(Pos != Map->end() && "no lookup entry for decl");
-        if (Pos->second.getAsVector() || Pos->second.getAsDecl() == ND)
+        // Remove the decl only if it is contained.
+        StoredDeclsList::DeclsTy *Vec = Pos->second.getAsVector();
+        if ((Vec && is_contained(*Vec, ND)) || Pos->second.getAsDecl() == ND)
           Pos->second.remove(ND);
       }
     } while (DC->isTransparentContext() && (DC = DC->getParent()));
diff --git a/lib/ASTMatchers/ASTMatchersInternal.cpp b/lib/ASTMatchers/ASTMatchersInternal.cpp
index 6a87a67275..e1aae172a8 100644
--- a/lib/ASTMatchers/ASTMatchersInternal.cpp
+++ b/lib/ASTMatchers/ASTMatchersInternal.cpp
@@ -606,6 +606,8 @@ const internal::VariadicDynCastAllOfMatcher
     cxxConversionDecl;
 const internal::VariadicDynCastAllOfMatcher varDecl;
 const internal::VariadicDynCastAllOfMatcher fieldDecl;
+const internal::VariadicDynCastAllOfMatcher
+    indirectFieldDecl;
 const internal::VariadicDynCastAllOfMatcher functionDecl;
 const internal::VariadicDynCastAllOfMatcher
     functionTemplateDecl;
diff --git a/lib/ASTMatchers/Dynamic/Registry.cpp b/lib/ASTMatchers/Dynamic/Registry.cpp
index 5f11c153dc..0bef326ca5 100644
--- a/lib/ASTMatchers/Dynamic/Registry.cpp
+++ b/lib/ASTMatchers/Dynamic/Registry.cpp
@@ -212,6 +212,7 @@ RegistryMaps::RegistryMaps() {
   REGISTER_MATCHER(expr);
   REGISTER_MATCHER(exprWithCleanups);
   REGISTER_MATCHER(fieldDecl);
+  REGISTER_MATCHER(indirectFieldDecl);
   REGISTER_MATCHER(floatLiteral);
   REGISTER_MATCHER(forEach);
   REGISTER_MATCHER(forEachArgumentWithParam);
diff --git a/unittests/AST/ASTImporterTest.cpp b/unittests/AST/ASTImporterTest.cpp
index 0450cb41a4..3407f7da6d 100644
--- a/unittests/AST/ASTImporterTest.cpp
+++ b/unittests/AST/ASTImporterTest.cpp
@@ -11,9 +11,10 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "clang/AST/ASTImporter.h"
 #include "MatchVerifier.h"
 #include "clang/AST/ASTContext.h"
-#include "clang/AST/ASTImporter.h"
+#include "clang/AST/DeclContextInternals.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
 #include "clang/ASTMatchers/ASTMatchers.h"
 #include "clang/Tooling/Tooling.h"
@@ -1808,6 +1809,65 @@ TEST_P(ASTImporterTestBase, ObjectsWithUnnamedStructType) {
   EXPECT_NE(To0->getCanonicalDecl(), To1->getCanonicalDecl());
 }
 
+TEST_P(ASTImporterTestBase, AnonymousRecords) {
+  auto *Code =
+      R"(
+      struct X {
+        struct { int a; };
+        struct { int b; };
+      };
+      )";
+  Decl *FromTU0 = getTuDecl(Code, Lang_C, "input0.c");
+
+  Decl *FromTU1 = getTuDecl(Code, Lang_C, "input1.c");
+
+  auto *X0 =
+      FirstDeclMatcher().match(FromTU0, recordDecl(hasName("X")));
+  auto *X1 =
+      FirstDeclMatcher().match(FromTU1, recordDecl(hasName("X")));
+  Import(X0, Lang_C);
+  Import(X1, Lang_C);
+
+  auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
+  // We expect no (ODR) warning during the import.
+  EXPECT_EQ(0u, ToTU->getASTContext().getDiagnostics().getNumWarnings());
+  EXPECT_EQ(1u,
+            DeclCounter().match(ToTU, recordDecl(hasName("X"))));
+}
+
+TEST_P(ASTImporterTestBase, AnonymousRecordsReversed) {
+  Decl *FromTU0 = getTuDecl(
+      R"(
+      struct X {
+        struct { int a; };
+        struct { int b; };
+      };
+      )",
+      Lang_C, "input0.c");
+
+  Decl *FromTU1 = getTuDecl(
+      R"(
+      struct X { // reversed order
+        struct { int b; };
+        struct { int a; };
+      };
+      )",
+      Lang_C, "input1.c");
+
+  auto *X0 =
+      FirstDeclMatcher().match(FromTU0, recordDecl(hasName("X")));
+  auto *X1 =
+      FirstDeclMatcher().match(FromTU1, recordDecl(hasName("X")));
+  Import(X0, Lang_C);
+  Import(X1, Lang_C);
+
+  auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
+  // We expect one (ODR) warning during the import.
+  EXPECT_EQ(1u, ToTU->getASTContext().getDiagnostics().getNumWarnings());
+  EXPECT_EQ(2u,
+            DeclCounter().match(ToTU, recordDecl(hasName("X"))));
+}
+
 TEST_P(ASTImporterTestBase, ImportDoesUpdateUsedFlag) {
   auto Pattern = varDecl(hasName("x"));
   VarDecl *Imported1;
@@ -2930,93 +2990,6 @@ TEST_P(ASTImporterTestBase, ImportUnnamedFieldsInCorrectOrder) {
   EXPECT_EQ(FromIndex, 3u);
 }
 
-TEST_P(
-    ASTImporterTestBase,
-    ImportOfFriendRecordDoesNotMergeDefinition) {
-  Decl *FromTU = getTuDecl(
-      R"(
-      class A {
-        template  class F {};
-        class X {
-          template  friend class F;
-        };
-      };
-      )",
-      Lang_CXX, "input0.cc");
-
-  auto *FromClass = FirstDeclMatcher().match(
-      FromTU, cxxRecordDecl(hasName("F"), isDefinition()));
-  auto *FromFriendClass = LastDeclMatcher().match(
-      FromTU, cxxRecordDecl(hasName("F")));
-
-  ASSERT_TRUE(FromClass);
-  ASSERT_TRUE(FromFriendClass);
-  ASSERT_NE(FromClass, FromFriendClass);
-  ASSERT_EQ(FromFriendClass->getDefinition(), FromClass);
-  ASSERT_EQ(FromFriendClass->getPreviousDecl(), FromClass);
-  ASSERT_EQ(
-      FromFriendClass->getDescribedClassTemplate()->getPreviousDecl(),
-      FromClass->getDescribedClassTemplate());
-
-  auto *ToClass = cast(Import(FromClass, Lang_CXX));
-  auto *ToFriendClass = cast(Import(FromFriendClass, Lang_CXX));
-
-  EXPECT_TRUE(ToClass);
-  EXPECT_TRUE(ToFriendClass);
-  EXPECT_NE(ToClass, ToFriendClass);
-  EXPECT_EQ(ToFriendClass->getDefinition(), ToClass);
-  EXPECT_EQ(ToFriendClass->getPreviousDecl(), ToClass);
-  EXPECT_EQ(
-      ToFriendClass->getDescribedClassTemplate()->getPreviousDecl(),
-      ToClass->getDescribedClassTemplate());
-}
-
-TEST_P(
-    ASTImporterTestBase,
-    ImportOfRecursiveFriendClass) {
-  Decl *FromTu = getTuDecl(
-      R"(
-      class declToImport {
-        friend class declToImport;
-      };
-      )",
-      Lang_CXX, "input.cc");
-
-  auto *FromD = FirstDeclMatcher().match(
-      FromTu, cxxRecordDecl(hasName("declToImport")));
-  auto *ToD = Import(FromD, Lang_CXX);
-  auto Pattern = cxxRecordDecl(hasName("declToImport"), has(friendDecl()));
-  ASSERT_TRUE(MatchVerifier{}.match(FromD, Pattern));
-  EXPECT_TRUE(MatchVerifier{}.match(ToD, Pattern));
-}
-
-TEST_P(
-    ASTImporterTestBase,
-    ImportOfRecursiveFriendClassTemplate) {
-  Decl *FromTu = getTuDecl(
-      R"(
-      template  class declToImport {
-        template  friend class declToImport;
-      };
-      )",
-      Lang_CXX, "input.cc");
-
-  auto *FromD = FirstDeclMatcher().match(
-      FromTu, classTemplateDecl(hasName("declToImport")));
-  auto *ToD = Import(FromD, Lang_CXX);
-
-  auto Pattern = classTemplateDecl(
-      has(cxxRecordDecl(has(friendDecl(has(classTemplateDecl()))))));
-  ASSERT_TRUE(MatchVerifier{}.match(FromD, Pattern));
-  EXPECT_TRUE(MatchVerifier{}.match(ToD, Pattern));
-
-  auto *Class =
-      FirstDeclMatcher().match(ToD, classTemplateDecl());
-  auto *Friend = FirstDeclMatcher().match(ToD, friendDecl());
-  EXPECT_NE(Friend->getFriendDecl(), Class);
-  EXPECT_EQ(Friend->getFriendDecl()->getPreviousDecl(), Class);
-}
-
 TEST_P(ASTImporterTestBase, MergeFieldDeclsOfClassTemplateSpecialization) {
   std::string ClassTemplate =
       R"(
@@ -3381,6 +3354,542 @@ TEST_P(ImportVariables, InitAndDefinitionAreInTheFromContext) {
   EXPECT_TRUE(ImportedD->getDefinition());
 }
 
+struct ImportClasses : ASTImporterTestBase {};
+
+TEST_P(ImportClasses,
+       PrototypeShouldBeImportedAsAPrototypeWhenThereIsNoDefinition) {
+  Decl *FromTU = getTuDecl("class X;", Lang_CXX);
+  auto Pattern = cxxRecordDecl(hasName("X"), unless(isImplicit()));
+  auto FromD = FirstDeclMatcher().match(FromTU, Pattern);
+
+  Decl *ImportedD = Import(FromD, Lang_CXX);
+  Decl *ToTU = ImportedD->getTranslationUnitDecl();
+
+  EXPECT_EQ(DeclCounter().match(ToTU, Pattern), 1u);
+  auto ToD = LastDeclMatcher().match(ToTU, Pattern);
+  EXPECT_TRUE(ImportedD == ToD);
+  EXPECT_FALSE(ToD->isThisDeclarationADefinition());
+}
+
+TEST_P(ImportClasses, ImportPrototypeAfterImportedPrototype) {
+  Decl *FromTU = getTuDecl("class X; class X;", Lang_CXX);
+  auto Pattern = cxxRecordDecl(hasName("X"), unless(isImplicit()));
+  auto From0 = FirstDeclMatcher().match(FromTU, Pattern);
+  auto From1 = LastDeclMatcher().match(FromTU, Pattern);
+
+  Decl *Imported0 = Import(From0, Lang_CXX);
+  Decl *Imported1 = Import(From1, Lang_CXX);
+  Decl *ToTU = Imported0->getTranslationUnitDecl();
+
+  EXPECT_EQ(DeclCounter().match(ToTU, Pattern), 2u);
+  auto To0 = FirstDeclMatcher().match(ToTU, Pattern);
+  auto To1 = LastDeclMatcher().match(ToTU, Pattern);
+  EXPECT_TRUE(Imported0 == To0);
+  EXPECT_TRUE(Imported1 == To1);
+  EXPECT_FALSE(To0->isThisDeclarationADefinition());
+  EXPECT_FALSE(To1->isThisDeclarationADefinition());
+  EXPECT_EQ(To1->getPreviousDecl(), To0);
+}
+
+TEST_P(ImportClasses, DefinitionShouldBeImportedAsADefinition) {
+  Decl *FromTU = getTuDecl("class X {};", Lang_CXX);
+  auto Pattern = cxxRecordDecl(hasName("X"), unless(isImplicit()));
+  auto *FromD = FirstDeclMatcher().match(FromTU, Pattern);
+
+  Decl *ImportedD = Import(FromD, Lang_CXX);
+  Decl *ToTU = ImportedD->getTranslationUnitDecl();
+
+  EXPECT_EQ(DeclCounter().match(ToTU, Pattern), 1u);
+  EXPECT_TRUE(cast(ImportedD)->isThisDeclarationADefinition());
+}
+
+TEST_P(ImportClasses, ImportPrototypeFromDifferentTUAfterImportedPrototype) {
+  Decl *FromTU0 = getTuDecl("class X;", Lang_CXX, "input0.cc");
+  Decl *FromTU1 = getTuDecl("class X;", Lang_CXX, "input1.cc");
+  auto Pattern = cxxRecordDecl(hasName("X"), unless(isImplicit()));
+  auto From0 = FirstDeclMatcher().match(FromTU0, Pattern);
+  auto From1 = FirstDeclMatcher().match(FromTU1, Pattern);
+
+  Decl *Imported0 = Import(From0, Lang_CXX);
+  Decl *Imported1 = Import(From1, Lang_CXX);
+  Decl *ToTU = Imported0->getTranslationUnitDecl();
+
+  EXPECT_EQ(DeclCounter().match(ToTU, Pattern), 2u);
+  auto To0 = FirstDeclMatcher().match(ToTU, Pattern);
+  auto To1 = LastDeclMatcher().match(ToTU, Pattern);
+  EXPECT_TRUE(Imported0 == To0);
+  EXPECT_TRUE(Imported1 == To1);
+  EXPECT_FALSE(To0->isThisDeclarationADefinition());
+  EXPECT_FALSE(To1->isThisDeclarationADefinition());
+  EXPECT_EQ(To1->getPreviousDecl(), To0);
+}
+
+TEST_P(ImportClasses, ImportDefinitions) {
+  Decl *FromTU0 = getTuDecl("class X {};", Lang_CXX, "input0.cc");
+  Decl *FromTU1 = getTuDecl("class X {};", Lang_CXX, "input1.cc");
+  auto Pattern = cxxRecordDecl(hasName("X"), unless(isImplicit()));
+  auto From0 = FirstDeclMatcher().match(FromTU0, Pattern);
+  auto From1 = FirstDeclMatcher().match(FromTU1, Pattern);
+
+  Decl *Imported0 = Import(From0, Lang_CXX);
+  Decl *Imported1 = Import(From1, Lang_CXX);
+  Decl *ToTU = Imported0->getTranslationUnitDecl();
+
+  EXPECT_EQ(Imported0, Imported1);
+  EXPECT_EQ(DeclCounter().match(ToTU, Pattern), 1u);
+  auto To0 = FirstDeclMatcher().match(ToTU, Pattern);
+  EXPECT_TRUE(Imported0 == To0);
+  EXPECT_TRUE(To0->isThisDeclarationADefinition());
+}
+
+TEST_P(ImportClasses, ImportDefinitionThenPrototype) {
+  Decl *FromTU0 = getTuDecl("class X {};", Lang_CXX, "input0.cc");
+  Decl *FromTU1 = getTuDecl("class X;", Lang_CXX, "input1.cc");
+  auto Pattern = cxxRecordDecl(hasName("X"), unless(isImplicit()));
+  auto FromDef = FirstDeclMatcher().match(FromTU0, Pattern);
+  auto FromProto = FirstDeclMatcher().match(FromTU1, Pattern);
+
+  Decl *ImportedDef = Import(FromDef, Lang_CXX);
+  Decl *ImportedProto = Import(FromProto, Lang_CXX);
+  Decl *ToTU = ImportedDef->getTranslationUnitDecl();
+
+  EXPECT_NE(ImportedDef, ImportedProto);
+  EXPECT_EQ(DeclCounter().match(ToTU, Pattern), 2u);
+  auto ToDef = FirstDeclMatcher().match(ToTU, Pattern);
+  auto ToProto = LastDeclMatcher().match(ToTU, Pattern);
+  EXPECT_TRUE(ImportedDef == ToDef);
+  EXPECT_TRUE(ImportedProto == ToProto);
+  EXPECT_TRUE(ToDef->isThisDeclarationADefinition());
+  EXPECT_FALSE(ToProto->isThisDeclarationADefinition());
+  EXPECT_EQ(ToProto->getPreviousDecl(), ToDef);
+}
+
+TEST_P(ImportClasses, ImportPrototypeThenDefinition) {
+  Decl *FromTU0 = getTuDecl("class X;", Lang_CXX, "input0.cc");
+  Decl *FromTU1 = getTuDecl("class X {};", Lang_CXX, "input1.cc");
+  auto Pattern = cxxRecordDecl(hasName("X"), unless(isImplicit()));
+  auto FromProto = FirstDeclMatcher().match(FromTU0, Pattern);
+  auto FromDef = FirstDeclMatcher().match(FromTU1, Pattern);
+
+  Decl *ImportedProto = Import(FromProto, Lang_CXX);
+  Decl *ImportedDef = Import(FromDef, Lang_CXX);
+  Decl *ToTU = ImportedDef->getTranslationUnitDecl();
+
+  EXPECT_NE(ImportedDef, ImportedProto);
+  EXPECT_EQ(DeclCounter().match(ToTU, Pattern), 2u);
+  auto ToProto = FirstDeclMatcher().match(ToTU, Pattern);
+  auto ToDef = LastDeclMatcher().match(ToTU, Pattern);
+  EXPECT_TRUE(ImportedDef == ToDef);
+  EXPECT_TRUE(ImportedProto == ToProto);
+  EXPECT_TRUE(ToDef->isThisDeclarationADefinition());
+  EXPECT_FALSE(ToProto->isThisDeclarationADefinition());
+  EXPECT_EQ(ToDef->getPreviousDecl(), ToProto);
+}
+
+struct ImportClassTemplates : ASTImporterTestBase {};
+
+TEST_P(ImportClassTemplates,
+       PrototypeShouldBeImportedAsAPrototypeWhenThereIsNoDefinition) {
+  Decl *FromTU = getTuDecl("template  class X;", Lang_CXX);
+  auto Pattern = classTemplateDecl(hasName("X"), unless(isImplicit()));
+  auto FromD = FirstDeclMatcher().match(FromTU, Pattern);
+
+  Decl *ImportedD = Import(FromD, Lang_CXX);
+  Decl *ToTU = ImportedD->getTranslationUnitDecl();
+
+  EXPECT_EQ(DeclCounter().match(ToTU, Pattern), 1u);
+  auto ToD = LastDeclMatcher().match(ToTU, Pattern);
+  EXPECT_TRUE(ImportedD == ToD);
+  ASSERT_TRUE(ToD->getTemplatedDecl());
+  EXPECT_FALSE(ToD->isThisDeclarationADefinition());
+}
+
+TEST_P(ImportClassTemplates, ImportPrototypeAfterImportedPrototype) {
+  Decl *FromTU = getTuDecl(
+      "template  class X; template  class X;", Lang_CXX);
+  auto Pattern = classTemplateDecl(hasName("X"), unless(isImplicit()));
+  auto From0 = FirstDeclMatcher().match(FromTU, Pattern);
+  auto From1 = LastDeclMatcher().match(FromTU, Pattern);
+
+  Decl *Imported0 = Import(From0, Lang_CXX);
+  Decl *Imported1 = Import(From1, Lang_CXX);
+  Decl *ToTU = Imported0->getTranslationUnitDecl();
+
+  EXPECT_EQ(DeclCounter().match(ToTU, Pattern), 2u);
+  auto To0 = FirstDeclMatcher().match(ToTU, Pattern);
+  auto To1 = LastDeclMatcher().match(ToTU, Pattern);
+  EXPECT_TRUE(Imported0 == To0);
+  EXPECT_TRUE(Imported1 == To1);
+  ASSERT_TRUE(To0->getTemplatedDecl());
+  ASSERT_TRUE(To1->getTemplatedDecl());
+  EXPECT_FALSE(To0->isThisDeclarationADefinition());
+  EXPECT_FALSE(To1->isThisDeclarationADefinition());
+  EXPECT_EQ(To1->getPreviousDecl(), To0);
+  EXPECT_EQ(To1->getTemplatedDecl()->getPreviousDecl(),
+            To0->getTemplatedDecl());
+}
+
+TEST_P(ImportClassTemplates, DefinitionShouldBeImportedAsADefinition) {
+  Decl *FromTU = getTuDecl("template  class X {};", Lang_CXX);
+  auto Pattern = classTemplateDecl(hasName("X"), unless(isImplicit()));
+  auto *FromD = FirstDeclMatcher().match(FromTU, Pattern);
+
+  Decl *ImportedD = Import(FromD, Lang_CXX);
+  Decl *ToTU = ImportedD->getTranslationUnitDecl();
+
+  EXPECT_EQ(DeclCounter().match(ToTU, Pattern), 1u);
+  auto ToD = LastDeclMatcher().match(ToTU, Pattern);
+  ASSERT_TRUE(ToD->getTemplatedDecl());
+  EXPECT_TRUE(ToD->isThisDeclarationADefinition());
+}
+
+TEST_P(ImportClassTemplates,
+       ImportPrototypeFromDifferentTUAfterImportedPrototype) {
+  Decl *FromTU0 =
+      getTuDecl("template  class X;", Lang_CXX, "input0.cc");
+  Decl *FromTU1 =
+      getTuDecl("template  class X;", Lang_CXX, "input1.cc");
+  auto Pattern = classTemplateDecl(hasName("X"), unless(isImplicit()));
+  auto From0 = FirstDeclMatcher().match(FromTU0, Pattern);
+  auto From1 = FirstDeclMatcher().match(FromTU1, Pattern);
+
+  Decl *Imported0 = Import(From0, Lang_CXX);
+  Decl *Imported1 = Import(From1, Lang_CXX);
+  Decl *ToTU = Imported0->getTranslationUnitDecl();
+
+  EXPECT_EQ(DeclCounter().match(ToTU, Pattern), 2u);
+  auto To0 = FirstDeclMatcher().match(ToTU, Pattern);
+  auto To1 = LastDeclMatcher().match(ToTU, Pattern);
+  EXPECT_TRUE(Imported0 == To0);
+  EXPECT_TRUE(Imported1 == To1);
+  ASSERT_TRUE(To0->getTemplatedDecl());
+  ASSERT_TRUE(To1->getTemplatedDecl());
+  EXPECT_FALSE(To0->isThisDeclarationADefinition());
+  EXPECT_FALSE(To1->isThisDeclarationADefinition());
+  EXPECT_EQ(To1->getPreviousDecl(), To0);
+  EXPECT_EQ(To1->getTemplatedDecl()->getPreviousDecl(),
+            To0->getTemplatedDecl());
+}
+
+TEST_P(ImportClassTemplates, ImportDefinitions) {
+  Decl *FromTU0 =
+      getTuDecl("template  class X {};", Lang_CXX, "input0.cc");
+  Decl *FromTU1 =
+      getTuDecl("template  class X {};", Lang_CXX, "input1.cc");
+  auto Pattern = classTemplateDecl(hasName("X"), unless(isImplicit()));
+  auto From0 = FirstDeclMatcher().match(FromTU0, Pattern);
+  auto From1 = FirstDeclMatcher().match(FromTU1, Pattern);
+
+  Decl *Imported0 = Import(From0, Lang_CXX);
+  Decl *Imported1 = Import(From1, Lang_CXX);
+  Decl *ToTU = Imported0->getTranslationUnitDecl();
+
+  EXPECT_EQ(Imported0, Imported1);
+  EXPECT_EQ(DeclCounter().match(ToTU, Pattern), 1u);
+  auto To0 = FirstDeclMatcher().match(ToTU, Pattern);
+  EXPECT_TRUE(Imported0 == To0);
+  ASSERT_TRUE(To0->getTemplatedDecl());
+  EXPECT_TRUE(To0->isThisDeclarationADefinition());
+}
+
+TEST_P(ImportClassTemplates, ImportDefinitionThenPrototype) {
+  Decl *FromTU0 =
+      getTuDecl("template  class X {};", Lang_CXX, "input0.cc");
+  Decl *FromTU1 =
+      getTuDecl("template  class X;", Lang_CXX, "input1.cc");
+  auto Pattern = classTemplateDecl(hasName("X"), unless(isImplicit()));
+  auto FromDef = FirstDeclMatcher().match(FromTU0, Pattern);
+  auto FromProto =
+      FirstDeclMatcher().match(FromTU1, Pattern);
+
+  Decl *ImportedDef = Import(FromDef, Lang_CXX);
+  Decl *ImportedProto = Import(FromProto, Lang_CXX);
+  Decl *ToTU = ImportedDef->getTranslationUnitDecl();
+
+  EXPECT_NE(ImportedDef, ImportedProto);
+  EXPECT_EQ(DeclCounter().match(ToTU, Pattern), 2u);
+  auto ToDef = FirstDeclMatcher().match(ToTU, Pattern);
+  auto ToProto = LastDeclMatcher().match(ToTU, Pattern);
+  EXPECT_TRUE(ImportedDef == ToDef);
+  EXPECT_TRUE(ImportedProto == ToProto);
+  ASSERT_TRUE(ToDef->getTemplatedDecl());
+  ASSERT_TRUE(ToProto->getTemplatedDecl());
+  EXPECT_TRUE(ToDef->isThisDeclarationADefinition());
+  EXPECT_FALSE(ToProto->isThisDeclarationADefinition());
+  EXPECT_EQ(ToProto->getPreviousDecl(), ToDef);
+  EXPECT_EQ(ToProto->getTemplatedDecl()->getPreviousDecl(),
+            ToDef->getTemplatedDecl());
+}
+
+TEST_P(ImportClassTemplates, ImportPrototypeThenDefinition) {
+  Decl *FromTU0 =
+      getTuDecl("template  class X;", Lang_CXX, "input0.cc");
+  Decl *FromTU1 =
+      getTuDecl("template  class X {};", Lang_CXX, "input1.cc");
+  auto Pattern = classTemplateDecl(hasName("X"), unless(isImplicit()));
+  auto FromProto =
+      FirstDeclMatcher().match(FromTU0, Pattern);
+  auto FromDef = FirstDeclMatcher().match(FromTU1, Pattern);
+
+  Decl *ImportedProto = Import(FromProto, Lang_CXX);
+  Decl *ImportedDef = Import(FromDef, Lang_CXX);
+  Decl *ToTU = ImportedDef->getTranslationUnitDecl();
+
+  EXPECT_NE(ImportedDef, ImportedProto);
+  EXPECT_EQ(DeclCounter().match(ToTU, Pattern), 2u);
+  auto ToProto = FirstDeclMatcher().match(ToTU, Pattern);
+  auto ToDef = LastDeclMatcher().match(ToTU, Pattern);
+  EXPECT_TRUE(ImportedDef == ToDef);
+  EXPECT_TRUE(ImportedProto == ToProto);
+  ASSERT_TRUE(ToProto->getTemplatedDecl());
+  ASSERT_TRUE(ToDef->getTemplatedDecl());
+  EXPECT_TRUE(ToDef->isThisDeclarationADefinition());
+  EXPECT_FALSE(ToProto->isThisDeclarationADefinition());
+  EXPECT_EQ(ToDef->getPreviousDecl(), ToProto);
+  EXPECT_EQ(ToDef->getTemplatedDecl()->getPreviousDecl(),
+            ToProto->getTemplatedDecl());
+}
+
+struct ImportFriendClasses : ASTImporterTestBase {};
+
+TEST_P(ImportFriendClasses, ImportOfFriendRecordDoesNotMergeDefinition) {
+  Decl *FromTU = getTuDecl(
+      R"(
+      class A {
+        template  class F {};
+        class X {
+          template  friend class F;
+        };
+      };
+      )",
+      Lang_CXX, "input0.cc");
+
+  auto *FromClass = FirstDeclMatcher().match(
+      FromTU, cxxRecordDecl(hasName("F"), isDefinition()));
+  auto *FromFriendClass = LastDeclMatcher().match(
+      FromTU, cxxRecordDecl(hasName("F")));
+
+  ASSERT_TRUE(FromClass);
+  ASSERT_TRUE(FromFriendClass);
+  ASSERT_NE(FromClass, FromFriendClass);
+  ASSERT_EQ(FromFriendClass->getDefinition(), FromClass);
+  ASSERT_EQ(FromFriendClass->getPreviousDecl(), FromClass);
+  ASSERT_EQ(FromFriendClass->getDescribedClassTemplate()->getPreviousDecl(),
+            FromClass->getDescribedClassTemplate());
+
+  auto *ToClass = cast(Import(FromClass, Lang_CXX));
+  auto *ToFriendClass = cast(Import(FromFriendClass, Lang_CXX));
+
+  EXPECT_TRUE(ToClass);
+  EXPECT_TRUE(ToFriendClass);
+  EXPECT_NE(ToClass, ToFriendClass);
+  EXPECT_EQ(ToFriendClass->getDefinition(), ToClass);
+  EXPECT_EQ(ToFriendClass->getPreviousDecl(), ToClass);
+  EXPECT_EQ(ToFriendClass->getDescribedClassTemplate()->getPreviousDecl(),
+            ToClass->getDescribedClassTemplate());
+}
+
+TEST_P(ImportFriendClasses, ImportOfRecursiveFriendClass) {
+  Decl *FromTu = getTuDecl(
+      R"(
+      class declToImport {
+        friend class declToImport;
+      };
+      )",
+      Lang_CXX, "input.cc");
+
+  auto *FromD = FirstDeclMatcher().match(
+      FromTu, cxxRecordDecl(hasName("declToImport")));
+  auto *ToD = Import(FromD, Lang_CXX);
+  auto Pattern = cxxRecordDecl(has(friendDecl()));
+  ASSERT_TRUE(MatchVerifier{}.match(FromD, Pattern));
+  EXPECT_TRUE(MatchVerifier{}.match(ToD, Pattern));
+}
+
+TEST_P(ImportFriendClasses, ImportOfRecursiveFriendClassTemplate) {
+  Decl *FromTu = getTuDecl(
+      R"(
+      template class declToImport {
+        template friend class declToImport;
+      };
+      )",
+      Lang_CXX, "input.cc");
+
+  auto *FromD =
+      FirstDeclMatcher().match(FromTu, classTemplateDecl());
+  auto *ToD = Import(FromD, Lang_CXX);
+
+  auto Pattern = classTemplateDecl(
+      has(cxxRecordDecl(has(friendDecl(has(classTemplateDecl()))))));
+  ASSERT_TRUE(MatchVerifier{}.match(FromD, Pattern));
+  EXPECT_TRUE(MatchVerifier{}.match(ToD, Pattern));
+
+  auto *Class =
+      FirstDeclMatcher().match(ToD, classTemplateDecl());
+  auto *Friend = FirstDeclMatcher().match(ToD, friendDecl());
+  EXPECT_NE(Friend->getFriendDecl(), Class);
+  EXPECT_EQ(Friend->getFriendDecl()->getPreviousDecl(), Class);
+}
+
+TEST_P(ImportFriendClasses, ProperPrevDeclForClassTemplateDecls) {
+  auto Pattern = classTemplateSpecializationDecl(hasName("X"));
+
+  ClassTemplateSpecializationDecl *Imported1;
+  {
+    Decl *FromTU = getTuDecl("template class X;"
+                             "struct Y { friend class X; };",
+                             Lang_CXX, "input0.cc");
+    auto *FromD = FirstDeclMatcher().match(
+        FromTU, Pattern);
+
+    Imported1 = cast(Import(FromD, Lang_CXX));
+  }
+  ClassTemplateSpecializationDecl *Imported2;
+  {
+    Decl *FromTU = getTuDecl("template class X;"
+                             "template<> class X{};"
+                             "struct Z { friend class X; };",
+                             Lang_CXX, "input1.cc");
+    auto *FromD = FirstDeclMatcher().match(
+        FromTU, Pattern);
+
+    Imported2 = cast(Import(FromD, Lang_CXX));
+  }
+
+  Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
+  EXPECT_EQ(DeclCounter().match(ToTU, Pattern),
+            2u);
+  ASSERT_TRUE(Imported2->getPreviousDecl());
+  EXPECT_EQ(Imported2->getPreviousDecl(), Imported1);
+}
+
+TEST_P(ImportFriendClasses, TypeForDeclShouldBeSetInTemplated) {
+  Decl *FromTU0 = getTuDecl(
+      R"(
+      class X {
+        class Y;
+      };
+      class X::Y {
+        template 
+        friend class F; // The decl context of F is the global namespace.
+      };
+      )",
+      Lang_CXX, "input0.cc");
+  auto *Fwd = FirstDeclMatcher().match(
+      FromTU0, classTemplateDecl(hasName("F")));
+  auto *Imported0 = cast(Import(Fwd, Lang_CXX));
+  Decl *FromTU1 = getTuDecl(
+      R"(
+      template 
+      class F {};
+      )",
+      Lang_CXX, "input1.cc");
+  auto *Definition = FirstDeclMatcher().match(
+      FromTU1, classTemplateDecl(hasName("F")));
+  auto *Imported1 = cast(Import(Definition, Lang_CXX));
+  EXPECT_EQ(Imported0->getTemplatedDecl()->getTypeForDecl(),
+            Imported1->getTemplatedDecl()->getTypeForDecl());
+}
+
+TEST_P(ImportFriendClasses, DeclsFromFriendsShouldBeInRedeclChains) {
+  Decl *From, *To;
+  std::tie(From, To) =
+      getImportedDecl("class declToImport {};", Lang_CXX,
+                      "class Y { friend class declToImport; };", Lang_CXX);
+  auto *Imported = cast(To);
+
+  EXPECT_TRUE(Imported->getPreviousDecl());
+}
+
+TEST_P(ImportFriendClasses,
+       ImportOfClassTemplateDefinitionShouldConnectToFwdFriend) {
+  Decl *ToTU = getToTuDecl(
+      R"(
+      class X {
+        class Y;
+      };
+      class X::Y {
+        template 
+        friend class F; // The decl context of F is the global namespace.
+      };
+      )",
+      Lang_CXX);
+  auto *ToDecl = FirstDeclMatcher().match(
+      ToTU, classTemplateDecl(hasName("F")));
+  Decl *FromTU = getTuDecl(
+      R"(
+      template 
+      class F {};
+      )",
+      Lang_CXX, "input0.cc");
+  auto *Definition = FirstDeclMatcher().match(
+      FromTU, classTemplateDecl(hasName("F")));
+  auto *ImportedDef = cast(Import(Definition, Lang_CXX));
+  EXPECT_TRUE(ImportedDef->getPreviousDecl());
+  EXPECT_EQ(ToDecl, ImportedDef->getPreviousDecl());
+  EXPECT_EQ(ToDecl->getTemplatedDecl(),
+            ImportedDef->getTemplatedDecl()->getPreviousDecl());
+}
+
+TEST_P(ImportFriendClasses,
+       ImportOfClassTemplateDefinitionAndFwdFriendShouldBeLinked) {
+  Decl *FromTU0 = getTuDecl(
+      R"(
+      class X {
+        class Y;
+      };
+      class X::Y {
+        template 
+        friend class F; // The decl context of F is the global namespace.
+      };
+      )",
+      Lang_CXX, "input0.cc");
+  auto *Fwd = FirstDeclMatcher().match(
+      FromTU0, classTemplateDecl(hasName("F")));
+  auto *ImportedFwd = cast(Import(Fwd, Lang_CXX));
+  Decl *FromTU1 = getTuDecl(
+      R"(
+      template 
+      class F {};
+      )",
+      Lang_CXX, "input1.cc");
+  auto *Definition = FirstDeclMatcher().match(
+      FromTU1, classTemplateDecl(hasName("F")));
+  auto *ImportedDef = cast(Import(Definition, Lang_CXX));
+  EXPECT_TRUE(ImportedDef->getPreviousDecl());
+  EXPECT_EQ(ImportedFwd, ImportedDef->getPreviousDecl());
+  EXPECT_EQ(ImportedFwd->getTemplatedDecl(),
+            ImportedDef->getTemplatedDecl()->getPreviousDecl());
+}
+
+TEST_P(ImportFriendClasses, ImportOfClassDefinitionAndFwdFriendShouldBeLinked) {
+  Decl *FromTU0 = getTuDecl(
+      R"(
+      class X {
+        class Y;
+      };
+      class X::Y {
+        friend class F; // The decl context of F is the global namespace.
+      };
+      )",
+      Lang_CXX, "input0.cc");
+  auto *Friend = FirstDeclMatcher().match(FromTU0, friendDecl());
+  QualType FT = Friend->getFriendType()->getType();
+  FT = FromTU0->getASTContext().getCanonicalType(FT);
+  auto *Fwd = cast(FT)->getDecl();
+  auto *ImportedFwd = Import(Fwd, Lang_CXX);
+  Decl *FromTU1 = getTuDecl(
+      R"(
+      class F {};
+      )",
+      Lang_CXX, "input1.cc");
+  auto *Definition = FirstDeclMatcher().match(
+      FromTU1, cxxRecordDecl(hasName("F")));
+  auto *ImportedDef = Import(Definition, Lang_CXX);
+  EXPECT_TRUE(ImportedDef->getPreviousDecl());
+  EXPECT_EQ(ImportedFwd, ImportedDef->getPreviousDecl());
+}
+
 struct DeclContextTest : ASTImporterTestBase {};
 
 TEST_P(DeclContextTest, removeDeclOfClassTemplateSpecialization) {
@@ -3410,6 +3919,40 @@ TEST_P(DeclContextTest, removeDeclOfClassTemplateSpecialization) {
   EXPECT_FALSE(NS->containsDecl(Spec));
 }
 
+TEST_P(DeclContextTest,
+       removeDeclShouldNotFailEvenIfWeHaveExternalVisibleStorage) {
+  Decl *TU = getTuDecl("extern int A; int A;", Lang_CXX);
+  auto *A0 = FirstDeclMatcher().match(TU, varDecl(hasName("A")));
+  auto *A1 = LastDeclMatcher().match(TU, varDecl(hasName("A")));
+
+  // Investigate the list.
+  auto *DC = A0->getDeclContext();
+  ASSERT_TRUE(DC->containsDecl(A0));
+  ASSERT_TRUE(DC->containsDecl(A1));
+
+  // Investigate the lookup table.
+  auto *Map = DC->getLookupPtr();
+  ASSERT_TRUE(Map);
+  auto I = Map->find(A0->getDeclName());
+  ASSERT_NE(I, Map->end());
+  StoredDeclsList &L = I->second;
+  // The lookup table contains the most recent decl of A.
+  ASSERT_NE(L.getAsDecl(), A0);
+  ASSERT_EQ(L.getAsDecl(), A1);
+
+  ASSERT_TRUE(L.getAsDecl());
+  // Simulate the private function DeclContext::reconcileExternalVisibleStorage.
+  // The point here is to have a Vec with only one element, which is not the
+  // one we are going to delete from the DC later.
+  L.setHasExternalDecls();
+  ASSERT_TRUE(L.getAsVector());
+  ASSERT_EQ(1u, L.getAsVector()->size());
+
+  // This asserts in the old implementation.
+  DC->removeDecl(A0);
+  EXPECT_FALSE(DC->containsDecl(A0));
+}
+
 struct ImportFunctionTemplateSpecializations : ASTImporterTestBase {};
 
 TEST_P(ImportFunctionTemplateSpecializations,
@@ -3827,6 +4370,15 @@ INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportFunctions,
 INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportFriendFunctions,
                         DefaultTestValuesForRunOptions, );
 
+INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportClasses,
+                        DefaultTestValuesForRunOptions, );
+
+INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportClassTemplates,
+                        DefaultTestValuesForRunOptions, );
+
+INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportFriendClasses,
+                        DefaultTestValuesForRunOptions, );
+
 INSTANTIATE_TEST_CASE_P(ParameterizedTests,
                         ImportFunctionTemplateSpecializations,
                         DefaultTestValuesForRunOptions, );
diff --git a/unittests/AST/StructuralEquivalenceTest.cpp b/unittests/AST/StructuralEquivalenceTest.cpp
index 7ff7736d4c..cd1f01d4bf 100644
--- a/unittests/AST/StructuralEquivalenceTest.cpp
+++ b/unittests/AST/StructuralEquivalenceTest.cpp
@@ -597,6 +597,77 @@ TEST_F(StructuralEquivalenceRecordTest, UnnamedRecordsShouldBeInequivalent) {
   EXPECT_FALSE(testStructuralMatch(R0, R1));
 }
 
+TEST_F(StructuralEquivalenceRecordTest, AnonymousRecordsShouldBeInequivalent) {
+  auto t = makeTuDecls(
+      R"(
+      struct X {
+        struct {
+          int a;
+        };
+        struct {
+          int b;
+        };
+      };
+      )",
+      "", Lang_C);
+  auto *TU = get<0>(t);
+  auto *A = FirstDeclMatcher().match(
+      TU, indirectFieldDecl(hasName("a")));
+  auto *FA = cast(A->chain().front());
+  RecordDecl *RA = cast(FA->getType().getTypePtr())->getDecl();
+  auto *B = FirstDeclMatcher().match(
+      TU, indirectFieldDecl(hasName("b")));
+  auto *FB = cast(B->chain().front());
+  RecordDecl *RB = cast(FB->getType().getTypePtr())->getDecl();
+
+  ASSERT_NE(RA, RB);
+  EXPECT_TRUE(testStructuralMatch(RA, RA));
+  EXPECT_TRUE(testStructuralMatch(RB, RB));
+  EXPECT_FALSE(testStructuralMatch(RA, RB));
+}
+
+TEST_F(StructuralEquivalenceRecordTest,
+       RecordsAreInequivalentIfOrderOfAnonRecordsIsDifferent) {
+  auto t = makeTuDecls(
+      R"(
+      struct X {
+        struct { int a; };
+        struct { int b; };
+      };
+      )",
+      R"(
+      struct X { // The order is reversed.
+        struct { int b; };
+        struct { int a; };
+      };
+      )",
+      Lang_C);
+
+  auto *TU = get<0>(t);
+  auto *A = FirstDeclMatcher().match(
+      TU, indirectFieldDecl(hasName("a")));
+  auto *FA = cast(A->chain().front());
+  RecordDecl *RA = cast(FA->getType().getTypePtr())->getDecl();
+
+  auto *TU1 = get<1>(t);
+  auto *A1 = FirstDeclMatcher().match(
+      TU1, indirectFieldDecl(hasName("a")));
+  auto *FA1 = cast(A1->chain().front());
+  RecordDecl *RA1 = cast(FA1->getType().getTypePtr())->getDecl();
+
+  RecordDecl *X =
+      FirstDeclMatcher().match(TU, recordDecl(hasName("X")));
+  RecordDecl *X1 =
+      FirstDeclMatcher().match(TU1, recordDecl(hasName("X")));
+  ASSERT_NE(X, X1);
+  EXPECT_FALSE(testStructuralMatch(X, X1));
+
+  ASSERT_NE(RA, RA1);
+  EXPECT_TRUE(testStructuralMatch(RA, RA));
+  EXPECT_TRUE(testStructuralMatch(RA1, RA1));
+  EXPECT_FALSE(testStructuralMatch(RA1, RA));
+}
+
 TEST_F(StructuralEquivalenceRecordTest,
        UnnamedRecordsShouldBeInequivalentEvenIfTheSecondIsBeingDefined) {
   auto Code =
-- 
cgit v1.2.3


From 564948e9bfee36801861b039545836737080cd35 Mon Sep 17 00:00:00 2001
From: Gabor Marton 
Date: Mon, 17 Dec 2018 13:53:12 +0000
Subject: [ASTImporter] Add importer specific lookup

Summary:
There are certain cases when normal C/C++ lookup (localUncachedLookup)
does not find AST nodes. E.g.:

Example 1:

  template 
  struct X {
    friend void foo(); // this is never found in the DC of the TU.
  };

Example 2:

  // The fwd decl to Foo is not found in the lookupPtr of the DC of the
  // translation unit decl.
  struct A { struct Foo *p; };

In these cases we create a new node instead of returning with the old one.
To fix it we create a new lookup table which holds every node and we are
not interested in any C++ specific visibility considerations.
Simply, we must know if there is an existing Decl in a given DC.

Reviewers: a_sidorin, a.sidorin

Subscribers: mgorny, rnkovacs, dkrupp, Szelethus, cfe-commits

Differential Revision: https://reviews.llvm.org/D53708

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349351 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/AST/ASTImporter.h              |  25 +-
 include/clang/AST/ASTImporterLookupTable.h   |  75 ++++
 include/clang/CrossTU/CrossTranslationUnit.h |   3 +
 lib/AST/ASTImporter.cpp                      | 176 ++++----
 lib/AST/ASTImporterLookupTable.cpp           | 129 ++++++
 lib/AST/CMakeLists.txt                       |   1 +
 lib/CrossTU/CrossTranslationUnit.cpp         |  13 +-
 lib/Frontend/ASTMerge.cpp                    |  11 +-
 unittests/AST/ASTImporterTest.cpp            | 579 +++++++++++++++++++++++++--
 9 files changed, 888 insertions(+), 124 deletions(-)
 create mode 100644 include/clang/AST/ASTImporterLookupTable.h
 create mode 100644 lib/AST/ASTImporterLookupTable.cpp

diff --git a/include/clang/AST/ASTImporter.h b/include/clang/AST/ASTImporter.h
index cbd5c3414b..dbb9cf35dd 100644
--- a/include/clang/AST/ASTImporter.h
+++ b/include/clang/AST/ASTImporter.h
@@ -33,6 +33,7 @@
 namespace clang {
 
 class ASTContext;
+class ASTImporterLookupTable;
 class CXXBaseSpecifier;
 class CXXCtorInitializer;
 class Decl;
@@ -80,12 +81,21 @@ class Attr;
   /// Imports selected nodes from one AST context into another context,
   /// merging AST nodes where appropriate.
   class ASTImporter {
+    friend class ASTNodeImporter;
   public:
     using NonEquivalentDeclSet = llvm::DenseSet>;
     using ImportedCXXBaseSpecifierMap =
         llvm::DenseMap;
 
   private:
+
+    /// Pointer to the import specific lookup table, which may be shared
+    /// amongst several ASTImporter objects.
+    /// This is an externally managed resource (and should exist during the
+    /// lifetime of the ASTImporter object)
+    /// If not set then the original C/C++ lookup is used.
+    ASTImporterLookupTable *LookupTable = nullptr;
+
     /// The contexts we're importing to and from.
     ASTContext &ToContext, &FromContext;
 
@@ -123,9 +133,13 @@ class Attr;
     /// (which we have already complained about).
     NonEquivalentDeclSet NonEquivalentDecls;
 
+    using FoundDeclsTy = SmallVector;
+    FoundDeclsTy findDeclsInToCtx(DeclContext *DC, DeclarationName Name);
+
+    void AddToLookupTable(Decl *ToD);
+
   public:
-    /// Create a new AST importer.
-    ///
+
     /// \param ToContext The context we'll be importing into.
     ///
     /// \param ToFileManager The file manager we'll be importing into.
@@ -137,9 +151,14 @@ class Attr;
     /// \param MinimalImport If true, the importer will attempt to import
     /// as little as it can, e.g., by importing declarations as forward
     /// declarations that can be completed at a later point.
+    ///
+    /// \param LookupTable The importer specific lookup table which may be
+    /// shared amongst several ASTImporter objects.
+    /// If not set then the original C/C++ lookup is used.
     ASTImporter(ASTContext &ToContext, FileManager &ToFileManager,
                 ASTContext &FromContext, FileManager &FromFileManager,
-                bool MinimalImport);
+                bool MinimalImport,
+                ASTImporterLookupTable *LookupTable = nullptr);
 
     virtual ~ASTImporter();
 
diff --git a/include/clang/AST/ASTImporterLookupTable.h b/include/clang/AST/ASTImporterLookupTable.h
new file mode 100644
index 0000000000..14cafe817d
--- /dev/null
+++ b/include/clang/AST/ASTImporterLookupTable.h
@@ -0,0 +1,75 @@
+//===- ASTImporterLookupTable.h - ASTImporter specific lookup--*- C++ -*---===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the ASTImporterLookupTable class which implements a
+//  lookup procedure for the import mechanism.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_ASTIMPORTERLOOKUPTABLE_H
+#define LLVM_CLANG_AST_ASTIMPORTERLOOKUPTABLE_H
+
+#include "clang/AST/DeclBase.h" // lookup_result
+#include "clang/AST/DeclarationName.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SetVector.h"
+
+namespace clang {
+
+class ASTContext;
+class NamedDecl;
+class DeclContext;
+
+// There are certain cases when normal C/C++ lookup (localUncachedLookup)
+// does not find AST nodes. E.g.:
+// Example 1:
+//   template 
+//   struct X {
+//     friend void foo(); // this is never found in the DC of the TU.
+//   };
+// Example 2:
+//   // The fwd decl to Foo is not found in the lookupPtr of the DC of the
+//   // translation unit decl.
+//   // Here we could find the node by doing a traverse throught the list of
+//   // the Decls in the DC, but that would not scale.
+//   struct A { struct Foo *p; };
+// This is a severe problem because the importer decides if it has to create a
+// new Decl or not based on the lookup results.
+// To overcome these cases we need an importer specific lookup table which
+// holds every node and we are not interested in any C/C++ specific visibility
+// considerations. Simply, we must know if there is an existing Decl in a
+// given DC. Once we found it then we can handle any visibility related tasks.
+class ASTImporterLookupTable {
+
+  // We store a list of declarations for each name.
+  // And we collect these lists for each DeclContext.
+  // We could have a flat map with (DeclContext, Name) tuple as key, but a two
+  // level map seems easier to handle.
+  using DeclList = llvm::SmallSetVector;
+  using NameMap = llvm::SmallDenseMap;
+  using DCMap = llvm::DenseMap;
+
+  void add(DeclContext *DC, NamedDecl *ND);
+  void remove(DeclContext *DC, NamedDecl *ND);
+
+  DCMap LookupTable;
+
+public:
+  ASTImporterLookupTable(TranslationUnitDecl &TU);
+  void add(NamedDecl *ND);
+  void remove(NamedDecl *ND);
+  using LookupResult = DeclList;
+  LookupResult lookup(DeclContext *DC, DeclarationName Name) const;
+  void dump(DeclContext *DC) const;
+  void dump() const;
+};
+
+} // namespace clang
+
+#endif // LLVM_CLANG_AST_ASTIMPORTERLOOKUPTABLE_H
diff --git a/include/clang/CrossTU/CrossTranslationUnit.h b/include/clang/CrossTU/CrossTranslationUnit.h
index b5371a6de7..a5cec7e05e 100644
--- a/include/clang/CrossTU/CrossTranslationUnit.h
+++ b/include/clang/CrossTU/CrossTranslationUnit.h
@@ -15,6 +15,7 @@
 #ifndef LLVM_CLANG_CROSSTU_CROSSTRANSLATIONUNIT_H
 #define LLVM_CLANG_CROSSTU_CROSSTRANSLATIONUNIT_H
 
+#include "clang/AST/ASTImporterLookupTable.h"
 #include "clang/Basic/LLVM.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/SmallPtrSet.h"
@@ -152,6 +153,7 @@ public:
   void emitCrossTUDiagnostics(const IndexError &IE);
 
 private:
+  void lazyInitLookupTable(TranslationUnitDecl *ToTU);
   ASTImporter &getOrCreateASTImporter(ASTContext &From);
   const FunctionDecl *findFunctionInDeclContext(const DeclContext *DC,
                                                 StringRef LookupFnName);
@@ -163,6 +165,7 @@ private:
       ASTUnitImporterMap;
   CompilerInstance &CI;
   ASTContext &Context;
+  std::unique_ptr LookupTable;
 };
 
 } // namespace cross_tu
diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp
index c67990cfcf..6a893c5035 100644
--- a/lib/AST/ASTImporter.cpp
+++ b/lib/AST/ASTImporter.cpp
@@ -13,6 +13,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/AST/ASTImporter.h"
+#include "clang/AST/ASTImporterLookupTable.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/ASTDiagnostic.h"
 #include "clang/AST/ASTStructuralEquivalence.h"
@@ -134,28 +135,6 @@ namespace clang {
       To->setIsUsed();
   }
 
-  Optional ASTImporter::getFieldIndex(Decl *F) {
-    assert(F && (isa(*F) || isa(*F)) &&
-        "Try to get field index for non-field.");
-
-    auto *Owner = dyn_cast(F->getDeclContext());
-    if (!Owner)
-      return None;
-
-    unsigned Index = 0;
-    for (const auto *D : Owner->decls()) {
-      if (D == F)
-        return Index;
-
-      if (isa(*D) || isa(*D))
-        ++Index;
-    }
-
-    llvm_unreachable("Field was not found in its parent context.");
-
-    return None;
-  }
-
   // FIXME: Temporary until every import returns Expected.
   template <>
   LLVM_NODISCARD Error
@@ -313,12 +292,14 @@ namespace clang {
       if (ToD)
         return true; // Already imported.
       ToD = CreateFun(std::forward(args)...);
+      // Keep track of imported Decls.
+      Importer.MapImported(FromD, ToD);
+      Importer.AddToLookupTable(ToD);
       InitializeImportedDecl(FromD, ToD);
       return false; // A new Decl is created.
     }
 
     void InitializeImportedDecl(Decl *FromD, Decl *ToD) {
-      Importer.MapImported(FromD, ToD);
       ToD->IdentifierNamespace = FromD->IdentifierNamespace;
       if (FromD->hasAttrs())
         for (const Attr *FromAttr : FromD->getAttrs())
@@ -2198,8 +2179,7 @@ ExpectedDecl ASTNodeImporter::VisitNamespaceDecl(NamespaceDecl *D) {
       MergeWithNamespace = cast(DC)->getAnonymousNamespace();
   } else {
     SmallVector ConflictingDecls;
-    SmallVector FoundDecls;
-    DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
+    auto FoundDecls = Importer.findDeclsInToCtx(DC, Name);
     for (auto *FoundDecl : FoundDecls) {
       if (!FoundDecl->isInIdentifierNamespace(Decl::IDNS_Namespace))
         continue;
@@ -2310,8 +2290,7 @@ ASTNodeImporter::VisitTypedefNameDecl(TypedefNameDecl *D, bool IsAlias) {
   if (!DC->isFunctionOrMethod()) {
     SmallVector ConflictingDecls;
     unsigned IDNS = Decl::IDNS_Ordinary;
-    SmallVector FoundDecls;
-    DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
+    auto FoundDecls = Importer.findDeclsInToCtx(DC, Name);
     for (auto *FoundDecl : FoundDecls) {
       if (!FoundDecl->isInIdentifierNamespace(IDNS))
         continue;
@@ -2399,8 +2378,7 @@ ASTNodeImporter::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
   if (!DC->isFunctionOrMethod()) {
     SmallVector ConflictingDecls;
     unsigned IDNS = Decl::IDNS_Ordinary;
-    SmallVector FoundDecls;
-    DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
+    auto FoundDecls = Importer.findDeclsInToCtx(DC, Name);
     for (auto *FoundDecl : FoundDecls) {
       if (!FoundDecl->isInIdentifierNamespace(IDNS))
         continue;
@@ -2502,8 +2480,8 @@ ExpectedDecl ASTNodeImporter::VisitEnumDecl(EnumDecl *D) {
   // We may already have an enum of the same name; try to find and match it.
   if (!DC->isFunctionOrMethod() && SearchName) {
     SmallVector ConflictingDecls;
-    SmallVector FoundDecls;
-    DC->getRedeclContext()->localUncachedLookup(SearchName, FoundDecls);
+    auto FoundDecls =
+        Importer.findDeclsInToCtx(DC, SearchName);
     for (auto *FoundDecl : FoundDecls) {
       if (!FoundDecl->isInIdentifierNamespace(IDNS))
         continue;
@@ -2615,9 +2593,8 @@ ExpectedDecl ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
   RecordDecl *PrevDecl = nullptr;
   if (!DC->isFunctionOrMethod()) {
     SmallVector ConflictingDecls;
-    SmallVector FoundDecls;
-    DC->getRedeclContext()->localUncachedLookup(SearchName, FoundDecls);
-
+    auto FoundDecls =
+        Importer.findDeclsInToCtx(DC, SearchName);
     if (!FoundDecls.empty()) {
       // We're going to have to compare D against potentially conflicting Decls, so complete it.
       if (D->hasExternalLexicalStorage() && !D->isCompleteDefinition())
@@ -2634,15 +2611,6 @@ ExpectedDecl ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
           Found = Tag->getDecl();
       }
 
-      if (D->getDescribedTemplate()) {
-        if (auto *Template = dyn_cast(Found)) {
-          Found = Template->getTemplatedDecl();
-        } else {
-          ConflictingDecls.push_back(FoundDecl);
-          continue;
-        }
-      }
-
       if (auto *FoundRecord = dyn_cast(Found)) {
         // Do not emit false positive diagnostic in case of unnamed
         // struct/union and in case of anonymous structs.  Would be false
@@ -2838,8 +2806,7 @@ ExpectedDecl ASTNodeImporter::VisitEnumConstantDecl(EnumConstantDecl *D) {
   if (!LexicalDC->isFunctionOrMethod()) {
     SmallVector ConflictingDecls;
     unsigned IDNS = Decl::IDNS_Ordinary;
-    SmallVector FoundDecls;
-    DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
+    auto FoundDecls = Importer.findDeclsInToCtx(DC, Name);
     for (auto *FoundDecl : FoundDecls) {
       if (!FoundDecl->isInIdentifierNamespace(IDNS))
         continue;
@@ -3005,9 +2972,9 @@ ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
   FunctionTemplateDecl *FromFT = D->getDescribedFunctionTemplate();
 
   // If this is a function template specialization, then try to find the same
-  // existing specialization in the "to" context. The localUncachedLookup
-  // below will not find any specialization, but would find the primary
-  // template; thus, we have to skip normal lookup in case of specializations.
+  // existing specialization in the "to" context. The lookup below will not
+  // find any specialization, but would find the primary template; thus, we
+  // have to skip normal lookup in case of specializations.
   // FIXME handle member function templates (TK_MemberSpecialization) similarly?
   if (D->getTemplatedKind() ==
       FunctionDecl::TK_FunctionTemplateSpecialization) {
@@ -3025,20 +2992,11 @@ ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
   else if (!LexicalDC->isFunctionOrMethod()) {
     SmallVector ConflictingDecls;
     unsigned IDNS = Decl::IDNS_Ordinary | Decl::IDNS_OrdinaryFriend;
-    SmallVector FoundDecls;
-    DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
+    auto FoundDecls = Importer.findDeclsInToCtx(DC, Name);
     for (auto *FoundDecl : FoundDecls) {
       if (!FoundDecl->isInIdentifierNamespace(IDNS))
         continue;
 
-      // If template was found, look at the templated function.
-      if (FromFT) {
-        if (auto *Template = dyn_cast(FoundDecl))
-          FoundDecl = Template->getTemplatedDecl();
-        else
-          continue;
-      }
-
       if (auto *FoundFunction = dyn_cast(FoundDecl)) {
         if (FoundFunction->hasExternalFormalLinkage() &&
             D->hasExternalFormalLinkage()) {
@@ -3299,8 +3257,7 @@ ExpectedDecl ASTNodeImporter::VisitFieldDecl(FieldDecl *D) {
     return ToD;
 
   // Determine whether we've already imported this field.
-  SmallVector FoundDecls;
-  DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
+  auto FoundDecls = Importer.findDeclsInToCtx(DC, Name);
   for (auto *FoundDecl : FoundDecls) {
     if (FieldDecl *FoundField = dyn_cast(FoundDecl)) {
       // For anonymous fields, match up by index.
@@ -3385,8 +3342,7 @@ ExpectedDecl ASTNodeImporter::VisitIndirectFieldDecl(IndirectFieldDecl *D) {
     return ToD;
 
   // Determine whether we've already imported this field.
-  SmallVector FoundDecls;
-  DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
+  auto FoundDecls = Importer.findDeclsInToCtx(DC, Name);
   for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
     if (auto *FoundField = dyn_cast(FoundDecls[I])) {
       // For anonymous indirect fields, match up by index.
@@ -3454,7 +3410,7 @@ ExpectedDecl ASTNodeImporter::VisitFriendDecl(FriendDecl *D) {
     return std::move(Err);
 
   // Determine whether we've already imported this decl.
-  // FriendDecl is not a NamedDecl so we cannot use localUncachedLookup.
+  // FriendDecl is not a NamedDecl so we cannot use lookup.
   auto *RD = cast(DC);
   FriendDecl *ImportedFriend = RD->getFirstFriend();
 
@@ -3532,8 +3488,7 @@ ExpectedDecl ASTNodeImporter::VisitObjCIvarDecl(ObjCIvarDecl *D) {
     return ToD;
 
   // Determine whether we've already imported this ivar
-  SmallVector FoundDecls;
-  DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
+  auto FoundDecls = Importer.findDeclsInToCtx(DC, Name);
   for (auto *FoundDecl : FoundDecls) {
     if (ObjCIvarDecl *FoundIvar = dyn_cast(FoundDecl)) {
       if (Importer.IsStructurallyEquivalent(D->getType(),
@@ -3603,8 +3558,7 @@ ExpectedDecl ASTNodeImporter::VisitVarDecl(VarDecl *D) {
   if (D->isFileVarDecl()) {
     SmallVector ConflictingDecls;
     unsigned IDNS = Decl::IDNS_Ordinary;
-    SmallVector FoundDecls;
-    DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
+    auto FoundDecls = Importer.findDeclsInToCtx(DC, Name);
     for (auto *FoundDecl : FoundDecls) {
       if (!FoundDecl->isInIdentifierNamespace(IDNS))
         continue;
@@ -3814,8 +3768,7 @@ ExpectedDecl ASTNodeImporter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
   if (ToD)
     return ToD;
 
-  SmallVector FoundDecls;
-  DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
+  auto FoundDecls = Importer.findDeclsInToCtx(DC, Name);
   for (auto *FoundDecl : FoundDecls) {
     if (auto *FoundMethod = dyn_cast(FoundDecl)) {
       if (FoundMethod->isInstanceMethod() != D->isInstanceMethod())
@@ -4122,8 +4075,7 @@ ExpectedDecl ASTNodeImporter::VisitObjCProtocolDecl(ObjCProtocolDecl *D) {
     return ToD;
 
   ObjCProtocolDecl *MergeWithProtocol = nullptr;
-  SmallVector FoundDecls;
-  DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
+  auto FoundDecls = Importer.findDeclsInToCtx(DC, Name);
   for (auto *FoundDecl : FoundDecls) {
     if (!FoundDecl->isInIdentifierNamespace(Decl::IDNS_ObjCProtocol))
       continue;
@@ -4548,8 +4500,7 @@ ExpectedDecl ASTNodeImporter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
 
   // Look for an existing interface with the same name.
   ObjCInterfaceDecl *MergeWithIface = nullptr;
-  SmallVector FoundDecls;
-  DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
+  auto FoundDecls = Importer.findDeclsInToCtx(DC, Name);
   for (auto *FoundDecl : FoundDecls) {
     if (!FoundDecl->isInIdentifierNamespace(Decl::IDNS_Ordinary))
       continue;
@@ -4724,8 +4675,7 @@ ExpectedDecl ASTNodeImporter::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
     return ToD;
 
   // Check whether we have already imported this property.
-  SmallVector FoundDecls;
-  DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
+  auto FoundDecls = Importer.findDeclsInToCtx(DC, Name);
   for (auto *FoundDecl : FoundDecls) {
     if (auto *FoundProp = dyn_cast(FoundDecl)) {
       // Check property types.
@@ -4995,8 +4945,7 @@ ExpectedDecl ASTNodeImporter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
   // We may already have a template of the same name; try to find and match it.
   if (!DC->isFunctionOrMethod()) {
     SmallVector ConflictingDecls;
-    SmallVector FoundDecls;
-    DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
+    auto FoundDecls = Importer.findDeclsInToCtx(DC, Name);
     for (auto *FoundDecl : FoundDecls) {
       if (!FoundDecl->isInIdentifierNamespace(Decl::IDNS_Ordinary |
                                               Decl::IDNS_TagFriend))
@@ -5304,8 +5253,7 @@ ExpectedDecl ASTNodeImporter::VisitVarTemplateDecl(VarTemplateDecl *D) {
   assert(!DC->isFunctionOrMethod() &&
          "Variable templates cannot be declared at function scope");
   SmallVector ConflictingDecls;
-  SmallVector FoundDecls;
-  DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
+  auto FoundDecls = Importer.findDeclsInToCtx(DC, Name);
   for (auto *FoundDecl : FoundDecls) {
     if (!FoundDecl->isInIdentifierNamespace(Decl::IDNS_Ordinary))
       continue;
@@ -5537,8 +5485,7 @@ ASTNodeImporter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
   // type, and in the same context as the function we're importing.
   if (!LexicalDC->isFunctionOrMethod()) {
     unsigned IDNS = Decl::IDNS_Ordinary;
-    SmallVector FoundDecls;
-    DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
+    auto FoundDecls = Importer.findDeclsInToCtx(DC, Name);
     for (auto *FoundDecl : FoundDecls) {
       if (!FoundDecl->isInIdentifierNamespace(IDNS))
         continue;
@@ -7666,12 +7613,14 @@ void ASTNodeImporter::ImportOverrides(CXXMethodDecl *ToMethod,
 
 ASTImporter::ASTImporter(ASTContext &ToContext, FileManager &ToFileManager,
                          ASTContext &FromContext, FileManager &FromFileManager,
-                         bool MinimalImport)
-    : ToContext(ToContext), FromContext(FromContext),
+                         bool MinimalImport,
+                         ASTImporterLookupTable *LookupTable)
+    : LookupTable(LookupTable), ToContext(ToContext), FromContext(FromContext),
       ToFileManager(ToFileManager), FromFileManager(FromFileManager),
       Minimal(MinimalImport) {
-  ImportedDecls[FromContext.getTranslationUnitDecl()]
-    = ToContext.getTranslationUnitDecl();
+
+  ImportedDecls[FromContext.getTranslationUnitDecl()] =
+      ToContext.getTranslationUnitDecl();
 }
 
 ASTImporter::~ASTImporter() = default;
@@ -7682,6 +7631,58 @@ Expected ASTImporter::Import_New(QualType FromT) {
     return make_error();
   return ToT;
 }
+
+Optional ASTImporter::getFieldIndex(Decl *F) {
+  assert(F && (isa(*F) || isa(*F)) &&
+      "Try to get field index for non-field.");
+
+  auto *Owner = dyn_cast(F->getDeclContext());
+  if (!Owner)
+    return None;
+
+  unsigned Index = 0;
+  for (const auto *D : Owner->decls()) {
+    if (D == F)
+      return Index;
+
+    if (isa(*D) || isa(*D))
+      ++Index;
+  }
+
+  llvm_unreachable("Field was not found in its parent context.");
+
+  return None;
+}
+
+ASTImporter::FoundDeclsTy
+ASTImporter::findDeclsInToCtx(DeclContext *DC, DeclarationName Name) {
+  // We search in the redecl context because of transparent contexts.
+  // E.g. a simple C language enum is a transparent context:
+  //   enum E { A, B };
+  // Now if we had a global variable in the TU
+  //   int A;
+  // then the enum constant 'A' and the variable 'A' violates ODR.
+  // We can diagnose this only if we search in the redecl context.
+  DeclContext *ReDC = DC->getRedeclContext();
+  if (LookupTable) {
+    ASTImporterLookupTable::LookupResult LookupResult =
+        LookupTable->lookup(ReDC, Name);
+    return FoundDeclsTy(LookupResult.begin(), LookupResult.end());
+  } else {
+    // FIXME Can we remove this kind of lookup?
+    // Or lldb really needs this C/C++ lookup?
+    FoundDeclsTy Result;
+    ReDC->localUncachedLookup(Name, Result);
+    return Result;
+  }
+}
+
+void ASTImporter::AddToLookupTable(Decl *ToD) {
+  if (LookupTable)
+    if (auto *ToND = dyn_cast(ToD))
+      LookupTable->add(ToND);
+}
+
 QualType ASTImporter::Import(QualType FromT) {
   if (FromT.isNull())
     return {};
@@ -7774,6 +7775,11 @@ Decl *ASTImporter::Import(Decl *FromD) {
   }
   ToD = *ToDOrErr;
 
+  // Once the decl is connected to the existing declarations, i.e. when the
+  // redecl chain is properly set then we populate the lookup again.
+  // This way the primary context will be able to find all decls.
+  AddToLookupTable(ToD);
+
   // Notify subclasses.
   Imported(FromD, ToD);
 
diff --git a/lib/AST/ASTImporterLookupTable.cpp b/lib/AST/ASTImporterLookupTable.cpp
new file mode 100644
index 0000000000..fbcd4f5cb3
--- /dev/null
+++ b/lib/AST/ASTImporterLookupTable.cpp
@@ -0,0 +1,129 @@
+//===- ASTImporterLookupTable.cpp - ASTImporter specific lookup -----------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the ASTImporterLookupTable class which implements a
+//  lookup procedure for the import mechanism.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/ASTImporterLookupTable.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/RecursiveASTVisitor.h"
+
+namespace clang {
+
+namespace {
+
+struct Builder : RecursiveASTVisitor {
+  ASTImporterLookupTable <
+  Builder(ASTImporterLookupTable <) : LT(LT) {}
+  bool VisitNamedDecl(NamedDecl *D) {
+    LT.add(D);
+    return true;
+  }
+  bool VisitFriendDecl(FriendDecl *D) {
+    if (D->getFriendType()) {
+      QualType Ty = D->getFriendType()->getType();
+      // FIXME Can this be other than elaborated?
+      QualType NamedTy = cast(Ty)->getNamedType();
+      if (!NamedTy->isDependentType()) {
+        if (const auto *RTy = dyn_cast(NamedTy))
+          LT.add(RTy->getAsCXXRecordDecl());
+        else if (const auto *SpecTy =
+                     dyn_cast(NamedTy)) {
+          LT.add(SpecTy->getAsCXXRecordDecl());
+        }
+      }
+    }
+    return true;
+  }
+
+  // Override default settings of base.
+  bool shouldVisitTemplateInstantiations() const { return true; }
+  bool shouldVisitImplicitCode() const { return true; }
+};
+
+} // anonymous namespace
+
+ASTImporterLookupTable::ASTImporterLookupTable(TranslationUnitDecl &TU) {
+  Builder B(*this);
+  B.TraverseDecl(&TU);
+}
+
+void ASTImporterLookupTable::add(DeclContext *DC, NamedDecl *ND) {
+  DeclList &Decls = LookupTable[DC][ND->getDeclName()];
+  // Inserts if and only if there is no element in the container equal to it.
+  Decls.insert(ND);
+}
+
+void ASTImporterLookupTable::remove(DeclContext *DC, NamedDecl *ND) {
+  DeclList &Decls = LookupTable[DC][ND->getDeclName()];
+  bool EraseResult = Decls.remove(ND);
+  (void)EraseResult;
+  assert(EraseResult == true && "Trying to remove not contained Decl");
+}
+
+void ASTImporterLookupTable::add(NamedDecl *ND) {
+  assert(ND);
+  DeclContext *DC = ND->getDeclContext()->getPrimaryContext();
+  add(DC, ND);
+  DeclContext *ReDC = DC->getRedeclContext()->getPrimaryContext();
+  if (DC != ReDC)
+    add(ReDC, ND);
+}
+
+void ASTImporterLookupTable::remove(NamedDecl *ND) {
+  assert(ND);
+  DeclContext *DC = ND->getDeclContext()->getPrimaryContext();
+  remove(DC, ND);
+  DeclContext *ReDC = DC->getRedeclContext()->getPrimaryContext();
+  if (DC != ReDC)
+    remove(ReDC, ND);
+}
+
+ASTImporterLookupTable::LookupResult
+ASTImporterLookupTable::lookup(DeclContext *DC, DeclarationName Name) const {
+  auto DCI = LookupTable.find(DC->getPrimaryContext());
+  if (DCI == LookupTable.end())
+    return {};
+
+  const auto &FoundNameMap = DCI->second;
+  auto NamesI = FoundNameMap.find(Name);
+  if (NamesI == FoundNameMap.end())
+    return {};
+
+  return NamesI->second;
+}
+
+void ASTImporterLookupTable::dump(DeclContext *DC) const {
+  auto DCI = LookupTable.find(DC->getPrimaryContext());
+  if (DCI == LookupTable.end())
+    llvm::errs() << "empty\n";
+  const auto &FoundNameMap = DCI->second;
+  for (const auto &Entry : FoundNameMap) {
+    DeclarationName Name = Entry.first;
+    llvm::errs() << "==== Name: ";
+    Name.dump();
+    const DeclList& List = Entry.second;
+    for (NamedDecl *ND : List) {
+      ND->dump();
+    }
+  }
+}
+
+void ASTImporterLookupTable::dump() const {
+  for (const auto &Entry : LookupTable) {
+    DeclContext *DC = Entry.first;
+    StringRef Primary = DC->getPrimaryContext() ? " primary" : "";
+    llvm::errs() << "== DC:" << cast(DC) << Primary << "\n";
+    dump(DC);
+  }
+}
+
+} // namespace clang
diff --git a/lib/AST/CMakeLists.txt b/lib/AST/CMakeLists.txt
index adeb9f7e64..570ca718ac 100644
--- a/lib/AST/CMakeLists.txt
+++ b/lib/AST/CMakeLists.txt
@@ -10,6 +10,7 @@ add_clang_library(clangAST
   ASTDiagnostic.cpp
   ASTDumper.cpp
   ASTImporter.cpp
+  ASTImporterLookupTable.cpp
   ASTStructuralEquivalence.cpp
   ASTTypeTraits.cpp
   AttrImpl.cpp
diff --git a/lib/CrossTU/CrossTranslationUnit.cpp b/lib/CrossTU/CrossTranslationUnit.cpp
index 5286b90f93..6ee329c2b5 100644
--- a/lib/CrossTU/CrossTranslationUnit.cpp
+++ b/lib/CrossTU/CrossTranslationUnit.cpp
@@ -342,14 +342,21 @@ CrossTranslationUnitContext::importDefinition(const FunctionDecl *FD) {
   return ToDecl;
 }
 
+void CrossTranslationUnitContext::lazyInitLookupTable(
+    TranslationUnitDecl *ToTU) {
+  if (!LookupTable)
+    LookupTable = llvm::make_unique(*ToTU);
+}
+
 ASTImporter &
 CrossTranslationUnitContext::getOrCreateASTImporter(ASTContext &From) {
   auto I = ASTUnitImporterMap.find(From.getTranslationUnitDecl());
   if (I != ASTUnitImporterMap.end())
     return *I->second;
-  ASTImporter *NewImporter =
-      new ASTImporter(Context, Context.getSourceManager().getFileManager(),
-                      From, From.getSourceManager().getFileManager(), false);
+  lazyInitLookupTable(Context.getTranslationUnitDecl());
+  ASTImporter *NewImporter = new ASTImporter(
+      Context, Context.getSourceManager().getFileManager(), From,
+      From.getSourceManager().getFileManager(), false, LookupTable.get());
   ASTUnitImporterMap[From.getTranslationUnitDecl()].reset(NewImporter);
   return *NewImporter;
 }
diff --git a/lib/Frontend/ASTMerge.cpp b/lib/Frontend/ASTMerge.cpp
index 2434113ab0..4f622da118 100644
--- a/lib/Frontend/ASTMerge.cpp
+++ b/lib/Frontend/ASTMerge.cpp
@@ -10,6 +10,7 @@
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/ASTDiagnostic.h"
 #include "clang/AST/ASTImporter.h"
+#include "clang/AST/ASTImporterLookupTable.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Frontend/FrontendActions.h"
@@ -38,6 +39,8 @@ void ASTMergeAction::ExecuteAction() {
                                        &CI.getASTContext());
   IntrusiveRefCntPtr
       DiagIDs(CI.getDiagnostics().getDiagnosticIDs());
+  ASTImporterLookupTable LookupTable(
+      *CI.getASTContext().getTranslationUnitDecl());
   for (unsigned I = 0, N = ASTFiles.size(); I != N; ++I) {
     IntrusiveRefCntPtr
         Diags(new DiagnosticsEngine(DiagIDs, &CI.getDiagnosticOpts(),
@@ -51,11 +54,9 @@ void ASTMergeAction::ExecuteAction() {
     if (!Unit)
       continue;
 
-    ASTImporter Importer(CI.getASTContext(),
-                         CI.getFileManager(),
-                         Unit->getASTContext(),
-                         Unit->getFileManager(),
-                         /*MinimalImport=*/false);
+    ASTImporter Importer(CI.getASTContext(), CI.getFileManager(),
+                         Unit->getASTContext(), Unit->getFileManager(),
+                         /*MinimalImport=*/false, &LookupTable);
 
     TranslationUnitDecl *TU = Unit->getASTContext().getTranslationUnitDecl();
     for (auto *D : TU->decls()) {
diff --git a/unittests/AST/ASTImporterTest.cpp b/unittests/AST/ASTImporterTest.cpp
index 3407f7da6d..aaadeb0b9d 100644
--- a/unittests/AST/ASTImporterTest.cpp
+++ b/unittests/AST/ASTImporterTest.cpp
@@ -15,6 +15,8 @@
 #include "MatchVerifier.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclContextInternals.h"
+#include "clang/AST/ASTImporter.h"
+#include "clang/AST/ASTImporterLookupTable.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
 #include "clang/ASTMatchers/ASTMatchers.h"
 #include "clang/Tooling/Tooling.h"
@@ -308,24 +310,27 @@ class ASTImporterTestBase : public ParameterizedTestsFixture {
       Unit->enableSourceFileDiagnostics();
     }
 
-    void lazyInitImporter(ASTUnit *ToAST) {
+    void lazyInitImporter(ASTImporterLookupTable &LookupTable, ASTUnit *ToAST) {
       assert(ToAST);
       if (!Importer) {
-        Importer.reset(new ASTImporter(
-            ToAST->getASTContext(), ToAST->getFileManager(),
-            Unit->getASTContext(), Unit->getFileManager(), false));
+        Importer.reset(
+            new ASTImporter(ToAST->getASTContext(), ToAST->getFileManager(),
+                            Unit->getASTContext(), Unit->getFileManager(),
+                            false, &LookupTable));
       }
       assert(&ToAST->getASTContext() == &Importer->getToContext());
       createVirtualFileIfNeeded(ToAST, FileName, Code);
     }
 
-    Decl *import(ASTUnit *ToAST, Decl *FromDecl) {
-      lazyInitImporter(ToAST);
+    Decl *import(ASTImporterLookupTable &LookupTable, ASTUnit *ToAST,
+                 Decl *FromDecl) {
+      lazyInitImporter(LookupTable, ToAST);
       return Importer->Import(FromDecl);
-     }
+    }
 
-    QualType import(ASTUnit *ToAST, QualType FromType) {
-      lazyInitImporter(ToAST);
+    QualType import(ASTImporterLookupTable &LookupTable, ASTUnit *ToAST,
+                    QualType FromType) {
+      lazyInitImporter(LookupTable, ToAST);
       return Importer->Import(FromType);
     }
   };
@@ -339,13 +344,23 @@ class ASTImporterTestBase : public ParameterizedTestsFixture {
   // vector is expanding, with the list we won't have these issues.
   std::list FromTUs;
 
-  void lazyInitToAST(Language ToLang) {
+  // Initialize the lookup table if not initialized already.
+  void lazyInitLookupTable(TranslationUnitDecl *ToTU) {
+    assert(ToTU);
+    if (!LookupTablePtr)
+      LookupTablePtr = llvm::make_unique(*ToTU);
+  }
+
+  void lazyInitToAST(Language ToLang, StringRef ToSrcCode, StringRef FileName) {
     if (ToAST)
       return;
     ArgVector ToArgs = getArgVectorForLanguage(ToLang);
+    // Source code must be a valid live buffer through the tests lifetime.
+    ToCode = ToSrcCode;
     // Build the AST from an empty file.
-    ToAST = tooling::buildASTFromCodeWithArgs(/*Code=*/"", ToArgs, "empty.cc");
+    ToAST = tooling::buildASTFromCodeWithArgs(ToCode, ToArgs, FileName);
     ToAST->enableSourceFileDiagnostics();
+    lazyInitLookupTable(ToAST->getASTContext().getTranslationUnitDecl());
   }
 
   TU *findFromTU(Decl *From) {
@@ -359,6 +374,10 @@ class ASTImporterTestBase : public ParameterizedTestsFixture {
     return &*It;
   }
 
+protected:
+
+  std::unique_ptr LookupTablePtr;
+
 public:
   // We may have several From context but only one To context.
   std::unique_ptr ToAST;
@@ -375,26 +394,23 @@ public:
     FromTUs.emplace_back(FromSrcCode, InputFileName, FromArgs);
     TU &FromTU = FromTUs.back();
 
-    ToCode = ToSrcCode;
     assert(!ToAST);
-    ToAST = tooling::buildASTFromCodeWithArgs(ToCode, ToArgs, OutputFileName);
-    ToAST->enableSourceFileDiagnostics();
+    lazyInitToAST(ToLang, ToSrcCode, OutputFileName);
 
     ASTContext &FromCtx = FromTU.Unit->getASTContext();
 
-    createVirtualFileIfNeeded(ToAST.get(), InputFileName, FromTU.Code);
-
     IdentifierInfo *ImportedII = &FromCtx.Idents.get(Identifier);
     assert(ImportedII && "Declaration with the given identifier "
                          "should be specified in test!");
     DeclarationName ImportDeclName(ImportedII);
-    SmallVector FoundDecls;
+    SmallVector FoundDecls;
     FromCtx.getTranslationUnitDecl()->localUncachedLookup(ImportDeclName,
                                                           FoundDecls);
 
     assert(FoundDecls.size() == 1);
 
-    Decl *Imported = FromTU.import(ToAST.get(), FoundDecls.front());
+    Decl *Imported =
+        FromTU.import(*LookupTablePtr, ToAST.get(), FoundDecls.front());
 
     assert(Imported);
     return std::make_tuple(*FoundDecls.begin(), Imported);
@@ -420,11 +436,8 @@ public:
   // Creates the To context with the given source code and returns the TU decl.
   TranslationUnitDecl *getToTuDecl(StringRef ToSrcCode, Language ToLang) {
     ArgVector ToArgs = getArgVectorForLanguage(ToLang);
-    ToCode = ToSrcCode;
     assert(!ToAST);
-    ToAST = tooling::buildASTFromCodeWithArgs(ToCode, ToArgs, OutputFileName);
-    ToAST->enableSourceFileDiagnostics();
-
+    lazyInitToAST(ToLang, ToSrcCode, OutputFileName);
     return ToAST->getASTContext().getTranslationUnitDecl();
   }
 
@@ -432,15 +445,17 @@ public:
   // May be called several times in a given test.
   // The different instances of the param From may have different ASTContext.
   Decl *Import(Decl *From, Language ToLang) {
-    lazyInitToAST(ToLang);
+    lazyInitToAST(ToLang, "", OutputFileName);
     TU *FromTU = findFromTU(From);
-    return FromTU->import(ToAST.get(), From);
+    assert(LookupTablePtr);
+    return FromTU->import(*LookupTablePtr, ToAST.get(), From);
   }
 
   QualType ImportType(QualType FromType, Decl *TUDecl, Language ToLang) {
-    lazyInitToAST(ToLang);
+    lazyInitToAST(ToLang, "", OutputFileName);
     TU *FromTU = findFromTU(TUDecl);
-    return FromTU->import(ToAST.get(), FromType);
+    assert(LookupTablePtr);
+    return FromTU->import(*LookupTablePtr, ToAST.get(), FromType);
    }
 
   ~ASTImporterTestBase() {
@@ -2727,6 +2742,7 @@ private:
       CXXMethodDecl *Method =
           FirstDeclMatcher().match(ToClass, MethodMatcher);
       ToClass->removeDecl(Method);
+      LookupTablePtr->remove(Method);
     }
 
     ASSERT_EQ(DeclCounter().match(ToClass, MethodMatcher), 0u);
@@ -3486,6 +3502,82 @@ TEST_P(ImportClasses, ImportPrototypeThenDefinition) {
   EXPECT_EQ(ToDef->getPreviousDecl(), ToProto);
 }
 
+TEST_P(ImportClasses, ImportDefinitionWhenProtoIsInToContext) {
+  Decl *ToTU = getToTuDecl("struct X;", Lang_C);
+  Decl *FromTU1 = getTuDecl("struct X {};", Lang_C, "input1.cc");
+  auto Pattern = recordDecl(hasName("X"), unless(isImplicit()));
+  auto ToProto = FirstDeclMatcher().match(ToTU, Pattern);
+  auto FromDef = FirstDeclMatcher().match(FromTU1, Pattern);
+
+  Decl *ImportedDef = Import(FromDef, Lang_C);
+
+  EXPECT_NE(ImportedDef, ToProto);
+  EXPECT_EQ(DeclCounter().match(ToTU, Pattern), 2u);
+  auto ToDef = LastDeclMatcher().match(ToTU, Pattern);
+  EXPECT_TRUE(ImportedDef == ToDef);
+  EXPECT_TRUE(ToDef->isThisDeclarationADefinition());
+  EXPECT_FALSE(ToProto->isThisDeclarationADefinition());
+  EXPECT_EQ(ToDef->getPreviousDecl(), ToProto);
+}
+
+TEST_P(ImportClasses, ImportDefinitionWhenProtoIsInNestedToContext) {
+  Decl *ToTU = getToTuDecl("struct A { struct X *Xp; };", Lang_C);
+  Decl *FromTU1 = getTuDecl("struct X {};", Lang_C, "input1.cc");
+  auto Pattern = recordDecl(hasName("X"), unless(isImplicit()));
+  auto ToProto = FirstDeclMatcher().match(ToTU, Pattern);
+  auto FromDef = FirstDeclMatcher().match(FromTU1, Pattern);
+
+  Decl *ImportedDef = Import(FromDef, Lang_C);
+
+  EXPECT_NE(ImportedDef, ToProto);
+  EXPECT_EQ(DeclCounter().match(ToTU, Pattern), 2u);
+  auto ToDef = LastDeclMatcher().match(ToTU, Pattern);
+  EXPECT_TRUE(ImportedDef == ToDef);
+  EXPECT_TRUE(ToDef->isThisDeclarationADefinition());
+  EXPECT_FALSE(ToProto->isThisDeclarationADefinition());
+  EXPECT_EQ(ToDef->getPreviousDecl(), ToProto);
+}
+
+TEST_P(ImportClasses, ImportDefinitionWhenProtoIsInNestedToContextCXX) {
+  Decl *ToTU = getToTuDecl("struct A { struct X *Xp; };", Lang_CXX);
+  Decl *FromTU1 = getTuDecl("struct X {};", Lang_CXX, "input1.cc");
+  auto Pattern = recordDecl(hasName("X"), unless(isImplicit()));
+  auto ToProto = FirstDeclMatcher().match(ToTU, Pattern);
+  auto FromDef = FirstDeclMatcher().match(FromTU1, Pattern);
+
+  Decl *ImportedDef = Import(FromDef, Lang_CXX);
+
+  EXPECT_NE(ImportedDef, ToProto);
+  EXPECT_EQ(DeclCounter().match(ToTU, Pattern), 2u);
+  auto ToDef = LastDeclMatcher().match(ToTU, Pattern);
+  EXPECT_TRUE(ImportedDef == ToDef);
+  EXPECT_TRUE(ToDef->isThisDeclarationADefinition());
+  EXPECT_FALSE(ToProto->isThisDeclarationADefinition());
+  EXPECT_EQ(ToDef->getPreviousDecl(), ToProto);
+}
+
+TEST_P(ImportClasses, ImportNestedPrototypeThenDefinition) {
+  Decl *FromTU0 = getTuDecl("struct A { struct X *Xp; };", Lang_C, "input0.cc");
+  Decl *FromTU1 = getTuDecl("struct X {};", Lang_C, "input1.cc");
+  auto Pattern = recordDecl(hasName("X"), unless(isImplicit()));
+  auto FromProto = FirstDeclMatcher().match(FromTU0, Pattern);
+  auto FromDef = FirstDeclMatcher().match(FromTU1, Pattern);
+
+  Decl *ImportedProto = Import(FromProto, Lang_C);
+  Decl *ImportedDef = Import(FromDef, Lang_C);
+  Decl *ToTU = ImportedDef->getTranslationUnitDecl();
+
+  EXPECT_NE(ImportedDef, ImportedProto);
+  EXPECT_EQ(DeclCounter().match(ToTU, Pattern), 2u);
+  auto ToProto = FirstDeclMatcher().match(ToTU, Pattern);
+  auto ToDef = LastDeclMatcher().match(ToTU, Pattern);
+  EXPECT_TRUE(ImportedDef == ToDef);
+  EXPECT_TRUE(ImportedProto == ToProto);
+  EXPECT_TRUE(ToDef->isThisDeclarationADefinition());
+  EXPECT_FALSE(ToProto->isThisDeclarationADefinition());
+  EXPECT_EQ(ToDef->getPreviousDecl(), ToProto);
+}
+
 struct ImportClassTemplates : ASTImporterTestBase {};
 
 TEST_P(ImportClassTemplates,
@@ -3890,6 +3982,24 @@ TEST_P(ImportFriendClasses, ImportOfClassDefinitionAndFwdFriendShouldBeLinked) {
   EXPECT_EQ(ImportedFwd, ImportedDef->getPreviousDecl());
 }
 
+TEST_P(ASTImporterTestBase, FriendFunInClassTemplate) {
+  auto *Code = R"(
+  template 
+  struct X {
+    friend void foo(){}
+  };
+      )";
+  TranslationUnitDecl *ToTU = getToTuDecl(Code, Lang_CXX);
+  auto *ToFoo = FirstDeclMatcher().match(
+      ToTU, functionDecl(hasName("foo")));
+
+  TranslationUnitDecl *FromTU = getTuDecl(Code, Lang_CXX, "input.cc");
+  auto *FromFoo = FirstDeclMatcher().match(
+      FromTU, functionDecl(hasName("foo")));
+  auto *ImportedFoo = Import(FromFoo, Lang_CXX);
+  EXPECT_EQ(ImportedFoo, ToFoo);
+}
+
 struct DeclContextTest : ASTImporterTestBase {};
 
 TEST_P(DeclContextTest, removeDeclOfClassTemplateSpecialization) {
@@ -4339,6 +4449,416 @@ TEST_P(ASTImporterTestBase, ImportingTypedefShouldImportTheCompleteType) {
   EXPECT_FALSE(ImportedD->getUnderlyingType()->isIncompleteType());
 }
 
+struct ASTImporterLookupTableTest : ASTImporterTestBase {};
+
+TEST_P(ASTImporterLookupTableTest, OneDecl) {
+  auto *ToTU = getToTuDecl("int a;", Lang_CXX);
+  auto *D = FirstDeclMatcher().match(ToTU, varDecl(hasName("a")));
+  ASTImporterLookupTable LT(*ToTU);
+  auto Res = LT.lookup(ToTU, D->getDeclName());
+  ASSERT_EQ(Res.size(), 1u);
+  EXPECT_EQ(*Res.begin(), D);
+}
+
+static Decl *findInDeclListOfDC(DeclContext *DC, DeclarationName Name) {
+  for (Decl *D : DC->decls()) {
+    if (auto *ND = dyn_cast(D))
+      if (ND->getDeclName() == Name)
+        return ND;
+  }
+  return nullptr;
+};
+
+TEST_P(ASTImporterLookupTableTest,
+    FriendWhichIsnotFoundByNormalLookupShouldBeFoundByImporterSpecificLookup) {
+  auto *Code = R"(
+  template 
+  struct X {
+    friend void foo(){}
+  };
+      )";
+  TranslationUnitDecl *ToTU = getToTuDecl(Code, Lang_CXX);
+  auto *X = FirstDeclMatcher().match(
+      ToTU, classTemplateDecl(hasName("X")));
+  auto *Foo = FirstDeclMatcher().match(
+      ToTU, functionDecl(hasName("foo")));
+  DeclContext *FooDC = Foo->getDeclContext();
+  DeclContext *FooLexicalDC = Foo->getLexicalDeclContext();
+  ASSERT_EQ(cast(FooLexicalDC), X->getTemplatedDecl());
+  ASSERT_EQ(cast(FooDC), ToTU);
+  DeclarationName FooName = Foo->getDeclName();
+
+  // Cannot find in the LookupTable of its DC (TUDecl)
+  SmallVector FoundDecls;
+  FooDC->getRedeclContext()->localUncachedLookup(FooName, FoundDecls);
+  EXPECT_EQ(FoundDecls.size(), 0u);
+
+  // Cannot find in the LookupTable of its LexicalDC (X)
+  FooLexicalDC->getRedeclContext()->localUncachedLookup(FooName, FoundDecls);
+  EXPECT_EQ(FoundDecls.size(), 0u);
+
+  // Can't find in the list of Decls of the DC.
+  EXPECT_EQ(findInDeclListOfDC(FooDC, FooName), nullptr);
+
+  // Can't find in the list of Decls of the LexicalDC
+  EXPECT_EQ(findInDeclListOfDC(FooLexicalDC, FooName), nullptr);
+
+  // ASTImporter specific lookup finds it.
+  ASTImporterLookupTable LT(*ToTU);
+  auto Res = LT.lookup(FooDC, Foo->getDeclName());
+  ASSERT_EQ(Res.size(), 1u);
+  EXPECT_EQ(*Res.begin(), Foo);
+}
+
+TEST_P(ASTImporterLookupTableTest,
+       FwdDeclStructShouldBeFoundByImporterSpecificLookup) {
+  TranslationUnitDecl *ToTU =
+      getToTuDecl("struct A { struct Foo *p; };", Lang_C);
+  auto *Foo =
+      FirstDeclMatcher().match(ToTU, recordDecl(hasName("Foo")));
+  auto *A =
+      FirstDeclMatcher().match(ToTU, recordDecl(hasName("A")));
+  DeclContext *FooDC = Foo->getDeclContext();
+  DeclContext *FooLexicalDC = Foo->getLexicalDeclContext();
+  ASSERT_EQ(cast(FooLexicalDC), A);
+  ASSERT_EQ(cast(FooDC), ToTU);
+  DeclarationName FooName = Foo->getDeclName();
+
+  // Cannot find in the LookupTable of its DC (TUDecl).
+  SmallVector FoundDecls;
+  FooDC->getRedeclContext()->localUncachedLookup(FooName, FoundDecls);
+  EXPECT_EQ(FoundDecls.size(), 0u);
+
+  // Cannot find in the LookupTable of its LexicalDC (A).
+  FooLexicalDC->getRedeclContext()->localUncachedLookup(FooName, FoundDecls);
+  EXPECT_EQ(FoundDecls.size(), 0u);
+
+  // Can't find in the list of Decls of the DC.
+  EXPECT_EQ(findInDeclListOfDC(FooDC, FooName), nullptr);
+
+  // Can find in the list of Decls of the LexicalDC.
+  EXPECT_EQ(findInDeclListOfDC(FooLexicalDC, FooName), Foo);
+
+  // ASTImporter specific lookup finds it.
+  ASTImporterLookupTable LT(*ToTU);
+  auto Res = LT.lookup(FooDC, Foo->getDeclName());
+  ASSERT_EQ(Res.size(), 1u);
+  EXPECT_EQ(*Res.begin(), Foo);
+}
+
+TEST_P(ASTImporterLookupTableTest, LookupFindsNamesInDifferentDC) {
+  TranslationUnitDecl *ToTU =
+      getToTuDecl("int V; struct A { int V; }; struct B { int V; };", Lang_C);
+  DeclarationName VName = FirstDeclMatcher()
+                              .match(ToTU, varDecl(hasName("V")))
+                              ->getDeclName();
+  auto *A =
+      FirstDeclMatcher().match(ToTU, recordDecl(hasName("A")));
+  auto *B =
+      FirstDeclMatcher().match(ToTU, recordDecl(hasName("B")));
+
+  ASTImporterLookupTable LT(*ToTU);
+
+  auto Res = LT.lookup(cast(A), VName);
+  ASSERT_EQ(Res.size(), 1u);
+  EXPECT_EQ(*Res.begin(), FirstDeclMatcher().match(
+                        ToTU, fieldDecl(hasName("V"),
+                                        hasParent(recordDecl(hasName("A"))))));
+  Res = LT.lookup(cast(B), VName);
+  ASSERT_EQ(Res.size(), 1u);
+  EXPECT_EQ(*Res.begin(), FirstDeclMatcher().match(
+                        ToTU, fieldDecl(hasName("V"),
+                                        hasParent(recordDecl(hasName("B"))))));
+  Res = LT.lookup(ToTU, VName);
+  ASSERT_EQ(Res.size(), 1u);
+  EXPECT_EQ(*Res.begin(), FirstDeclMatcher().match(
+                        ToTU, varDecl(hasName("V"),
+                                        hasParent(translationUnitDecl()))));
+}
+
+TEST_P(ASTImporterLookupTableTest, LookupFindsOverloadedNames) {
+  TranslationUnitDecl *ToTU = getToTuDecl(
+      R"(
+      void foo();
+      void foo(int);
+      void foo(int, int);
+      )",
+      Lang_CXX);
+
+  ASTImporterLookupTable LT(*ToTU);
+  auto *F0 = FirstDeclMatcher().match(ToTU, functionDecl());
+  auto *F2 = LastDeclMatcher().match(ToTU, functionDecl());
+  DeclarationName Name = F0->getDeclName();
+  auto Res = LT.lookup(ToTU, Name);
+  EXPECT_EQ(Res.size(), 3u);
+  EXPECT_EQ(Res.count(F0), 1u);
+  EXPECT_EQ(Res.count(F2), 1u);
+}
+
+static const RecordDecl * getRecordDeclOfFriend(FriendDecl *FD) {
+  QualType Ty = FD->getFriendType()->getType();
+  QualType NamedTy = cast(Ty)->getNamedType();
+  return cast(NamedTy)->getDecl();
+}
+
+TEST_P(ASTImporterLookupTableTest, LookupFindsFwdFriendClassDecl) {
+  TranslationUnitDecl *ToTU = getToTuDecl(
+      R"(
+      class Y { friend class F; };
+      )",
+      Lang_CXX);
+
+  // In this case, the CXXRecordDecl is hidden, the FriendDecl is not a parent.
+  // So we must dig up the underlying CXXRecordDecl.
+  ASTImporterLookupTable LT(*ToTU);
+  auto *FriendD = FirstDeclMatcher().match(ToTU, friendDecl());
+  const RecordDecl *RD = getRecordDeclOfFriend(FriendD);
+  auto *Y = FirstDeclMatcher().match(
+      ToTU, cxxRecordDecl(hasName("Y")));
+
+  DeclarationName Name = RD->getDeclName();
+  auto Res = LT.lookup(ToTU, Name);
+  EXPECT_EQ(Res.size(), 1u);
+  EXPECT_EQ(*Res.begin(), RD);
+
+  Res = LT.lookup(Y, Name);
+  EXPECT_EQ(Res.size(), 0u);
+}
+
+TEST_P(ASTImporterLookupTableTest, LookupFindsFwdFriendClassTemplateDecl) {
+  TranslationUnitDecl *ToTU = getToTuDecl(
+      R"(
+      class Y { template  friend class F; };
+      )",
+      Lang_CXX);
+
+  ASTImporterLookupTable LT(*ToTU);
+  auto *F = FirstDeclMatcher().match(
+      ToTU, classTemplateDecl(hasName("F")));
+  DeclarationName Name = F->getDeclName();
+  auto Res = LT.lookup(ToTU, Name);
+  EXPECT_EQ(Res.size(), 2u);
+  EXPECT_EQ(Res.count(F), 1u);
+  EXPECT_EQ(Res.count(F->getTemplatedDecl()), 1u);
+}
+
+TEST_P(ASTImporterLookupTableTest, DependentFriendClass) {
+  TranslationUnitDecl *ToTU = getToTuDecl(
+      R"(
+      template 
+      class F;
+
+      template 
+      class Y {
+        friend class F;
+      };
+      )",
+      Lang_CXX);
+
+  ASTImporterLookupTable LT(*ToTU);
+  auto *F = FirstDeclMatcher().match(
+      ToTU, classTemplateDecl(hasName("F")));
+  DeclarationName Name = F->getDeclName();
+  auto Res = LT.lookup(ToTU, Name);
+  EXPECT_EQ(Res.size(), 2u);
+  EXPECT_EQ(Res.count(F), 1u);
+  EXPECT_EQ(Res.count(F->getTemplatedDecl()), 1u);
+}
+
+TEST_P(ASTImporterLookupTableTest, FriendClassTemplateSpecialization) {
+  TranslationUnitDecl *ToTU = getToTuDecl(
+      R"(
+      template 
+      class F;
+
+      class Y {
+        friend class F;
+      };
+      )",
+      Lang_CXX);
+
+  ASTImporterLookupTable LT(*ToTU);
+  auto *F = FirstDeclMatcher().match(
+      ToTU, classTemplateDecl(hasName("F")));
+  DeclarationName Name = F->getDeclName();
+  auto Res = LT.lookup(ToTU, Name);
+  ASSERT_EQ(Res.size(), 3u);
+  EXPECT_EQ(Res.count(F), 1u);
+  EXPECT_EQ(Res.count(F->getTemplatedDecl()), 1u);
+  EXPECT_EQ(Res.count(*F->spec_begin()), 1u);
+}
+
+TEST_P(ASTImporterLookupTableTest, LookupFindsFwdFriendFunctionDecl) {
+  TranslationUnitDecl *ToTU = getToTuDecl(
+      R"(
+      class Y { friend void F(); };
+      )",
+      Lang_CXX);
+
+  ASTImporterLookupTable LT(*ToTU);
+  auto *F =
+      FirstDeclMatcher().match(ToTU, functionDecl(hasName("F")));
+  DeclarationName Name = F->getDeclName();
+  auto Res = LT.lookup(ToTU, Name);
+  EXPECT_EQ(Res.size(), 1u);
+  EXPECT_EQ(*Res.begin(), F);
+}
+
+TEST_P(ASTImporterLookupTableTest,
+       LookupFindsDeclsInClassTemplateSpecialization) {
+  TranslationUnitDecl *ToTU = getToTuDecl(
+      R"(
+      template 
+      struct X {
+        int F;
+      };
+      void foo() {
+        X xc;
+      }
+      )",
+      Lang_CXX);
+
+  ASTImporterLookupTable LT(*ToTU);
+
+  auto *Template = FirstDeclMatcher().match(
+      ToTU, classTemplateDecl(hasName("X")));
+  auto *FieldInTemplate = FirstDeclMatcher().match(
+      ToTU,
+      fieldDecl(hasParent(cxxRecordDecl(hasParent(classTemplateDecl())))));
+
+  auto *Spec = FirstDeclMatcher().match(
+      ToTU, classTemplateSpecializationDecl(hasName("X")));
+  FieldDecl *FieldInSpec = *Spec->field_begin();
+  ASSERT_TRUE(FieldInSpec);
+
+  DeclarationName Name = FieldInSpec->getDeclName();
+  auto TemplateDC = cast(Template->getTemplatedDecl());
+
+  SmallVector FoundDecls;
+  TemplateDC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
+  EXPECT_EQ(FoundDecls.size(), 1u);
+  EXPECT_EQ(FoundDecls[0], FieldInTemplate);
+
+  auto Res = LT.lookup(TemplateDC, Name);
+  ASSERT_EQ(Res.size(), 1u);
+  EXPECT_EQ(*Res.begin(), FieldInTemplate);
+
+  cast(Spec)->getRedeclContext()->localUncachedLookup(Name,
+                                                                   FoundDecls);
+  EXPECT_EQ(FoundDecls.size(), 1u);
+  EXPECT_EQ(FoundDecls[0], FieldInSpec);
+
+  Res = LT.lookup(cast(Spec), Name);
+  ASSERT_EQ(Res.size(), 1u);
+  EXPECT_EQ(*Res.begin(), FieldInSpec);
+}
+
+TEST_P(ASTImporterLookupTableTest, LookupFindsFwdFriendFunctionTemplateDecl) {
+  TranslationUnitDecl *ToTU = getToTuDecl(
+      R"(
+      class Y { template  friend void F(); };
+      )",
+      Lang_CXX);
+
+  ASTImporterLookupTable LT(*ToTU);
+  auto *F = FirstDeclMatcher().match(
+      ToTU, functionTemplateDecl(hasName("F")));
+  DeclarationName Name = F->getDeclName();
+  auto Res = LT.lookup(ToTU, Name);
+  EXPECT_EQ(Res.size(), 2u);
+  EXPECT_EQ(Res.count(F), 1u);
+  EXPECT_EQ(Res.count(F->getTemplatedDecl()), 1u);
+}
+
+TEST_P(ASTImporterLookupTableTest, MultipleBefriendingClasses) {
+  TranslationUnitDecl *ToTU = getToTuDecl(
+      R"(
+      struct X;
+      struct A {
+        friend struct X;
+      };
+      struct B {
+        friend struct X;
+      };
+      )",
+      Lang_CXX);
+
+  ASTImporterLookupTable LT(*ToTU);
+  auto *X = FirstDeclMatcher().match(
+      ToTU, cxxRecordDecl(hasName("X")));
+  auto *FriendD0 = FirstDeclMatcher().match(ToTU, friendDecl());
+  auto *FriendD1 = LastDeclMatcher().match(ToTU, friendDecl());
+  const RecordDecl *RD0 = getRecordDeclOfFriend(FriendD0);
+  const RecordDecl *RD1 = getRecordDeclOfFriend(FriendD1);
+  ASSERT_EQ(RD0, RD1);
+  ASSERT_EQ(RD1, X);
+
+  DeclarationName Name = X->getDeclName();
+  auto Res = LT.lookup(ToTU, Name);
+  EXPECT_EQ(Res.size(), 1u);
+  EXPECT_EQ(*Res.begin(), X);
+}
+
+TEST_P(ASTImporterLookupTableTest, EnumConstantDecl) {
+  TranslationUnitDecl *ToTU = getToTuDecl(
+      R"(
+      enum E {
+        A,
+        B
+      };
+      )",
+      Lang_C);
+
+  ASTImporterLookupTable LT(*ToTU);
+  auto *E = FirstDeclMatcher().match(ToTU, enumDecl(hasName("E")));
+  auto *A = FirstDeclMatcher().match(
+      ToTU, enumConstantDecl(hasName("A")));
+
+  DeclarationName Name = A->getDeclName();
+  // Redecl context is the TU.
+  ASSERT_EQ(E->getRedeclContext(), ToTU);
+
+  SmallVector FoundDecls;
+  // Normal lookup finds in the DC.
+  E->localUncachedLookup(Name, FoundDecls);
+  EXPECT_EQ(FoundDecls.size(), 1u);
+
+  // Normal lookup finds in the Redecl context.
+  ToTU->localUncachedLookup(Name, FoundDecls);
+  EXPECT_EQ(FoundDecls.size(), 1u);
+
+  // Import specific lookup finds in the DC.
+  auto Res = LT.lookup(E, Name);
+  ASSERT_EQ(Res.size(), 1u);
+  EXPECT_EQ(*Res.begin(), A);
+
+  // Import specific lookup finds in the Redecl context.
+  Res = LT.lookup(ToTU, Name);
+  ASSERT_EQ(Res.size(), 1u);
+  EXPECT_EQ(*Res.begin(), A);
+}
+
+TEST_P(ASTImporterLookupTableTest, LookupSearchesInTheWholeRedeclChain) {
+  TranslationUnitDecl *ToTU = getToTuDecl(
+      R"(
+      namespace N {
+        int A;
+      }
+      namespace N {
+      }
+      )",
+      Lang_CXX);
+  auto *N1 =
+      LastDeclMatcher().match(ToTU, namespaceDecl(hasName("N")));
+  auto *A = FirstDeclMatcher().match(ToTU, varDecl(hasName("A")));
+  DeclarationName Name = A->getDeclName();
+
+  ASTImporterLookupTable LT(*ToTU);
+  auto Res = LT.lookup(N1, Name);
+  ASSERT_EQ(Res.size(), 1u);
+  EXPECT_EQ(*Res.begin(), A);
+}
+
 INSTANTIATE_TEST_CASE_P(ParameterizedTests, DeclContextTest,
                         ::testing::Values(ArgVector()), );
 
@@ -4352,6 +4872,9 @@ auto DefaultTestValuesForRunOptions = ::testing::Values(
     ArgVector{"-fms-compatibility"},
     ArgVector{"-fdelayed-template-parsing", "-fms-compatibility"});
 
+INSTANTIATE_TEST_CASE_P(ParameterizedTests, ASTImporterLookupTableTest,
+                        DefaultTestValuesForRunOptions, );
+
 INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportExpr,
                         DefaultTestValuesForRunOptions, );
 
@@ -4367,10 +4890,10 @@ INSTANTIATE_TEST_CASE_P(ParameterizedTests, ASTImporterTestBase,
 INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportFunctions,
                         DefaultTestValuesForRunOptions, );
 
-INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportFriendFunctions,
+INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportClasses,
                         DefaultTestValuesForRunOptions, );
 
-INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportClasses,
+INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportFriendFunctions,
                         DefaultTestValuesForRunOptions, );
 
 INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportClassTemplates,
-- 
cgit v1.2.3


From e5939c6db50a7240bb0c3d391d7ef32e8f8b3092 Mon Sep 17 00:00:00 2001
From: Simon Pilgrim 
Date: Mon, 17 Dec 2018 15:14:08 +0000
Subject: Build ASTImporterTest.cpp with /bigobj on MSVC builds to keep
 llvm-clang-x86_64-expensive-checks-win buildbot happy

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349357 91177308-0d34-0410-b5e6-96231b3b80d8
---
 unittests/AST/CMakeLists.txt | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/unittests/AST/CMakeLists.txt b/unittests/AST/CMakeLists.txt
index 6621ce681b..c416e5b996 100644
--- a/unittests/AST/CMakeLists.txt
+++ b/unittests/AST/CMakeLists.txt
@@ -2,6 +2,10 @@ set(LLVM_LINK_COMPONENTS
   Support
   )
 
+if (MSVC)
+  set_source_files_properties(ASTImporterTest.cpp PROPERTIES COMPILE_FLAGS /bigobj)
+endif()
+
 add_clang_unittest(ASTTests
   ASTContextParentMapTest.cpp
   ASTImporterTest.cpp
-- 
cgit v1.2.3


From dbc63abadbe81029b9f65b6e8160046fa26f1646 Mon Sep 17 00:00:00 2001
From: Ilya Biryukov 
Date: Mon, 17 Dec 2018 16:37:52 +0000
Subject: [CodeComplete] Fix test failure on different host and target configs

This should fix PR40033.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349362 91177308-0d34-0410-b5e6-96231b3b80d8
---
 unittests/Sema/CodeCompleteTest.cpp | 27 +++++++++++++++++++++------
 1 file changed, 21 insertions(+), 6 deletions(-)

diff --git a/unittests/Sema/CodeCompleteTest.cpp b/unittests/Sema/CodeCompleteTest.cpp
index 294807c56c..28faa0c1ee 100644
--- a/unittests/Sema/CodeCompleteTest.cpp
+++ b/unittests/Sema/CodeCompleteTest.cpp
@@ -31,6 +31,9 @@ const char TestCCName[] = "test.cc";
 struct CompletionContext {
   std::vector VisitedNamespaces;
   std::string PreferredType;
+  // String representation of std::ptrdiff_t on a given platform. This is a hack
+  // to properly account for different configurations of clang.
+  std::string PtrDiffType;
 };
 
 class VisitedContextFinder : public CodeCompleteConsumer {
@@ -47,6 +50,8 @@ public:
     ResultCtx.VisitedNamespaces =
         getVisitedNamespace(Context.getVisitedContexts());
     ResultCtx.PreferredType = Context.getPreferredType().getAsString();
+    ResultCtx.PtrDiffType =
+        S.getASTContext().getPointerDiffType().getAsString();
   }
 
   CodeCompletionAllocator &getAllocator() override {
@@ -133,11 +138,19 @@ CompletionContext runCodeCompleteOnCode(StringRef AnnotatedCode) {
   return runCompletion(P.Code, P.Points.front());
 }
 
-std::vector collectPreferredTypes(StringRef AnnotatedCode) {
+std::vector
+collectPreferredTypes(StringRef AnnotatedCode,
+                      std::string *PtrDiffType = nullptr) {
   ParsedAnnotations P = parseAnnotations(AnnotatedCode);
   std::vector Types;
-  for (size_t Point : P.Points)
-    Types.push_back(runCompletion(P.Code, Point).PreferredType);
+  for (size_t Point : P.Points) {
+    auto Results = runCompletion(P.Code, Point);
+    if (PtrDiffType) {
+      assert(PtrDiffType->empty() || *PtrDiffType == Results.PtrDiffType);
+      *PtrDiffType = Results.PtrDiffType;
+    }
+    Types.push_back(Results.PreferredType);
+  }
   return Types;
 }
 
@@ -213,9 +226,11 @@ TEST(PreferredTypeTest, BinaryExpr) {
       ptr += ^10;
       ptr -= ^10;
     })cpp";
-  // Expect the normalized ptrdiff_t type, which is typically long or long long.
-  const char *PtrDiff = sizeof(void *) == sizeof(long) ? "long" : "long long";
-  EXPECT_THAT(collectPreferredTypes(Code), Each(PtrDiff));
+  {
+    std::string PtrDiff;
+    auto Types = collectPreferredTypes(Code, &PtrDiff);
+    EXPECT_THAT(Types, Each(PtrDiff));
+  }
 
   // Comparison operators.
   Code = R"cpp(
-- 
cgit v1.2.3


From 228f2c50c5313094fa41671e6ac2d1548db7d19d Mon Sep 17 00:00:00 2001
From: Alex Lorenz 
Date: Mon, 17 Dec 2018 19:19:15 +0000
Subject: [darwin] parse the SDK settings from SDKSettings.json if it exists
 and pass in the -target-sdk-version to the compiler and backend

This commit adds support for reading the SDKSettings.json file in the Darwin
driver. This file is used by the driver to determine the SDK's version, and it
uses that information to pass it down to the compiler using the new
-target-sdk-version= option. This option is then used to set the appropriate
SDK Version module metadata introduced in r349119.

Note: I had to adjust the two ast tests as the SDKROOT environment variable
on macOS caused SDK version to be picked up for the compilation of source file
but not the AST.

rdar://45774000

Differential Revision: https://reviews.llvm.org/D55673


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349380 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/Basic/DiagnosticDriverKinds.td       |   4 +
 include/clang/Basic/TargetInfo.h                   |   6 ++
 include/clang/Basic/TargetOptions.h                |   8 +-
 include/clang/Driver/CC1Options.td                 |   2 +
 include/clang/Driver/DarwinSDKInfo.h               |  42 ++++++++
 lib/CodeGen/ModuleBuilder.cpp                      |   3 +
 lib/Driver/CMakeLists.txt                          |   1 +
 lib/Driver/DarwinSDKInfo.cpp                       |  44 ++++++++
 lib/Driver/ToolChains/Darwin.cpp                   | 115 ++++++++++++++++-----
 lib/Driver/ToolChains/Darwin.h                     |   6 +-
 lib/Frontend/CompilerInvocation.cpp                |   8 ++
 test/CodeGen/darwin-sdk-version.c                  |   4 +
 .../Driver/Inputs/MacOSX10.14.sdk/SDKSettings.json |   1 +
 test/Driver/darwin-sdk-version.c                   |  37 +++++++
 test/Frontend/ast-main.c                           |   6 +-
 test/Frontend/ast-main.cpp                         |   6 +-
 16 files changed, 256 insertions(+), 37 deletions(-)
 create mode 100644 include/clang/Driver/DarwinSDKInfo.h
 create mode 100644 lib/Driver/DarwinSDKInfo.cpp
 create mode 100644 test/CodeGen/darwin-sdk-version.c
 create mode 100644 test/Driver/Inputs/MacOSX10.14.sdk/SDKSettings.json
 create mode 100644 test/Driver/darwin-sdk-version.c

diff --git a/include/clang/Basic/DiagnosticDriverKinds.td b/include/clang/Basic/DiagnosticDriverKinds.td
index af528e1718..a154443248 100644
--- a/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/include/clang/Basic/DiagnosticDriverKinds.td
@@ -405,4 +405,8 @@ def warn_drv_experimental_isel_incomplete_opt : Warning<
 def warn_drv_moutline_unsupported_opt : Warning<
   "The '%0' architecture does not support -moutline; flag ignored">,
   InGroup;
+
+def warn_drv_darwin_sdk_invalid_settings : Warning<
+  "SDK settings were ignored as 'SDKSettings.json' could not be parsed">,
+  InGroup>;
 }
diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h
index 4a7254e02c..786b1c251c 100644
--- a/include/clang/Basic/TargetInfo.h
+++ b/include/clang/Basic/TargetInfo.h
@@ -1321,6 +1321,12 @@ public:
     return None;
   }
 
+  /// \returns The version of the SDK which was used during the compilation if
+  /// one was specified, or an empty version otherwise.
+  const llvm::VersionTuple &getSDKVersion() const {
+    return getTargetOpts().SDKVersion;
+  }
+
   /// Check the target is valid after it is fully initialized.
   virtual bool validateTarget(DiagnosticsEngine &Diags) const {
     return true;
diff --git a/include/clang/Basic/TargetOptions.h b/include/clang/Basic/TargetOptions.h
index 7559e3169e..711e53627f 100644
--- a/include/clang/Basic/TargetOptions.h
+++ b/include/clang/Basic/TargetOptions.h
@@ -15,10 +15,11 @@
 #ifndef LLVM_CLANG_BASIC_TARGETOPTIONS_H
 #define LLVM_CLANG_BASIC_TARGETOPTIONS_H
 
-#include 
-#include 
 #include "clang/Basic/OpenCLOptions.h"
+#include "llvm/Support/VersionTuple.h"
 #include "llvm/Target/TargetOptions.h"
+#include 
+#include 
 
 namespace clang {
 
@@ -73,6 +74,9 @@ public:
   // "default" for the case when the user has not explicitly specified a
   // code model.
   std::string CodeModel;
+
+  /// The version of the SDK which was used during the compilation.
+  VersionTuple SDKVersion;
 };
 
 }  // end namespace clang
diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td
index 9d2d2df7d2..742787bf0c 100644
--- a/include/clang/Driver/CC1Options.td
+++ b/include/clang/Driver/CC1Options.td
@@ -27,6 +27,8 @@ def triple : Separate<["-"], "triple">,
   HelpText<"Specify target triple (e.g. i686-apple-darwin9)">;
 def target_abi : Separate<["-"], "target-abi">,
   HelpText<"Target a particular ABI type">;
+def target_sdk_version_EQ : Joined<["-"], "target-sdk-version=">,
+  HelpText<"The version of target SDK used for compilation">;
 
 }
 
diff --git a/include/clang/Driver/DarwinSDKInfo.h b/include/clang/Driver/DarwinSDKInfo.h
new file mode 100644
index 0000000000..4ffb02fea3
--- /dev/null
+++ b/include/clang/Driver/DarwinSDKInfo.h
@@ -0,0 +1,42 @@
+//===--- DarwinSDKInfo.h - SDK Information parser for darwin ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_DRIVER_DARWIN_SDK_INFO_H
+#define LLVM_CLANG_DRIVER_DARWIN_SDK_INFO_H
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/VersionTuple.h"
+#include "llvm/Support/VirtualFileSystem.h"
+
+namespace clang {
+namespace driver {
+
+/// The information about the darwin SDK that was used during this compilation.
+class DarwinSDKInfo {
+public:
+  DarwinSDKInfo(llvm::VersionTuple Version) : Version(Version) {}
+
+  const llvm::VersionTuple &getVersion() const { return Version; }
+
+private:
+  llvm::VersionTuple Version;
+};
+
+/// Parse the SDK information from the SDKSettings.json file.
+///
+/// \returns an error if the SDKSettings.json file is invalid, None if the
+/// SDK has no SDKSettings.json, or a valid \c DarwinSDKInfo otherwise.
+Expected> parseDarwinSDKInfo(llvm::vfs::FileSystem &VFS,
+                                                     StringRef SDKRootPath);
+
+} // end namespace driver
+} // end namespace clang
+
+#endif // LLVM_CLANG_DRIVER_DARWIN_SDK_INFO_H
diff --git a/lib/CodeGen/ModuleBuilder.cpp b/lib/CodeGen/ModuleBuilder.cpp
index 1264893ec1..c0a37698e7 100644
--- a/lib/CodeGen/ModuleBuilder.cpp
+++ b/lib/CodeGen/ModuleBuilder.cpp
@@ -132,6 +132,9 @@ namespace {
 
       M->setTargetTriple(Ctx->getTargetInfo().getTriple().getTriple());
       M->setDataLayout(Ctx->getTargetInfo().getDataLayout());
+      const auto &SDKVersion = Ctx->getTargetInfo().getSDKVersion();
+      if (!SDKVersion.empty())
+        M->setSDKVersion(SDKVersion);
       Builder.reset(new CodeGen::CodeGenModule(Context, HeaderSearchOpts,
                                                PreprocessorOpts, CodeGenOpts,
                                                *M, Diags, CoverageInfo));
diff --git a/lib/Driver/CMakeLists.txt b/lib/Driver/CMakeLists.txt
index bc96098d0a..084176b524 100644
--- a/lib/Driver/CMakeLists.txt
+++ b/lib/Driver/CMakeLists.txt
@@ -12,6 +12,7 @@ endif()
 add_clang_library(clangDriver
   Action.cpp
   Compilation.cpp
+  DarwinSDKInfo.cpp
   Distro.cpp
   Driver.cpp
   DriverOptions.cpp
diff --git a/lib/Driver/DarwinSDKInfo.cpp b/lib/Driver/DarwinSDKInfo.cpp
new file mode 100644
index 0000000000..547978b2f9
--- /dev/null
+++ b/lib/Driver/DarwinSDKInfo.cpp
@@ -0,0 +1,44 @@
+//===--- DarwinSDKInfo.cpp - SDK Information parser for darwin - ----------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Driver/DarwinSDKInfo.h"
+#include "llvm/Support/ErrorOr.h"
+#include "llvm/Support/JSON.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Path.h"
+
+using namespace clang::driver;
+using namespace clang;
+
+Expected>
+driver::parseDarwinSDKInfo(llvm::vfs::FileSystem &VFS, StringRef SDKRootPath) {
+  llvm::SmallString<256> Filepath = SDKRootPath;
+  llvm::sys::path::append(Filepath, "SDKSettings.json");
+  llvm::ErrorOr> File =
+      VFS.getBufferForFile(Filepath);
+  if (!File) {
+    // If the file couldn't be read, assume it just doesn't exist.
+    return None;
+  }
+  Expected Result =
+      llvm::json::parse(File.get()->getBuffer());
+  if (!Result)
+    return Result.takeError();
+
+  if (const auto *Obj = Result->getAsObject()) {
+    auto VersionString = Obj->getString("Version");
+    if (VersionString) {
+      VersionTuple Version;
+      if (!Version.tryParse(*VersionString))
+        return DarwinSDKInfo(Version);
+    }
+  }
+  return llvm::make_error("invalid SDKSettings.json",
+                                             llvm::inconvertibleErrorCode());
+}
diff --git a/lib/Driver/ToolChains/Darwin.cpp b/lib/Driver/ToolChains/Darwin.cpp
index e5dafa2b09..0cc187ab47 100644
--- a/lib/Driver/ToolChains/Darwin.cpp
+++ b/lib/Driver/ToolChains/Darwin.cpp
@@ -1287,6 +1287,18 @@ struct DarwinPlatform {
     return DarwinPlatform(InferredFromArch, getPlatformFromOS(OS), Value);
   }
 
+  /// Constructs an inferred SDKInfo value based on the version inferred from
+  /// the SDK path itself. Only works for values that were created by inferring
+  /// the platform from the SDKPath.
+  DarwinSDKInfo inferSDKInfo() {
+    assert(Kind == InferredFromSDK && "can infer SDK info only");
+    llvm::VersionTuple Version;
+    bool IsValid = !Version.tryParse(OSVersion);
+    (void)IsValid;
+    assert(IsValid && "invalid SDK version");
+    return DarwinSDKInfo(Version);
+  }
+
 private:
   DarwinPlatform(SourceKind Kind, DarwinPlatformKind Platform, Arg *Argument)
       : Kind(Kind), Platform(Platform), Argument(Argument) {}
@@ -1420,8 +1432,11 @@ getDeploymentTargetFromEnvironmentVariables(const Driver &TheDriver,
 }
 
 /// Tries to infer the deployment target from the SDK specified by -isysroot
-/// (or SDKROOT).
-Optional inferDeploymentTargetFromSDK(DerivedArgList &Args) {
+/// (or SDKROOT). Uses the version specified in the SDKSettings.json file if
+/// it's available.
+Optional
+inferDeploymentTargetFromSDK(DerivedArgList &Args,
+                             const Optional &SDKInfo) {
   const Arg *A = Args.getLastArg(options::OPT_isysroot);
   if (!A)
     return None;
@@ -1429,28 +1444,37 @@ Optional inferDeploymentTargetFromSDK(DerivedArgList &Args) {
   StringRef SDK = Darwin::getSDKName(isysroot);
   if (!SDK.size())
     return None;
-  // Slice the version number out.
-  // Version number is between the first and the last number.
-  size_t StartVer = SDK.find_first_of("0123456789");
-  size_t EndVer = SDK.find_last_of("0123456789");
-  if (StartVer != StringRef::npos && EndVer > StartVer) {
-    StringRef Version = SDK.slice(StartVer, EndVer + 1);
-    if (SDK.startswith("iPhoneOS") || SDK.startswith("iPhoneSimulator"))
-      return DarwinPlatform::createFromSDK(
-          Darwin::IPhoneOS, Version,
-          /*IsSimulator=*/SDK.startswith("iPhoneSimulator"));
-    else if (SDK.startswith("MacOSX"))
-      return DarwinPlatform::createFromSDK(Darwin::MacOS,
-                                           getSystemOrSDKMacOSVersion(Version));
-    else if (SDK.startswith("WatchOS") || SDK.startswith("WatchSimulator"))
-      return DarwinPlatform::createFromSDK(
-          Darwin::WatchOS, Version,
-          /*IsSimulator=*/SDK.startswith("WatchSimulator"));
-    else if (SDK.startswith("AppleTVOS") || SDK.startswith("AppleTVSimulator"))
-      return DarwinPlatform::createFromSDK(
-          Darwin::TvOS, Version,
-          /*IsSimulator=*/SDK.startswith("AppleTVSimulator"));
-  }
+
+  std::string Version;
+  if (SDKInfo) {
+    // Get the version from the SDKSettings.json if it's available.
+    Version = SDKInfo->getVersion().getAsString();
+  } else {
+    // Slice the version number out.
+    // Version number is between the first and the last number.
+    size_t StartVer = SDK.find_first_of("0123456789");
+    size_t EndVer = SDK.find_last_of("0123456789");
+    if (StartVer != StringRef::npos && EndVer > StartVer)
+      Version = SDK.slice(StartVer, EndVer + 1);
+  }
+  if (Version.empty())
+    return None;
+
+  if (SDK.startswith("iPhoneOS") || SDK.startswith("iPhoneSimulator"))
+    return DarwinPlatform::createFromSDK(
+        Darwin::IPhoneOS, Version,
+        /*IsSimulator=*/SDK.startswith("iPhoneSimulator"));
+  else if (SDK.startswith("MacOSX"))
+    return DarwinPlatform::createFromSDK(Darwin::MacOS,
+                                         getSystemOrSDKMacOSVersion(Version));
+  else if (SDK.startswith("WatchOS") || SDK.startswith("WatchSimulator"))
+    return DarwinPlatform::createFromSDK(
+        Darwin::WatchOS, Version,
+        /*IsSimulator=*/SDK.startswith("WatchSimulator"));
+  else if (SDK.startswith("AppleTVOS") || SDK.startswith("AppleTVSimulator"))
+    return DarwinPlatform::createFromSDK(
+        Darwin::TvOS, Version,
+        /*IsSimulator=*/SDK.startswith("AppleTVSimulator"));
   return None;
 }
 
@@ -1525,6 +1549,22 @@ Optional getDeploymentTargetFromTargetArg(
                                           Args.getLastArg(options::OPT_target));
 }
 
+Optional parseSDKSettings(llvm::vfs::FileSystem &VFS,
+                                         const ArgList &Args,
+                                         const Driver &TheDriver) {
+  const Arg *A = Args.getLastArg(options::OPT_isysroot);
+  if (!A)
+    return None;
+  StringRef isysroot = A->getValue();
+  auto SDKInfoOrErr = driver::parseDarwinSDKInfo(VFS, isysroot);
+  if (!SDKInfoOrErr) {
+    llvm::consumeError(SDKInfoOrErr.takeError());
+    TheDriver.Diag(diag::warn_drv_darwin_sdk_invalid_settings);
+    return None;
+  }
+  return *SDKInfoOrErr;
+}
+
 } // namespace
 
 void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
@@ -1549,6 +1589,10 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
     }
   }
 
+  // Read the SDKSettings.json file for more information, like the SDK version
+  // that we can pass down to the compiler.
+  SDKInfo = parseSDKSettings(getVFS(), Args, getDriver());
+
   // The OS and the version can be specified using the -target argument.
   Optional OSTarget =
       getDeploymentTargetFromTargetArg(Args, getTriple(), getDriver());
@@ -1594,16 +1638,22 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
           getDeploymentTargetFromEnvironmentVariables(getDriver(), getTriple());
       if (OSTarget) {
         // Don't infer simulator from the arch when the SDK is also specified.
-        Optional SDKTarget = inferDeploymentTargetFromSDK(Args);
+        Optional SDKTarget =
+            inferDeploymentTargetFromSDK(Args, SDKInfo);
         if (SDKTarget)
           OSTarget->setEnvironment(SDKTarget->getEnvironment());
       }
     }
     // If there is no command-line argument to specify the Target version and
     // no environment variable defined, see if we can set the default based
-    // on -isysroot.
-    if (!OSTarget)
-      OSTarget = inferDeploymentTargetFromSDK(Args);
+    // on -isysroot using SDKSettings.json if it exists.
+    if (!OSTarget) {
+      OSTarget = inferDeploymentTargetFromSDK(Args, SDKInfo);
+      /// If the target was successfully constructed from the SDK path, try to
+      /// infer the SDK info if the SDK doesn't have it.
+      if (OSTarget && !SDKInfo)
+        SDKInfo = OSTarget->inferSDKInfo();
+    }
     // If no OS targets have been specified, try to guess platform from -target
     // or arch name and compute the version from the triple.
     if (!OSTarget)
@@ -2046,6 +2096,15 @@ void Darwin::addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
                                 options::OPT_fno_aligned_allocation) &&
       isAlignedAllocationUnavailable())
     CC1Args.push_back("-faligned-alloc-unavailable");
+
+  if (SDKInfo) {
+    /// Pass the SDK version to the compiler when the SDK information is
+    /// available.
+    std::string Arg;
+    llvm::raw_string_ostream OS(Arg);
+    OS << "-target-sdk-version=" << SDKInfo->getVersion();
+    CC1Args.push_back(DriverArgs.MakeArgString(OS.str()));
+  }
 }
 
 DerivedArgList *
diff --git a/lib/Driver/ToolChains/Darwin.h b/lib/Driver/ToolChains/Darwin.h
index e6a88dce3c..d753f8967a 100644
--- a/lib/Driver/ToolChains/Darwin.h
+++ b/lib/Driver/ToolChains/Darwin.h
@@ -11,9 +11,10 @@
 #define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_DARWIN_H
 
 #include "Cuda.h"
-#include "clang/Driver/XRayArgs.h"
+#include "clang/Driver/DarwinSDKInfo.h"
 #include "clang/Driver/Tool.h"
 #include "clang/Driver/ToolChain.h"
+#include "clang/Driver/XRayArgs.h"
 
 namespace clang {
 namespace driver {
@@ -288,6 +289,9 @@ public:
   /// The OS version we are targeting.
   mutable VersionTuple TargetVersion;
 
+  /// The information about the darwin SDK that was used.
+  mutable Optional SDKInfo;
+
   CudaInstallationDetector CudaInstallation;
 
 private:
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index d491f35769..eaa61b29d9 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -3193,6 +3193,14 @@ static void ParseTargetArgs(TargetOptions &Opts, ArgList &Args,
   Opts.ForceEnableInt128 = Args.hasArg(OPT_fforce_enable_int128);
   Opts.NVPTXUseShortPointers = Args.hasFlag(
       options::OPT_fcuda_short_ptr, options::OPT_fno_cuda_short_ptr, false);
+  if (Arg *A = Args.getLastArg(options::OPT_target_sdk_version_EQ)) {
+    llvm::VersionTuple Version;
+    if (Version.tryParse(A->getValue()))
+      Diags.Report(diag::err_drv_invalid_value)
+          << A->getAsString(Args) << A->getValue();
+    else
+      Opts.SDKVersion = Version;
+  }
 }
 
 bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res,
diff --git a/test/CodeGen/darwin-sdk-version.c b/test/CodeGen/darwin-sdk-version.c
new file mode 100644
index 0000000000..23c43f5932
--- /dev/null
+++ b/test/CodeGen/darwin-sdk-version.c
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.14 -target-sdk-version=10.14.1 -emit-llvm -o - %s | FileCheck %s
+
+// CHECK: !llvm.module.flags = !{!0
+// CHECK: !0 = !{i32 2, !"SDK Version", [3 x i32] [i32 10, i32 14, i32 1]}
diff --git a/test/Driver/Inputs/MacOSX10.14.sdk/SDKSettings.json b/test/Driver/Inputs/MacOSX10.14.sdk/SDKSettings.json
new file mode 100644
index 0000000000..bca56e4f1e
--- /dev/null
+++ b/test/Driver/Inputs/MacOSX10.14.sdk/SDKSettings.json
@@ -0,0 +1 @@
+{"Version":"10.14"}
diff --git a/test/Driver/darwin-sdk-version.c b/test/Driver/darwin-sdk-version.c
new file mode 100644
index 0000000000..a80ed39c60
--- /dev/null
+++ b/test/Driver/darwin-sdk-version.c
@@ -0,0 +1,37 @@
+// RUN: %clang -target x86_64-apple-macosx10.13 -isysroot %S/Inputs/MacOSX10.14.sdk -c -### %s 2>&1 \
+// RUN:   | FileCheck %s
+// RUN: env SDKROOT=%S/Inputs/MacOSX10.14.sdk %clang -target x86_64-apple-macosx10.13 -c -### %s 2>&1 \
+// RUN:   | FileCheck %s
+//
+// RUN: rm -rf %t/SDKs/MacOSX10.10.sdk
+// RUN: mkdir -p %t/SDKs/MacOSX10.10.sdk
+// RUN: %clang -isysroot %t/SDKs/MacOSX10.10.sdk -c -### %s 2>&1 \
+// RUN:   | FileCheck --check-prefix=INFER_SDK_VERSION %s
+// RUN: cp %S/Inputs/MacOSX10.14.sdk/SDKSettings.json %t/SDKs/MacOSX10.10.sdk
+// RUN: %clang -isysroot %t/SDKs/MacOSX10.10.sdk -c -### %s 2>&1 \
+// RUN:   | FileCheck --check-prefix=INFER_DEPLOYMENT_TARGET_VERSION %s
+// REQUIRES: system-darwin && native
+//
+// RUN: rm -rf %t/SDKs/MacOSX10.14.sdk
+// RUN: mkdir -p %t/SDKs/MacOSX10.14.sdk
+// RUN: %clang -target x86_64-apple-macosx10.13 -isysroot %t/SDKs/MacOSX10.14.sdk -c -### %s 2>&1 \
+// RUN:   | FileCheck --check-prefix=NO_VERSION %s
+//
+// RUN: rm -rf %t/SDKs/MacOSX10.14.sdk
+// RUN: mkdir -p %t/SDKs/MacOSX10.14.sdk
+// RUN: echo '{broken json' > %t/SDKs/MacOSX10.14.sdk/SDKSettings.json
+// RUN: %clang -target x86_64-apple-macosx10.13 -isysroot %t/SDKs/MacOSX10.14.sdk -c -### %s 2>&1 \
+// RUN:   | FileCheck --check-prefixes=NO_VERSION,ERROR %s
+//
+// RUN: rm -rf %t/SDKs/MacOSX10.14.sdk
+// RUN: mkdir -p %t/SDKs/MacOSX10.14.sdk
+// RUN: echo '{"Version":1}' > %t/SDKs/MacOSX10.14.sdk/SDKSettings.json
+// RUN: %clang -target x86_64-apple-macosx10.13 -isysroot %t/SDKs/MacOSX10.14.sdk -c -### %s 2>&1 \
+// RUN:   | FileCheck --check-prefixes=NO_VERSION,ERROR %s
+
+// CHECK: -target-sdk-version=10.14
+// INFER_SDK_VERSION: "-triple" "x86_64-apple-macosx10.10.0"
+// INFER_SDK_VERSION-SAME: -target-sdk-version=10.10
+// INFER_DEPLOYMENT_TARGET_VERSION: "-triple" "x86_64-apple-macosx10.14.0"
+// NO_VERSION-NOT: target-sdk-version
+// ERROR: warning: SDK settings were ignored as 'SDKSettings.json' could not be parsed
diff --git a/test/Frontend/ast-main.c b/test/Frontend/ast-main.c
index 43237a12ef..74e8bcf6db 100644
--- a/test/Frontend/ast-main.c
+++ b/test/Frontend/ast-main.c
@@ -1,6 +1,6 @@
-// RUN: %clang -emit-llvm -S -o %t1.ll -x c - < %s
-// RUN: %clang -emit-ast -o %t.ast %s
-// RUN: %clang -emit-llvm -S -o %t2.ll -x ast - < %t.ast
+// RUN: env SDKROOT="/" %clang -emit-llvm -S -o %t1.ll -x c - < %s
+// RUN: env SDKROOT="/" %clang -emit-ast -o %t.ast %s
+// RUN: env SDKROOT="/" %clang -emit-llvm -S -o %t2.ll -x ast - < %t.ast
 // RUN: diff %t1.ll %t2.ll
 
 int main() {
diff --git a/test/Frontend/ast-main.cpp b/test/Frontend/ast-main.cpp
index 4bddbe1372..89fd5e5a63 100644
--- a/test/Frontend/ast-main.cpp
+++ b/test/Frontend/ast-main.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang -emit-llvm -S -o %t1.ll -x c++ - < %s
-// RUN: %clang -fno-delayed-template-parsing -emit-ast -o %t.ast %s
-// RUN: %clang -emit-llvm -S -o %t2.ll -x ast - < %t.ast
+// RUN: env SDKROOT="/" %clang -emit-llvm -S -o %t1.ll -x c++ - < %s
+// RUN: env SDKROOT="/" %clang -fno-delayed-template-parsing -emit-ast -o %t.ast %s
+// RUN: env SDKROOT="/" %clang -emit-llvm -S -o %t2.ll -x ast - < %t.ast
 // RUN: diff %t1.ll %t2.ll
 
 // http://llvm.org/bugs/show_bug.cgi?id=15377
-- 
cgit v1.2.3


From 20b6772f9f70f3fce39ec18a0e25ba85aff094fe Mon Sep 17 00:00:00 2001
From: Francis Visoiu Mistrih 
Date: Mon, 17 Dec 2018 19:29:27 +0000
Subject: [Driver] Don't override '-march' when using '-arch x86_64h'

On Darwin, using '-arch x86_64h' would always override the option passed
through '-march'.

This patch allows users to use '-march' with x86_64h, while keeping the
default to 'core-avx2'

Differential Revision: https://reviews.llvm.org/D55775

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349381 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/Driver/ToolChains/Arch/X86.cpp | 6 +-----
 lib/Driver/ToolChains/Darwin.cpp   | 6 +-----
 test/Driver/clang-translation.c    | 5 +++++
 3 files changed, 7 insertions(+), 10 deletions(-)

diff --git a/lib/Driver/ToolChains/Arch/X86.cpp b/lib/Driver/ToolChains/Arch/X86.cpp
index bc707857d8..45648945d5 100644
--- a/lib/Driver/ToolChains/Arch/X86.cpp
+++ b/lib/Driver/ToolChains/Arch/X86.cpp
@@ -23,12 +23,8 @@ using namespace llvm::opt;
 const char *x86::getX86TargetCPU(const ArgList &Args,
                                  const llvm::Triple &Triple) {
   if (const Arg *A = Args.getLastArg(clang::driver::options::OPT_march_EQ)) {
-    if (StringRef(A->getValue()) != "native") {
-      if (Triple.isOSDarwin() && Triple.getArchName() == "x86_64h")
-        return "core-avx2";
-
+    if (StringRef(A->getValue()) != "native")
       return A->getValue();
-    }
 
     // FIXME: Reject attempts to use -march=native unless the target matches
     // the host.
diff --git a/lib/Driver/ToolChains/Darwin.cpp b/lib/Driver/ToolChains/Darwin.cpp
index 0cc187ab47..4e306fd960 100644
--- a/lib/Driver/ToolChains/Darwin.cpp
+++ b/lib/Driver/ToolChains/Darwin.cpp
@@ -2017,12 +2017,8 @@ DerivedArgList *MachO::TranslateArgs(const DerivedArgList &Args,
     else if (Name == "pentIIm3")
       DAL->AddJoinedArg(nullptr, MArch, "pentium2");
 
-    else if (Name == "x86_64")
+    else if (Name == "x86_64" || Name == "x86_64h")
       DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_m64));
-    else if (Name == "x86_64h") {
-      DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_m64));
-      DAL->AddJoinedArg(nullptr, MArch, "x86_64h");
-    }
 
     else if (Name == "arm")
       DAL->AddJoinedArg(nullptr, MArch, "armv4t");
diff --git a/test/Driver/clang-translation.c b/test/Driver/clang-translation.c
index ed24ae27fb..4360ea44ae 100644
--- a/test/Driver/clang-translation.c
+++ b/test/Driver/clang-translation.c
@@ -33,6 +33,11 @@
 // AVX2: "-target-cpu"
 // AVX2: "core-avx2"
 
+// RUN: %clang -target x86_64h-apple-darwin -march=skx -### %s -o /dev/null 2>&1 | \
+// RUN: FileCheck -check-prefix=X8664HSKX %s
+// X8664HSKX: "-target-cpu"
+// X8664HSKX: "skx"
+
 // RUN: %clang -target i386-apple-macosx10.12 -### -S %s -o %t.s 2>&1 | \
 // RUN: FileCheck -check-prefix=PENRYN %s
 // RUN: %clang -target x86_64-apple-macosx10.12 -### -S %s -o %t.s 2>&1 | \
-- 
cgit v1.2.3


From 468c31a4de61378fca7ab17718d3bce6afa10a38 Mon Sep 17 00:00:00 2001
From: Alex Lorenz 
Date: Mon, 17 Dec 2018 19:30:46 +0000
Subject: [darwin][arm64] use the "cyclone" CPU for Darwin even when `-arch` is
 not specified

The -target option allows the user to specify the build target using LLVM
triple. The triple includes the arch, and so the -arch option is redundant.
This should work just as well without the -arch. However, the driver has a bug
in which it doesn't target the "Cyclone" CPU for darwin if -target is used
without -arch. This commit fixes this issue.

rdar://46743182

Differential Revision: https://reviews.llvm.org/D55731


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349382 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/Driver/ToolChains/Arch/AArch64.cpp | 30 ++++++++++++++++++++----------
 lib/Driver/ToolChains/Arch/AArch64.h   |  5 +++--
 lib/Driver/ToolChains/Clang.cpp        |  2 +-
 lib/Driver/ToolChains/CommonArgs.cpp   |  2 +-
 test/Driver/aarch64-cpus.c             |  3 +++
 5 files changed, 28 insertions(+), 14 deletions(-)

diff --git a/lib/Driver/ToolChains/Arch/AArch64.cpp b/lib/Driver/ToolChains/Arch/AArch64.cpp
index 1dc516b963..71e55fe79e 100644
--- a/lib/Driver/ToolChains/Arch/AArch64.cpp
+++ b/lib/Driver/ToolChains/Arch/AArch64.cpp
@@ -19,10 +19,17 @@ using namespace clang::driver::tools;
 using namespace clang;
 using namespace llvm::opt;
 
+/// \returns true if the given triple can determine the default CPU type even
+/// if -arch is not specified.
+static bool isCPUDeterminedByTriple(const llvm::Triple &Triple) {
+  return Triple.isOSDarwin();
+}
+
 /// getAArch64TargetCPU - Get the (LLVM) name of the AArch64 cpu we are
 /// targeting. Set \p A to the Arg corresponding to the -mcpu argument if it is
 /// provided, or to nullptr otherwise.
-std::string aarch64::getAArch64TargetCPU(const ArgList &Args, Arg *&A) {
+std::string aarch64::getAArch64TargetCPU(const ArgList &Args,
+                                         const llvm::Triple &Triple, Arg *&A) {
   std::string CPU;
   // If we have -mcpu, use that.
   if ((A = Args.getLastArg(options::OPT_mcpu_EQ))) {
@@ -36,9 +43,9 @@ std::string aarch64::getAArch64TargetCPU(const ArgList &Args, Arg *&A) {
   else if (CPU.size())
     return CPU;
 
-  // Make sure we pick "cyclone" if -arch is used.
-  // FIXME: Should this be picked by checking the target triple instead?
-  if (Args.getLastArg(options::OPT_arch))
+  // Make sure we pick "cyclone" if -arch is used or when targetting a Darwin
+  // OS.
+  if (Args.getLastArg(options::OPT_arch) || Triple.isOSDarwin())
     return "cyclone";
 
   return "generic";
@@ -152,7 +159,9 @@ getAArch64MicroArchFeaturesFromMcpu(const Driver &D, StringRef Mcpu,
   return getAArch64MicroArchFeaturesFromMtune(D, CPU, Args, Features);
 }
 
-void aarch64::getAArch64TargetFeatures(const Driver &D, const ArgList &Args,
+void aarch64::getAArch64TargetFeatures(const Driver &D,
+                                       const llvm::Triple &Triple,
+                                       const ArgList &Args,
                                        std::vector &Features) {
   Arg *A;
   bool success = true;
@@ -162,9 +171,9 @@ void aarch64::getAArch64TargetFeatures(const Driver &D, const ArgList &Args,
     success = getAArch64ArchFeaturesFromMarch(D, A->getValue(), Args, Features);
   else if ((A = Args.getLastArg(options::OPT_mcpu_EQ)))
     success = getAArch64ArchFeaturesFromMcpu(D, A->getValue(), Args, Features);
-  else if (Args.hasArg(options::OPT_arch))
-    success = getAArch64ArchFeaturesFromMcpu(D, getAArch64TargetCPU(Args, A),
-                                             Args, Features);
+  else if (Args.hasArg(options::OPT_arch) || isCPUDeterminedByTriple(Triple))
+    success = getAArch64ArchFeaturesFromMcpu(
+        D, getAArch64TargetCPU(Args, Triple, A), Args, Features);
 
   if (success && (A = Args.getLastArg(clang::driver::options::OPT_mtune_EQ)))
     success =
@@ -172,9 +181,10 @@ void aarch64::getAArch64TargetFeatures(const Driver &D, const ArgList &Args,
   else if (success && (A = Args.getLastArg(options::OPT_mcpu_EQ)))
     success =
         getAArch64MicroArchFeaturesFromMcpu(D, A->getValue(), Args, Features);
-  else if (success && Args.hasArg(options::OPT_arch))
+  else if (success &&
+           (Args.hasArg(options::OPT_arch) || isCPUDeterminedByTriple(Triple)))
     success = getAArch64MicroArchFeaturesFromMcpu(
-        D, getAArch64TargetCPU(Args, A), Args, Features);
+        D, getAArch64TargetCPU(Args, Triple, A), Args, Features);
 
   if (!success)
     D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
diff --git a/lib/Driver/ToolChains/Arch/AArch64.h b/lib/Driver/ToolChains/Arch/AArch64.h
index 62e419cc19..5f6148ebd6 100644
--- a/lib/Driver/ToolChains/Arch/AArch64.h
+++ b/lib/Driver/ToolChains/Arch/AArch64.h
@@ -21,11 +21,12 @@ namespace driver {
 namespace tools {
 namespace aarch64 {
 
-void getAArch64TargetFeatures(const Driver &D, const llvm::opt::ArgList &Args,
+void getAArch64TargetFeatures(const Driver &D, const llvm::Triple &Triple,
+                              const llvm::opt::ArgList &Args,
                               std::vector &Features);
 
 std::string getAArch64TargetCPU(const llvm::opt::ArgList &Args,
-                                llvm::opt::Arg *&A);
+                                const llvm::Triple &Triple, llvm::opt::Arg *&A);
 
 } // end namespace aarch64
 } // end namespace target
diff --git a/lib/Driver/ToolChains/Clang.cpp b/lib/Driver/ToolChains/Clang.cpp
index e3dfb09c73..809607f5e6 100644
--- a/lib/Driver/ToolChains/Clang.cpp
+++ b/lib/Driver/ToolChains/Clang.cpp
@@ -341,7 +341,7 @@ static void getTargetFeatures(const ToolChain &TC, const llvm::Triple &Triple,
     break;
   case llvm::Triple::aarch64:
   case llvm::Triple::aarch64_be:
-    aarch64::getAArch64TargetFeatures(D, Args, Features);
+    aarch64::getAArch64TargetFeatures(D, Triple, Args, Features);
     break;
   case llvm::Triple::x86:
   case llvm::Triple::x86_64:
diff --git a/lib/Driver/ToolChains/CommonArgs.cpp b/lib/Driver/ToolChains/CommonArgs.cpp
index 2bdff39f0d..a0762a7cca 100644
--- a/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/lib/Driver/ToolChains/CommonArgs.cpp
@@ -271,7 +271,7 @@ std::string tools::getCPUName(const ArgList &Args, const llvm::Triple &T,
 
   case llvm::Triple::aarch64:
   case llvm::Triple::aarch64_be:
-    return aarch64::getAArch64TargetCPU(Args, A);
+    return aarch64::getAArch64TargetCPU(Args, T, A);
 
   case llvm::Triple::arm:
   case llvm::Triple::armeb:
diff --git a/test/Driver/aarch64-cpus.c b/test/Driver/aarch64-cpus.c
index 51d5d062e3..75174b7904 100644
--- a/test/Driver/aarch64-cpus.c
+++ b/test/Driver/aarch64-cpus.c
@@ -21,7 +21,10 @@
 // ARM64-NATIVE-NOT: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "native"
 
 // RUN: %clang -target arm64-apple-darwin -arch arm64 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-DARWIN %s
+// RUN: %clang -target arm64-apple-darwin -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-DARWIN %s
+// RUN: %clang -target arm64-apple-ios12.0 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-DARWIN %s
 // ARM64-DARWIN: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "cyclone"
+// ARM64-DARWIN-SAME: "-target-feature" "+aes"
 
 // RUN: %clang -target aarch64 -mcpu=cortex-a35 -### -c %s 2>&1 | FileCheck -check-prefix=CA35 %s
 // RUN: %clang -target aarch64 -mlittle-endian -mcpu=cortex-a35 -### -c %s 2>&1 | FileCheck -check-prefix=CA35 %s
-- 
cgit v1.2.3


From 43436b31e62c45dcac4c2306184ca7f56785f9bc Mon Sep 17 00:00:00 2001
From: "Tan S. B" 
Date: Mon, 17 Dec 2018 19:53:22 +0000
Subject: [NFC] Test commit: tweak whitespace in comment

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349384 91177308-0d34-0410-b5e6-96231b3b80d8
---
 test/CXX/temp/temp.param/p3.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/test/CXX/temp/temp.param/p3.cpp b/test/CXX/temp/temp.param/p3.cpp
index c3c93396cb..f709630504 100644
--- a/test/CXX/temp/temp.param/p3.cpp
+++ b/test/CXX/temp/temp.param/p3.cpp
@@ -16,7 +16,7 @@ template class Y> struct X1 {
 // [Note: because of the name lookup rules, a template-parameter that
 // could be interpreted as either a non-type template-parameter or a
 // type-parameter (because its identifier is the name of an already
-// existing class) is taken as a type-parameter. For example, 
+// existing class) is taken as a type-parameter. For example,
 class T { /* ... */ };  // expected-note{{candidate constructor (the implicit copy constructor) not viable}}
 #if __cplusplus >= 201103L // C++11 or later
 // expected-note@-2 {{candidate constructor (the implicit move constructor) not viable}}
@@ -27,7 +27,7 @@ int i;
 template struct X2 {
   void f(T t) 
   { 
-    T t1 = i; //template-parameters T and i 
+    T t1 = i; // template-parameters T and i
     ::T t2 = ::i; // global namespace members T and i  \
     // expected-error{{no viable conversion}}
   } 
-- 
cgit v1.2.3


From 2905053bebb519735d0b17745dd006aa497ab6e7 Mon Sep 17 00:00:00 2001
From: Alex Lorenz 
Date: Mon, 17 Dec 2018 20:25:41 +0000
Subject: Fix build after r349380

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349388 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/Basic/TargetOptions.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/clang/Basic/TargetOptions.h b/include/clang/Basic/TargetOptions.h
index 711e53627f..fcccc5331a 100644
--- a/include/clang/Basic/TargetOptions.h
+++ b/include/clang/Basic/TargetOptions.h
@@ -76,7 +76,7 @@ public:
   std::string CodeModel;
 
   /// The version of the SDK which was used during the compilation.
-  VersionTuple SDKVersion;
+  llvm::VersionTuple SDKVersion;
 };
 
 }  // end namespace clang
-- 
cgit v1.2.3


From 6138c88ecafacb940701524001d2ae88bb8c3cf1 Mon Sep 17 00:00:00 2001
From: Alex Lorenz 
Date: Mon, 17 Dec 2018 21:01:04 +0000
Subject: Make test/Driver/darwin-sdk-version.c pass on hosts < macOS10.14

The test test/Driver/darwin-sdk-version.c from r349380 checks if the macOS
deployment target can be correctly inferred from the SDK version. When the
SDK version is > host version, the driver will pick the host version, so
the old test failed on macOS < 10.14. This commit makes this test more
resilient by using an older SDK version.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349393 91177308-0d34-0410-b5e6-96231b3b80d8
---
 test/Driver/darwin-sdk-version.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/test/Driver/darwin-sdk-version.c b/test/Driver/darwin-sdk-version.c
index a80ed39c60..89f587ede2 100644
--- a/test/Driver/darwin-sdk-version.c
+++ b/test/Driver/darwin-sdk-version.c
@@ -7,7 +7,7 @@
 // RUN: mkdir -p %t/SDKs/MacOSX10.10.sdk
 // RUN: %clang -isysroot %t/SDKs/MacOSX10.10.sdk -c -### %s 2>&1 \
 // RUN:   | FileCheck --check-prefix=INFER_SDK_VERSION %s
-// RUN: cp %S/Inputs/MacOSX10.14.sdk/SDKSettings.json %t/SDKs/MacOSX10.10.sdk
+// RUN: sed -e 's/10\.14/10\.8/g' %S/Inputs/MacOSX10.14.sdk/SDKSettings.json > %t/SDKs/MacOSX10.10.sdk/SDKSettings.json
 // RUN: %clang -isysroot %t/SDKs/MacOSX10.10.sdk -c -### %s 2>&1 \
 // RUN:   | FileCheck --check-prefix=INFER_DEPLOYMENT_TARGET_VERSION %s
 // REQUIRES: system-darwin && native
@@ -32,6 +32,6 @@
 // CHECK: -target-sdk-version=10.14
 // INFER_SDK_VERSION: "-triple" "x86_64-apple-macosx10.10.0"
 // INFER_SDK_VERSION-SAME: -target-sdk-version=10.10
-// INFER_DEPLOYMENT_TARGET_VERSION: "-triple" "x86_64-apple-macosx10.14.0"
+// INFER_DEPLOYMENT_TARGET_VERSION: "-triple" "x86_64-apple-macosx10.8.0"
 // NO_VERSION-NOT: target-sdk-version
 // ERROR: warning: SDK settings were ignored as 'SDKSettings.json' could not be parsed
-- 
cgit v1.2.3


From a827fb79585ef92e27c40a5dda6e145777e94be9 Mon Sep 17 00:00:00 2001
From: Artem Dergachev 
Date: Mon, 17 Dec 2018 21:07:38 +0000
Subject: [analyzer] MoveChecker: Squash the bit field because it causes a GCC
 warning.

The warning seems spurious (GCC bug 51242), but the bit field is
simply not worth the hassle.

rdar://problem/41349073


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349394 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/StaticAnalyzer/Checkers/MoveChecker.cpp | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/lib/StaticAnalyzer/Checkers/MoveChecker.cpp b/lib/StaticAnalyzer/Checkers/MoveChecker.cpp
index 6436a6c6cb..6efa2dfbe5 100644
--- a/lib/StaticAnalyzer/Checkers/MoveChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/MoveChecker.cpp
@@ -63,9 +63,7 @@ public:
 
 private:
   enum MisuseKind { MK_FunCall, MK_Copy, MK_Move, MK_Dereference };
-  // This needs to be unsigned in order to avoid undefined behavior
-  // when putting it into a tight bitfield.
-  enum StdObjectKind : unsigned { SK_NonStd, SK_Unsafe, SK_Safe, SK_SmartPtr };
+  enum StdObjectKind { SK_NonStd, SK_Unsafe, SK_Safe, SK_SmartPtr };
 
   enum AggressivenessKind { // In any case, don't warn after a reset.
     AK_Invalid = -1,
@@ -81,9 +79,9 @@ private:
 
   struct ObjectKind {
     // Is this a local variable or a local rvalue reference?
-    bool IsLocal : 1;
+    bool IsLocal;
     // Is this an STL object? If so, of what kind?
-    StdObjectKind StdKind : 2;
+    StdObjectKind StdKind;
   };
 
   // STL smart pointers are automatically re-initialized to null when moved
-- 
cgit v1.2.3


From 4d6bcd5b3263a86818db792ec700d8fb6333c8ea Mon Sep 17 00:00:00 2001
From: Reid Kleckner 
Date: Mon, 17 Dec 2018 23:10:43 +0000
Subject: Update Microsoft name mangling scheme for exception specifiers in the
 type system

Summary:
The msvc exception specifier for noexcept function types has changed
from the prior default of "Z" to "_E" if the function cannot throw when
compiling with /std:C++17.

Patch by Zachary Henkel!

Reviewers: zturner, rnk

Reviewed By: rnk

Subscribers: cfe-commits

Differential Revision: https://reviews.llvm.org/D55685

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349414 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/Basic/LangOptions.h | 13 ++++++++-----
 lib/AST/MicrosoftMangle.cpp       | 29 ++++++++++++++++++-----------
 lib/Driver/ToolChains/MSVC.cpp    |  2 +-
 lib/Sema/SemaDeclAttr.cpp         |  5 +++++
 4 files changed, 32 insertions(+), 17 deletions(-)

diff --git a/include/clang/Basic/LangOptions.h b/include/clang/Basic/LangOptions.h
index 34f510f5ca..b4f7fd867a 100644
--- a/include/clang/Basic/LangOptions.h
+++ b/include/clang/Basic/LangOptions.h
@@ -98,11 +98,14 @@ public:
 
   enum AddrSpaceMapMangling { ASMM_Target, ASMM_On, ASMM_Off };
 
+  // Corresponds to _MSC_VER
   enum MSVCMajorVersion {
-    MSVC2010 = 16,
-    MSVC2012 = 17,
-    MSVC2013 = 18,
-    MSVC2015 = 19
+    MSVC2010 = 1600,
+    MSVC2012 = 1700,
+    MSVC2013 = 1800,
+    MSVC2015 = 1900,
+    MSVC2017 = 1910,
+    MSVC2017_5 = 1912
   };
 
   /// Clang versions with different platform ABI conformance.
@@ -271,7 +274,7 @@ public:
   }
 
   bool isCompatibleWithMSVC(MSVCMajorVersion MajorVersion) const {
-    return MSCompatibilityVersion >= MajorVersion * 10000000U;
+    return MSCompatibilityVersion >= MajorVersion * 100000U;
   }
 
   /// Reset all of the options that are not considered when building a
diff --git a/lib/AST/MicrosoftMangle.cpp b/lib/AST/MicrosoftMangle.cpp
index db0d770d9a..caa3af598d 100644
--- a/lib/AST/MicrosoftMangle.cpp
+++ b/lib/AST/MicrosoftMangle.cpp
@@ -316,7 +316,8 @@ public:
                   QualifierMangleMode QMM = QMM_Mangle);
   void mangleFunctionType(const FunctionType *T,
                           const FunctionDecl *D = nullptr,
-                          bool ForceThisQuals = false);
+                          bool ForceThisQuals = false,
+                          bool MangleExceptionSpec = true);
   void mangleNestedName(const NamedDecl *ND);
 
 private:
@@ -513,7 +514,7 @@ void MicrosoftCXXNameMangler::mangleFunctionEncoding(const FunctionDecl *FD,
 
     mangleFunctionClass(FD);
 
-    mangleFunctionType(FT, FD);
+    mangleFunctionType(FT, FD, false, false);
   } else {
     Out << '9';
   }
@@ -2127,7 +2128,8 @@ void MicrosoftCXXNameMangler::mangleType(const FunctionNoProtoType *T,
 
 void MicrosoftCXXNameMangler::mangleFunctionType(const FunctionType *T,
                                                  const FunctionDecl *D,
-                                                 bool ForceThisQuals) {
+                                                 bool ForceThisQuals,
+                                                 bool MangleExceptionSpec) {
   //  ::=  
   //                       
   const FunctionProtoType *Proto = dyn_cast(T);
@@ -2260,7 +2262,12 @@ void MicrosoftCXXNameMangler::mangleFunctionType(const FunctionType *T,
       Out << '@';
   }
 
-  mangleThrowSpecification(Proto);
+  if (MangleExceptionSpec && getASTContext().getLangOpts().CPlusPlus17 &&
+      getASTContext().getLangOpts().isCompatibleWithMSVC(
+          LangOptions::MSVC2017_5))
+    mangleThrowSpecification(Proto);
+  else
+    Out << 'Z';
 }
 
 void MicrosoftCXXNameMangler::mangleFunctionClass(const FunctionDecl *FD) {
@@ -2365,15 +2372,15 @@ void MicrosoftCXXNameMangler::mangleCallingConvention(CallingConv CC) {
 void MicrosoftCXXNameMangler::mangleCallingConvention(const FunctionType *T) {
   mangleCallingConvention(T->getCallConv());
 }
+
 void MicrosoftCXXNameMangler::mangleThrowSpecification(
                                                 const FunctionProtoType *FT) {
-  //  ::= Z # throw(...) (default)
-  //              ::= @ # throw() or __declspec/__attribute__((nothrow))
-  //              ::= +
-  // NOTE: Since the Microsoft compiler ignores throw specifications, they are
-  // all actually mangled as 'Z'. (They're ignored because their associated
-  // functionality isn't implemented, and probably never will be.)
-  Out << 'Z';
+  //  ::= Z # (default)
+  //              ::= _E # noexcept
+  if (FT->canThrow())
+    Out << 'Z';
+  else
+    Out << "_E";
 }
 
 void MicrosoftCXXNameMangler::mangleType(const UnresolvedUsingType *T,
diff --git a/lib/Driver/ToolChains/MSVC.cpp b/lib/Driver/ToolChains/MSVC.cpp
index 839f313623..7e34b0df5c 100644
--- a/lib/Driver/ToolChains/MSVC.cpp
+++ b/lib/Driver/ToolChains/MSVC.cpp
@@ -1286,7 +1286,7 @@ VersionTuple MSVCToolChain::computeMSVCVersion(const Driver *D,
   if (MSVT.empty() &&
       Args.hasFlag(options::OPT_fms_extensions, options::OPT_fno_ms_extensions,
                    IsWindowsMSVC)) {
-    // -fms-compatibility-version=19.11 is default, aka 2017
+    // -fms-compatibility-version=19.11 is default, aka 2017, 15.3
     MSVT = VersionTuple(19, 11);
   }
   return MSVT;
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index ba041a8786..3e0fa53041 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -5694,6 +5694,11 @@ static void handleLayoutVersion(Sema &S, Decl *D, const ParsedAttr &AL) {
   if (!checkUInt32Argument(S, AL, AL.getArgAsExpr(0), Version))
     return;
 
+  // The attribute expects a "major" version number like 19, but new versions of
+  // MSVC have moved to updating the "minor", or less significant numbers, so we
+  // have to multiply by 100 now.
+  Version *= 100;
+
   // TODO: Investigate what happens with the next major version of MSVC.
   if (Version != LangOptions::MSVC2015) {
     S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
-- 
cgit v1.2.3


From d1d2af094696e5f2d1614f1fcdf62b858e3dff3d Mon Sep 17 00:00:00 2001
From: Reid Kleckner 
Date: Mon, 17 Dec 2018 23:16:43 +0000
Subject: Fix ms-layout_version declspec test and add missing new test

Now that MSVC compatibility versions are stored as a four digit number
(1912) instead of a two digit number (19), we need to adjust how we
handle this attribute.

Also add a new test that was intended to be part of r349414.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349415 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/Sema/SemaDeclAttr.cpp                    | 12 ++++----
 test/CodeGenCXX/mangle-ms-exception-spec.cpp | 42 ++++++++++++++++++++++++++++
 2 files changed, 48 insertions(+), 6 deletions(-)
 create mode 100644 test/CodeGenCXX/mangle-ms-exception-spec.cpp

diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index 3e0fa53041..829bc9a104 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -5694,18 +5694,18 @@ static void handleLayoutVersion(Sema &S, Decl *D, const ParsedAttr &AL) {
   if (!checkUInt32Argument(S, AL, AL.getArgAsExpr(0), Version))
     return;
 
-  // The attribute expects a "major" version number like 19, but new versions of
-  // MSVC have moved to updating the "minor", or less significant numbers, so we
-  // have to multiply by 100 now.
-  Version *= 100;
-
   // TODO: Investigate what happens with the next major version of MSVC.
-  if (Version != LangOptions::MSVC2015) {
+  if (Version != LangOptions::MSVC2015 / 100) {
     S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
         << AL << Version << VersionExpr->getSourceRange();
     return;
   }
 
+  // The attribute expects a "major" version number like 19, but new versions of
+  // MSVC have moved to updating the "minor", or less significant numbers, so we
+  // have to multiply by 100 now.
+  Version *= 100;
+
   D->addAttr(::new (S.Context)
                  LayoutVersionAttr(AL.getRange(), S.Context, Version,
                                    AL.getAttributeSpellingListIndex()));
diff --git a/test/CodeGenCXX/mangle-ms-exception-spec.cpp b/test/CodeGenCXX/mangle-ms-exception-spec.cpp
new file mode 100644
index 0000000000..1aaf2486ea
--- /dev/null
+++ b/test/CodeGenCXX/mangle-ms-exception-spec.cpp
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -std=c++11 -fms-extensions -emit-llvm %s -o - -triple=x86_64-pc-win32 -Wno-noexcept-type -fms-compatibility-version=19.12 | FileCheck %s --check-prefix=CHECK --check-prefix=CXX11
+// RUN: %clang_cc1 -std=c++17 -fms-extensions -emit-llvm %s -o - -triple=x86_64-pc-win32 | FileCheck %s --check-prefix=CHECK --check-prefix=NOCOMPAT
+// RUN: %clang_cc1 -std=c++17 -fms-extensions -emit-llvm %s -o - -triple=x86_64-pc-win32 -fms-compatibility-version=19.12 | FileCheck %s --check-prefix=CHECK --check-prefix=CXX17
+
+// Prove that mangling only changed for noexcept types under /std:C++17, not all noexcept functions
+// CHECK-DAG: @"?nochange@@YAXXZ"
+void nochange() noexcept {}
+
+// CXX11-DAG: @"?a@@YAXP6AHXZ@Z"
+// NOCOMPAT-DAG: @"?a@@YAXP6AHXZ@Z"
+// CXX17-DAG: @"?a@@YAXP6AHX_E@Z"
+void a(int() noexcept) {}
+// CHECK-DAG: @"?b@@YAXP6AHXZ@Z"
+void b(int() noexcept(false)) {}
+// CXX11-DAG: @"?c@@YAXP6AHXZ@Z"
+// NOCOMPAT-DAG: @"?c@@YAXP6AHXZ@Z"
+// CXX17-DAG: @"?c@@YAXP6AHX_E@Z"
+void c(int() noexcept(true)) {}
+// CHECK-DAG: @"?d@@YAXP6AHXZ@Z"
+void d(int()) {}
+
+template 
+class e;
+template 
+class e {
+  // CXX11-DAG: @"?ee@?$e@$$A6AXXZ@@EEAAXXZ"
+  // NOCOMPAT-DAG: @"?ee@?$e@$$A6AXXZ@@EEAAXXZ"
+  // CXX17-DAG: @"?ee@?$e@$$A6AXX_E@@EEAAXXZ"
+  virtual T ee(U &&...) noexcept {};
+};
+
+e e1;
+
+template 
+class f;
+template 
+class f {
+  // CHECK-DAG: @"?ff@?$f@$$A6AXXZ@@EEAAXXZ"
+  virtual T ff(U &&...) noexcept {};
+};
+
+f f1;
-- 
cgit v1.2.3


From 3eb970db6b61d0c310dd50cf4380f4045060b3ee Mon Sep 17 00:00:00 2001
From: JF Bastien 
Date: Tue, 18 Dec 2018 05:12:21 +0000
Subject: Automatic variable initialization

Summary:
Add an option to initialize automatic variables with either a pattern or with
zeroes. The default is still that automatic variables are uninitialized. Also
add attributes to request uninitialized on a per-variable basis, mainly to disable
initialization of large stack arrays when deemed too expensive.

This isn't meant to change the semantics of C and C++. Rather, it's meant to be
a last-resort when programmers inadvertently have some undefined behavior in
their code. This patch aims to make undefined behavior hurt less, which
security-minded people will be very happy about. Notably, this means that
there's no inadvertent information leak when:

  - The compiler re-uses stack slots, and a value is used uninitialized.
  - The compiler re-uses a register, and a value is used uninitialized.
  - Stack structs / arrays / unions with padding are copied.

This patch only addresses stack and register information leaks. There's many
more infoleaks that we could address, and much more undefined behavior that
could be tamed. Let's keep this patch focused, and I'm happy to address related
issues elsewhere.

To keep the patch simple, only some `undef` is removed for now, see
`replaceUndef`. The padding-related infoleaks are therefore not all gone yet.
This will be addressed in a follow-up, mainly because addressing padding-related
leaks should be a stand-alone option which is implied by variable
initialization.

There are three options when it comes to automatic variable initialization:

  0. Uninitialized

    This is C and C++'s default. It's not changing. Depending on code
    generation, a programmer who runs into undefined behavior by using an
    uninialized automatic variable may observe any previous value (including
    program secrets), or any value which the compiler saw fit to materialize on
    the stack or in a register (this could be to synthesize an immediate, to
    refer to code or data locations, to generate cookies, etc).

  1. Pattern initialization

    This is the recommended initialization approach. Pattern initialization's
    goal is to initialize automatic variables with values which will likely
    transform logic bugs into crashes down the line, are easily recognizable in
    a crash dump, without being values which programmers can rely on for useful
    program semantics. At the same time, pattern initialization tries to
    generate code which will optimize well. You'll find the following details in
    `patternFor`:

    - Integers are initialized with repeated 0xAA bytes (infinite scream).
    - Vectors of integers are also initialized with infinite scream.
    - Pointers are initialized with infinite scream on 64-bit platforms because
      it's an unmappable pointer value on architectures I'm aware of. Pointers
      are initialize to 0x000000AA (small scream) on 32-bit platforms because
      32-bit platforms don't consistently offer unmappable pages. When they do
      it's usually the zero page. As people try this out, I expect that we'll
      want to allow different platforms to customize this, let's do so later.
    - Vectors of pointers are initialized the same way pointers are.
    - Floating point values and vectors are initialized with a negative quiet
      NaN with repeated 0xFF payload (e.g. 0xffffffff and 0xffffffffffffffff).
      NaNs are nice (here, anways) because they propagate on arithmetic, making
      it more likely that entire computations become NaN when a single
      uninitialized value sneaks in.
    - Arrays are initialized to their homogeneous elements' initialization
      value, repeated. Stack-based Variable-Length Arrays (VLAs) are
      runtime-initialized to the allocated size (no effort is made for negative
      size, but zero-sized VLAs are untouched even if technically undefined).
    - Structs are initialized to their heterogeneous element's initialization
      values. Zero-size structs are initialized as 0xAA since they're allocated
      a single byte.
    - Unions are initialized using the initialization for the largest member of
      the union.

    Expect the values used for pattern initialization to change over time, as we
    refine heuristics (both for performance and security). The goal is truly to
    avoid injecting semantics into undefined behavior, and we should be
    comfortable changing these values when there's a worthwhile point in doing
    so.

    Why so much infinite scream? Repeated byte patterns tend to be easy to
    synthesize on most architectures, and otherwise memset is usually very
    efficient. For values which aren't entirely repeated byte patterns, LLVM
    will often generate code which does memset + a few stores.

  2. Zero initialization

    Zero initialize all values. This has the unfortunate side-effect of
    providing semantics to otherwise undefined behavior, programs therefore
    might start to rely on this behavior, and that's sad. However, some
    programmers believe that pattern initialization is too expensive for them,
    and data might show that they're right. The only way to make these
    programmers wrong is to offer zero-initialization as an option, figure out
    where they are right, and optimize the compiler into submission. Until the
    compiler provides acceptable performance for all security-minded code, zero
    initialization is a useful (if blunt) tool.

I've been asked for a fourth initialization option: user-provided byte value.
This might be useful, and can easily be added later.

Why is an out-of band initialization mecanism desired? We could instead use
-Wuninitialized! Indeed we could, but then we're forcing the programmer to
provide semantics for something which doesn't actually have any (it's
uninitialized!). It's then unclear whether `int derp = 0;` lends meaning to `0`,
or whether it's just there to shut that warning up. It's also way easier to use
a compiler flag than it is to manually and intelligently initialize all values
in a program.

Why not just rely on static analysis? Because it cannot reason about all dynamic
code paths effectively, and it has false positives. It's a great tool, could get
even better, but it's simply incapable of catching all uses of uninitialized
values.

Why not just rely on memory sanitizer? Because it's not universally available,
has a 3x performance cost, and shouldn't be deployed in production. Again, it's
a great tool, it'll find the dynamic uses of uninitialized variables that your
test coverage hits, but it won't find the ones that you encounter in production.

What's the performance like? Not too bad! Previous publications [0] have cited
2.7 to 4.5% averages. We've commmitted a few patches over the last few months to
address specific regressions, both in code size and performance. In all cases,
the optimizations are generally useful, but variable initialization benefits
from them a lot more than regular code does. We've got a handful of other
optimizations in mind, but the code is in good enough shape and has found enough
latent issues that it's a good time to get the change reviewed, checked in, and
have others kick the tires. We'll continue reducing overheads as we try this out
on diverse codebases.

Is it a good idea? Security-minded folks think so, and apparently so does the
Microsoft Visual Studio team [1] who say "Between 2017 and mid 2018, this
feature would have killed 49 MSRC cases that involved uninitialized struct data
leaking across a trust boundary. It would have also mitigated a number of bugs
involving uninitialized struct data being used directly.". They seem to use pure
zero initialization, and claim to have taken the overheads down to within noise.
Don't just trust Microsoft though, here's another relevant person asking for
this [2]. It's been proposed for GCC [3] and LLVM [4] before.

What are the caveats? A few!

  - Variables declared in unreachable code, and used later, aren't initialized.
    This goto, Duff's device, other objectionable uses of switch. This should
    instead be a hard-error in any serious codebase.
  - Volatile stack variables are still weird. That's pre-existing, it's really
    the language's fault and this patch keeps it weird. We should deprecate
    volatile [5].
  - As noted above, padding isn't fully handled yet.

I don't think these caveats make the patch untenable because they can be
addressed separately.

Should this be on by default? Maybe, in some circumstances. It's a conversation
we can have when we've tried it out sufficiently, and we're confident that we've
eliminated enough of the overheads that most codebases would want to opt-in.
Let's keep our precious undefined behavior until that point in time.

How do I use it:

  1. On the command-line:

    -ftrivial-auto-var-init=uninitialized (the default)
    -ftrivial-auto-var-init=pattern
    -ftrivial-auto-var-init=zero -enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang

  2. Using an attribute:

    int dont_initialize_me __attribute((uninitialized));

  [0]: https://users.elis.ugent.be/~jsartor/researchDocs/OOPSLA2011Zero-submit.pdf
  [1]: https://twitter.com/JosephBialek/status/1062774315098112001
  [2]: https://outflux.net/slides/2018/lss/danger.pdf
  [3]: https://gcc.gnu.org/ml/gcc-patches/2014-06/msg00615.html
  [4]: https://github.com/AndroidHardeningArchive/platform_external_clang/commit/776a0955ef6686d23a82d2e6a3cbd4a6a882c31c
  [5]: http://wg21.link/p1152

I've also posted an RFC to cfe-dev: http://lists.llvm.org/pipermail/cfe-dev/2018-November/060172.html



Reviewers: pcc, kcc, rsmith

Subscribers: JDevlieghere, jkorous, dexonsmith, cfe-commits

Differential Revision: https://reviews.llvm.org/D54604

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349442 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/Basic/Attr.td                        |   6 +
 include/clang/Basic/AttrDocs.td                    |  12 +
 include/clang/Basic/DiagnosticDriverKinds.td       |   5 +
 include/clang/Basic/LangOptions.def                |   2 +
 include/clang/Basic/LangOptions.h                  |   5 +
 include/clang/Driver/Options.td                    |   6 +
 include/clang/Driver/ToolChain.h                   |   8 +-
 lib/CodeGen/CGDecl.cpp                             | 257 +++++++++++++++-
 lib/Driver/ToolChains/Clang.cpp                    |  45 +++
 lib/Frontend/CompilerInvocation.cpp                |  13 +
 lib/Sema/SemaDeclAttr.cpp                          |  12 +
 test/CodeGenCXX/auto-var-init.cpp                  | 336 ++++++++++++++++++++-
 .../CodeGenCXX/trivial-auto-var-init-attribute.cpp |  23 ++
 test/CodeGenCXX/trivial-auto-var-init.cpp          | 216 +++++++++++++
 test/Driver/clang_f_opts.c                         |   9 +
 test/Sema/attr-uninitialized.c                     |  21 ++
 test/Sema/uninit-variables.c                       |   1 +
 17 files changed, 961 insertions(+), 16 deletions(-)
 create mode 100644 test/CodeGenCXX/trivial-auto-var-init-attribute.cpp
 create mode 100644 test/CodeGenCXX/trivial-auto-var-init.cpp
 create mode 100644 test/Sema/attr-uninitialized.c

diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td
index 04125e67b2..b3c7a4f4b8 100644
--- a/include/clang/Basic/Attr.td
+++ b/include/clang/Basic/Attr.td
@@ -3131,3 +3131,9 @@ def SpeculativeLoadHardening : InheritableAttr {
   let Subjects = SubjectList<[Function, ObjCMethod], ErrorDiag>;
   let Documentation = [SpeculativeLoadHardeningDocs];
 }
+
+def Uninitialized : InheritableAttr {
+  let Spellings = [Clang<"uninitialized", 0>];
+  let Subjects = SubjectList<[LocalVar]>;
+  let Documentation = [UninitializedDocs];
+}
diff --git a/include/clang/Basic/AttrDocs.td b/include/clang/Basic/AttrDocs.td
index e72ef253f0..5dc9a05f4e 100644
--- a/include/clang/Basic/AttrDocs.td
+++ b/include/clang/Basic/AttrDocs.td
@@ -3704,6 +3704,18 @@ invoking clang with -fno-c++-static-destructors.
   }];
 }
 
+def UninitializedDocs : Documentation {
+  let Category = DocCatVariable;
+  let Content = [{
+The command-line parameter ``-ftrivial-auto-var-init=*`` can be used to
+initialize trivial automatic stack variables. By default, trivial automatic
+stack variables are uninitialized. This attribute is used to override the
+command-line parameter, forcing variables to remain uninitialized. It has no
+semantic meaning in that using uninitialized values is undefined behavior,
+it rather documents the programmer's intent.
+  }];
+}
+
 def GnuInlineDocs : Documentation {
   let Category = DocCatFunction;
   let Content = [{
diff --git a/include/clang/Basic/DiagnosticDriverKinds.td b/include/clang/Basic/DiagnosticDriverKinds.td
index a154443248..2d6db287cd 100644
--- a/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/include/clang/Basic/DiagnosticDriverKinds.td
@@ -409,4 +409,9 @@ def warn_drv_moutline_unsupported_opt : Warning<
 def warn_drv_darwin_sdk_invalid_settings : Warning<
   "SDK settings were ignored as 'SDKSettings.json' could not be parsed">,
   InGroup>;
+
+def err_drv_trivial_auto_var_init_zero_disabled : Error<
+  "-ftrivial-auto-var-init=zero hasn't been enabled. Enable it at your own peril for benchmarking purpose only with "
+  "-enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang">;
+
 }
diff --git a/include/clang/Basic/LangOptions.def b/include/clang/Basic/LangOptions.def
index be4491d512..512baa463b 100644
--- a/include/clang/Basic/LangOptions.def
+++ b/include/clang/Basic/LangOptions.def
@@ -263,6 +263,8 @@ ENUM_LANGOPT(TypeVisibilityMode, Visibility, 3, DefaultVisibility,
              "type symbol visibility")
 ENUM_LANGOPT(StackProtector, StackProtectorMode, 2, SSPOff,
              "stack protector mode")
+ENUM_LANGOPT(TrivialAutoVarInit, TrivialAutoVarInitKind, 2, TrivialAutoVarInitKind::Uninitialized,
+             "trivial automatic variable initialization")
 ENUM_LANGOPT(SignedOverflowBehavior, SignedOverflowBehaviorTy, 2, SOB_Undefined,
              "signed integer overflow handling")
 
diff --git a/include/clang/Basic/LangOptions.h b/include/clang/Basic/LangOptions.h
index b4f7fd867a..9cff7c5160 100644
--- a/include/clang/Basic/LangOptions.h
+++ b/include/clang/Basic/LangOptions.h
@@ -54,6 +54,11 @@ public:
   enum GCMode { NonGC, GCOnly, HybridGC };
   enum StackProtectorMode { SSPOff, SSPOn, SSPStrong, SSPReq };
 
+  // Automatic variables live on the stack, and when trivial they're usually
+  // uninitialized because it's undefined behavior to use them without
+  // initializing them.
+  enum class TrivialAutoVarInitKind { Uninitialized, Zero, Pattern };
+
   enum SignedOverflowBehaviorTy {
     // Default C standard behavior.
     SOB_Undefined,
diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td
index 50aa0833e1..809b28b9dd 100644
--- a/include/clang/Driver/Options.td
+++ b/include/clang/Driver/Options.td
@@ -1651,6 +1651,12 @@ def fstack_protector : Flag<["-"], "fstack-protector">, Group,
            "if they contain a char (or 8bit integer) array or constant sized calls to "
            "alloca, which are of greater size than ssp-buffer-size (default: 8 bytes). "
            "All variable sized calls to alloca are considered vulnerable">;
+def ftrivial_auto_var_init : Joined<["-"], "ftrivial-auto-var-init=">, Group,
+  Flags<[CC1Option]>, HelpText<"Initialize trivial automatic stack variables: uninitialized (default)"
+  " | pattern">, Values<"uninitialized,pattern">;
+def enable_trivial_var_init_zero : Joined<["-"], "enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang">,
+  Flags<[CC1Option]>,
+  HelpText<"Trivial automatic variable initialization to zero is only here for benchmarks, it'll eventually be removed, and I'm OK with that because I'm only using it to benchmark">;
 def fstandalone_debug : Flag<["-"], "fstandalone-debug">, Group, Flags<[CoreOption]>,
   HelpText<"Emit full debug info for all types used by the program">;
 def fno_standalone_debug : Flag<["-"], "fno-standalone-debug">, Group, Flags<[CoreOption]>,
diff --git a/include/clang/Driver/ToolChain.h b/include/clang/Driver/ToolChain.h
index 43a82a7b43..d5f75b8271 100644
--- a/include/clang/Driver/ToolChain.h
+++ b/include/clang/Driver/ToolChain.h
@@ -12,8 +12,8 @@
 
 #include "clang/Basic/DebugInfoOptions.h"
 #include "clang/Basic/LLVM.h"
+#include "clang/Basic/LangOptions.h"
 #include "clang/Basic/Sanitizers.h"
-#include "clang/Basic/DebugInfoOptions.h"
 #include "clang/Driver/Action.h"
 #include "clang/Driver/Multilib.h"
 #include "clang/Driver/Types.h"
@@ -350,6 +350,12 @@ public:
     return 0;
   }
 
+  /// Get the default trivial automatic variable initialization.
+  virtual LangOptions::TrivialAutoVarInitKind
+  GetDefaultTrivialAutoVarInit() const {
+    return LangOptions::TrivialAutoVarInitKind::Uninitialized;
+  }
+
   /// GetDefaultLinker - Get the default linker to use.
   virtual const char *getDefaultLinker() const { return "ld"; }
 
diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp
index f4fef45a12..2b3696a4f2 100644
--- a/lib/CodeGen/CGDecl.cpp
+++ b/lib/CodeGen/CGDecl.cpp
@@ -963,6 +963,85 @@ static llvm::Value *shouldUseMemSetToInitialize(llvm::Constant *Init,
   return llvm::isBytewiseValue(Init);
 }
 
+static llvm::Constant *patternFor(CodeGenModule &CGM, llvm::Type *Ty) {
+  // The following value is a guaranteed unmappable pointer value and has a
+  // repeated byte-pattern which makes it easier to synthesize. We use it for
+  // pointers as well as integers so that aggregates are likely to be
+  // initialized with this repeated value.
+  constexpr uint64_t LargeValue = 0xAAAAAAAAAAAAAAAAull;
+  // For 32-bit platforms it's a bit trickier because, across systems, only the
+  // zero page can reasonably be expected to be unmapped, and even then we need
+  // a very low address. We use a smaller value, and that value sadly doesn't
+  // have a repeated byte-pattern. We don't use it for integers.
+  constexpr uint32_t SmallValue = 0x000000AA;
+  // Floating-point values are initialized as NaNs because they propagate. Using
+  // a repeated byte pattern means that it will be easier to initialize
+  // all-floating-point aggregates and arrays with memset. Further, aggregates
+  // which mix integral and a few floats might also initialize with memset
+  // followed by a handful of stores for the floats. Using fairly unique NaNs
+  // also means they'll be easier to distinguish in a crash.
+  constexpr bool NegativeNaN = true;
+  constexpr uint64_t NaNPayload = 0xFFFFFFFFFFFFFFFFull;
+  if (Ty->isIntOrIntVectorTy()) {
+    unsigned BitWidth = cast(
+                            Ty->isVectorTy() ? Ty->getVectorElementType() : Ty)
+                            ->getBitWidth();
+    if (BitWidth <= 64)
+      return llvm::ConstantInt::get(Ty, LargeValue);
+    return llvm::ConstantInt::get(
+        Ty, llvm::APInt::getSplat(BitWidth, llvm::APInt(64, LargeValue)));
+  }
+  if (Ty->isPtrOrPtrVectorTy()) {
+    auto *PtrTy = cast(
+        Ty->isVectorTy() ? Ty->getVectorElementType() : Ty);
+    unsigned PtrWidth = CGM.getContext().getTargetInfo().getPointerWidth(
+        PtrTy->getAddressSpace());
+    llvm::Type *IntTy = llvm::IntegerType::get(CGM.getLLVMContext(), PtrWidth);
+    uint64_t IntValue;
+    switch (PtrWidth) {
+    default:
+      llvm_unreachable("pattern initialization of unsupported pointer width");
+    case 64:
+      IntValue = LargeValue;
+      break;
+    case 32:
+      IntValue = SmallValue;
+      break;
+    }
+    auto *Int = llvm::ConstantInt::get(IntTy, IntValue);
+    return llvm::ConstantExpr::getIntToPtr(Int, PtrTy);
+  }
+  if (Ty->isFPOrFPVectorTy()) {
+    unsigned BitWidth = llvm::APFloat::semanticsSizeInBits(
+        (Ty->isVectorTy() ? Ty->getVectorElementType() : Ty)
+            ->getFltSemantics());
+    llvm::APInt Payload(64, NaNPayload);
+    if (BitWidth >= 64)
+      Payload = llvm::APInt::getSplat(BitWidth, Payload);
+    return llvm::ConstantFP::getQNaN(Ty, NegativeNaN, &Payload);
+  }
+  if (Ty->isArrayTy()) {
+    // Note: this doesn't touch tail padding (at the end of an object, before
+    // the next array object). It is instead handled by replaceUndef.
+    auto *ArrTy = cast(Ty);
+    llvm::SmallVector Element(
+        ArrTy->getNumElements(), patternFor(CGM, ArrTy->getElementType()));
+    return llvm::ConstantArray::get(ArrTy, Element);
+  }
+
+  // Note: this doesn't touch struct padding. It will initialize as much union
+  // padding as is required for the largest type in the union. Padding is
+  // instead handled by replaceUndef. Stores to structs with volatile members
+  // don't have a volatile qualifier when initialized according to C++. This is
+  // fine because stack-based volatiles don't really have volatile semantics
+  // anyways, and the initialization shouldn't be observable.
+  auto *StructTy = cast(Ty);
+  llvm::SmallVector Struct(StructTy->getNumElements());
+  for (unsigned El = 0; El != Struct.size(); ++El)
+    Struct[El] = patternFor(CGM, StructTy->getElementType(El));
+  return llvm::ConstantStruct::get(StructTy, Struct);
+}
+
 static Address createUnnamedGlobalFrom(CodeGenModule &CGM, const VarDecl &D,
                                        CGBuilderTy &Builder,
                                        llvm::Constant *Constant,
@@ -1010,13 +1089,20 @@ static void emitStoresForConstant(CodeGenModule &CGM, const VarDecl &D,
                                   Address Loc, bool isVolatile,
                                   CGBuilderTy &Builder,
                                   llvm::Constant *constant) {
+  auto *Ty = constant->getType();
+  bool isScalar = Ty->isIntOrIntVectorTy() || Ty->isPtrOrPtrVectorTy() ||
+                  Ty->isFPOrFPVectorTy();
+  if (isScalar) {
+    Builder.CreateStore(constant, Loc, isVolatile);
+    return;
+  }
+
   auto *Int8Ty = llvm::IntegerType::getInt8Ty(CGM.getLLVMContext());
   auto *IntPtrTy = CGM.getDataLayout().getIntPtrType(CGM.getLLVMContext());
 
   // If the initializer is all or mostly the same, codegen with bzero / memset
   // then do a few stores afterward.
-  uint64_t ConstantSize =
-      CGM.getDataLayout().getTypeAllocSize(constant->getType());
+  uint64_t ConstantSize = CGM.getDataLayout().getTypeAllocSize(Ty);
   auto *SizeVal = llvm::ConstantInt::get(IntPtrTy, ConstantSize);
   if (shouldUseBZeroPlusStoresToInitialize(constant, ConstantSize)) {
     Builder.CreateMemSet(Loc, llvm::ConstantInt::get(Int8Ty, 0), SizeVal,
@@ -1025,8 +1111,7 @@ static void emitStoresForConstant(CodeGenModule &CGM, const VarDecl &D,
     bool valueAlreadyCorrect =
         constant->isNullValue() || isa(constant);
     if (!valueAlreadyCorrect) {
-      Loc = Builder.CreateBitCast(
-          Loc, constant->getType()->getPointerTo(Loc.getAddressSpace()));
+      Loc = Builder.CreateBitCast(Loc, Ty->getPointerTo(Loc.getAddressSpace()));
       emitStoresForInitAfterBZero(CGM, constant, Loc, isVolatile, Builder);
     }
     return;
@@ -1051,6 +1136,58 @@ static void emitStoresForConstant(CodeGenModule &CGM, const VarDecl &D,
       SizeVal, isVolatile);
 }
 
+static void emitStoresForZeroInit(CodeGenModule &CGM, const VarDecl &D,
+                                  Address Loc, bool isVolatile,
+                                  CGBuilderTy &Builder) {
+  llvm::Type *ElTy = Loc.getElementType();
+  llvm::Constant *constant = llvm::Constant::getNullValue(ElTy);
+  emitStoresForConstant(CGM, D, Loc, isVolatile, Builder, constant);
+}
+
+static void emitStoresForPatternInit(CodeGenModule &CGM, const VarDecl &D,
+                                     Address Loc, bool isVolatile,
+                                     CGBuilderTy &Builder) {
+  llvm::Type *ElTy = Loc.getElementType();
+  llvm::Constant *constant = patternFor(CGM, ElTy);
+  assert(!isa(constant));
+  emitStoresForConstant(CGM, D, Loc, isVolatile, Builder, constant);
+}
+
+static bool containsUndef(llvm::Constant *constant) {
+  auto *Ty = constant->getType();
+  if (isa(constant))
+    return true;
+  if (Ty->isStructTy() || Ty->isArrayTy() || Ty->isVectorTy())
+    for (llvm::Use &Op : constant->operands())
+      if (containsUndef(cast(Op)))
+        return true;
+  return false;
+}
+
+static llvm::Constant *replaceUndef(llvm::Constant *constant) {
+  // FIXME: when doing pattern initialization, replace undef with 0xAA instead.
+  // FIXME: also replace padding between values by creating a new struct type
+  //        which has no padding.
+  auto *Ty = constant->getType();
+  if (isa(constant))
+    return llvm::Constant::getNullValue(Ty);
+  if (!(Ty->isStructTy() || Ty->isArrayTy() || Ty->isVectorTy()))
+    return constant;
+  if (!containsUndef(constant))
+    return constant;
+  llvm::SmallVector Values(constant->getNumOperands());
+  for (unsigned Op = 0, NumOp = constant->getNumOperands(); Op != NumOp; ++Op) {
+    auto *OpValue = cast(constant->getOperand(Op));
+    Values[Op] = replaceUndef(OpValue);
+  }
+  if (Ty->isStructTy())
+    return llvm::ConstantStruct::get(cast(Ty), Values);
+  if (Ty->isArrayTy())
+    return llvm::ConstantArray::get(cast(Ty), Values);
+  assert(Ty->isVectorTy());
+  return llvm::ConstantVector::get(Values);
+}
+
 /// EmitAutoVarDecl - Emit code and set up an entry in LocalDeclMap for a
 /// variable declaration with auto, register, or no storage class specifier.
 /// These turn into simple stack objects, or GlobalValues depending on target.
@@ -1442,6 +1579,8 @@ void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) {
   auto DL = ApplyDebugLocation::CreateDefaultArtificial(*this, D.getLocation());
   QualType type = D.getType();
 
+  bool isVolatile = type.isVolatileQualified();
+
   // If this local has an initializer, emit it now.
   const Expr *Init = D.getInit();
 
@@ -1469,24 +1608,120 @@ void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) {
     return;
   }
 
-  if (isTrivialInitializer(Init))
-    return;
-
   // Check whether this is a byref variable that's potentially
   // captured and moved by its own initializer.  If so, we'll need to
   // emit the initializer first, then copy into the variable.
-  bool capturedByInit = emission.IsEscapingByRef && isCapturedBy(D, Init);
+  bool capturedByInit =
+      Init && emission.IsEscapingByRef && isCapturedBy(D, Init);
 
   Address Loc =
-    capturedByInit ? emission.Addr : emission.getObjectAddress(*this);
+      capturedByInit ? emission.Addr : emission.getObjectAddress(*this);
+
+  // Note: constexpr already initializes everything correctly.
+  LangOptions::TrivialAutoVarInitKind trivialAutoVarInit =
+      (D.isConstexpr()
+           ? LangOptions::TrivialAutoVarInitKind::Uninitialized
+           : (D.getAttr()
+                  ? LangOptions::TrivialAutoVarInitKind::Uninitialized
+                  : getContext().getLangOpts().getTrivialAutoVarInit()));
+
+  auto initializeWhatIsTechnicallyUninitialized = [&]() {
+    if (trivialAutoVarInit ==
+        LangOptions::TrivialAutoVarInitKind::Uninitialized)
+      return;
+
+    CharUnits Size = getContext().getTypeSizeInChars(type);
+    if (!Size.isZero()) {
+      switch (trivialAutoVarInit) {
+      case LangOptions::TrivialAutoVarInitKind::Uninitialized:
+        llvm_unreachable("Uninitialized handled above");
+      case LangOptions::TrivialAutoVarInitKind::Zero:
+        emitStoresForZeroInit(CGM, D, Loc, isVolatile, Builder);
+        break;
+      case LangOptions::TrivialAutoVarInitKind::Pattern:
+        emitStoresForPatternInit(CGM, D, Loc, isVolatile, Builder);
+        break;
+      }
+      return;
+    }
+
+    // VLAs look zero-sized to getTypeInfo. We can't emit constant stores to
+    // them, so emit a memcpy with the VLA size to initialize each element.
+    // Technically zero-sized or negative-sized VLAs are undefined, and UBSan
+    // will catch that code, but there exists code which generates zero-sized
+    // VLAs. Be nice and initialize whatever they requested.
+    const VariableArrayType *VlaType =
+        dyn_cast_or_null(getContext().getAsArrayType(type));
+    if (!VlaType)
+      return;
+    auto VlaSize = getVLASize(VlaType);
+    auto SizeVal = VlaSize.NumElts;
+    CharUnits EltSize = getContext().getTypeSizeInChars(VlaSize.Type);
+    switch (trivialAutoVarInit) {
+    case LangOptions::TrivialAutoVarInitKind::Uninitialized:
+      llvm_unreachable("Uninitialized handled above");
+
+    case LangOptions::TrivialAutoVarInitKind::Zero:
+      if (!EltSize.isOne())
+        SizeVal = Builder.CreateNUWMul(SizeVal, CGM.getSize(EltSize));
+      Builder.CreateMemSet(Loc, llvm::ConstantInt::get(Int8Ty, 0), SizeVal,
+                           isVolatile);
+      break;
+
+    case LangOptions::TrivialAutoVarInitKind::Pattern: {
+      llvm::Type *ElTy = Loc.getElementType();
+      llvm::Constant *Constant = patternFor(CGM, ElTy);
+      CharUnits ConstantAlign = getContext().getTypeAlignInChars(VlaSize.Type);
+      llvm::BasicBlock *SetupBB = createBasicBlock("vla-setup.loop");
+      llvm::BasicBlock *LoopBB = createBasicBlock("vla-init.loop");
+      llvm::BasicBlock *ContBB = createBasicBlock("vla-init.cont");
+      llvm::Value *IsZeroSizedVLA = Builder.CreateICmpEQ(
+          SizeVal, llvm::ConstantInt::get(SizeVal->getType(), 0),
+          "vla.iszerosized");
+      Builder.CreateCondBr(IsZeroSizedVLA, ContBB, SetupBB);
+      EmitBlock(SetupBB);
+      if (!EltSize.isOne())
+        SizeVal = Builder.CreateNUWMul(SizeVal, CGM.getSize(EltSize));
+      llvm::Value *BaseSizeInChars =
+          llvm::ConstantInt::get(IntPtrTy, EltSize.getQuantity());
+      Address Begin = Builder.CreateElementBitCast(Loc, Int8Ty, "vla.begin");
+      llvm::Value *End =
+          Builder.CreateInBoundsGEP(Begin.getPointer(), SizeVal, "vla.end");
+      llvm::BasicBlock *OriginBB = Builder.GetInsertBlock();
+      EmitBlock(LoopBB);
+      llvm::PHINode *Cur = Builder.CreatePHI(Begin.getType(), 2, "vla.cur");
+      Cur->addIncoming(Begin.getPointer(), OriginBB);
+      CharUnits CurAlign = Loc.getAlignment().alignmentOfArrayElement(EltSize);
+      Builder.CreateMemCpy(
+          Address(Cur, CurAlign),
+          createUnnamedGlobalFrom(CGM, D, Builder, Constant, ConstantAlign),
+          BaseSizeInChars, isVolatile);
+      llvm::Value *Next =
+          Builder.CreateInBoundsGEP(Int8Ty, Cur, BaseSizeInChars, "vla.next");
+      llvm::Value *Done = Builder.CreateICmpEQ(Next, End, "vla-init.isdone");
+      Builder.CreateCondBr(Done, ContBB, LoopBB);
+      Cur->addIncoming(Next, LoopBB);
+      EmitBlock(ContBB);
+    } break;
+    }
+  };
+
+  if (isTrivialInitializer(Init)) {
+    initializeWhatIsTechnicallyUninitialized();
+    return;
+  }
 
   llvm::Constant *constant = nullptr;
   if (emission.IsConstantAggregate || D.isConstexpr()) {
     assert(!capturedByInit && "constant init contains a capturing block?");
     constant = ConstantEmitter(*this).tryEmitAbstractForInitializer(D);
+    if (constant && trivialAutoVarInit !=
+                        LangOptions::TrivialAutoVarInitKind::Uninitialized)
+      constant = replaceUndef(constant);
   }
 
   if (!constant) {
+    initializeWhatIsTechnicallyUninitialized();
     LValue lv = MakeAddrLValue(Loc, type);
     lv.setNonGC(true);
     return EmitExprAsInit(Init, &D, lv, capturedByInit);
@@ -1499,10 +1734,6 @@ void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) {
     return EmitStoreThroughLValue(RValue::get(constant), lv, true);
   }
 
-  // If this is a simple aggregate initialization, we can optimize it
-  // in various ways.
-  bool isVolatile = type.isVolatileQualified();
-
   llvm::Type *BP = CGM.Int8Ty->getPointerTo(Loc.getAddressSpace());
   if (Loc.getType() != BP)
     Loc = Builder.CreateBitCast(Loc, BP);
diff --git a/lib/Driver/ToolChains/Clang.cpp b/lib/Driver/ToolChains/Clang.cpp
index 809607f5e6..5b74ffa96c 100644
--- a/lib/Driver/ToolChains/Clang.cpp
+++ b/lib/Driver/ToolChains/Clang.cpp
@@ -2472,6 +2472,50 @@ static void RenderSSPOptions(const ToolChain &TC, const ArgList &Args,
   }
 }
 
+static void RenderTrivialAutoVarInitOptions(const Driver &D,
+                                            const ToolChain &TC,
+                                            const ArgList &Args,
+                                            ArgStringList &CmdArgs) {
+  auto DefaultTrivialAutoVarInit = TC.GetDefaultTrivialAutoVarInit();
+  StringRef TrivialAutoVarInit = "";
+
+  for (const Arg *A : Args) {
+    switch (A->getOption().getID()) {
+    default:
+      continue;
+    case options::OPT_ftrivial_auto_var_init: {
+      A->claim();
+      StringRef Val = A->getValue();
+      if (Val == "uninitialized" || Val == "zero" || Val == "pattern")
+        TrivialAutoVarInit = Val;
+      else
+        D.Diag(diag::err_drv_unsupported_option_argument)
+            << A->getOption().getName() << Val;
+      break;
+    }
+    }
+  }
+
+  if (TrivialAutoVarInit.empty())
+    switch (DefaultTrivialAutoVarInit) {
+    case LangOptions::TrivialAutoVarInitKind::Uninitialized:
+      break;
+    case LangOptions::TrivialAutoVarInitKind::Pattern:
+      TrivialAutoVarInit = "pattern";
+      break;
+    case LangOptions::TrivialAutoVarInitKind::Zero:
+      TrivialAutoVarInit = "zero";
+      break;
+    }
+
+  if (!TrivialAutoVarInit.empty()) {
+    if (TrivialAutoVarInit == "zero" && !Args.hasArg(options::OPT_enable_trivial_var_init_zero))
+      D.Diag(diag::err_drv_trivial_auto_var_init_zero_disabled);
+    CmdArgs.push_back(
+        Args.MakeArgString("-ftrivial-auto-var-init=" + TrivialAutoVarInit));
+  }
+}
+
 static void RenderOpenCLOptions(const ArgList &Args, ArgStringList &CmdArgs) {
   const unsigned ForwardedArguments[] = {
       options::OPT_cl_opt_disable,
@@ -4463,6 +4507,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
     CmdArgs.push_back(Args.MakeArgString("-mspeculative-load-hardening"));
 
   RenderSSPOptions(TC, Args, CmdArgs, KernelOrKext);
+  RenderTrivialAutoVarInitOptions(D, TC, Args, CmdArgs);
 
   // Translate -mstackrealign
   if (Args.hasFlag(options::OPT_mstackrealign, options::OPT_mno_stackrealign,
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index eaa61b29d9..220cad2738 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -2938,6 +2938,19 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
   case 3: Opts.setStackProtector(LangOptions::SSPReq); break;
   }
 
+  if (Arg *A = Args.getLastArg(OPT_ftrivial_auto_var_init)) {
+    StringRef Val = A->getValue();
+    if (Val == "uninitialized")
+      Opts.setTrivialAutoVarInit(
+          LangOptions::TrivialAutoVarInitKind::Uninitialized);
+    else if (Val == "zero")
+      Opts.setTrivialAutoVarInit(LangOptions::TrivialAutoVarInitKind::Zero);
+    else if (Val == "pattern")
+      Opts.setTrivialAutoVarInit(LangOptions::TrivialAutoVarInitKind::Pattern);
+    else
+      Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Val;
+  }
+
   // Parse -fsanitize= arguments.
   parseSanitizerKinds("-fsanitize=", Args.getAllArgValues(OPT_fsanitize_EQ),
                       Diags, Opts.Sanitize);
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index 829bc9a104..63501d9291 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -6085,6 +6085,14 @@ static void handleDestroyAttr(Sema &S, Decl *D, const ParsedAttr &A) {
     handleSimpleAttributeWithExclusions(S, D, A);
 }
 
+static void handleUninitializedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
+  assert(cast(D)->getStorageDuration() == SD_Automatic &&
+         "uninitialized is only valid on automatic duration variables");
+  unsigned Index = AL.getAttributeSpellingListIndex();
+  D->addAttr(::new (S.Context)
+                 UninitializedAttr(AL.getLoc(), S.Context, Index));
+}
+
 //===----------------------------------------------------------------------===//
 // Top Level Sema Entry Points
 //===----------------------------------------------------------------------===//
@@ -6776,6 +6784,10 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
   case ParsedAttr::AT_NoDestroy:
     handleDestroyAttr(S, D, AL);
     break;
+
+  case ParsedAttr::AT_Uninitialized:
+    handleUninitializedAttr(S, D, AL);
+    break;
   }
 }
 
diff --git a/test/CodeGenCXX/auto-var-init.cpp b/test/CodeGenCXX/auto-var-init.cpp
index f9fe986ef6..0d13c0af4e 100644
--- a/test/CodeGenCXX/auto-var-init.cpp
+++ b/test/CodeGenCXX/auto-var-init.cpp
@@ -1,4 +1,6 @@
 // RUN: %clang_cc1 -triple x86_64-unknown-unknown -fblocks %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fblocks -ftrivial-auto-var-init=pattern %s -emit-llvm -o - | FileCheck %s -check-prefix=PATTERN
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fblocks -ftrivial-auto-var-init=zero %s -emit-llvm -o - | FileCheck %s -check-prefix=ZERO
 
 template void used(T &) noexcept;
 
@@ -24,28 +26,108 @@ template void used(T &) noexcept;
     used(custom);                               \
   }
 
+// None of the synthesized globals should contain `undef`.
+// PATTERN-NOT: undef
+// ZERO-NOT: undef
+
+// PATTERN: @__const.test_empty_uninit.uninit = private unnamed_addr constant %struct.empty { i8 -86 }, align 1
 struct empty {};
+// PATTERN: @__const.test_small_uninit.uninit = private unnamed_addr constant %struct.small { i8 -86 }, align 1
+// PATTERN: @__const.test_small_custom.custom = private unnamed_addr constant %struct.small { i8 42 }, align 1
+// ZERO: @__const.test_small_custom.custom = private unnamed_addr constant %struct.small { i8 42 }, align 1
 struct small { char c; };
+// PATTERN: @__const.test_smallinit_uninit.uninit = private unnamed_addr constant %struct.smallinit { i8 -86 }, align 1
+// PATTERN: @__const.test_smallinit_braces.braces = private unnamed_addr constant %struct.smallinit { i8 -86 }, align 1
+// PATTERN: @__const.test_smallinit_custom.custom = private unnamed_addr constant %struct.smallinit { i8 -86 }, align 1
 struct smallinit { char c = 42; };
+// PATTERN: @__const.test_smallpartinit_uninit.uninit = private unnamed_addr constant %struct.smallpartinit { i8 -86, i8 -86 }, align 1
+// PATTERN: @__const.test_smallpartinit_braces.braces = private unnamed_addr constant %struct.smallpartinit { i8 -86, i8 -86 }, align 1
+// PATTERN: @__const.test_smallpartinit_custom.custom = private unnamed_addr constant %struct.smallpartinit { i8 -86, i8 -86 }, align 1
 struct smallpartinit { char c = 42, d; };
+// PATTERN: @__const.test_nullinit_uninit.uninit = private unnamed_addr constant %struct.nullinit { i8* inttoptr (i64 -6148914691236517206 to i8*) }, align 8
+// PATTERN: @__const.test_nullinit_braces.braces = private unnamed_addr constant %struct.nullinit { i8* inttoptr (i64 -6148914691236517206 to i8*) }, align 8
+// PATTERN: @__const.test_nullinit_custom.custom = private unnamed_addr constant %struct.nullinit { i8* inttoptr (i64 -6148914691236517206 to i8*) }, align 8
 struct nullinit { char* null = nullptr; };
+// PATTERN: @__const.test_padded_uninit.uninit = private unnamed_addr constant %struct.padded { i8 -86, i32 -1431655766 }, align 4
+// PATTERN: @__const.test_padded_custom.custom = private unnamed_addr constant %struct.padded { i8 42, i32 13371337 }, align 4
+// ZERO: @__const.test_padded_custom.custom = private unnamed_addr constant %struct.padded { i8 42, i32 13371337 }, align 4
 struct padded { char c; int i; };
+// PATTERN: @__const.test_paddednullinit_uninit.uninit = private unnamed_addr constant %struct.paddednullinit { i8 -86, i32 -1431655766 }, align 4
+// PATTERN: @__const.test_paddednullinit_braces.braces = private unnamed_addr constant %struct.paddednullinit { i8 -86, i32 -1431655766 }, align 4
+// PATTERN: @__const.test_paddednullinit_custom.custom = private unnamed_addr constant %struct.paddednullinit { i8 -86, i32 -1431655766 }, align 4
 struct paddednullinit { char c = 0; int i = 0; };
+// PATTERN: @__const.test_bitfield_uninit.uninit = private unnamed_addr constant %struct.bitfield { i8 -86, [3 x i8] c"\AA\AA\AA" }, align 4
+// PATTERN: @__const.test_bitfield_custom.custom = private unnamed_addr constant %struct.bitfield { i8 20, [3 x i8] zeroinitializer }, align 4
+// ZERO: @__const.test_bitfield_custom.custom = private unnamed_addr constant %struct.bitfield { i8 20, [3 x i8] zeroinitializer }, align 4
 struct bitfield { int i : 4; int j : 2; };
+// PATTERN: @__const.test_bitfieldaligned_uninit.uninit = private unnamed_addr constant %struct.bitfieldaligned { i8 -86, [3 x i8] c"\AA\AA\AA", i8 -86, [3 x i8] c"\AA\AA\AA" }, align 4
+// PATTERN: @__const.test_bitfieldaligned_custom.custom = private unnamed_addr constant %struct.bitfieldaligned { i8 4, [3 x i8] zeroinitializer, i8 1, [3 x i8] zeroinitializer }, align 4
+// ZERO: @__const.test_bitfieldaligned_custom.custom = private unnamed_addr constant %struct.bitfieldaligned { i8 4, [3 x i8] zeroinitializer, i8 1, [3 x i8] zeroinitializer }, align 4
 struct bitfieldaligned { int i : 4; int : 0; int j : 2; };
 struct big { unsigned a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z; };
+// PATTERN: @__const.test_arraytail_uninit.uninit = private unnamed_addr constant %struct.arraytail { i32 -1431655766, [0 x i32] zeroinitializer }, align 4
+// PATTERN: @__const.test_arraytail_custom.custom = private unnamed_addr constant %struct.arraytail { i32 57005, [0 x i32] zeroinitializer }, align 4
+// ZERO: @__const.test_arraytail_custom.custom = private unnamed_addr constant %struct.arraytail { i32 57005, [0 x i32] zeroinitializer }, align 4
 struct arraytail { int i; int arr[]; };
+// PATTERN: @__const.test_int1_uninit.uninit = private unnamed_addr constant [1 x i32] [i32 -1431655766], align 4
+// PATTERN: @__const.test_int1_custom.custom = private unnamed_addr constant [1 x i32] [i32 858993459], align 4
+// ZERO: @__const.test_int1_custom.custom = private unnamed_addr constant [1 x i32] [i32 858993459], align 4
+// PATTERN: @__const.test_bool4_uninit.uninit = private unnamed_addr constant [4 x i8] c"\AA\AA\AA\AA", align 1
+// PATTERN: @__const.test_bool4_custom.custom = private unnamed_addr constant [4 x i8] c"\01\01\01\01", align 1
+// ZERO: @__const.test_bool4_custom.custom = private unnamed_addr constant [4 x i8] c"\01\01\01\01", align 1
+// PATTERN: @__const.test_intptr4_uninit.uninit = private unnamed_addr constant [4 x i32*] [i32* inttoptr (i64 -6148914691236517206 to i32*), i32* inttoptr (i64 -6148914691236517206 to i32*), i32* inttoptr (i64 -6148914691236517206 to i32*), i32* inttoptr (i64 -6148914691236517206 to i32*)], align 16
+// PATTERN: @__const.test_intptr4_custom.custom = private unnamed_addr constant [4 x i32*] [i32* inttoptr (i64 572662306 to i32*), i32* inttoptr (i64 572662306 to i32*), i32* inttoptr (i64 572662306 to i32*), i32* inttoptr (i64 572662306 to i32*)], align 16
+// ZERO: @__const.test_intptr4_custom.custom = private unnamed_addr constant [4 x i32*] [i32* inttoptr (i64 572662306 to i32*), i32* inttoptr (i64 572662306 to i32*), i32* inttoptr (i64 572662306 to i32*), i32* inttoptr (i64 572662306 to i32*)], align 16
+// PATTERN: @__const.test_tailpad4_uninit.uninit = private unnamed_addr constant [4 x %struct.tailpad] [%struct.tailpad { i16 -21846, i8 -86 }, %struct.tailpad { i16 -21846, i8 -86 }, %struct.tailpad { i16 -21846, i8 -86 }, %struct.tailpad { i16 -21846, i8 -86 }], align 16
+// PATTERN: @__const.test_tailpad4_custom.custom = private unnamed_addr constant [4 x %struct.tailpad] [%struct.tailpad { i16 257, i8 1 }, %struct.tailpad { i16 257, i8 1 }, %struct.tailpad { i16 257, i8 1 }, %struct.tailpad { i16 257, i8 1 }], align 16
+// ZERO: @__const.test_tailpad4_custom.custom = private unnamed_addr constant [4 x %struct.tailpad] [%struct.tailpad { i16 257, i8 1 }, %struct.tailpad { i16 257, i8 1 }, %struct.tailpad { i16 257, i8 1 }, %struct.tailpad { i16 257, i8 1 }], align 16
 struct tailpad { short s; char c; };
+// PATTERN: @__const.test_atomicnotlockfree_uninit.uninit = private unnamed_addr constant %struct.notlockfree { [4 x i64] [i64 -6148914691236517206, i64 -6148914691236517206, i64 -6148914691236517206, i64 -6148914691236517206] }, align 8
 struct notlockfree { long long a[4]; };
+// PATTERN: @__const.test_atomicpadded_uninit.uninit = private unnamed_addr constant %struct.padded { i8 -86, i32 -1431655766 }, align 8
+// PATTERN: @__const.test_atomictailpad_uninit.uninit = private unnamed_addr constant %struct.tailpad { i16 -21846, i8 -86 }, align 4
+// PATTERN: @__const.test_complexfloat_uninit.uninit = private unnamed_addr constant { float, float } { float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000 }, align 4
+// PATTERN: @__const.test_complexfloat_braces.braces = private unnamed_addr constant { float, float } { float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000 }, align 4
+// PATTERN: @__const.test_complexfloat_custom.custom = private unnamed_addr constant { float, float } { float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000 }, align 4
+// PATTERN: @__const.test_complexdouble_uninit.uninit = private unnamed_addr constant { double, double } { double 0xFFFFFFFFFFFFFFFF, double 0xFFFFFFFFFFFFFFFF }, align 8
+// PATTERN: @__const.test_complexdouble_braces.braces = private unnamed_addr constant { double, double } { double 0xFFFFFFFFFFFFFFFF, double 0xFFFFFFFFFFFFFFFF }, align 8
+// PATTERN: @__const.test_complexdouble_custom.custom = private unnamed_addr constant { double, double } { double 0xFFFFFFFFFFFFFFFF, double 0xFFFFFFFFFFFFFFFF }, align 8
+// PATTERN: @__const.test_semivolatile_uninit.uninit = private unnamed_addr constant %struct.semivolatile { i32 -1431655766, i32 -1431655766 }, align 4
+// PATTERN: @__const.test_semivolatile_custom.custom = private unnamed_addr constant %struct.semivolatile { i32 1145324612, i32 1145324612 }, align 4
 struct semivolatile { int i; volatile int vi; };
+// PATTERN: @__const.test_semivolatileinit_uninit.uninit = private unnamed_addr constant %struct.semivolatileinit { i32 -1431655766, i32 -1431655766 }, align 4
+// PATTERN: @__const.test_semivolatileinit_braces.braces = private unnamed_addr constant %struct.semivolatileinit { i32 -1431655766, i32 -1431655766 }, align 4
+// PATTERN: @__const.test_semivolatileinit_custom.custom = private unnamed_addr constant %struct.semivolatileinit { i32 -1431655766, i32 -1431655766 }, align 4
+// ZERO: @__const.test_semivolatile_custom.custom = private unnamed_addr constant %struct.semivolatile { i32 1145324612, i32 1145324612 }, align 4
 struct semivolatileinit { int i = 0x11111111; volatile int vi = 0x11111111; };
+// PATTERN: @__const.test_base_uninit.uninit = private unnamed_addr constant %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) }, align 8
+// PATTERN: @__const.test_base_braces.braces = private unnamed_addr constant %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) }, align 8
 struct base { virtual ~base(); };
+// PATTERN: @__const.test_derived_uninit.uninit = private unnamed_addr constant %struct.derived { %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) } }, align 8
+// PATTERN: @__const.test_derived_braces.braces = private unnamed_addr constant %struct.derived { %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) } }, align 8
 struct derived : public base {};
+// PATTERN: @__const.test_virtualderived_uninit.uninit = private unnamed_addr constant %struct.virtualderived { %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) }, %struct.derived { %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) } } }, align 8
+// PATTERN: @__const.test_virtualderived_braces.braces = private unnamed_addr constant %struct.virtualderived { %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) }, %struct.derived { %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) } } }, align 8
 struct virtualderived : public virtual base, public virtual derived {};
+// PATTERN: @__const.test_matching_uninit.uninit = private unnamed_addr constant %union.matching { i32 -1431655766 }, align 4
+// PATTERN: @__const.test_matching_custom.custom = private unnamed_addr constant { float } { float 6.145500e+04 }, align 4
 union matching { int i; float f; };
+// PATTERN: @__const.test_matchingreverse_uninit.uninit = private unnamed_addr constant %union.matchingreverse { float 0xFFFFFFFFE0000000 }, align 4
+// PATTERN: @__const.test_matchingreverse_custom.custom = private unnamed_addr constant { i32 } { i32 61455 }, align 4
+// ZERO: @__const.test_matching_custom.custom = private unnamed_addr constant { float } { float 6.145500e+04 }, align 4
 union matchingreverse { float f; int i; };
+// PATTERN: @__const.test_unmatched_uninit.uninit = private unnamed_addr constant %union.unmatched { i32 -1431655766 }, align 4
+// PATTERN: @__const.test_unmatched_custom.custom = private unnamed_addr constant %union.unmatched { i32 1001242351 }, align 4
+// ZERO: @__const.test_matchingreverse_custom.custom = private unnamed_addr constant { i32 } { i32 61455 }, align 4
 union unmatched { char c; int i; };
+// PATTERN: @__const.test_unmatchedreverse_uninit.uninit = private unnamed_addr constant %union.unmatchedreverse { i32 -1431655766 }, align 4
+// PATTERN: @__const.test_unmatchedreverse_custom.custom = private unnamed_addr constant { i8, [3 x i8] } { i8 42, [3 x i8] zeroinitializer }, align 4
+// ZERO: @__const.test_unmatched_custom.custom = private unnamed_addr constant %union.unmatched { i32 1001242351 }, align 4
 union unmatchedreverse { int i; char c; };
+// PATTERN: @__const.test_unmatchedfp_uninit.uninit = private unnamed_addr constant %union.unmatchedfp { double 0xFFFFFFFFFFFFFFFF }, align 8
+// PATTERN: @__const.test_unmatchedfp_custom.custom = private unnamed_addr constant %union.unmatchedfp { double 0x400921FB54442D18 }, align 8
+// ZERO: @__const.test_unmatchedreverse_custom.custom = private unnamed_addr constant { i8, [3 x i8] } { i8 42, [3 x i8] zeroinitializer }, align 4
+// ZERO: @__const.test_unmatchedfp_custom.custom = private unnamed_addr constant %union.unmatchedfp { double 0x400921FB54442D18 }, align 8
 union unmatchedfp { float f; double d; };
 enum emptyenum {};
 enum smallenum { VALUE };
@@ -56,6 +138,10 @@ TEST_UNINIT(char, char);
 // CHECK-LABEL: @test_char_uninit()
 // CHECK:       %uninit = alloca i8, align
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_char_uninit()
+// PATTERN: store i8 -86, i8* %uninit, align 1
+// ZERO-LABEL: @test_char_uninit()
+// ZERO: store i8 0, i8* %uninit, align 1
 
 TEST_BRACES(char, char);
 // CHECK-LABEL: @test_char_braces()
@@ -67,6 +153,10 @@ TEST_UNINIT(uchar, unsigned char);
 // CHECK-LABEL: @test_uchar_uninit()
 // CHECK:       %uninit = alloca i8, align
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_uchar_uninit()
+// PATTERN: store i8 -86, i8* %uninit, align 1
+// ZERO-LABEL: @test_uchar_uninit()
+// ZERO: store i8 0, i8* %uninit, align 1
 
 TEST_BRACES(uchar, unsigned char);
 // CHECK-LABEL: @test_uchar_braces()
@@ -78,6 +168,10 @@ TEST_UNINIT(schar, signed char);
 // CHECK-LABEL: @test_schar_uninit()
 // CHECK:       %uninit = alloca i8, align
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_schar_uninit()
+// PATTERN: store i8 -86, i8* %uninit, align 1
+// ZERO-LABEL: @test_schar_uninit()
+// ZERO: store i8 0, i8* %uninit, align 1
 
 TEST_BRACES(schar, signed char);
 // CHECK-LABEL: @test_schar_braces()
@@ -89,6 +183,10 @@ TEST_UNINIT(wchar_t, wchar_t);
 // CHECK-LABEL: @test_wchar_t_uninit()
 // CHECK:       %uninit = alloca i32, align
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_wchar_t_uninit()
+// PATTERN: store i32 -1431655766, i32* %uninit, align
+// ZERO-LABEL: @test_wchar_t_uninit()
+// ZERO: store i32 0, i32* %uninit, align
 
 TEST_BRACES(wchar_t, wchar_t);
 // CHECK-LABEL: @test_wchar_t_braces()
@@ -100,6 +198,10 @@ TEST_UNINIT(short, short);
 // CHECK-LABEL: @test_short_uninit()
 // CHECK:       %uninit = alloca i16, align
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_short_uninit()
+// PATTERN: store i16 -21846, i16* %uninit, align
+// ZERO-LABEL: @test_short_uninit()
+// ZERO: store i16 0, i16* %uninit, align
 
 TEST_BRACES(short, short);
 // CHECK-LABEL: @test_short_braces()
@@ -111,6 +213,10 @@ TEST_UNINIT(ushort, unsigned short);
 // CHECK-LABEL: @test_ushort_uninit()
 // CHECK:       %uninit = alloca i16, align
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_ushort_uninit()
+// PATTERN: store i16 -21846, i16* %uninit, align
+// ZERO-LABEL: @test_ushort_uninit()
+// ZERO: store i16 0, i16* %uninit, align
 
 TEST_BRACES(ushort, unsigned short);
 // CHECK-LABEL: @test_ushort_braces()
@@ -122,6 +228,10 @@ TEST_UNINIT(int, int);
 // CHECK-LABEL: @test_int_uninit()
 // CHECK:       %uninit = alloca i32, align
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_int_uninit()
+// PATTERN: store i32 -1431655766, i32* %uninit, align
+// ZERO-LABEL: @test_int_uninit()
+// ZERO: store i32 0, i32* %uninit, align
 
 TEST_BRACES(int, int);
 // CHECK-LABEL: @test_int_braces()
@@ -133,6 +243,10 @@ TEST_UNINIT(unsigned, unsigned);
 // CHECK-LABEL: @test_unsigned_uninit()
 // CHECK:       %uninit = alloca i32, align
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_unsigned_uninit()
+// PATTERN: store i32 -1431655766, i32* %uninit, align
+// ZERO-LABEL: @test_unsigned_uninit()
+// ZERO: store i32 0, i32* %uninit, align
 
 TEST_BRACES(unsigned, unsigned);
 // CHECK-LABEL: @test_unsigned_braces()
@@ -144,6 +258,10 @@ TEST_UNINIT(long, long);
 // CHECK-LABEL: @test_long_uninit()
 // CHECK:       %uninit = alloca i64, align
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_long_uninit()
+// PATTERN: store i64 -6148914691236517206, i64* %uninit, align
+// ZERO-LABEL: @test_long_uninit()
+// ZERO: store i64 0, i64* %uninit, align
 
 TEST_BRACES(long, long);
 // CHECK-LABEL: @test_long_braces()
@@ -155,6 +273,10 @@ TEST_UNINIT(ulong, unsigned long);
 // CHECK-LABEL: @test_ulong_uninit()
 // CHECK:       %uninit = alloca i64, align
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_ulong_uninit()
+// PATTERN: store i64 -6148914691236517206, i64* %uninit, align
+// ZERO-LABEL: @test_ulong_uninit()
+// ZERO: store i64 0, i64* %uninit, align
 
 TEST_BRACES(ulong, unsigned long);
 // CHECK-LABEL: @test_ulong_braces()
@@ -166,6 +288,10 @@ TEST_UNINIT(longlong, long long);
 // CHECK-LABEL: @test_longlong_uninit()
 // CHECK:       %uninit = alloca i64, align
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_longlong_uninit()
+// PATTERN: store i64 -6148914691236517206, i64* %uninit, align
+// ZERO-LABEL: @test_longlong_uninit()
+// ZERO: store i64 0, i64* %uninit, align
 
 TEST_BRACES(longlong, long long);
 // CHECK-LABEL: @test_longlong_braces()
@@ -177,6 +303,10 @@ TEST_UNINIT(ulonglong, unsigned long long);
 // CHECK-LABEL: @test_ulonglong_uninit()
 // CHECK:       %uninit = alloca i64, align
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_ulonglong_uninit()
+// PATTERN: store i64 -6148914691236517206, i64* %uninit, align
+// ZERO-LABEL: @test_ulonglong_uninit()
+// ZERO: store i64 0, i64* %uninit, align
 
 TEST_BRACES(ulonglong, unsigned long long);
 // CHECK-LABEL: @test_ulonglong_braces()
@@ -188,6 +318,10 @@ TEST_UNINIT(int128, __int128);
 // CHECK-LABEL: @test_int128_uninit()
 // CHECK:       %uninit = alloca i128, align
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_int128_uninit()
+// PATTERN: store i128 -113427455640312821154458202477256070486, i128* %uninit, align
+// ZERO-LABEL: @test_int128_uninit()
+// ZERO: store i128 0, i128* %uninit, align
 
 TEST_BRACES(int128, __int128);
 // CHECK-LABEL: @test_int128_braces()
@@ -199,6 +333,10 @@ TEST_UNINIT(uint128, unsigned __int128);
 // CHECK-LABEL: @test_uint128_uninit()
 // CHECK:       %uninit = alloca i128, align
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_uint128_uninit()
+// PATTERN: store i128 -113427455640312821154458202477256070486, i128* %uninit, align
+// ZERO-LABEL: @test_uint128_uninit()
+// ZERO: store i128 0, i128* %uninit, align
 
 TEST_BRACES(uint128, unsigned __int128);
 // CHECK-LABEL: @test_uint128_braces()
@@ -211,6 +349,10 @@ TEST_UNINIT(fp16, __fp16);
 // CHECK-LABEL: @test_fp16_uninit()
 // CHECK:       %uninit = alloca half, align
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_fp16_uninit()
+// PATTERN: store half 0xHFFFF, half* %uninit, align
+// ZERO-LABEL: @test_fp16_uninit()
+// ZERO: store half 0xH0000, half* %uninit, align
 
 TEST_BRACES(fp16, __fp16);
 // CHECK-LABEL: @test_fp16_braces()
@@ -222,6 +364,10 @@ TEST_UNINIT(float, float);
 // CHECK-LABEL: @test_float_uninit()
 // CHECK:       %uninit = alloca float, align
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_float_uninit()
+// PATTERN: store float 0xFFFFFFFFE0000000, float* %uninit, align
+// ZERO-LABEL: @test_float_uninit()
+// ZERO: store float 0.000000e+00, float* %uninit, align
 
 TEST_BRACES(float, float);
 // CHECK-LABEL: @test_float_braces()
@@ -233,6 +379,10 @@ TEST_UNINIT(double, double);
 // CHECK-LABEL: @test_double_uninit()
 // CHECK:       %uninit = alloca double, align
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_double_uninit()
+// PATTERN: store double 0xFFFFFFFFFFFFFFFF, double* %uninit, align
+// ZERO-LABEL: @test_double_uninit()
+// ZERO: store double 0.000000e+00, double* %uninit, align
 
 TEST_BRACES(double, double);
 // CHECK-LABEL: @test_double_braces()
@@ -244,6 +394,10 @@ TEST_UNINIT(longdouble, long double);
 // CHECK-LABEL: @test_longdouble_uninit()
 // CHECK:       %uninit = alloca x86_fp80, align
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_longdouble_uninit()
+// PATTERN: store x86_fp80 0xKFFFFFFFFFFFFFFFFFFFF, x86_fp80* %uninit, align
+// ZERO-LABEL: @test_longdouble_uninit()
+// ZERO: store x86_fp80 0xK00000000000000000000, x86_fp80* %uninit, align
 
 TEST_BRACES(longdouble, long double);
 // CHECK-LABEL: @test_longdouble_braces()
@@ -256,6 +410,10 @@ TEST_UNINIT(intptr, int*);
 // CHECK-LABEL: @test_intptr_uninit()
 // CHECK:       %uninit = alloca i32*, align
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_intptr_uninit()
+// PATTERN: store i32* inttoptr (i64 -6148914691236517206 to i32*), i32** %uninit, align
+// ZERO-LABEL: @test_intptr_uninit()
+// ZERO: store i32* null, i32** %uninit, align
 
 TEST_BRACES(intptr, int*);
 // CHECK-LABEL: @test_intptr_braces()
@@ -267,6 +425,10 @@ TEST_UNINIT(intptrptr, int**);
 // CHECK-LABEL: @test_intptrptr_uninit()
 // CHECK:       %uninit = alloca i32**, align
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_intptrptr_uninit()
+// PATTERN: store i32** inttoptr (i64 -6148914691236517206 to i32**), i32*** %uninit, align
+// ZERO-LABEL: @test_intptrptr_uninit()
+// ZERO: store i32** null, i32*** %uninit, align
 
 TEST_BRACES(intptrptr, int**);
 // CHECK-LABEL: @test_intptrptr_braces()
@@ -278,6 +440,10 @@ TEST_UNINIT(function, void(*)());
 // CHECK-LABEL: @test_function_uninit()
 // CHECK:       %uninit = alloca void ()*, align
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_function_uninit()
+// PATTERN: store void ()* inttoptr (i64 -6148914691236517206 to void ()*), void ()** %uninit, align
+// ZERO-LABEL: @test_function_uninit()
+// ZERO: store void ()* null, void ()** %uninit, align
 
 TEST_BRACES(function, void(*)());
 // CHECK-LABEL: @test_function_braces()
@@ -289,6 +455,10 @@ TEST_UNINIT(bool, bool);
 // CHECK-LABEL: @test_bool_uninit()
 // CHECK:       %uninit = alloca i8, align
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_bool_uninit()
+// PATTERN: store i8 -86, i8* %uninit, align 1
+// ZERO-LABEL: @test_bool_uninit()
+// ZERO: store i8 0, i8* %uninit, align 1
 
 TEST_BRACES(bool, bool);
 // CHECK-LABEL: @test_bool_braces()
@@ -301,6 +471,10 @@ TEST_UNINIT(empty, empty);
 // CHECK-LABEL: @test_empty_uninit()
 // CHECK:       %uninit = alloca %struct.empty, align
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_empty_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_empty_uninit.uninit
+// ZERO-LABEL: @test_empty_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
 
 TEST_BRACES(empty, empty);
 // CHECK-LABEL: @test_empty_braces()
@@ -313,6 +487,10 @@ TEST_UNINIT(small, small);
 // CHECK-LABEL: @test_small_uninit()
 // CHECK:       %uninit = alloca %struct.small, align
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_small_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_small_uninit.uninit
+// ZERO-LABEL: @test_small_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
 
 TEST_BRACES(small, small);
 // CHECK-LABEL: @test_small_braces()
@@ -321,7 +499,7 @@ TEST_BRACES(small, small);
 // CHECK-NEXT:  call void @llvm.memset{{.*}}(i8* align [[ALIGN]] %{{.*}}, i8 0, i64 1, i1 false)
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%braces)
 
-  TEST_CUSTOM(small, small, { 42 });
+TEST_CUSTOM(small, small, { 42 });
 // CHECK-LABEL: @test_small_custom()
 // CHECK:       %custom = alloca %struct.small, align
 // CHECK-NEXT:  bitcast
@@ -353,6 +531,10 @@ TEST_UNINIT(smallpartinit, smallpartinit);
 // CHECK:       %uninit = alloca %struct.smallpartinit, align
 // CHECK-NEXT:  call void @{{.*}}smallpartinit{{.*}}%uninit)
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_smallpartinit_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_smallpartinit_uninit.uninit
+// ZERO-LABEL: @test_smallpartinit_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
 
 TEST_BRACES(smallpartinit, smallpartinit);
 // CHECK-LABEL: @test_smallpartinit_braces()
@@ -396,6 +578,10 @@ TEST_UNINIT(padded, padded);
 // CHECK-LABEL: @test_padded_uninit()
 // CHECK:       %uninit = alloca %struct.padded, align
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_padded_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_padded_uninit.uninit
+// ZERO-LABEL: @test_padded_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
 
 TEST_BRACES(padded, padded);
 // CHECK-LABEL: @test_padded_braces()
@@ -416,6 +602,10 @@ TEST_UNINIT(paddednullinit, paddednullinit);
 // CHECK:       %uninit = alloca %struct.paddednullinit, align
 // CHECK-NEXT:  call void @{{.*}}paddednullinit{{.*}}%uninit)
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_paddednullinit_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_paddednullinit_uninit.uninit
+// ZERO-LABEL: @test_paddednullinit_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
 
 TEST_BRACES(paddednullinit, paddednullinit);
 // CHECK-LABEL: @test_paddednullinit_braces()
@@ -439,6 +629,10 @@ TEST_UNINIT(bitfield, bitfield);
 // CHECK-LABEL: @test_bitfield_uninit()
 // CHECK:       %uninit = alloca %struct.bitfield, align
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_bitfield_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_bitfield_uninit.uninit
+// ZERO-LABEL: @test_bitfield_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
 
 TEST_BRACES(bitfield, bitfield);
 // CHECK-LABEL: @test_bitfield_braces()
@@ -458,6 +652,10 @@ TEST_UNINIT(bitfieldaligned, bitfieldaligned);
 // CHECK-LABEL: @test_bitfieldaligned_uninit()
 // CHECK:       %uninit = alloca %struct.bitfieldaligned, align
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_bitfieldaligned_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_bitfieldaligned_uninit.uninit
+// ZERO-LABEL: @test_bitfieldaligned_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
 
 TEST_BRACES(bitfieldaligned, bitfieldaligned);
 // CHECK-LABEL: @test_bitfieldaligned_braces()
@@ -477,6 +675,10 @@ TEST_UNINIT(big, big);
 // CHECK-LABEL: @test_big_uninit()
 // CHECK:       %uninit = alloca %struct.big, align
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_big_uninit()
+// PATTERN: call void @llvm.memset{{.*}}, i8 -86,
+// ZERO-LABEL: @test_big_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
 
 TEST_BRACES(big, big);
 // CHECK-LABEL: @test_big_braces()
@@ -496,6 +698,10 @@ TEST_UNINIT(arraytail, arraytail);
 // CHECK-LABEL: @test_arraytail_uninit()
 // CHECK:       %uninit = alloca %struct.arraytail, align
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_arraytail_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_arraytail_uninit.uninit
+// ZERO-LABEL: @test_arraytail_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
 
 TEST_BRACES(arraytail, arraytail);
 // CHECK-LABEL: @test_arraytail_braces()
@@ -516,6 +722,12 @@ TEST_UNINIT(int0, int[0]);
 // CHECK-LABEL: @test_int0_uninit()
 // CHECK:       %uninit = alloca [0 x i32], align
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_int0_uninit()
+// PATTERN:       %uninit = alloca [0 x i32], align
+// PATTERN-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// ZERO-LABEL: @test_int0_uninit()
+// ZERO:       %uninit = alloca [0 x i32], align
+// ZERO-NEXT:  call void @{{.*}}used{{.*}}%uninit)
 
 TEST_BRACES(int0, int[0]);
 // CHECK-LABEL: @test_int0_braces()
@@ -528,6 +740,10 @@ TEST_UNINIT(int1, int[1]);
 // CHECK-LABEL: @test_int1_uninit()
 // CHECK:       %uninit = alloca [1 x i32], align [[ALIGN:[0-9]*]]
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_int1_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_int1_uninit.uninit
+// ZERO-LABEL: @test_int1_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
 
 TEST_BRACES(int1, int[1]);
 // CHECK-LABEL: @test_int1_braces()
@@ -547,6 +763,10 @@ TEST_UNINIT(int64, int[64]);
 // CHECK-LABEL: @test_int64_uninit()
 // CHECK:       %uninit = alloca [64 x i32], align
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_int64_uninit()
+// PATTERN: call void @llvm.memset{{.*}}, i8 -86,
+// ZERO-LABEL: @test_int64_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
 
 TEST_BRACES(int64, int[64]);
 // CHECK-LABEL: @test_int64_braces()
@@ -566,6 +786,10 @@ TEST_UNINIT(bool4, bool[4]);
 // CHECK-LABEL: @test_bool4_uninit()
 // CHECK:       %uninit = alloca [4 x i8], align
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_bool4_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_bool4_uninit.uninit
+// ZERO-LABEL: @test_bool4_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
 
 TEST_BRACES(bool4, bool[4]);
 // CHECK-LABEL: @test_bool4_braces()
@@ -585,6 +809,10 @@ TEST_UNINIT(intptr4, int*[4]);
 // CHECK-LABEL: @test_intptr4_uninit()
 // CHECK:       %uninit = alloca [4 x i32*], align
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_intptr4_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_intptr4_uninit.uninit
+// ZERO-LABEL: @test_intptr4_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
 
 TEST_BRACES(intptr4, int*[4]);
 // CHECK-LABEL: @test_intptr4_braces()
@@ -604,6 +832,10 @@ TEST_UNINIT(tailpad4, tailpad[4]);
 // CHECK-LABEL: @test_tailpad4_uninit()
 // CHECK:       %uninit = alloca [4 x %struct.tailpad], align
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_tailpad4_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_tailpad4_uninit.uninit
+// ZERO-LABEL: @test_tailpad4_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
 
 TEST_BRACES(tailpad4, tailpad[4]);
 // CHECK-LABEL: @test_tailpad4_braces()
@@ -623,6 +855,10 @@ TEST_UNINIT(tailpad9, tailpad[9]);
 // CHECK-LABEL: @test_tailpad9_uninit()
 // CHECK:       %uninit = alloca [9 x %struct.tailpad], align
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_tailpad9_uninit()
+// PATTERN: call void @llvm.memset{{.*}}, i8 -86,
+// ZERO-LABEL: @test_tailpad9_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
 
 TEST_BRACES(tailpad9, tailpad[9]);
 // CHECK-LABEL: @test_tailpad9_braces()
@@ -643,37 +879,65 @@ TEST_UNINIT(atomicbool, _Atomic(bool));
 // CHECK-LABEL: @test_atomicbool_uninit()
 // CHECK:       %uninit = alloca i8, align
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_atomicbool_uninit()
+// PATTERN: store i8 -86, i8* %uninit, align 1
+// ZERO-LABEL: @test_atomicbool_uninit()
+// ZERO: store i8 0, i8* %uninit, align 1
 
 TEST_UNINIT(atomicint, _Atomic(int));
 // CHECK-LABEL: @test_atomicint_uninit()
 // CHECK:       %uninit = alloca i32, align
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_atomicint_uninit()
+// PATTERN: store i32 -1431655766, i32* %uninit, align 4
+// ZERO-LABEL: @test_atomicint_uninit()
+// ZERO: store i32 0, i32* %uninit, align 4
 
 TEST_UNINIT(atomicdouble, _Atomic(double));
 // CHECK-LABEL: @test_atomicdouble_uninit()
 // CHECK:       %uninit = alloca double, align
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_atomicdouble_uninit()
+// PATTERN: store double 0xFFFFFFFFFFFFFFFF, double* %uninit, align 8
+// ZERO-LABEL: @test_atomicdouble_uninit()
+// ZERO: store double 0.000000e+00, double* %uninit, align 8
 
 TEST_UNINIT(atomicnotlockfree, _Atomic(notlockfree));
 // CHECK-LABEL: @test_atomicnotlockfree_uninit()
 // CHECK:       %uninit = alloca %struct.notlockfree, align
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_atomicnotlockfree_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_atomicnotlockfree_uninit.uninit
+// ZERO-LABEL: @test_atomicnotlockfree_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
 
 TEST_UNINIT(atomicpadded, _Atomic(padded));
 // CHECK-LABEL: @test_atomicpadded_uninit()
 // CHECK:       %uninit = alloca %struct.padded, align
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_atomicpadded_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_atomicpadded_uninit.uninit
+// ZERO-LABEL: @test_atomicpadded_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
 
 TEST_UNINIT(atomictailpad, _Atomic(tailpad));
 // CHECK-LABEL: @test_atomictailpad_uninit()
 // CHECK:       %uninit = alloca %struct.tailpad, align
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_atomictailpad_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_atomictailpad_uninit.uninit
+// ZERO-LABEL: @test_atomictailpad_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
 
 
 TEST_UNINIT(complexfloat, _Complex float);
 // CHECK-LABEL: @test_complexfloat_uninit()
 // CHECK:       %uninit = alloca { float, float }, align
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_complexfloat_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_complexfloat_uninit.uninit
+// ZERO-LABEL: @test_complexfloat_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
 
 TEST_BRACES(complexfloat, _Complex float);
 // CHECK-LABEL: @test_complexfloat_braces()
@@ -697,6 +961,10 @@ TEST_UNINIT(complexdouble, _Complex double);
 // CHECK-LABEL: @test_complexdouble_uninit()
 // CHECK:       %uninit = alloca { double, double }, align
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_complexdouble_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_complexdouble_uninit.uninit
+// ZERO-LABEL: @test_complexdouble_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
 
 TEST_BRACES(complexdouble, _Complex double);
 // CHECK-LABEL: @test_complexdouble_braces()
@@ -721,6 +989,10 @@ TEST_UNINIT(volatileint, volatile int);
 // CHECK-LABEL: @test_volatileint_uninit()
 // CHECK:       %uninit = alloca i32, align
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_volatileint_uninit()
+// PATTERN: store volatile i32 -1431655766, i32* %uninit, align 4
+// ZERO-LABEL: @test_volatileint_uninit()
+// ZERO: store volatile i32 0, i32* %uninit, align 4
 
 TEST_BRACES(volatileint, volatile int);
 // CHECK-LABEL: @test_volatileint_braces()
@@ -732,6 +1004,10 @@ TEST_UNINIT(semivolatile, semivolatile);
 // CHECK-LABEL: @test_semivolatile_uninit()
 // CHECK:       %uninit = alloca %struct.semivolatile, align
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_semivolatile_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_semivolatile_uninit.uninit
+// ZERO-LABEL: @test_semivolatile_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
 
 TEST_BRACES(semivolatile, semivolatile);
 // CHECK-LABEL: @test_semivolatile_braces()
@@ -777,6 +1053,10 @@ TEST_UNINIT(base, base);
 // CHECK:       %uninit = alloca %struct.base, align
 // CHECK-NEXT:  call void @{{.*}}base{{.*}}%uninit)
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_base_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_base_uninit.uninit
+// ZERO-LABEL: @test_base_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
 
 TEST_BRACES(base, base);
 // CHECK-LABEL: @test_base_braces()
@@ -791,6 +1071,10 @@ TEST_UNINIT(derived, derived);
 // CHECK:       %uninit = alloca %struct.derived, align
 // CHECK-NEXT:  call void @{{.*}}derived{{.*}}%uninit)
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_derived_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_derived_uninit.uninit
+// ZERO-LABEL: @test_derived_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
 
 TEST_BRACES(derived, derived);
 // CHECK-LABEL: @test_derived_braces()
@@ -805,6 +1089,10 @@ TEST_UNINIT(virtualderived, virtualderived);
 // CHECK:       %uninit = alloca %struct.virtualderived, align
 // CHECK-NEXT:  call void @{{.*}}virtualderived{{.*}}%uninit)
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_virtualderived_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_virtualderived_uninit.uninit
+// ZERO-LABEL: @test_virtualderived_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
 
 TEST_BRACES(virtualderived, virtualderived);
 // CHECK-LABEL: @test_virtualderived_braces()
@@ -819,6 +1107,10 @@ TEST_UNINIT(matching, matching);
 // CHECK-LABEL: @test_matching_uninit()
 // CHECK:       %uninit = alloca %union.matching, align
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_matching_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_matching_uninit.uninit
+// ZERO-LABEL: @test_matching_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
 
 TEST_BRACES(matching, matching);
 // CHECK-LABEL: @test_matching_braces()
@@ -838,6 +1130,10 @@ TEST_UNINIT(matchingreverse, matchingreverse);
 // CHECK-LABEL: @test_matchingreverse_uninit()
 // CHECK:       %uninit = alloca %union.matchingreverse, align
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_matchingreverse_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_matchingreverse_uninit.uninit
+// ZERO-LABEL: @test_matchingreverse_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
 
 TEST_BRACES(matchingreverse, matchingreverse);
 // CHECK-LABEL: @test_matchingreverse_braces()
@@ -857,6 +1153,10 @@ TEST_UNINIT(unmatched, unmatched);
 // CHECK-LABEL: @test_unmatched_uninit()
 // CHECK:       %uninit = alloca %union.unmatched, align
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_unmatched_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_unmatched_uninit.uninit
+// ZERO-LABEL: @test_unmatched_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
 
 TEST_BRACES(unmatched, unmatched);
 // CHECK-LABEL: @test_unmatched_braces()
@@ -876,6 +1176,10 @@ TEST_UNINIT(unmatchedreverse, unmatchedreverse);
 // CHECK-LABEL: @test_unmatchedreverse_uninit()
 // CHECK:       %uninit = alloca %union.unmatchedreverse, align
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_unmatchedreverse_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_unmatchedreverse_uninit.uninit
+// ZERO-LABEL: @test_unmatchedreverse_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
 
 TEST_BRACES(unmatchedreverse, unmatchedreverse);
 // CHECK-LABEL: @test_unmatchedreverse_braces()
@@ -895,6 +1199,10 @@ TEST_UNINIT(unmatchedfp, unmatchedfp);
 // CHECK-LABEL: @test_unmatchedfp_uninit()
 // CHECK:       %uninit = alloca %union.unmatchedfp, align
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_unmatchedfp_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_unmatchedfp_uninit.uninit
+// ZERO-LABEL: @test_unmatchedfp_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
 
 TEST_BRACES(unmatchedfp, unmatchedfp);
 // CHECK-LABEL: @test_unmatchedfp_braces()
@@ -915,6 +1223,10 @@ TEST_UNINIT(emptyenum, emptyenum);
 // CHECK-LABEL: @test_emptyenum_uninit()
 // CHECK:       %uninit = alloca i32, align
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_emptyenum_uninit()
+// PATTERN: store i32 -1431655766, i32* %braces, align 4
+// ZERO-LABEL: @test_emptyenum_uninit()
+// ZERO: store i32 0, i32* %braces, align 4
 
 TEST_BRACES(emptyenum, emptyenum);
 // CHECK-LABEL: @test_emptyenum_braces()
@@ -932,6 +1244,10 @@ TEST_UNINIT(smallenum, smallenum);
 // CHECK-LABEL: @test_smallenum_uninit()
 // CHECK:       %uninit = alloca i32, align
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_smallenum_uninit()
+// PATTERN: store i32 -1431655766, i32* %braces, align 4
+// ZERO-LABEL: @test_smallenum_uninit()
+// ZERO: store i32 0, i32* %braces, align 4
 
 TEST_BRACES(smallenum, smallenum);
 // CHECK-LABEL: @test_smallenum_braces()
@@ -950,6 +1266,10 @@ TEST_UNINIT(intvec16, int  __attribute__((vector_size(16))));
 // CHECK-LABEL: @test_intvec16_uninit()
 // CHECK:       %uninit = alloca <4 x i32>, align
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_intvec16_uninit()
+// PATTERN: store <4 x i32> , <4 x i32>* %uninit, align 16
+// ZERO-LABEL: @test_intvec16_uninit()
+// ZERO: store <4 x i32> zeroinitializer, <4 x i32>* %uninit, align 16
 
 TEST_BRACES(intvec16, int  __attribute__((vector_size(16))));
 // CHECK-LABEL: @test_intvec16_braces()
@@ -957,7 +1277,7 @@ TEST_BRACES(intvec16, int  __attribute__((vector_size(16))));
 // CHECK-NEXT:  store <4 x i32> zeroinitializer, <4 x i32>* %braces, align [[ALIGN]]
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%braces)
 
-  TEST_CUSTOM(intvec16, int  __attribute__((vector_size(16))), { 0x44444444, 0x44444444, 0x44444444, 0x44444444 });
+TEST_CUSTOM(intvec16, int  __attribute__((vector_size(16))), { 0x44444444, 0x44444444, 0x44444444, 0x44444444 });
 // CHECK-LABEL: @test_intvec16_custom()
 // CHECK:       %custom = alloca <4 x i32>, align [[ALIGN:[0-9]*]]
 // CHECK-NEXT:  store <4 x i32> , <4 x i32>* %custom, align [[ALIGN]]
@@ -967,6 +1287,10 @@ TEST_UNINIT(longlongvec32, long long  __attribute__((vector_size(32))));
 // CHECK-LABEL: @test_longlongvec32_uninit()
 // CHECK:       %uninit = alloca <4 x i64>, align
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_longlongvec32_uninit()
+// PATTERN: store <4 x i64> , <4 x i64>* %uninit, align 32
+// ZERO-LABEL: @test_longlongvec32_uninit()
+// ZERO: store <4 x i64> zeroinitializer, <4 x i64>* %uninit, align 32
 
 TEST_BRACES(longlongvec32, long long  __attribute__((vector_size(32))));
 // CHECK-LABEL: @test_longlongvec32_braces()
@@ -984,6 +1308,10 @@ TEST_UNINIT(floatvec16, float  __attribute__((vector_size(16))));
 // CHECK-LABEL: @test_floatvec16_uninit()
 // CHECK:       %uninit = alloca <4 x float>, align
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_floatvec16_uninit()
+// PATTERN: store <4 x float> , <4 x float>* %uninit, align 16
+// ZERO-LABEL: @test_floatvec16_uninit()
+// ZERO: store <4 x float> zeroinitializer, <4 x float>* %uninit, align 16
 
 TEST_BRACES(floatvec16, float  __attribute__((vector_size(16))));
 // CHECK-LABEL: @test_floatvec16_braces()
@@ -1001,6 +1329,10 @@ TEST_UNINIT(doublevec32, double  __attribute__((vector_size(32))));
 // CHECK-LABEL: @test_doublevec32_uninit()
 // CHECK:       %uninit = alloca <4 x double>, align
 // CHECK-NEXT:  call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_doublevec32_uninit()
+// PATTERN: store <4 x double> , <4 x double>* %uninit, align 32
+// ZERO-LABEL: @test_doublevec32_uninit()
+// ZERO: store <4 x double> zeroinitializer, <4 x double>* %uninit, align 32
 
 TEST_BRACES(doublevec32, double  __attribute__((vector_size(32))));
 // CHECK-LABEL: @test_doublevec32_braces()
diff --git a/test/CodeGenCXX/trivial-auto-var-init-attribute.cpp b/test/CodeGenCXX/trivial-auto-var-init-attribute.cpp
new file mode 100644
index 0000000000..e7c9e9ac2a
--- /dev/null
+++ b/test/CodeGenCXX/trivial-auto-var-init-attribute.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fblocks %s -emit-llvm -o - | FileCheck %s -check-prefix=UNINIT
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fblocks -ftrivial-auto-var-init=pattern %s -emit-llvm -o - | FileCheck %s -check-prefix=PATTERN
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fblocks -ftrivial-auto-var-init=zero %s -emit-llvm -o - | FileCheck %s -check-prefix=ZERO
+
+template void used(T &) noexcept;
+
+extern "C" {
+
+// UNINIT-LABEL:  test_attribute_uninitialized(
+// UNINIT:      alloca
+// UNINIT-NEXT: call void
+// ZERO-LABEL:    test_attribute_uninitialized(
+// ZERO:      alloca
+// ZERO-NEXT: call void
+// PATTERN-LABEL: test_attribute_uninitialized(
+// PATTERN:      alloca
+// PATTERN-NEXT: call void
+void test_attribute_uninitialized() {
+  [[clang::uninitialized]] int i;
+  used(i);
+}
+
+} // extern "C"
diff --git a/test/CodeGenCXX/trivial-auto-var-init.cpp b/test/CodeGenCXX/trivial-auto-var-init.cpp
new file mode 100644
index 0000000000..8b35fdb441
--- /dev/null
+++ b/test/CodeGenCXX/trivial-auto-var-init.cpp
@@ -0,0 +1,216 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fblocks %s -emit-llvm -o - | FileCheck %s -check-prefix=UNINIT
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fblocks -ftrivial-auto-var-init=pattern %s -emit-llvm -o - | FileCheck %s -check-prefix=PATTERN
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fblocks -ftrivial-auto-var-init=zero %s -emit-llvm -o - | FileCheck %s -check-prefix=ZERO
+
+// None of the synthesized globals should contain `undef`.
+// PATTERN-NOT: undef
+// ZERO-NOT: undef
+
+template void used(T &) noexcept;
+
+extern "C" {
+
+// UNINIT-LABEL:  test_selfinit(
+// ZERO-LABEL:    test_selfinit(
+// ZERO: store i32 0, i32* %self, align 4
+// PATTERN-LABEL: test_selfinit(
+// PATTERN: store i32 -1431655766, i32* %self, align 4
+void test_selfinit() {
+  int self = self + 1;
+  used(self);
+}
+
+// UNINIT-LABEL:  test_block(
+// ZERO-LABEL:    test_block(
+// ZERO: store i32 0, i32* %block, align 4
+// PATTERN-LABEL: test_block(
+// PATTERN: store i32 -1431655766, i32* %block, align 4
+void test_block() {
+  __block int block;
+  used(block);
+}
+
+// This type of code is currently not handled by zero / pattern initialization.
+// The test will break when that is fixed.
+// UNINIT-LABEL:  test_goto_unreachable_value(
+// ZERO-LABEL:    test_goto_unreachable_value(
+// ZERO-NOT: store {{.*}}%oops
+// PATTERN-LABEL: test_goto_unreachable_value(
+// PATTERN-NOT: store {{.*}}%oops
+void test_goto_unreachable_value() {
+  goto jump;
+  int oops;
+ jump:
+  used(oops);
+}
+
+// This type of code is currently not handled by zero / pattern initialization.
+// The test will break when that is fixed.
+// UNINIT-LABEL:  test_goto(
+// ZERO-LABEL:    test_goto(
+// ZERO: if.then:
+// ZERO: br label %jump
+// ZERO: store i32 0, i32* %oops, align 4
+// ZERO: br label %jump
+// ZERO: jump:
+// PATTERN-LABEL: test_goto(
+// PATTERN: if.then:
+// PATTERN: br label %jump
+// PATTERN: store i32 -1431655766, i32* %oops, align 4
+// PATTERN: br label %jump
+// PATTERN: jump:
+void test_goto(int i) {
+  if (i)
+    goto jump;
+  int oops;
+ jump:
+  used(oops);
+}
+
+// This type of code is currently not handled by zero / pattern initialization.
+// The test will break when that is fixed.
+// UNINIT-LABEL:  test_switch(
+// ZERO-LABEL:    test_switch(
+// ZERO:      sw.bb:
+// ZERO-NEXT: store i32 0, i32* %oops, align 4
+// ZERO:      sw.bb1:
+// ZERO-NEXT: call void @{{.*}}used
+// PATTERN-LABEL: test_switch(
+// PATTERN:      sw.bb:
+// PATTERN-NEXT: store i32 -1431655766, i32* %oops, align 4
+// PATTERN:      sw.bb1:
+// PATTERN-NEXT: call void @{{.*}}used
+void test_switch(int i) {
+  switch (i) {
+  case 0:
+    int oops;
+    break;
+  case 1:
+    used(oops);
+  }
+}
+
+// UNINIT-LABEL:  test_vla(
+// ZERO-LABEL:    test_vla(
+// ZERO:  %[[SIZE:[0-9]+]] = mul nuw i64 %{{.*}}, 4
+// ZERO:  call void @llvm.memset{{.*}}(i8* align 16 %{{.*}}, i8 0, i64 %[[SIZE]], i1 false)
+// PATTERN-LABEL: test_vla(
+// PATTERN:  %vla.iszerosized = icmp eq i64 %{{.*}}, 0
+// PATTERN:  br i1 %vla.iszerosized, label %vla-init.cont, label %vla-setup.loop
+// PATTERN: vla-setup.loop:
+// PATTERN:  %[[SIZE:[0-9]+]] = mul nuw i64 %{{.*}}, 4
+// PATTERN:  %vla.begin = bitcast i32* %vla to i8*
+// PATTERN:  %vla.end = getelementptr inbounds i8, i8* %vla.begin, i64 %[[SIZE]]
+// PATTERN:  br label %vla-init.loop
+// PATTERN: vla-init.loop:
+// PATTERN:  %vla.cur = phi i8* [ %vla.begin, %vla-setup.loop ], [ %vla.next, %vla-init.loop ]
+// PATTERN:  call void @llvm.memcpy{{.*}} %vla.cur, {{.*}}@__const.test_vla.vla
+// PATTERN:  %vla.next = getelementptr inbounds i8, i8* %vla.cur, i64 4
+// PATTERN:  %vla-init.isdone = icmp eq i8* %vla.next, %vla.end
+// PATTERN:  br i1 %vla-init.isdone, label %vla-init.cont, label %vla-init.loop
+// PATTERN: vla-init.cont:
+// PATTERN:  call void @{{.*}}used
+void test_vla(int size) {
+  // Variable-length arrays can't have a zero size according to C11 6.7.6.2/5.
+  // Neither can they be negative-sized.
+  //
+  // We don't use the former fact because some code creates zero-sized VLAs and
+  // doesn't use them. clang makes these share locations with other stack
+  // values, which leads to initialization of the wrong values.
+  //
+  // We rely on the later fact because it generates better code.
+  //
+  // Both cases are caught by UBSan.
+  int vla[size];
+  int *ptr = vla;
+  used(ptr);
+}
+
+// UNINIT-LABEL:  test_struct_vla(
+// ZERO-LABEL:    test_struct_vla(
+// ZERO:  %[[SIZE:[0-9]+]] = mul nuw i64 %{{.*}}, 16
+// ZERO:  call void @llvm.memset{{.*}}(i8* align 16 %{{.*}}, i8 0, i64 %[[SIZE]], i1 false)
+// PATTERN-LABEL: test_struct_vla(
+// PATTERN:  %vla.iszerosized = icmp eq i64 %{{.*}}, 0
+// PATTERN:  br i1 %vla.iszerosized, label %vla-init.cont, label %vla-setup.loop
+// PATTERN: vla-setup.loop:
+// PATTERN:  %[[SIZE:[0-9]+]] = mul nuw i64 %{{.*}}, 16
+// PATTERN:  %vla.begin = bitcast %struct.anon* %vla to i8*
+// PATTERN:  %vla.end = getelementptr inbounds i8, i8* %vla.begin, i64 %[[SIZE]]
+// PATTERN:  br label %vla-init.loop
+// PATTERN: vla-init.loop:
+// PATTERN:  %vla.cur = phi i8* [ %vla.begin, %vla-setup.loop ], [ %vla.next, %vla-init.loop ]
+// PATTERN:  call void @llvm.memcpy{{.*}} %vla.cur, {{.*}}@__const.test_struct_vla.vla
+// PATTERN:  %vla.next = getelementptr inbounds i8, i8* %vla.cur, i64 16
+// PATTERN:  %vla-init.isdone = icmp eq i8* %vla.next, %vla.end
+// PATTERN:  br i1 %vla-init.isdone, label %vla-init.cont, label %vla-init.loop
+// PATTERN: vla-init.cont:
+// PATTERN:  call void @{{.*}}used
+void test_struct_vla(int size) {
+  // Same as above, but with a struct that doesn't just memcpy.
+  struct {
+    float f;
+    char c;
+    void *ptr;
+  } vla[size];
+  void *ptr = static_cast(vla);
+  used(ptr);
+}
+
+// UNINIT-LABEL:  test_zsa(
+// ZERO-LABEL:    test_zsa(
+// ZERO: %zsa = alloca [0 x i32], align 4
+// ZERO-NOT: %zsa
+// ZERO:  call void @{{.*}}used
+// PATTERN-LABEL: test_zsa(
+// PATTERN: %zsa = alloca [0 x i32], align 4
+// PATTERN-NOT: %zsa
+// PATTERN:  call void @{{.*}}used
+void test_zsa(int size) {
+  // Technically not valid, but as long as clang accepts them we should do
+  // something sensible (i.e. not store to the zero-size array).
+  int zsa[0];
+  used(zsa);
+}
+  
+// UNINIT-LABEL:  test_huge_uninit(
+// ZERO-LABEL:    test_huge_uninit(
+// ZERO: call void @llvm.memset{{.*}}, i8 0, i64 65536,
+// PATTERN-LABEL: test_huge_uninit(
+// PATTERN: call void @llvm.memset{{.*}}, i8 -86, i64 65536,
+void test_huge_uninit() {
+  // We can't emit this as an inline constant to a store instruction because
+  // SDNode hits an internal size limit.
+  char big[65536];
+  used(big);
+}
+
+// UNINIT-LABEL:  test_huge_small_init(
+// ZERO-LABEL:    test_huge_small_init(
+// ZERO: call void @llvm.memset{{.*}}, i8 0, i64 65536,
+// ZERO: store i8 97,
+// ZERO: store i8 98,
+// ZERO: store i8 99,
+// ZERO: store i8 100,
+// PATTERN-LABEL: test_huge_small_init(
+// PATTERN: call void @llvm.memset{{.*}}, i8 0, i64 65536,
+// PATTERN: store i8 97,
+// PATTERN: store i8 98,
+// PATTERN: store i8 99,
+// PATTERN: store i8 100,
+void test_huge_small_init() {
+  char big[65536] = { 'a', 'b', 'c', 'd' };
+  used(big);
+}
+
+// UNINIT-LABEL:  test_huge_larger_init(
+// ZERO-LABEL:    test_huge_larger_init(
+// ZERO:  call void @llvm.memcpy{{.*}} @__const.test_huge_larger_init.big, {{.*}}, i64 65536,
+// PATTERN-LABEL: test_huge_larger_init(
+// PATTERN:  call void @llvm.memcpy{{.*}} @__const.test_huge_larger_init.big, {{.*}}, i64 65536,
+void test_huge_larger_init() {
+  char big[65536] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
+  used(big);
+}
+
+} // extern "C"
diff --git a/test/Driver/clang_f_opts.c b/test/Driver/clang_f_opts.c
index 984244679d..866b368bea 100644
--- a/test/Driver/clang_f_opts.c
+++ b/test/Driver/clang_f_opts.c
@@ -557,3 +557,12 @@
 // CHECK-RECORD-GCC-SWITCHES: "-record-command-line"
 // CHECK-NO-RECORD-GCC-SWITCHES-NOT: "-record-command-line"
 // CHECK-RECORD-GCC-SWITCHES-ERROR: error: unsupported option '-frecord-command-line' for target
+
+// RUN: %clang -### -S -ftrivial-auto-var-init=uninitialized %s 2>&1 | FileCheck -check-prefix=CHECK-TRIVIAL-UNINIT %s
+// RUN: %clang -### -S -ftrivial-auto-var-init=pattern %s 2>&1 | FileCheck -check-prefix=CHECK-TRIVIAL-PATTERN %s
+// RUN: %clang -### -S -ftrivial-auto-var-init=zero -enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang %s 2>&1 | FileCheck -check-prefix=CHECK-TRIVIAL-ZERO-GOOD %s
+// RUN: %clang -### -S -ftrivial-auto-var-init=zero %s 2>&1 | FileCheck -check-prefix=CHECK-TRIVIAL-ZERO-BAD %s
+// CHECK-TRIVIAL-UNINIT-NOT: hasn't been enabled
+// CHECK-TRIVIAL-PATTERN-NOT: hasn't been enabled
+// CHECK-TRIVIAL-ZERO-GOOD-NOT: hasn't been enabled
+// CHECK-TRIVIAL-ZERO-BAD: hasn't been enabled
diff --git a/test/Sema/attr-uninitialized.c b/test/Sema/attr-uninitialized.c
new file mode 100644
index 0000000000..44c7b4a54e
--- /dev/null
+++ b/test/Sema/attr-uninitialized.c
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only
+
+void good() {
+  int dont_initialize_me __attribute((uninitialized));
+}
+
+void bad() {
+  int im_bad __attribute((uninitialized("zero")));  // expected-error {{'uninitialized' attribute takes no arguments}}
+  static int im_baaad __attribute((uninitialized)); // expected-warning {{'uninitialized' attribute only applies to local variables}}
+}
+
+extern int come_on __attribute((uninitialized));                    // expected-warning {{'uninitialized' attribute only applies to local variables}}
+int you_know __attribute((uninitialized));                          // expected-warning {{'uninitialized' attribute only applies to local variables}}
+static int and_the_whole_world_has_to __attribute((uninitialized)); // expected-warning {{'uninitialized' attribute only applies to local variables}}
+
+void answer_right_now() __attribute((uninitialized)) {}                        // expected-warning {{'uninitialized' attribute only applies to local variables}}
+void just_to_tell_you_once_again(__attribute((uninitialized)) int whos_bad) {} // expected-warning {{'uninitialized' attribute only applies to local variables}}
+
+struct TheWordIsOut {
+  __attribute((uninitialized)) int youre_doin_wrong; // expected-warning {{'uninitialized' attribute only applies to local variables}}
+} __attribute((uninitialized));                      // expected-warning {{'uninitialized' attribute only applies to local variables}}
diff --git a/test/Sema/uninit-variables.c b/test/Sema/uninit-variables.c
index 89ea190cbc..e2d9835493 100644
--- a/test/Sema/uninit-variables.c
+++ b/test/Sema/uninit-variables.c
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -fsyntax-only -Wuninitialized -Wconditional-uninitialized -fsyntax-only -fblocks %s -verify
+// RUN: %clang_cc1 -fsyntax-only -Wuninitialized -Wconditional-uninitialized -ftrivial-auto-var-init=pattern -fsyntax-only -fblocks %s -verify
 
 typedef __typeof(sizeof(int)) size_t;
 void *malloc(size_t);
-- 
cgit v1.2.3


From 053bd3c0257702859088b3ad059f8bbfe3ab043c Mon Sep 17 00:00:00 2001
From: "Tan S. B" 
Date: Tue, 18 Dec 2018 07:38:06 +0000
Subject: [ExprConstant] Handle compound assignment when LHS has integral type
 and RHS has floating point type

Fixes PR39858

Differential Revision: https://reviews.llvm.org/D55413

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349444 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/AST/ExprConstant.cpp                   | 26 +++++++++++++++++++-------
 test/SemaCXX/constant-expression-cxx1y.cpp |  8 ++++++++
 2 files changed, 27 insertions(+), 7 deletions(-)

diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index 837dc9c2a8..2022b07bff 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -3439,19 +3439,31 @@ struct CompoundAssignSubobjectHandler {
     if (!checkConst(SubobjType))
       return false;
 
-    if (!SubobjType->isIntegerType() || !RHS.isInt()) {
+    if (!SubobjType->isIntegerType()) {
       // We don't support compound assignment on integer-cast-to-pointer
       // values.
       Info.FFDiag(E);
       return false;
     }
 
-    APSInt LHS = HandleIntToIntCast(Info, E, PromotedLHSType,
-                                    SubobjType, Value);
-    if (!handleIntIntBinOp(Info, E, LHS, Opcode, RHS.getInt(), LHS))
-      return false;
-    Value = HandleIntToIntCast(Info, E, SubobjType, PromotedLHSType, LHS);
-    return true;
+    if (RHS.isInt()) {
+      APSInt LHS =
+          HandleIntToIntCast(Info, E, PromotedLHSType, SubobjType, Value);
+      if (!handleIntIntBinOp(Info, E, LHS, Opcode, RHS.getInt(), LHS))
+        return false;
+      Value = HandleIntToIntCast(Info, E, SubobjType, PromotedLHSType, LHS);
+      return true;
+    } else if (RHS.isFloat()) {
+      APFloat FValue(0.0);
+      return HandleIntToFloatCast(Info, E, SubobjType, Value, PromotedLHSType,
+                                  FValue) &&
+             handleFloatFloatBinOp(Info, E, FValue, Opcode, RHS.getFloat()) &&
+             HandleFloatToIntCast(Info, E, PromotedLHSType, FValue, SubobjType,
+                                  Value);
+    }
+
+    Info.FFDiag(E);
+    return false;
   }
   bool found(APFloat &Value, QualType SubobjType) {
     return checkConst(SubobjType) &&
diff --git a/test/SemaCXX/constant-expression-cxx1y.cpp b/test/SemaCXX/constant-expression-cxx1y.cpp
index a71dbc0eb5..3c57ac573f 100644
--- a/test/SemaCXX/constant-expression-cxx1y.cpp
+++ b/test/SemaCXX/constant-expression-cxx1y.cpp
@@ -356,6 +356,14 @@ namespace compound_assign {
     if (a != 13) return false;
     a &= 14;
     if (a != 12) return false;
+    a += -1.2;
+    if (a != 10) return false;
+    a -= 3.1;
+    if (a != 6) return false;
+    a *= 2.2;
+    if (a != 13) return false;
+    if (&(a /= 1.5) != &a) return false;
+    if (a != 8) return false;
     return true;
   }
   static_assert(test_int(), "");
-- 
cgit v1.2.3


From 08e6d377b981edb4779bd3b24fc75335ba42a308 Mon Sep 17 00:00:00 2001
From: Serge Guelton 
Date: Tue, 18 Dec 2018 08:22:47 +0000
Subject: Portable Python script across Python version

dict no longer have the `has_key` method in Python3. Instead, one can
use the `in` keyword which already works in Python2.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349447 91177308-0d34-0410-b5e6-96231b3b80d8
---
 docs/tools/dump_format_style.py    | 4 ++--
 tools/scan-view/share/startfile.py | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/docs/tools/dump_format_style.py b/docs/tools/dump_format_style.py
index 2e1e8c1229..f2682edc77 100755
--- a/docs/tools/dump_format_style.py
+++ b/docs/tools/dump_format_style.py
@@ -180,9 +180,9 @@ def read_options(header):
                            'std::vector',
                            'std::vector',
                            'std::vector']:
-      if enums.has_key(option.type):
+      if option.type in enums:
         option.enum = enums[option.type]
-      elif nested_structs.has_key(option.type):
+      elif option.type in nested_structs:
         option.nested_struct = nested_structs[option.type]
       else:
         raise Exception('Unknown type: %s' % option.type)
diff --git a/tools/scan-view/share/startfile.py b/tools/scan-view/share/startfile.py
index f58dbeeaf8..58023d0271 100644
--- a/tools/scan-view/share/startfile.py
+++ b/tools/scan-view/share/startfile.py
@@ -189,7 +189,7 @@ else:
             return _controllers[controller_name].open
 
         except KeyError:
-            if _controllers.has_key('xdg-open'):
+            if 'xdg-open' in _controllers:
                 return _controllers['xdg-open'].open
             else:
                 return webbrowser.open
-- 
cgit v1.2.3


From 3241c3649e96c7aaf63db8093035208dab3b7e13 Mon Sep 17 00:00:00 2001
From: Serge Guelton 
Date: Tue, 18 Dec 2018 08:24:06 +0000
Subject: Portable Python script across Python version

Replace `xrange(...)` by either `range(...)` or `list(range(...))` depending on the context.

Differential Revision: https://reviews.llvm.org/D55193

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349448 91177308-0d34-0410-b5e6-96231b3b80d8
---
 bindings/python/clang/cindex.py | 6 ++----
 utils/ABITest/Enumeration.py    | 2 +-
 utils/ABITest/TypeGen.py        | 2 +-
 utils/modfuzz.py                | 2 +-
 4 files changed, 5 insertions(+), 7 deletions(-)

diff --git a/bindings/python/clang/cindex.py b/bindings/python/clang/cindex.py
index 939213d302..72e8fdb8a8 100644
--- a/bindings/python/clang/cindex.py
+++ b/bindings/python/clang/cindex.py
@@ -109,8 +109,6 @@ if sys.version_info[0] == 3:
             return x
         return x.encode('utf8')
 
-    xrange = range
-
 elif sys.version_info[0] == 2:
     # Python 2 strings are utf8 byte strings, no translation is needed for
     # C-interop.
@@ -556,7 +554,7 @@ class TokenGroup(object):
 
         token_group = TokenGroup(tu, tokens_memory, tokens_count)
 
-        for i in xrange(0, count):
+        for i in range(0, count):
             token = Token()
             token.int_data = tokens_array[i].int_data
             token.ptr_data = tokens_array[i].ptr_data
@@ -3190,7 +3188,7 @@ class CompileCommand(object):
         Invariant : the first argument is the compiler executable
         """
         length = conf.lib.clang_CompileCommand_getNumArgs(self.cmd)
-        for i in xrange(length):
+        for i in range(length):
             yield conf.lib.clang_CompileCommand_getArg(self.cmd, i)
 
 class CompileCommands(object):
diff --git a/utils/ABITest/Enumeration.py b/utils/ABITest/Enumeration.py
index 01830a38cd..29a81b4f13 100644
--- a/utils/ABITest/Enumeration.py
+++ b/utils/ABITest/Enumeration.py
@@ -199,7 +199,7 @@ def getNthPairVariableBounds(N, bounds):
         raise ValueError("Invalid input (out of bounds)")
 
     level = 0
-    active = range(len(bounds))
+    active = list(range(len(bounds)))
     active.sort(key=lambda i: bounds[i])
     prevLevel = 0
     for i,index in enumerate(active):
diff --git a/utils/ABITest/TypeGen.py b/utils/ABITest/TypeGen.py
index 8330340cd3..f8a4d07e11 100644
--- a/utils/ABITest/TypeGen.py
+++ b/utils/ABITest/TypeGen.py
@@ -242,7 +242,7 @@ def combinations(values, k):
     # combinations, selections of a sequence
     if k==0: yield []
     else:
-        for i in xrange(len(values)-k+1):
+        for i in range(len(values)-k+1):
             for cc in combinations(values[i+1:],k-1):
                 yield [values[i]]+cc
 
diff --git a/utils/modfuzz.py b/utils/modfuzz.py
index 885621d14e..948603338c 100644
--- a/utils/modfuzz.py
+++ b/utils/modfuzz.py
@@ -106,7 +106,7 @@ def generate():
   try:
     while True:
       assert m, 'got a failure with no steps; broken clang binary?'
-      i = random.choice(range(len(m)))
+      i = random.choice(list(range(len(m))))
       x = m[0:i] + m[i+1:]
       m2 = CodeModel()
       for d in x:
-- 
cgit v1.2.3


From 7f12885bea75c6242ba20076979031f0eb15ac60 Mon Sep 17 00:00:00 2001
From: Serge Guelton 
Date: Tue, 18 Dec 2018 08:25:25 +0000
Subject: Portable Python script across Python version

ConfigParser module has been renamed as configparser in Python3

Differential Revision: https://reviews.llvm.org/D55200

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349449 91177308-0d34-0410-b5e6-96231b3b80d8
---
 tools/scan-view/share/ScanView.py | 7 +++++--
 utils/check_cfc/check_cfc.py      | 7 +++++--
 2 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/tools/scan-view/share/ScanView.py b/tools/scan-view/share/ScanView.py
index b489589d00..b465c971db 100644
--- a/tools/scan-view/share/ScanView.py
+++ b/tools/scan-view/share/ScanView.py
@@ -16,7 +16,10 @@ import socket
 import itertools
 
 import Reporter
-import ConfigParser
+try:
+    import configparser
+except ImportError:
+    import ConfigParser as configparser
 
 ###
 # Various patterns matched or replaced by server.
@@ -126,7 +129,7 @@ class ScanViewServer(HTTPServer):
         self.load_config()
 
     def load_config(self):
-        self.config = ConfigParser.RawConfigParser()
+        self.config = configparser.RawConfigParser()
 
         # Add defaults
         self.config.add_section('ScanView')
diff --git a/utils/check_cfc/check_cfc.py b/utils/check_cfc/check_cfc.py
index 7a739f46e3..0228f1d625 100755
--- a/utils/check_cfc/check_cfc.py
+++ b/utils/check_cfc/check_cfc.py
@@ -56,7 +56,10 @@ import shutil
 import subprocess
 import sys
 import tempfile
-import ConfigParser
+try:
+    import configparser
+except ImportError:
+    import ConfigParser as configparser
 import io
 
 import obj_diff
@@ -318,7 +321,7 @@ if __name__ == '__main__':
     for c in checks:
         default_config += "{} = false\n".format(c)
 
-    config = ConfigParser.RawConfigParser()
+    config = configparser.RawConfigParser()
     config.readfp(io.BytesIO(default_config))
     scriptdir = get_main_dir()
     config_path = os.path.join(scriptdir, 'check_cfc.cfg')
-- 
cgit v1.2.3


From da4951c2074af6b344fe24e6a56dc9e6b90502d6 Mon Sep 17 00:00:00 2001
From: Martin Storsjo 
Date: Tue, 18 Dec 2018 08:36:10 +0000
Subject: [Driver] Automatically enable -munwind-tables if -fseh-exceptions is
 enabled

For targets where SEH exceptions are used by default (on MinGW,
only x86_64 so far), -munwind-tables are added automatically. If
-fseh-exeptions is enabled on a target where SEH exeptions are
availble but not enabled by default yet (aarch64), we need to
pass -munwind-tables if -fseh-exceptions was specified.

Differential Revision: https://reviews.llvm.org/D55749

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349452 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/Driver/ToolChains/MinGW.cpp    | 6 ++++++
 test/Driver/windows-exceptions.cpp | 3 +++
 2 files changed, 9 insertions(+)

diff --git a/lib/Driver/ToolChains/MinGW.cpp b/lib/Driver/ToolChains/MinGW.cpp
index 836d7c1551..2d5217d03d 100644
--- a/lib/Driver/ToolChains/MinGW.cpp
+++ b/lib/Driver/ToolChains/MinGW.cpp
@@ -429,6 +429,12 @@ bool toolchains::MinGW::HasNativeLLVMSupport() const {
 }
 
 bool toolchains::MinGW::IsUnwindTablesDefault(const ArgList &Args) const {
+  Arg *ExceptionArg = Args.getLastArg(options::OPT_fsjlj_exceptions,
+                                      options::OPT_fseh_exceptions,
+                                      options::OPT_fdwarf_exceptions);
+  if (ExceptionArg &&
+      ExceptionArg->getOption().matches(options::OPT_fseh_exceptions))
+    return true;
   return getArch() == llvm::Triple::x86_64;
 }
 
diff --git a/test/Driver/windows-exceptions.cpp b/test/Driver/windows-exceptions.cpp
index 8bce3b8dd8..2eefe22bcd 100644
--- a/test/Driver/windows-exceptions.cpp
+++ b/test/Driver/windows-exceptions.cpp
@@ -2,8 +2,11 @@
 // RUN: %clang -target x86_64-windows-msvc -c %s -### 2>&1 | FileCheck -check-prefix=MSVC %s
 // RUN: %clang -target i686-windows-gnu -c %s -### 2>&1 | FileCheck -check-prefix=MINGW-DWARF %s
 // RUN: %clang -target x86_64-windows-gnu -c %s -### 2>&1 | FileCheck -check-prefix=MINGW-SEH %s
+// RUN: %clang -target aarch64-windows-gnu -c %s -### 2>&1 | FileCheck -check-prefix=MINGW-DWARF %s
+// RUN: %clang -target aarch64-windows-gnu -fseh-exceptions -c %s -### 2>&1 | FileCheck -check-prefix=MINGW-SEH %s
 
 MSVC-NOT: -fdwarf-exceptions
 MSVC-NOT: -fseh-exceptions
 MINGW-DWARF: -fdwarf-exceptions
+MINGW-SEH: -munwind-tables
 MINGW-SEH: -fseh-exceptions
-- 
cgit v1.2.3


From 69150282888f67763b847e6d1c2709f4c272abaa Mon Sep 17 00:00:00 2001
From: Martin Storsjo 
Date: Tue, 18 Dec 2018 08:36:16 +0000
Subject: [unittests] Remove superfluous semicolon, fixing warnings with GCC.
 NFC.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349453 91177308-0d34-0410-b5e6-96231b3b80d8
---
 unittests/AST/ASTImporterTest.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/unittests/AST/ASTImporterTest.cpp b/unittests/AST/ASTImporterTest.cpp
index aaadeb0b9d..c6acf573e5 100644
--- a/unittests/AST/ASTImporterTest.cpp
+++ b/unittests/AST/ASTImporterTest.cpp
@@ -4467,7 +4467,7 @@ static Decl *findInDeclListOfDC(DeclContext *DC, DeclarationName Name) {
         return ND;
   }
   return nullptr;
-};
+}
 
 TEST_P(ASTImporterLookupTableTest,
     FriendWhichIsnotFoundByNormalLookupShouldBeFoundByImporterSpecificLookup) {
-- 
cgit v1.2.3


From 4f672fc63af4f838531fa8b85152024c037ccea3 Mon Sep 17 00:00:00 2001
From: Serge Guelton 
Date: Tue, 18 Dec 2018 08:36:33 +0000
Subject: Portable Python script across Python version

Using from __future__ import print_function it is possible to have a compatible behavior of `print(...)` across Python version.

Differential Revision: https://reviews.llvm.org/D55213

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349454 91177308-0d34-0410-b5e6-96231b3b80d8
---
 bindings/python/clang/cindex.py               |   1 +
 docs/conf.py                                  |   9 +-
 docs/tools/dump_ast_matchers.py               |   8 +-
 tools/clang-format/clang-format-diff.py       |   1 +
 tools/scan-build-py/libscanbuild/arguments.py |   1 +
 tools/scan-view/bin/scan-view                 |  12 ++-
 tools/scan-view/share/ScanView.py             |  31 +++---
 utils/ABITest/ABITestGen.py                   | 133 +++++++++++++-------------
 utils/ABITest/Enumeration.py                  |  17 ++--
 utils/ABITest/TypeGen.py                      |   5 +-
 utils/CIndex/completion_logger_server.py      |   5 +-
 utils/TestUtils/deep-stack.py                 |  17 ++--
 utils/analyzer/CmpRuns.py                     |   5 +-
 utils/analyzer/SATestAdd.py                   |  17 ++--
 utils/analyzer/SATestBuild.py                 |  14 +--
 utils/analyzer/SATestUpdateDiffs.py           |  11 ++-
 utils/analyzer/SumTimerInfo.py                |  29 +++---
 utils/check_cfc/setup.py                      |   5 +-
 utils/clangdiag.py                            |   3 +-
 utils/modfuzz.py                              |   3 +-
 utils/token-delta.py                          |  21 ++--
 21 files changed, 184 insertions(+), 164 deletions(-)

diff --git a/bindings/python/clang/cindex.py b/bindings/python/clang/cindex.py
index 72e8fdb8a8..5dbe809af9 100644
--- a/bindings/python/clang/cindex.py
+++ b/bindings/python/clang/cindex.py
@@ -44,6 +44,7 @@ The major indexing objects are:
 Most object information is exposed using properties, when the underlying API
 call is efficient.
 """
+from __future__ import print_function
 
 # TODO
 # ====
diff --git a/docs/conf.py b/docs/conf.py
index dc69f8a848..a18ce3a304 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -11,6 +11,7 @@
 # All configuration values have a default; values that are commented out
 # serve to show the default.
 
+from __future__ import print_function
 import sys, os
 from datetime import date
 
@@ -233,14 +234,14 @@ for name in os.listdir(command_guide_path):
         header = f.readline().rstrip('\n')
 
         if len(header) != len(title):
-            print >>sys.stderr, (
+            print((
                 "error: invalid header in %r (does not match title)" % (
-                    file_subpath,))
+                    file_subpath,)), file=sys.stderr)
         if ' - ' not in title:
-            print >>sys.stderr, (
+            print((
                 ("error: invalid title in %r "
                  "(expected ' - ')") % (
-                    file_subpath,))
+                    file_subpath,)), file=sys.stderr)
 
         # Split the name out of the title.
         name,description = title.split(' - ', 1)
diff --git a/docs/tools/dump_ast_matchers.py b/docs/tools/dump_ast_matchers.py
index 2c0cbafa8a..cae27b20a9 100755
--- a/docs/tools/dump_ast_matchers.py
+++ b/docs/tools/dump_ast_matchers.py
@@ -41,7 +41,7 @@ def esc(text):
     url = 'https://clang.llvm.org/doxygen/classclang_1_1%s.html' % name
     if url not in doxygen_probes:
       try:
-        print 'Probing %s...' % url
+        print('Probing %s...' % url)
         urllib2.urlopen(url)
         doxygen_probes[url] = True
       except:
@@ -307,14 +307,14 @@ def act_on_decl(declaration, comment, allowed_types):
       if not result_types:
         if not comment:
           # Only overloads don't have their own doxygen comments; ignore those.
-          print 'Ignoring "%s"' % name
+          print('Ignoring "%s"' % name)
         else:
-          print 'Cannot determine result type for "%s"' % name
+          print('Cannot determine result type for "%s"' % name)
       else:
         for result_type in result_types:
           add_matcher(result_type, name, args, comment)
     else:
-      print '*** Unparsable: "' + declaration + '" ***'
+      print('*** Unparsable: "' + declaration + '" ***')
 
 def sort_table(matcher_type, matcher_map):
   """Returns the sorted html table for the given row map."""
diff --git a/tools/clang-format/clang-format-diff.py b/tools/clang-format/clang-format-diff.py
index ce4c1d6e0a..1721d8a430 100755
--- a/tools/clang-format/clang-format-diff.py
+++ b/tools/clang-format/clang-format-diff.py
@@ -21,6 +21,7 @@ Example usage for git/svn users:
   svn diff --diff-cmd=diff -x-U0 | clang-format-diff.py -i
 
 """
+from __future__ import print_function
 
 import argparse
 import difflib
diff --git a/tools/scan-build-py/libscanbuild/arguments.py b/tools/scan-build-py/libscanbuild/arguments.py
index a5d0c6bda6..73a7f24e67 100644
--- a/tools/scan-build-py/libscanbuild/arguments.py
+++ b/tools/scan-build-py/libscanbuild/arguments.py
@@ -12,6 +12,7 @@ earlier.)
 It also implements basic validation methods, related to the command.
 Validations are mostly calling specific help methods, or mangling values.
 """
+from __future__ import print_function
 
 import os
 import sys
diff --git a/tools/scan-view/bin/scan-view b/tools/scan-view/bin/scan-view
index 6e384ec217..e3abb1c834 100755
--- a/tools/scan-view/bin/scan-view
+++ b/tools/scan-view/bin/scan-view
@@ -1,5 +1,7 @@
 #!/usr/bin/env python
 
+from __future__ import print_function
+
 """The clang static analyzer results viewer.
 """
 
@@ -52,10 +54,10 @@ def start_browser(port, options):
             sys.stderr.flush()
         time.sleep(kSleepTimeout)
     else:
-        print >> sys.stderr, 'WARNING: Unable to detect that server started.'
+        print('WARNING: Unable to detect that server started.', file=sys.stderr) 
 
     if options.debug:
-        print >> sys.stderr, '%s: Starting webbrowser...' % sys.argv[0]
+        print('%s: Starting webbrowser...' % sys.argv[0], file=sys.stderr)
     webbrowser.open(url)
 
 
@@ -69,9 +71,9 @@ def run(port, options, root):
 
     import ScanView
     try:
-        print 'Starting scan-view at: http://%s:%d' % (options.host,
-                                                       port)
-        print '  Use Ctrl-C to exit.'
+        print('Starting scan-view at: http://%s:%d' % (options.host,
+                                                       port))
+        print('  Use Ctrl-C to exit.')
         httpd = ScanView.create_server((options.host, port),
                                        options, root)
         httpd.serve_forever()
diff --git a/tools/scan-view/share/ScanView.py b/tools/scan-view/share/ScanView.py
index b465c971db..b1ce8c3d3a 100644
--- a/tools/scan-view/share/ScanView.py
+++ b/tools/scan-view/share/ScanView.py
@@ -1,3 +1,4 @@
+from __future__ import print_function
 try:
     from http.server import HTTPServer, SimpleHTTPRequestHandler
 except ImportError:
@@ -102,20 +103,20 @@ class ReporterThread(threading.Thread):
         result = None
         try:
             if self.server.options.debug:
-                print >>sys.stderr, "%s: SERVER: submitting bug."%(sys.argv[0],)
+                print("%s: SERVER: submitting bug."%(sys.argv[0],), file=sys.stderr)
             self.status = self.reporter.fileReport(self.report, self.parameters)
             self.success = True
             time.sleep(3)
             if self.server.options.debug:
-                print >>sys.stderr, "%s: SERVER: submission complete."%(sys.argv[0],)
+                print("%s: SERVER: submission complete."%(sys.argv[0],), file=sys.stderr)
         except Reporter.ReportFailure as e:
             self.status = e.value
         except Exception as e:
             s = StringIO.StringIO()
             import traceback
-            print >>s,'Unhandled Exception
'
-            traceback.print_exc(e,file=s)
-            print >>s,'
' + print('Unhandled Exception
', file=s)
+            traceback.print_exc(file=s)
+            print('
', file=s) self.status = s.getvalue() class ScanViewServer(HTTPServer): @@ -161,16 +162,16 @@ class ScanViewServer(HTTPServer): def halt(self): self.halted = True if self.options.debug: - print >>sys.stderr, "%s: SERVER: halting." % (sys.argv[0],) + print("%s: SERVER: halting." % (sys.argv[0],), file=sys.stderr) def serve_forever(self): while not self.halted: if self.options.debug > 1: - print >>sys.stderr, "%s: SERVER: waiting..." % (sys.argv[0],) + print("%s: SERVER: waiting..." % (sys.argv[0],), file=sys.stderr) try: self.handle_request() except OSError as e: - print 'OSError',e.errno + print('OSError',e.errno) def finish_request(self, request, client_address): if self.options.autoReload: @@ -183,7 +184,7 @@ class ScanViewServer(HTTPServer): info = sys.exc_info() if info and isinstance(info[1], socket.error): if self.options.debug > 1: - print >>sys.stderr, "%s: SERVER: ignored socket error." % (sys.argv[0],) + print("%s: SERVER: ignored socket error." % (sys.argv[0],), file=sys.stderr) return HTTPServer.handle_error(self, request, client_address) @@ -270,8 +271,8 @@ class ScanViewRequestHandler(SimpleHTTPRequestHandler): def handle_exception(self, exc): import traceback s = StringIO.StringIO() - print >>s, "INTERNAL ERROR\n" - traceback.print_exc(exc, s) + print("INTERNAL ERROR\n", file=s) + traceback.print_exc(file=s) f = self.send_string(s.getvalue(), 'text/plain') if f: self.copyfile(f, self.wfile) @@ -416,8 +417,8 @@ Submit import startfile if self.server.options.debug: - print >>sys.stderr, '%s: SERVER: opening "%s"'%(sys.argv[0], - file) + print('%s: SERVER: opening "%s"'%(sys.argv[0], + file), file=sys.stderr) status = startfile.open(file) if status: @@ -696,8 +697,8 @@ File Bug path = posixpath.join(self.server.root, relpath) if self.server.options.debug > 1: - print >>sys.stderr, '%s: SERVER: sending path "%s"'%(sys.argv[0], - path) + print('%s: SERVER: sending path "%s"'%(sys.argv[0], + path), file=sys.stderr) return self.send_path(path) def send_404(self): diff --git a/utils/ABITest/ABITestGen.py b/utils/ABITest/ABITestGen.py index 0e588f056c..d42e08e123 100755 --- a/utils/ABITest/ABITestGen.py +++ b/utils/ABITest/ABITestGen.py @@ -1,5 +1,6 @@ #!/usr/bin/env python +from __future__ import print_function from pprint import pprint import random, atexit, time from random import randrange @@ -28,42 +29,42 @@ class TypePrinter(object): if info: for f in (self.output,self.outputHeader,self.outputTests,self.outputDriver): if f: - print >>f,info + print(info, file=f) if self.writeBody: - print >>self.output, '#include \n' + print('#include \n', file=self.output) if self.outputTests: - print >>self.outputTests, '#include ' - print >>self.outputTests, '#include ' - print >>self.outputTests, '#include \n' + print('#include ', file=self.outputTests) + print('#include ', file=self.outputTests) + print('#include \n', file=self.outputTests) if headerName: for f in (self.output,self.outputTests,self.outputDriver): if f is not None: - print >>f, '#include "%s"\n'%(headerName,) + print('#include "%s"\n'%(headerName,), file=f) if self.outputDriver: - print >>self.outputDriver, '#include ' - print >>self.outputDriver, '#include \n' - print >>self.outputDriver, 'int main(int argc, char **argv) {' - print >>self.outputDriver, ' int index = -1;' - print >>self.outputDriver, ' if (argc > 1) index = atoi(argv[1]);' + print('#include ', file=self.outputDriver) + print('#include \n', file=self.outputDriver) + print('int main(int argc, char **argv) {', file=self.outputDriver) + print(' int index = -1;', file=self.outputDriver) + print(' if (argc > 1) index = atoi(argv[1]);', file=self.outputDriver) def finish(self): if self.layoutTests: - print >>self.output, 'int main(int argc, char **argv) {' - print >>self.output, ' int index = -1;' - print >>self.output, ' if (argc > 1) index = atoi(argv[1]);' + print('int main(int argc, char **argv) {', file=self.output) + print(' int index = -1;', file=self.output) + print(' if (argc > 1) index = atoi(argv[1]);', file=self.output) for i,f in self.layoutTests: - print >>self.output, ' if (index == -1 || index == %d)' % i - print >>self.output, ' %s();' % f - print >>self.output, ' return 0;' - print >>self.output, '}' + print(' if (index == -1 || index == %d)' % i, file=self.output) + print(' %s();' % f, file=self.output) + print(' return 0;', file=self.output) + print('}', file=self.output) if self.outputDriver: - print >>self.outputDriver, ' printf("DONE\\n");' - print >>self.outputDriver, ' return 0;' - print >>self.outputDriver, '}' + print(' printf("DONE\\n");', file=self.outputDriver) + print(' return 0;', file=self.outputDriver) + print('}', file=self.outputDriver) def addDeclaration(self, decl): if decl in self.declarations: @@ -71,11 +72,11 @@ class TypePrinter(object): self.declarations.add(decl) if self.outputHeader: - print >>self.outputHeader, decl + print(decl, file=self.outputHeader) else: - print >>self.output, decl + print(decl, file=self.output) if self.outputTests: - print >>self.outputTests, decl + print(decl, file=self.outputTests) return True def getTypeName(self, T): @@ -91,12 +92,12 @@ class TypePrinter(object): tyNameClean = tyName.replace(' ','_').replace('*','star') fnName = 'test_%s' % tyNameClean - print >>self.output,'void %s(void) {' % fnName + print('void %s(void) {' % fnName, file=self.output) self.printSizeOfType(' %s'%fnName, tyName, ty, self.output) self.printAlignOfType(' %s'%fnName, tyName, ty, self.output) self.printOffsetsOfType(' %s'%fnName, tyName, ty, self.output) - print >>self.output,'}' - print >>self.output + print('}', file=self.output) + print(file=self.output) self.layoutTests.append((i,fnName)) @@ -115,71 +116,71 @@ class TypePrinter(object): fnName = 'fn%d'%(FT.index,) if self.outputHeader: - print >>self.outputHeader,'%s %s(%s);'%(retvalTypeName, fnName, args) + print('%s %s(%s);'%(retvalTypeName, fnName, args), file=self.outputHeader) elif self.outputTests: - print >>self.outputTests,'%s %s(%s);'%(retvalTypeName, fnName, args) + print('%s %s(%s);'%(retvalTypeName, fnName, args), file=self.outputTests) - print >>self.output,'%s %s(%s)'%(retvalTypeName, fnName, args), + print('%s %s(%s)'%(retvalTypeName, fnName, args), end=' ', file=self.output) if self.writeBody: - print >>self.output, '{' + print('{', file=self.output) for i,t in enumerate(FT.argTypes): self.printValueOfType(' %s'%fnName, 'arg%d'%i, t) if retvalName is not None: - print >>self.output, ' return %s;'%(retvalName,) - print >>self.output, '}' + print(' return %s;'%(retvalName,), file=self.output) + print('}', file=self.output) else: - print >>self.output, '{}' - print >>self.output + print('{}', file=self.output) + print(file=self.output) if self.outputDriver: - print >>self.outputDriver, ' if (index == -1 || index == %d) {' % i - print >>self.outputDriver, ' extern void test_%s(void);' % fnName - print >>self.outputDriver, ' test_%s();' % fnName - print >>self.outputDriver, ' }' + print(' if (index == -1 || index == %d) {' % i, file=self.outputDriver) + print(' extern void test_%s(void);' % fnName, file=self.outputDriver) + print(' test_%s();' % fnName, file=self.outputDriver) + print(' }', file=self.outputDriver) if self.outputTests: if self.outputHeader: - print >>self.outputHeader, 'void test_%s(void);'%(fnName,) + print('void test_%s(void);'%(fnName,), file=self.outputHeader) if retvalName is None: retvalTests = None else: retvalTests = self.getTestValuesArray(FT.returnType) tests = map(self.getTestValuesArray, FT.argTypes) - print >>self.outputTests, 'void test_%s(void) {'%(fnName,) + print('void test_%s(void) {'%(fnName,), file=self.outputTests) if retvalTests is not None: - print >>self.outputTests, ' printf("%s: testing return.\\n");'%(fnName,) - print >>self.outputTests, ' for (int i=0; i<%d; ++i) {'%(retvalTests[1],) + print(' printf("%s: testing return.\\n");'%(fnName,), file=self.outputTests) + print(' for (int i=0; i<%d; ++i) {'%(retvalTests[1],), file=self.outputTests) args = ', '.join(['%s[%d]'%(t,randrange(l)) for t,l in tests]) - print >>self.outputTests, ' %s RV;'%(retvalTypeName,) - print >>self.outputTests, ' %s = %s[i];'%(retvalName, retvalTests[0]) - print >>self.outputTests, ' RV = %s(%s);'%(fnName, args) + print(' %s RV;'%(retvalTypeName,), file=self.outputTests) + print(' %s = %s[i];'%(retvalName, retvalTests[0]), file=self.outputTests) + print(' RV = %s(%s);'%(fnName, args), file=self.outputTests) self.printValueOfType(' %s_RV'%fnName, 'RV', FT.returnType, output=self.outputTests, indent=4) self.checkTypeValues('RV', '%s[i]' % retvalTests[0], FT.returnType, output=self.outputTests, indent=4) - print >>self.outputTests, ' }' + print(' }', file=self.outputTests) if tests: - print >>self.outputTests, ' printf("%s: testing arguments.\\n");'%(fnName,) + print(' printf("%s: testing arguments.\\n");'%(fnName,), file=self.outputTests) for i,(array,length) in enumerate(tests): for j in range(length): args = ['%s[%d]'%(t,randrange(l)) for t,l in tests] args[i] = '%s[%d]'%(array,j) - print >>self.outputTests, ' %s(%s);'%(fnName, ', '.join(args),) - print >>self.outputTests, '}' + print(' %s(%s);'%(fnName, ', '.join(args),), file=self.outputTests) + print('}', file=self.outputTests) def getTestReturnValue(self, type): typeName = self.getTypeName(type) info = self.testReturnValues.get(typeName) if info is None: name = '%s_retval'%(typeName.replace(' ','_').replace('*','star'),) - print >>self.output, '%s %s;'%(typeName,name) + print('%s %s;'%(typeName,name), file=self.output) if self.outputHeader: - print >>self.outputHeader, 'extern %s %s;'%(typeName,name) + print('extern %s %s;'%(typeName,name), file=self.outputHeader) elif self.outputTests: - print >>self.outputTests, 'extern %s %s;'%(typeName,name) + print('extern %s %s;'%(typeName,name), file=self.outputTests) info = self.testReturnValues[typeName] = name return info @@ -188,12 +189,12 @@ class TypePrinter(object): info = self.testValues.get(typeName) if info is None: name = '%s_values'%(typeName.replace(' ','_').replace('*','star'),) - print >>self.outputTests, 'static %s %s[] = {'%(typeName,name) + print('static %s %s[] = {'%(typeName,name), file=self.outputTests) length = 0 for item in self.getTestValues(type): - print >>self.outputTests, '\t%s,'%(item,) + print('\t%s,'%(item,), file=self.outputTests) length += 1 - print >>self.outputTests,'};' + print('};', file=self.outputTests) info = self.testValues[typeName] = (name,length) return info @@ -253,16 +254,16 @@ class TypePrinter(object): raise NotImplementedError('Cannot make tests values of type: "%s"'%(t,)) def printSizeOfType(self, prefix, name, t, output=None, indent=2): - print >>output, '%*sprintf("%s: sizeof(%s) = %%ld\\n", (long)sizeof(%s));'%(indent, '', prefix, name, name) + print('%*sprintf("%s: sizeof(%s) = %%ld\\n", (long)sizeof(%s));'%(indent, '', prefix, name, name), file=output) def printAlignOfType(self, prefix, name, t, output=None, indent=2): - print >>output, '%*sprintf("%s: __alignof__(%s) = %%ld\\n", (long)__alignof__(%s));'%(indent, '', prefix, name, name) + print('%*sprintf("%s: __alignof__(%s) = %%ld\\n", (long)__alignof__(%s));'%(indent, '', prefix, name, name), file=output) def printOffsetsOfType(self, prefix, name, t, output=None, indent=2): if isinstance(t, RecordType): for i,f in enumerate(t.fields): if f.isBitField(): continue fname = 'field%d' % i - print >>output, '%*sprintf("%s: __builtin_offsetof(%s, %s) = %%ld\\n", (long)__builtin_offsetof(%s, %s));'%(indent, '', prefix, name, fname, name, fname) + print('%*sprintf("%s: __builtin_offsetof(%s, %s) = %%ld\\n", (long)__builtin_offsetof(%s, %s));'%(indent, '', prefix, name, fname, name, fname), file=output) def printValueOfType(self, prefix, name, t, output=None, indent=2): if output is None: @@ -286,13 +287,13 @@ class TypePrinter(object): code = 'Lf' else: code = 'p' - print >>output, '%*sprintf("%s: %s = %%%s\\n", %s);'%( - indent, '', prefix, name, code, value_expr) + print('%*sprintf("%s: %s = %%%s\\n", %s);'%( + indent, '', prefix, name, code, value_expr), file=output) elif isinstance(t, EnumType): - print >>output, '%*sprintf("%s: %s = %%d\\n", %s);'%(indent, '', prefix, name, name) + print('%*sprintf("%s: %s = %%d\\n", %s);'%(indent, '', prefix, name, name), file=output) elif isinstance(t, RecordType): if not t.fields: - print >>output, '%*sprintf("%s: %s (empty)\\n");'%(indent, '', prefix, name) + print('%*sprintf("%s: %s (empty)\\n");'%(indent, '', prefix, name), file=output) for i,f in enumerate(t.fields): if f.isPaddingBitField(): continue @@ -317,9 +318,9 @@ class TypePrinter(object): if output is None: output = self.output if isinstance(t, BuiltinType): - print >>output, '%*sassert(%s == %s);' % (indent, '', nameLHS, nameRHS) + print('%*sassert(%s == %s);' % (indent, '', nameLHS, nameRHS), file=output) elif isinstance(t, EnumType): - print >>output, '%*sassert(%s == %s);' % (indent, '', nameLHS, nameRHS) + print('%*sassert(%s == %s);' % (indent, '', nameLHS, nameRHS), file=output) elif isinstance(t, RecordType): for i,f in enumerate(t.fields): if f.isPaddingBitField(): @@ -644,7 +645,7 @@ def main(): FT = ftg.get(N) except RuntimeError as e: if e.args[0]=='maximum recursion depth exceeded': - print >>sys.stderr,'WARNING: Skipped %d, recursion limit exceeded (bad arguments?)'%(N,) + print('WARNING: Skipped %d, recursion limit exceeded (bad arguments?)'%(N,), file=sys.stderr) return raise if opts.testLayout: diff --git a/utils/ABITest/Enumeration.py b/utils/ABITest/Enumeration.py index 29a81b4f13..76067243d1 100644 --- a/utils/ABITest/Enumeration.py +++ b/utils/ABITest/Enumeration.py @@ -1,5 +1,6 @@ """Utilities for enumeration of finite and countably infinite sets. """ +from __future__ import print_function ### # Countable iteration @@ -234,18 +235,18 @@ def testPairs(): for i in range(min(W*H,40)): x,y = getNthPairBounded(i,W,H) x2,y2 = getNthPairBounded(i,W,H,useDivmod=True) - print i,(x,y),(x2,y2) + print(i,(x,y),(x2,y2)) a[y][x] = '%2d'%i b[y2][x2] = '%2d'%i - print '-- a --' + print('-- a --') for ln in a[::-1]: if ''.join(ln).strip(): - print ' '.join(ln) - print '-- b --' + print(' '.join(ln)) + print('-- b --') for ln in b[::-1]: if ''.join(ln).strip(): - print ' '.join(ln) + print(' '.join(ln)) def testPairsVB(): bounds = [2,2,4,aleph0,5,aleph0] @@ -253,13 +254,13 @@ def testPairsVB(): b = [[' ' for x in range(15)] for y in range(15)] for i in range(min(sum(bounds),40)): x,y = getNthPairVariableBounds(i, bounds) - print i,(x,y) + print(i,(x,y)) a[y][x] = '%2d'%i - print '-- a --' + print('-- a --') for ln in a[::-1]: if ''.join(ln).strip(): - print ' '.join(ln) + print(' '.join(ln)) ### diff --git a/utils/ABITest/TypeGen.py b/utils/ABITest/TypeGen.py index f8a4d07e11..608089429a 100644 --- a/utils/ABITest/TypeGen.py +++ b/utils/ABITest/TypeGen.py @@ -1,4 +1,5 @@ """Flexible enumeration of C types.""" +from __future__ import print_function from Enumeration import * @@ -462,7 +463,7 @@ def test(): atg.addGenerator( btg ) atg.addGenerator( RecordTypeGenerator(fields0, False, 4) ) atg.addGenerator( etg ) - print 'Cardinality:',atg.cardinality + print('Cardinality:',atg.cardinality) for i in range(100): if i == atg.cardinality: try: @@ -470,7 +471,7 @@ def test(): raise RuntimeError("Cardinality was wrong") except AssertionError: break - print '%4d: %s'%(i, atg.get(i)) + print('%4d: %s'%(i, atg.get(i))) if __name__ == '__main__': test() diff --git a/utils/CIndex/completion_logger_server.py b/utils/CIndex/completion_logger_server.py index 0652b1f4a8..818d10d73b 100755 --- a/utils/CIndex/completion_logger_server.py +++ b/utils/CIndex/completion_logger_server.py @@ -1,4 +1,5 @@ #!/usr/bin/env python +from __future__ import print_function import sys from socket import * from time import strftime @@ -6,7 +7,7 @@ import datetime def main(): if len(sys.argv) < 4: - print "completion_logger_server.py " + print("completion_logger_server.py ") exit(1) host = sys.argv[1] @@ -18,7 +19,7 @@ def main(): UDPSock = socket(AF_INET,SOCK_DGRAM) UDPSock.bind(addr) - print "Listing on {0}:{1} and logging to '{2}'".format(host, port, sys.argv[3]) + print("Listing on {0}:{1} and logging to '{2}'".format(host, port, sys.argv[3])) # Open the logging file. f = open(sys.argv[3], "a") diff --git a/utils/TestUtils/deep-stack.py b/utils/TestUtils/deep-stack.py index 1750a5fca0..8636efabec 100755 --- a/utils/TestUtils/deep-stack.py +++ b/utils/TestUtils/deep-stack.py @@ -1,22 +1,23 @@ #!/usr/bin/env python +from __future__ import print_function def pcall(f, N): if N == 0: - print >>f, ' f(0)' + print(' f(0)', file=f) return - print >>f, ' f(' + print(' f(', file=f) pcall(f, N - 1) - print >>f, ' )' + print(' )', file=f) def main(): f = open('t.c','w') - print >>f, 'int f(int n) { return n; }' - print >>f, 'int t() {' - print >>f, ' return' + print('int f(int n) { return n; }', file=f) + print('int t() {', file=f) + print(' return', file=f) pcall(f, 10000) - print >>f, ' ;' - print >>f, '}' + print(' ;', file=f) + print('}', file=f) if __name__ == "__main__": import sys diff --git a/utils/analyzer/CmpRuns.py b/utils/analyzer/CmpRuns.py index 43d1fe83b9..14be963296 100755 --- a/utils/analyzer/CmpRuns.py +++ b/utils/analyzer/CmpRuns.py @@ -25,6 +25,7 @@ Usage: diff = compareResults(resultsA, resultsB) """ +from __future__ import print_function from collections import defaultdict @@ -318,7 +319,7 @@ def compareStats(resultsA, resultsB): statsB = deriveStats(resultsB) keys = sorted(statsA.keys()) for key in keys: - print key + print(key) for kkey in statsA[key]: valA = float(statsA[key][kkey]) valB = float(statsB[key][kkey]) @@ -331,7 +332,7 @@ def compareStats(resultsA, resultsB): report = Colors.GREEN + report + Colors.CLEAR elif ratio > 0.2: report = Colors.RED + report + Colors.CLEAR - print "\t %s %s" % (kkey, report) + print("\t %s %s" % (kkey, report)) def dumpScanBuildResultsDiff(dirA, dirB, opts, deleteEmpty=True, Stdout=sys.stdout): diff --git a/utils/analyzer/SATestAdd.py b/utils/analyzer/SATestAdd.py index 041b24409f..377897e143 100755 --- a/utils/analyzer/SATestAdd.py +++ b/utils/analyzer/SATestAdd.py @@ -42,6 +42,7 @@ the Repository Directory. diff -ur CachedSource PatchedSource \ > changes_for_analyzer.patch """ +from __future__ import print_function import SATestBuild import os @@ -66,7 +67,7 @@ def addNewProject(ID, BuildMode): CurDir = os.path.abspath(os.curdir) Dir = SATestBuild.getProjectDir(ID) if not os.path.exists(Dir): - print "Error: Project directory is missing: %s" % Dir + print("Error: Project directory is missing: %s" % Dir) sys.exit(-1) # Build the project. @@ -78,30 +79,30 @@ def addNewProject(ID, BuildMode): if os.path.exists(ProjectMapPath): FileMode = "r+b" else: - print "Warning: Creating the Project Map file!!" + print("Warning: Creating the Project Map file!!") FileMode = "w+b" with open(ProjectMapPath, FileMode) as PMapFile: if (isExistingProject(PMapFile, ID)): - print >> sys.stdout, 'Warning: Project with ID \'', ID, \ - '\' already exists.' - print >> sys.stdout, "Reference output has been regenerated." + print('Warning: Project with ID \'', ID, \ + '\' already exists.', file=sys.stdout) + print("Reference output has been regenerated.", file=sys.stdout) else: PMapWriter = csv.writer(PMapFile) PMapWriter.writerow((ID, int(BuildMode))) - print "The project map is updated: ", ProjectMapPath + print("The project map is updated: ", ProjectMapPath) # TODO: Add an option not to build. # TODO: Set the path to the Repository directory. if __name__ == '__main__': if len(sys.argv) < 2 or sys.argv[1] in ('-h', '--help'): - print >> sys.stderr, 'Add a new project for testing to the analyzer'\ + print('Add a new project for testing to the analyzer'\ '\nUsage: ', sys.argv[0],\ 'project_ID \n' \ 'mode: 0 for single file project, ' \ '1 for scan_build, ' \ - '2 for single file c++11 project' + '2 for single file c++11 project', file=sys.stderr) sys.exit(-1) BuildMode = 1 diff --git a/utils/analyzer/SATestBuild.py b/utils/analyzer/SATestBuild.py index ef0ab195f1..70c425d38e 100755 --- a/utils/analyzer/SATestBuild.py +++ b/utils/analyzer/SATestBuild.py @@ -122,7 +122,7 @@ if 'CC' in os.environ: else: Clang = SATestUtils.which("clang", os.environ['PATH']) if not Clang: - print "Error: cannot find 'clang' in PATH" + print("Error: cannot find 'clang' in PATH") sys.exit(1) # Number of jobs. @@ -570,8 +570,8 @@ def runCmpResults(Dir, Strictness=0): NewList.remove(os.path.join(NewDir, LogFolderName)) if len(RefList) != len(NewList): - print "Mismatch in number of results folders: %s vs %s" % ( - RefList, NewList) + print("Mismatch in number of results folders: %s vs %s" % ( + RefList, NewList)) sys.exit(1) # There might be more then one folder underneath - one per each scan-build @@ -719,11 +719,11 @@ def validateProjectFile(PMapFile): """ for I in iterateOverProjects(PMapFile): if len(I) != 2: - print "Error: Rows in the ProjectMapFile should have 2 entries." + print("Error: Rows in the ProjectMapFile should have 2 entries.") raise Exception() if I[1] not in ('0', '1', '2'): - print "Error: Second entry in the ProjectMapFile should be 0" \ - " (single file), 1 (project), or 2(single file c++11)." + print("Error: Second entry in the ProjectMapFile should be 0" \ + " (single file), 1 (project), or 2(single file c++11).") raise Exception() def singleThreadedTestAll(Args, ProjectsToTest): @@ -806,5 +806,5 @@ if __name__ == '__main__': TestsPassed = testAll(Args) if not TestsPassed: - print "ERROR: Tests failed." + print("ERROR: Tests failed.") sys.exit(42) diff --git a/utils/analyzer/SATestUpdateDiffs.py b/utils/analyzer/SATestUpdateDiffs.py index 3f1aafa690..64e6ca43db 100755 --- a/utils/analyzer/SATestUpdateDiffs.py +++ b/utils/analyzer/SATestUpdateDiffs.py @@ -3,6 +3,7 @@ """ Update reference results for static analyzer. """ +from __future__ import print_function import SATestBuild @@ -15,7 +16,7 @@ Verbose = 0 def runCmd(Command, **kwargs): if Verbose: - print "Executing %s" % Command + print("Executing %s" % Command) check_call(Command, shell=True, **kwargs) @@ -30,8 +31,8 @@ def updateReferenceResults(ProjName, ProjBuildMode): SATestBuild.getSBOutputDirName(IsReferenceBuild=False)) if not os.path.exists(CreatedResultsPath): - print >> sys.stderr, "New results not found, was SATestBuild.py "\ - "previously run?" + print("New results not found, was SATestBuild.py "\ + "previously run?", file=sys.stderr) sys.exit(1) BuildLogPath = SATestBuild.getBuildLogPath(RefResultsPath) @@ -62,9 +63,9 @@ def updateReferenceResults(ProjName, ProjBuildMode): def main(argv): if len(argv) == 2 and argv[1] in ('-h', '--help'): - print >> sys.stderr, "Update static analyzer reference results based "\ + print("Update static analyzer reference results based "\ "\non the previous run of SATestBuild.py.\n"\ - "\nN.B.: Assumes that SATestBuild.py was just run" + "\nN.B.: Assumes that SATestBuild.py was just run", file=sys.stderr) sys.exit(1) with SATestBuild.projectFileHandler() as f: diff --git a/utils/analyzer/SumTimerInfo.py b/utils/analyzer/SumTimerInfo.py index 50e1cb854f..b3219b00c7 100644 --- a/utils/analyzer/SumTimerInfo.py +++ b/utils/analyzer/SumTimerInfo.py @@ -6,13 +6,14 @@ Script to Summarize statistics in the scan-build output. Statistics are enabled by passing '-internal-stats' option to scan-build (or '-analyzer-stats' to the analyzer). """ +from __future__ import print_function import sys if __name__ == '__main__': if len(sys.argv) < 2: - print >> sys.stderr, 'Usage: ', sys.argv[0],\ - 'scan_build_output_file' + print('Usage: ', sys.argv[0],\ + 'scan_build_output_file', file=sys.stderr) sys.exit(-1) f = open(sys.argv[1], 'r') @@ -65,15 +66,15 @@ if __name__ == '__main__': s = line.split() TotalTime = TotalTime + float(s[6]) - print "TU Count %d" % (Count) - print "Time %f" % (Time) - print "Warnings %d" % (Warnings) - print "Functions Analyzed %d" % (FunctionsAnalyzed) - print "Reachable Blocks %d" % (ReachableBlocks) - print "Reached Max Steps %d" % (ReachedMaxSteps) - print "Number of Steps %d" % (NumSteps) - print "Number of Inlined calls %d (bifurcated %d)" % ( - NumInlinedCallSites, NumBifurcatedCallSites) - print "MaxTime %f" % (MaxTime) - print "TotalTime %f" % (TotalTime) - print "Max CFG Size %d" % (MaxCFGSize) + print("TU Count %d" % (Count)) + print("Time %f" % (Time)) + print("Warnings %d" % (Warnings)) + print("Functions Analyzed %d" % (FunctionsAnalyzed)) + print("Reachable Blocks %d" % (ReachableBlocks)) + print("Reached Max Steps %d" % (ReachedMaxSteps)) + print("Number of Steps %d" % (NumSteps)) + print("Number of Inlined calls %d (bifurcated %d)" % ( + NumInlinedCallSites, NumBifurcatedCallSites)) + print("MaxTime %f" % (MaxTime)) + print("TotalTime %f" % (TotalTime)) + print("Max CFG Size %d" % (MaxCFGSize)) diff --git a/utils/check_cfc/setup.py b/utils/check_cfc/setup.py index b5fc473639..6005f6f411 100644 --- a/utils/check_cfc/setup.py +++ b/utils/check_cfc/setup.py @@ -1,6 +1,7 @@ """For use on Windows. Run with: python.exe setup.py py2exe """ +from __future__ import print_function from distutils.core import setup try: import py2exe @@ -8,10 +9,10 @@ except ImportError: import platform import sys if platform.system() == 'Windows': - print "Could not find py2exe. Please install then run setup.py py2exe." + print("Could not find py2exe. Please install then run setup.py py2exe.") raise else: - print "setup.py only required on Windows." + print("setup.py only required on Windows.") sys.exit(1) setup( diff --git a/utils/clangdiag.py b/utils/clangdiag.py index 9a80e2696d..d449194e28 100755 --- a/utils/clangdiag.py +++ b/utils/clangdiag.py @@ -9,6 +9,7 @@ # (lldb) command script import /path/to/clandiag.py #---------------------------------------------------------------------- +from __future__ import print_function import lldb import argparse import commands @@ -189,4 +190,4 @@ def __lldb_init_module(debugger, dict): # Add any commands contained in this module to LLDB debugger.HandleCommand( 'command script add -f clangdiag.the_diag_command clangdiag') - print 'The "clangdiag" command has been installed, type "help clangdiag" or "clangdiag --help" for detailed help.' + print('The "clangdiag" command has been installed, type "help clangdiag" or "clangdiag --help" for detailed help.') diff --git a/utils/modfuzz.py b/utils/modfuzz.py index 948603338c..4dc25e8469 100644 --- a/utils/modfuzz.py +++ b/utils/modfuzz.py @@ -4,6 +4,7 @@ # 1) Update the 'decls' list below with your fuzzing configuration. # 2) Run with the clang binary as the command-line argument. +from __future__ import print_function import random import subprocess import sys @@ -97,7 +98,7 @@ def generate(): if not model.fails(): return except KeyboardInterrupt: - print + print() return True sys.stdout.write('\nReducing:\n') diff --git a/utils/token-delta.py b/utils/token-delta.py index 5efb65cb2f..9fc5646bb7 100755 --- a/utils/token-delta.py +++ b/utils/token-delta.py @@ -1,5 +1,6 @@ #!/usr/bin/env python +from __future__ import print_function import os import re import subprocess @@ -165,7 +166,7 @@ class TMBDDelta(DeltaAlgorithm): byFile = self.writeFiles(changes, self.tempFiles) if self.log: - print >>sys.stderr, 'TEST - ', + print('TEST - ', end=' ', file=sys.stderr) if self.log > 1: for i,(file,_) in enumerate(self.tokenLists): indices = byFile[i] @@ -184,8 +185,8 @@ class TMBDDelta(DeltaAlgorithm): sys.stderr.write(str(byFile[i][-1])) sys.stderr.write('] ') else: - print >>sys.stderr, ', '.join(['%s:%d tokens' % (file, len(byFile[i])) - for i,(file,_) in enumerate(self.tokenLists)]), + print(', '.join(['%s:%d tokens' % (file, len(byFile[i])) + for i,(file,_) in enumerate(self.tokenLists)]), end=' ', file=sys.stderr) p = subprocess.Popen([self.testProgram] + self.tempFiles) res = p.wait() == 0 @@ -194,10 +195,10 @@ class TMBDDelta(DeltaAlgorithm): self.writeFiles(changes, self.targetFiles) if self.log: - print >>sys.stderr, '=> %s' % res + print('=> %s' % res, file=sys.stderr) else: if res: - print '\nSUCCESS (%d tokens)' % len(changes) + print('\nSUCCESS (%d tokens)' % len(changes)) else: sys.stderr.write('.') @@ -209,7 +210,7 @@ class TMBDDelta(DeltaAlgorithm): for j in range(len(tokens))]) self.writeFiles(res, self.targetFiles) if not self.log: - print >>sys.stderr + print(file=sys.stderr) return res def tokenBasedMultiDelta(program, files, log): @@ -218,15 +219,15 @@ def tokenBasedMultiDelta(program, files, log): for file in files] numTokens = sum([len(tokens) for _,tokens in tokenLists]) - print "Delta on %s with %d tokens." % (', '.join(files), numTokens) + print("Delta on %s with %d tokens." % (', '.join(files), numTokens)) tbmd = TMBDDelta(program, tokenLists, log) res = tbmd.run() - print "Finished %s with %d tokens (in %d tests)." % (', '.join(tbmd.targetFiles), + print("Finished %s with %d tokens (in %d tests)." % (', '.join(tbmd.targetFiles), len(res), - tbmd.numTests) + tbmd.numTests)) def main(): from optparse import OptionParser, OptionGroup @@ -247,5 +248,5 @@ if __name__ == '__main__': try: main() except KeyboardInterrupt: - print >>sys.stderr,'Interrupted.' + print('Interrupted.', file=sys.stderr) os._exit(1) # Avoid freeing our giant cache. -- cgit v1.2.3 From 8d4d731fb7848841adb91cfb3bed162a14c679e7 Mon Sep 17 00:00:00 2001 From: Serge Guelton Date: Tue, 18 Dec 2018 08:38:50 +0000 Subject: Portable Python script across Python version In Python2, division between integer yields an integer, while it yields a float in Python3. Use a combination of from __future__ import division and // operator to get a portable behavior. Differential Revision: https://reviews.llvm.org/D55204 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349455 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/ABITest/TypeGen.py | 4 ++-- utils/analyzer/CmpRuns.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/utils/ABITest/TypeGen.py b/utils/ABITest/TypeGen.py index 608089429a..698e358829 100644 --- a/utils/ABITest/TypeGen.py +++ b/utils/ABITest/TypeGen.py @@ -1,5 +1,5 @@ """Flexible enumeration of C types.""" -from __future__ import print_function +from __future__ import division, print_function from Enumeration import * @@ -235,7 +235,7 @@ def fact(n): # Compute the number of combinations (n choose k) def num_combinations(n, k): - return fact(n) / (fact(k) * fact(n - k)) + return fact(n) // (fact(k) * fact(n - k)) # Enumerate the combinations choosing k elements from the list of values def combinations(values, k): diff --git a/utils/analyzer/CmpRuns.py b/utils/analyzer/CmpRuns.py index 14be963296..87d5eda7a1 100755 --- a/utils/analyzer/CmpRuns.py +++ b/utils/analyzer/CmpRuns.py @@ -25,7 +25,7 @@ Usage: diff = compareResults(resultsA, resultsB) """ -from __future__ import print_function +from __future__ import division, print_function from collections import defaultdict @@ -308,7 +308,7 @@ def deriveStats(results): "mean": sum(values) / len(values), "90th %tile": computePercentile(values, 0.9), "95th %tile": computePercentile(values, 0.95), - "median": sorted(values)[len(values) / 2], + "median": sorted(values)[len(values) // 2], "total": sum(values) } return combined_stats -- cgit v1.2.3 From 39c76de299e55185d374fca5e44e1fbd2bf22749 Mon Sep 17 00:00:00 2001 From: Stefan Pintilie Date: Tue, 18 Dec 2018 15:08:03 +0000 Subject: [PowerPC] Make no-PIC default to match GCC - CLANG Make -fno-PIC default on PowerPC for Little Endian Linux. Differential Revision: https://reviews.llvm.org/D53384 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349489 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Driver/ToolChains/Gnu.cpp | 2 +- test/Driver/clang-offload-bundler.c | 2 +- test/Driver/ppc-abi.c | 42 ++++++++++++++++++++++++++++++++++--- 3 files changed, 41 insertions(+), 5 deletions(-) diff --git a/lib/Driver/ToolChains/Gnu.cpp b/lib/Driver/ToolChains/Gnu.cpp index 3850e1c02e..fbd4dc72e5 100644 --- a/lib/Driver/ToolChains/Gnu.cpp +++ b/lib/Driver/ToolChains/Gnu.cpp @@ -2435,7 +2435,7 @@ bool Generic_GCC::isPICDefault() const { case llvm::Triple::x86_64: return getTriple().isOSWindows(); case llvm::Triple::ppc64: - case llvm::Triple::ppc64le: + // Big endian PPC is PIC by default return !getTriple().isOSBinFormatMachO() && !getTriple().isMacOSX(); case llvm::Triple::mips64: case llvm::Triple::mips64el: diff --git a/test/Driver/clang-offload-bundler.c b/test/Driver/clang-offload-bundler.c index adf13f59d4..15092dd127 100644 --- a/test/Driver/clang-offload-bundler.c +++ b/test/Driver/clang-offload-bundler.c @@ -115,7 +115,7 @@ // CK-TEXTI: // __CLANG_OFFLOAD_BUNDLE____END__ openmp-x86_64-pc-linux-gnu // CK-TEXTLL: ; __CLANG_OFFLOAD_BUNDLE____START__ host-powerpc64le-ibm-linux-gnu -// CK-TEXTLL: @A = global i32 0 +// CK-TEXTLL: @A = dso_local global i32 0 // CK-TEXTLL: define {{.*}}@test_func() // CK-TEXTLL: ; __CLANG_OFFLOAD_BUNDLE____END__ host-powerpc64le-ibm-linux-gnu // CK-TEXTLL: ; __CLANG_OFFLOAD_BUNDLE____START__ openmp-powerpc64le-ibm-linux-gnu diff --git a/test/Driver/ppc-abi.c b/test/Driver/ppc-abi.c index cebc90d3f9..a82a01de27 100644 --- a/test/Driver/ppc-abi.c +++ b/test/Driver/ppc-abi.c @@ -13,12 +13,12 @@ // RUN: %clang -target powerpc64-unknown-linux-gnu %s -### -o %t.o 2>&1 \ // RUN: -mcpu=a2q -mno-qpx | FileCheck -check-prefix=CHECK-ELFv1 %s // RUN: %clang -target powerpc64-unknown-linux-gnu %s -### -o %t.o 2>&1 \ -// RUN: -mabi=elfv2 | FileCheck -check-prefix=CHECK-ELFv2 %s +// RUN: -mabi=elfv2 | FileCheck -check-prefix=CHECK-ELFv2-BE %s // RUN: %clang -target powerpc64le-unknown-linux-gnu %s -### -o %t.o 2>&1 \ // RUN: | FileCheck -check-prefix=CHECK-ELFv2 %s // RUN: %clang -target powerpc64le-unknown-linux-gnu %s -### -o %t.o 2>&1 \ -// RUN: -mabi=elfv1 | FileCheck -check-prefix=CHECK-ELFv1 %s +// RUN: -mabi=elfv1 | FileCheck -check-prefix=CHECK-ELFv1-LE %s // RUN: %clang -target powerpc64le-unknown-linux-gnu %s -### -o %t.o 2>&1 \ // RUN: -mabi=elfv2 | FileCheck -check-prefix=CHECK-ELFv2 %s // RUN: %clang -target powerpc64le-unknown-linux-gnu %s -### -o %t.o 2>&1 \ @@ -26,8 +26,44 @@ // CHECK-ELFv1: "-mrelocation-model" "pic" "-pic-level" "2" // CHECK-ELFv1: "-target-abi" "elfv1" +// CHECK-ELFv1-LE: "-mrelocation-model" "static" +// CHECK-ELFv1-LE: "-target-abi" "elfv1" // CHECK-ELFv1-QPX: "-mrelocation-model" "pic" "-pic-level" "2" // CHECK-ELFv1-QPX: "-target-abi" "elfv1-qpx" -// CHECK-ELFv2: "-mrelocation-model" "pic" "-pic-level" "2" +// CHECK-ELFv2: "-mrelocation-model" "static" // CHECK-ELFv2: "-target-abi" "elfv2" +// CHECK-ELFv2-BE: "-mrelocation-model" "pic" "-pic-level" "2" +// CHECK-ELFv2-BE: "-target-abi" "elfv2" + +// RUN: %clang -fPIC -target powerpc64-unknown-linux-gnu %s -### -o %t.o 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK-ELFv1-PIC %s +// RUN: %clang -fPIC -target powerpc64-unknown-linux-gnu %s -### -o %t.o 2>&1 \ +// RUN: -mabi=elfv1 | FileCheck -check-prefix=CHECK-ELFv1-PIC %s +// RUN: %clang -fPIC -target powerpc64-unknown-linux-gnu %s -### -o %t.o 2>&1 \ +// RUN: -mabi=elfv1-qpx | FileCheck -check-prefix=CHECK-ELFv1-QPX-PIC %s +// RUN: %clang -fPIC -target powerpc64-unknown-linux-gnu %s -### -o %t.o 2>&1 \ +// RUN: -mcpu=a2q | FileCheck -check-prefix=CHECK-ELFv1-QPX-PIC %s +// RUN: %clang -fPIC -target powerpc64-unknown-linux-gnu %s -### -o %t.o 2>&1 \ +// RUN: -mcpu=a2 -mqpx | FileCheck -check-prefix=CHECK-ELFv1-QPX-PIC %s +// RUN: %clang -fPIC -target powerpc64-unknown-linux-gnu %s -### -o %t.o 2>&1 \ +// RUN: -mcpu=a2q -mno-qpx | FileCheck -check-prefix=CHECK-ELFv1-PIC %s +// RUN: %clang -fPIC -target powerpc64-unknown-linux-gnu %s -### -o %t.o 2>&1 \ +// RUN: -mabi=elfv2 | FileCheck -check-prefix=CHECK-ELFv2-PIC %s + +// RUN: %clang -fPIC -target powerpc64le-unknown-linux-gnu %s -### -o %t.o 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK-ELFv2-PIC %s +// RUN: %clang -fPIC -target powerpc64le-unknown-linux-gnu %s -### -o %t.o 2>&1 \ +// RUN: -mabi=elfv1 | FileCheck -check-prefix=CHECK-ELFv1-PIC %s +// RUN: %clang -fPIC -target powerpc64le-unknown-linux-gnu %s -### -o %t.o 2>&1 \ +// RUN: -mabi=elfv2 | FileCheck -check-prefix=CHECK-ELFv2-PIC %s +// RUN: %clang -fPIC -target powerpc64le-unknown-linux-gnu %s -### -o %t.o 2>&1 \ +// RUN: -mabi=altivec | FileCheck -check-prefix=CHECK-ELFv2-PIC %s + +// CHECK-ELFv1-PIC: "-mrelocation-model" "pic" "-pic-level" "2" +// CHECK-ELFv1-PIC: "-target-abi" "elfv1" +// CHECK-ELFv1-QPX-PIC: "-mrelocation-model" "pic" "-pic-level" "2" +// CHECK-ELFv1-QPX-PIC: "-target-abi" "elfv1-qpx" +// CHECK-ELFv2-PIC: "-mrelocation-model" "pic" "-pic-level" "2" +// CHECK-ELFv2-PIC: "-target-abi" "elfv2" + -- cgit v1.2.3 From 44eff1bd110e830f47e8f8da780bc6e00b95a342 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Tue, 18 Dec 2018 15:29:12 +0000 Subject: [AST] Unify the code paths of traversing lambda expressions. Summary: This supposes to be a non-functional change. We have two code paths when traversing lambda expressions: 1) traverse the function proto typeloc when parameters and return type are explicit; 2) otherwise fallback to traverse parameter decls and return type loc individually; This patch unifies the code path to always traverse parameters and return type, rather than relying on traversing the full type-loc. Reviewers: ilya-biryukov Subscribers: arphaman, cfe-commits Differential Revision: https://reviews.llvm.org/D55820 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349494 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/RecursiveASTVisitor.h | 31 ++++++++++++------------------- test/Index/cxx11-lambdas.cpp | 2 +- tools/libclang/CIndex.cpp | 28 +++++++++++----------------- 3 files changed, 24 insertions(+), 37 deletions(-) diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h index eb582c7a7a..0d88517010 100644 --- a/include/clang/AST/RecursiveASTVisitor.h +++ b/include/clang/AST/RecursiveASTVisitor.h @@ -2414,27 +2414,20 @@ DEF_TRAVERSE_STMT(LambdaExpr, { TypeLoc TL = S->getCallOperator()->getTypeSourceInfo()->getTypeLoc(); FunctionProtoTypeLoc Proto = TL.getAsAdjusted(); - if (S->hasExplicitParameters() && S->hasExplicitResultType()) { - // Visit the whole type. - TRY_TO(TraverseTypeLoc(TL)); - } else { - if (S->hasExplicitParameters()) { - // Visit parameters. - for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I) { - TRY_TO(TraverseDecl(Proto.getParam(I))); - } - } else if (S->hasExplicitResultType()) { - TRY_TO(TraverseTypeLoc(Proto.getReturnLoc())); - } + if (S->hasExplicitParameters()) { + // Visit parameters. + for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I) + TRY_TO(TraverseDecl(Proto.getParam(I))); + } + if (S->hasExplicitResultType()) + TRY_TO(TraverseTypeLoc(Proto.getReturnLoc())); - auto *T = Proto.getTypePtr(); - for (const auto &E : T->exceptions()) { - TRY_TO(TraverseType(E)); - } + auto *T = Proto.getTypePtr(); + for (const auto &E : T->exceptions()) + TRY_TO(TraverseType(E)); - if (Expr *NE = T->getNoexceptExpr()) - TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(NE); - } + if (Expr *NE = T->getNoexceptExpr()) + TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(NE); ReturnValue = TRAVERSE_STMT_BASE(LambdaBody, LambdaExpr, S, Queue); ShouldVisitChildren = false; diff --git a/test/Index/cxx11-lambdas.cpp b/test/Index/cxx11-lambdas.cpp index d0ee908059..66df09ad29 100644 --- a/test/Index/cxx11-lambdas.cpp +++ b/test/Index/cxx11-lambdas.cpp @@ -14,9 +14,9 @@ struct X { // CHECK-LOAD: cxx11-lambdas.cpp:7:19: LambdaExpr= Extent=[7:19 - 9:6] // CHECK-LOAD: cxx11-lambdas.cpp:7:21: VariableRef=localA:6:9 Extent=[7:21 - 7:27] // CHECK-LOAD: cxx11-lambdas.cpp:7:29: VariableRef=localB:6:17 Extent=[7:29 - 7:35] -// CHECK-LOAD: cxx11-lambdas.cpp:7:52: TypeRef=Integer:3:13 Extent=[7:52 - 7:59] // CHECK-LOAD: cxx11-lambdas.cpp:7:46: ParmDecl=x:7:46 (Definition) Extent=[7:38 - 7:47] // CHECK-LOAD: cxx11-lambdas.cpp:7:38: TypeRef=Integer:3:13 Extent=[7:38 - 7:45] +// CHECK-LOAD: cxx11-lambdas.cpp:7:52: TypeRef=Integer:3:13 Extent=[7:52 - 7:59] // CHECK-LOAD: cxx11-lambdas.cpp:7:60: CompoundStmt= Extent=[7:60 - 9:6] // CHECK-LOAD: cxx11-lambdas.cpp:8:7: ReturnStmt= Extent=[8:7 - 8:33] // CHECK-LOAD: cxx11-lambdas.cpp:8:14: DeclRefExpr=localA:6:9 Extent=[8:14 - 8:20] diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp index ca8b4baf6c..bc791954fc 100644 --- a/tools/libclang/CIndex.cpp +++ b/tools/libclang/CIndex.cpp @@ -3135,25 +3135,19 @@ bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) { return true; } + TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc(); // Visit parameters and return type, if present. - if (E->hasExplicitParameters() || E->hasExplicitResultType()) { - TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc(); - if (E->hasExplicitParameters() && E->hasExplicitResultType()) { - // Visit the whole type. - if (Visit(TL)) - return true; - } else if (FunctionProtoTypeLoc Proto = - TL.getAs()) { - if (E->hasExplicitParameters()) { - // Visit parameters. - for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I) - if (Visit(MakeCXCursor(Proto.getParam(I), TU))) - return true; - } else { - // Visit result type. - if (Visit(Proto.getReturnLoc())) + if (FunctionTypeLoc Proto = TL.getAs()) { + if (E->hasExplicitParameters()) { + // Visit parameters. + for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I) + if (Visit(MakeCXCursor(Proto.getParam(I), TU))) return true; - } + } + if (E->hasExplicitResultType()) { + // Visit result type. + if (Visit(Proto.getReturnLoc())) + return true; } } break; -- cgit v1.2.3 From 38ed7e5d7917d18c9c7af9c49c5d83a112c6222a Mon Sep 17 00:00:00 2001 From: Aaron Ballman Date: Tue, 18 Dec 2018 15:54:38 +0000 Subject: Emit -Wformat properly for bit-field promotions. Only explicitly look through integer and floating-point promotion where the result type is actually a promotion, which is not always the case for bit-fields in C. Patch by Bevin Hansson. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349497 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaChecking.cpp | 32 +++++++++++++++++++++---- test/Sema/format-strings-bitfield-promotion.c | 18 ++++++++++++++ test/Sema/format-strings-bitfield-promotion.cxx | 21 ++++++++++++++++ 3 files changed, 67 insertions(+), 4 deletions(-) create mode 100644 test/Sema/format-strings-bitfield-promotion.c create mode 100644 test/Sema/format-strings-bitfield-promotion.cxx diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index 46cac25eed..b06f793b17 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -7771,6 +7771,30 @@ shouldNotPrintDirectly(const ASTContext &Context, return std::make_pair(QualType(), StringRef()); } +/// Return true if \p ICE is an implicit argument promotion of an arithmetic +/// type. Bit-field 'promotions' from a higher ranked type to a lower ranked +/// type do not count. +static bool +isArithmeticArgumentPromotion(Sema &S, const ImplicitCastExpr *ICE) { + QualType From = ICE->getSubExpr()->getType(); + QualType To = ICE->getType(); + // It's an integer promotion if the destination type is the promoted + // source type. + if (ICE->getCastKind() == CK_IntegralCast && + From->isPromotableIntegerType() && + S.Context.getPromotedIntegerType(From) == To) + return true; + // Look through vector types, since we do default argument promotion for + // those in OpenCL. + if (const auto *VecTy = From->getAs()) + From = VecTy->getElementType(); + if (const auto *VecTy = To->getAs()) + To = VecTy->getElementType(); + // It's a floating promotion if the source type is a lower rank. + return ICE->getCastKind() == CK_FloatingCast && + S.Context.getFloatingTypeOrder(From, To) < 0; +} + bool CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS, const char *StartSpecifier, @@ -7798,11 +7822,11 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS, // Look through argument promotions for our error message's reported type. // This includes the integral and floating promotions, but excludes array - // and function pointer decay; seeing that an argument intended to be a - // string has type 'char [6]' is probably more confusing than 'char *'. + // and function pointer decay (seeing that an argument intended to be a + // string has type 'char [6]' is probably more confusing than 'char *') and + // certain bitfield promotions (bitfields can be 'demoted' to a lesser type). if (const ImplicitCastExpr *ICE = dyn_cast(E)) { - if (ICE->getCastKind() == CK_IntegralCast || - ICE->getCastKind() == CK_FloatingCast) { + if (isArithmeticArgumentPromotion(S, ICE)) { E = ICE->getSubExpr(); ExprTy = E->getType(); diff --git a/test/Sema/format-strings-bitfield-promotion.c b/test/Sema/format-strings-bitfield-promotion.c new file mode 100644 index 0000000000..cbe00e7510 --- /dev/null +++ b/test/Sema/format-strings-bitfield-promotion.c @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple x86_64-unknown-windows-msvc -fsyntax-only -verify %s + +int printf(const char *restrict, ...); + +struct bitfields { + long a : 2; + unsigned long b : 2; + long c : 32; // assumes that int is 32 bits + unsigned long d : 32; // assumes that int is 32 bits +} bf; + +void bitfield_promotion() { + printf("%ld", bf.a); // expected-warning {{format specifies type 'long' but the argument has type 'int'}} + printf("%lu", bf.b); // expected-warning {{format specifies type 'unsigned long' but the argument has type 'int'}} + printf("%ld", bf.c); // expected-warning {{format specifies type 'long' but the argument has type 'int'}} + printf("%lu", bf.d); // expected-warning {{format specifies type 'unsigned long' but the argument has type 'unsigned int'}} +} diff --git a/test/Sema/format-strings-bitfield-promotion.cxx b/test/Sema/format-strings-bitfield-promotion.cxx new file mode 100644 index 0000000000..2309e98066 --- /dev/null +++ b/test/Sema/format-strings-bitfield-promotion.cxx @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple x86_64-unknown-windows-msvc -fsyntax-only -verify %s + +// In C++, the bitfield promotion from long to int does not occur, unlike C. +// expected-no-diagnostics + +int printf(const char *restrict, ...); + +struct bitfields { + long a : 2; + unsigned long b : 2; + long c : 32; // assumes that int is 32 bits + unsigned long d : 32; // assumes that int is 32 bits +} bf; + +void bitfield_promotion() { + printf("%ld", bf.a); + printf("%lu", bf.b); + printf("%ld", bf.c); + printf("%lu", bf.d); +} -- cgit v1.2.3 From bd8d3419e1b6a1c7ec82e1ceb1f22b407a38dac9 Mon Sep 17 00:00:00 2001 From: Serge Guelton Date: Tue, 18 Dec 2018 16:04:21 +0000 Subject: Portable Python script across Python version In Python3, dict.items, dict.keys, dict.values, zip, map and filter no longer return lists, they create generator instead. The portability patch consists in forcing an extra `list` call if the result is actually used as a list. `map` are replaced by list comprehension and `filter` by filtered list comprehension. Differential Revision: https://reviews.llvm.org/D55197 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349501 91177308-0d34-0410-b5e6-96231b3b80d8 --- bindings/python/examples/cindex/cindex-dump.py | 2 +- tools/scan-view/share/Reporter.py | 6 +++--- tools/scan-view/share/ScanView.py | 2 +- utils/ABITest/ABITestGen.py | 6 +++--- utils/ABITest/TypeGen.py | 6 +++--- utils/analyzer/CmpRuns.py | 4 ++-- utils/analyzer/SATestBuild.py | 3 +-- utils/check_cfc/check_cfc.py | 4 ++-- utils/check_cfc/obj_diff.py | 4 ++-- utils/perf-training/perf-helper.py | 6 +++--- www/builtins.py | 2 +- 11 files changed, 22 insertions(+), 23 deletions(-) diff --git a/bindings/python/examples/cindex/cindex-dump.py b/bindings/python/examples/cindex/cindex-dump.py index 5556ad121a..acec7e0e00 100644 --- a/bindings/python/examples/cindex/cindex-dump.py +++ b/bindings/python/examples/cindex/cindex-dump.py @@ -79,7 +79,7 @@ def main(): if not tu: parser.error("unable to load input") - pprint(('diags', map(get_diag_info, tu.diagnostics))) + pprint(('diags', [get_diag_info(d) for d in tu.diagnostics])) pprint(('nodes', get_info(tu.cursor))) if __name__ == '__main__': diff --git a/tools/scan-view/share/Reporter.py b/tools/scan-view/share/Reporter.py index 7887636559..b1ff16142e 100644 --- a/tools/scan-view/share/Reporter.py +++ b/tools/scan-view/share/Reporter.py @@ -80,7 +80,7 @@ class EmailReporter(object): return 'Email' def getParameters(self): - return map(lambda x:TextParameter(x),['To', 'From', 'SMTP Server', 'SMTP Port']) + return [TextParameter(x) for x in ['To', 'From', 'SMTP Server', 'SMTP Port']] # Lifted from python email module examples. def attachFile(self, outer, path): @@ -148,7 +148,7 @@ class BugzillaReporter(object): return 'Bugzilla' def getParameters(self): - return map(lambda x:TextParameter(x),['URL','Product']) + return [TextParameter(x) for x in ['URL','Product']] def fileReport(self, report, parameters): raise NotImplementedError @@ -211,7 +211,7 @@ class RadarReporter(object): script = os.path.join(os.path.dirname(__file__),'../share/scan-view/FileRadar.scpt') args = ['osascript', script, component, componentVersion, classification, personID, report.title, - report.description, diagnosis, config] + map(os.path.abspath, report.files) + report.description, diagnosis, config] + [os.path.abspath(f) for f in report.files] # print >>sys.stderr, args try: p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) diff --git a/tools/scan-view/share/ScanView.py b/tools/scan-view/share/ScanView.py index b1ce8c3d3a..b4227f4a28 100644 --- a/tools/scan-view/share/ScanView.py +++ b/tools/scan-view/share/ScanView.py @@ -192,7 +192,7 @@ class ScanViewServer(HTTPServer): def parse_query(qs, fields=None): if fields is None: fields = {} - for chunk in filter(None, qs.split('&')): + for chunk in (_f for _f in qs.split('&') if _f): if '=' not in chunk: name = chunk value = '' diff --git a/utils/ABITest/ABITestGen.py b/utils/ABITest/ABITestGen.py index d42e08e123..a829f925df 100755 --- a/utils/ABITest/ABITestGen.py +++ b/utils/ABITest/ABITestGen.py @@ -148,7 +148,7 @@ class TypePrinter(object): retvalTests = None else: retvalTests = self.getTestValuesArray(FT.returnType) - tests = map(self.getTestValuesArray, FT.argTypes) + tests = [self.getTestValuesArray(ty) for ty in FT.argTypes] print('void test_%s(void) {'%(fnName,), file=self.outputTests) if retvalTests is not None: @@ -231,10 +231,10 @@ class TypePrinter(object): yield '{ %s }' % v return - fieldValues = map(list, map(self.getTestValues, nonPadding)) + fieldValues = [list(v) for v in map(self.getTestValues, nonPadding)] for i,values in enumerate(fieldValues): for v in values: - elements = map(random.choice,fieldValues) + elements = [random.choice(fv) for fv in fieldValues] elements[i] = v yield '{ %s }'%(', '.join(elements)) diff --git a/utils/ABITest/TypeGen.py b/utils/ABITest/TypeGen.py index 698e358829..8561baea61 100644 --- a/utils/ABITest/TypeGen.py +++ b/utils/ABITest/TypeGen.py @@ -110,7 +110,7 @@ class RecordType(Type): t.getBitFieldSize()) else: return '%s field%d;'%(printer.getTypeName(t),i) - fields = map(getField, enumerate(self.fields)) + fields = [getField(f) for f in enumerate(self.fields)] # Name the struct for more readable LLVM IR. return 'typedef %s %s { %s } %s;'%(('struct','union')[self.isUnion], name, ' '.join(fields), name) @@ -372,7 +372,7 @@ class RecordTypeGenerator(TypeGenerator): isUnion,I = False,N if self.useUnion: isUnion,I = (I&1),I>>1 - fields = map(self.typeGen.get,getNthTuple(I,self.maxSize,self.typeGen.cardinality)) + fields = [self.typeGen.get(f) for f in getNthTuple(I,self.maxSize,self.typeGen.cardinality)] return RecordType(N, isUnion, fields) class FunctionTypeGenerator(TypeGenerator): @@ -405,7 +405,7 @@ class FunctionTypeGenerator(TypeGenerator): else: retTy = None argIndices = getNthTuple(N, self.maxSize, self.typeGen.cardinality) - args = map(self.typeGen.get, argIndices) + args = [self.typeGen.get(i) for i in argIndices] return FunctionType(N, retTy, args) class AnyTypeGenerator(TypeGenerator): diff --git a/utils/analyzer/CmpRuns.py b/utils/analyzer/CmpRuns.py index 87d5eda7a1..be50349962 100755 --- a/utils/analyzer/CmpRuns.py +++ b/utils/analyzer/CmpRuns.py @@ -298,10 +298,10 @@ def deriveStats(results): combined_data['PathsLength'].append(diagnostic.getPathLength()) for stat in results.stats: - for key, value in stat.iteritems(): + for key, value in stat.items(): combined_data[key].append(value) combined_stats = {} - for key, values in combined_data.iteritems(): + for key, values in combined_data.items(): combined_stats[str(key)] = { "max": max(values), "min": min(values), diff --git a/utils/analyzer/SATestBuild.py b/utils/analyzer/SATestBuild.py index 70c425d38e..1c96cd8838 100755 --- a/utils/analyzer/SATestBuild.py +++ b/utils/analyzer/SATestBuild.py @@ -583,8 +583,7 @@ def runCmpResults(Dir, Strictness=0): # Iterate and find the differences. NumDiffs = 0 - PairList = zip(RefList, NewList) - for P in PairList: + for P in zip(RefList, NewList): RefDir = P[0] NewDir = P[1] diff --git a/utils/check_cfc/check_cfc.py b/utils/check_cfc/check_cfc.py index 0228f1d625..aea9bdd638 100755 --- a/utils/check_cfc/check_cfc.py +++ b/utils/check_cfc/check_cfc.py @@ -98,8 +98,8 @@ def remove_dir_from_path(path_var, directory): PATH""" pathlist = path_var.split(os.pathsep) norm_directory = os.path.normpath(os.path.normcase(directory)) - pathlist = filter(lambda x: os.path.normpath( - os.path.normcase(x)) != norm_directory, pathlist) + pathlist = [x for x in pathlist if os.path.normpath( + os.path.normcase(x)) != norm_directory] return os.pathsep.join(pathlist) def path_without_wrapper(): diff --git a/utils/check_cfc/obj_diff.py b/utils/check_cfc/obj_diff.py index cc4c2a97d5..61b9118df8 100755 --- a/utils/check_cfc/obj_diff.py +++ b/utils/check_cfc/obj_diff.py @@ -25,7 +25,7 @@ def disassemble(objfile): if p.returncode or err: print("Disassemble failed: {}".format(objfile)) sys.exit(1) - return filter(keep_line, out.split(os.linesep)) + return [line for line in out.split(os.linesep) if keep_line(line)] def dump_debug(objfile): """Dump all of the debug info from a file.""" @@ -34,7 +34,7 @@ def dump_debug(objfile): if p.returncode or err: print("Dump debug failed: {}".format(objfile)) sys.exit(1) - return filter(keep_line, out.split(os.linesep)) + return [line for line in out.split(os.linesep) if keep_line(line)] def first_diff(a, b, fromfile, tofile): """Returns the first few lines of a difference, if there is one. Python diff --git a/utils/perf-training/perf-helper.py b/utils/perf-training/perf-helper.py index 30b9caeffd..6337a9b19a 100644 --- a/utils/perf-training/perf-helper.py +++ b/utils/perf-training/perf-helper.py @@ -295,8 +295,8 @@ def form_by_frequency(symbol_lists): for a in symbols: counts[a] = counts.get(a,0) + 1 - by_count = counts.items() - by_count.sort(key = lambda (_,n): -n) + by_count = list(counts.items()) + by_count.sort(key = lambda __n: -__n[1]) return [s for s,n in by_count] def form_by_random(symbol_lists): @@ -333,7 +333,7 @@ def genOrderFile(args): help="write a list of the unordered symbols to PATH (requires --binary)", default=None, metavar="PATH") parser.add_argument("--method", dest="method", - help="order file generation method to use", choices=methods.keys(), + help="order file generation method to use", choices=list(methods.keys()), default='call_order') opts = parser.parse_args(args) diff --git a/www/builtins.py b/www/builtins.py index 18f86ab9e2..f0bcf1962a 100755 --- a/www/builtins.py +++ b/www/builtins.py @@ -151,7 +151,7 @@ def report_cant(builtin): sys.stderr.write("%s:%d: x86 builtin %s used, too many replacements\n" % (fileinput.filename(), fileinput.filelineno(), builtin)) for line in fileinput.input(inplace=1): - for builtin, repl in repl_map.iteritems(): + for builtin, repl in repl_map.items(): if builtin in line: line = line.replace(builtin, repl) report_repl(builtin, repl) -- cgit v1.2.3 From cf888dadbd8a75717f099042d4942f4a62d869ca Mon Sep 17 00:00:00 2001 From: Serge Guelton Date: Tue, 18 Dec 2018 16:07:06 +0000 Subject: Portable Python script across Python version commands.getoutput has been move to subprocess module in Python3 Differential Revision: https://reviews.llvm.org/D55205 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349503 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/scan-view/share/startfile.py | 9 ++++++--- utils/clangdiag.py | 1 - 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/tools/scan-view/share/startfile.py b/tools/scan-view/share/startfile.py index 58023d0271..9eb548bc43 100644 --- a/tools/scan-view/share/startfile.py +++ b/tools/scan-view/share/startfile.py @@ -110,7 +110,10 @@ elif sys.platform == 'darwin': # Platform support for Unix else: - import commands + try: + from commands import getoutput + except ImportError: + from subprocess import getoutput # @WARNING: use the private API of the webbrowser module from webbrowser import _iscommand @@ -125,7 +128,7 @@ else: def detect_kde_version(self): kde_version = None try: - info = commands.getoutput('kde-config --version') + info = getoutput('kde-config --version') for line in info.splitlines(): if line.startswith('KDE'): @@ -158,7 +161,7 @@ else: desktop_environment = 'gnome' else: try: - info = commands.getoutput('xprop -root _DT_SAVE_MODE') + info = getoutput('xprop -root _DT_SAVE_MODE') if ' = "xfce4"' in info: desktop_environment = 'xfce' except (OSError, RuntimeError): diff --git a/utils/clangdiag.py b/utils/clangdiag.py index d449194e28..a9656c55d8 100755 --- a/utils/clangdiag.py +++ b/utils/clangdiag.py @@ -12,7 +12,6 @@ from __future__ import print_function import lldb import argparse -import commands import shlex import os import re -- cgit v1.2.3 From 4090d6c943078cd267f5b642e30283270fc17801 Mon Sep 17 00:00:00 2001 From: Serge Guelton Date: Tue, 18 Dec 2018 16:07:37 +0000 Subject: Portable Python script across Python version Make scripts more future-proof by importing most __future__ stuff. Differential Revision: https://reviews.llvm.org/D55208 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349504 91177308-0d34-0410-b5e6-96231b3b80d8 --- bindings/python/clang/cindex.py | 2 +- docs/conf.py | 2 +- tools/clang-format/clang-format-diff.py | 2 +- tools/clang-format/clang-format-sublime.py | 2 +- tools/clang-format/clang-format.py | 2 +- tools/clang-format/git-clang-format | 2 +- tools/clang-rename/clang-rename.py | 2 +- tools/scan-build-py/libscanbuild/arguments.py | 2 +- utils/ABITest/ABITestGen.py | 2 +- utils/ABITest/Enumeration.py | 2 +- utils/CIndex/completion_logger_server.py | 2 +- utils/TestUtils/deep-stack.py | 2 +- utils/analyzer/SATestAdd.py | 2 +- utils/analyzer/SATestUpdateDiffs.py | 2 +- utils/analyzer/SumTimerInfo.py | 2 +- utils/check_cfc/check_cfc.py | 2 +- utils/check_cfc/obj_diff.py | 2 +- utils/check_cfc/setup.py | 2 +- utils/clangdiag.py | 2 +- utils/hmaptool/hmaptool | 2 +- utils/modfuzz.py | 2 +- utils/perf-training/perf-helper.py | 2 +- utils/token-delta.py | 2 +- 23 files changed, 23 insertions(+), 23 deletions(-) diff --git a/bindings/python/clang/cindex.py b/bindings/python/clang/cindex.py index 5dbe809af9..54514b8dae 100644 --- a/bindings/python/clang/cindex.py +++ b/bindings/python/clang/cindex.py @@ -44,7 +44,7 @@ The major indexing objects are: Most object information is exposed using properties, when the underlying API call is efficient. """ -from __future__ import print_function +from __future__ import absolute_import, division, print_function # TODO # ==== diff --git a/docs/conf.py b/docs/conf.py index a18ce3a304..19113d0d5a 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -11,7 +11,7 @@ # All configuration values have a default; values that are commented out # serve to show the default. -from __future__ import print_function +from __future__ import absolute_import, division, print_function import sys, os from datetime import date diff --git a/tools/clang-format/clang-format-diff.py b/tools/clang-format/clang-format-diff.py index 1721d8a430..54347ce759 100755 --- a/tools/clang-format/clang-format-diff.py +++ b/tools/clang-format/clang-format-diff.py @@ -21,7 +21,7 @@ Example usage for git/svn users: svn diff --diff-cmd=diff -x-U0 | clang-format-diff.py -i """ -from __future__ import print_function +from __future__ import absolute_import, division, print_function import argparse import difflib diff --git a/tools/clang-format/clang-format-sublime.py b/tools/clang-format/clang-format-sublime.py index 16ff56e502..5ea9a27825 100644 --- a/tools/clang-format/clang-format-sublime.py +++ b/tools/clang-format/clang-format-sublime.py @@ -12,7 +12,7 @@ # It operates on the current, potentially unsaved buffer and does not create # or save any files. To revert a formatting, just undo. -from __future__ import print_function +from __future__ import absolute_import, division, print_function import sublime import sublime_plugin import subprocess diff --git a/tools/clang-format/clang-format.py b/tools/clang-format/clang-format.py index 5fe592a920..fe068bd41c 100644 --- a/tools/clang-format/clang-format.py +++ b/tools/clang-format/clang-format.py @@ -25,7 +25,7 @@ # # It operates on the current, potentially unsaved buffer and does not create # or save any files. To revert a formatting, just undo. -from __future__ import print_function +from __future__ import absolute_import, division, print_function import difflib import json diff --git a/tools/clang-format/git-clang-format b/tools/clang-format/git-clang-format index 0b2103962a..96e3b4e8a2 100755 --- a/tools/clang-format/git-clang-format +++ b/tools/clang-format/git-clang-format @@ -23,7 +23,7 @@ git clang-format -h Requires Python 2.7 or Python 3 """ -from __future__ import print_function +from __future__ import absolute_import, division, print_function import argparse import collections import contextlib diff --git a/tools/clang-rename/clang-rename.py b/tools/clang-rename/clang-rename.py index 0cb8a26d27..3381c5267f 100644 --- a/tools/clang-rename/clang-rename.py +++ b/tools/clang-rename/clang-rename.py @@ -22,7 +22,7 @@ you would like to rename and press 'cr'. You will be prompted for a new name if the cursor points to a valid symbol. ''' -from __future__ import print_function +from __future__ import absolute_import, division, print_function import vim import subprocess import sys diff --git a/tools/scan-build-py/libscanbuild/arguments.py b/tools/scan-build-py/libscanbuild/arguments.py index 73a7f24e67..eb8ea0d9ff 100644 --- a/tools/scan-build-py/libscanbuild/arguments.py +++ b/tools/scan-build-py/libscanbuild/arguments.py @@ -12,7 +12,7 @@ earlier.) It also implements basic validation methods, related to the command. Validations are mostly calling specific help methods, or mangling values. """ -from __future__ import print_function +from __future__ import absolute_import, division, print_function import os import sys diff --git a/utils/ABITest/ABITestGen.py b/utils/ABITest/ABITestGen.py index a829f925df..93a6de9306 100755 --- a/utils/ABITest/ABITestGen.py +++ b/utils/ABITest/ABITestGen.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -from __future__ import print_function +from __future__ import absolute_import, division, print_function from pprint import pprint import random, atexit, time from random import randrange diff --git a/utils/ABITest/Enumeration.py b/utils/ABITest/Enumeration.py index 76067243d1..24f5b5fba2 100644 --- a/utils/ABITest/Enumeration.py +++ b/utils/ABITest/Enumeration.py @@ -1,6 +1,6 @@ """Utilities for enumeration of finite and countably infinite sets. """ -from __future__ import print_function +from __future__ import absolute_import, division, print_function ### # Countable iteration diff --git a/utils/CIndex/completion_logger_server.py b/utils/CIndex/completion_logger_server.py index 818d10d73b..201667117f 100755 --- a/utils/CIndex/completion_logger_server.py +++ b/utils/CIndex/completion_logger_server.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -from __future__ import print_function +from __future__ import absolute_import, division, print_function import sys from socket import * from time import strftime diff --git a/utils/TestUtils/deep-stack.py b/utils/TestUtils/deep-stack.py index 8636efabec..10bf47acb1 100755 --- a/utils/TestUtils/deep-stack.py +++ b/utils/TestUtils/deep-stack.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -from __future__ import print_function +from __future__ import absolute_import, division, print_function def pcall(f, N): if N == 0: print(' f(0)', file=f) diff --git a/utils/analyzer/SATestAdd.py b/utils/analyzer/SATestAdd.py index 377897e143..52089f4e06 100755 --- a/utils/analyzer/SATestAdd.py +++ b/utils/analyzer/SATestAdd.py @@ -42,7 +42,7 @@ the Repository Directory. diff -ur CachedSource PatchedSource \ > changes_for_analyzer.patch """ -from __future__ import print_function +from __future__ import absolute_import, division, print_function import SATestBuild import os diff --git a/utils/analyzer/SATestUpdateDiffs.py b/utils/analyzer/SATestUpdateDiffs.py index 64e6ca43db..ea3c08cc21 100755 --- a/utils/analyzer/SATestUpdateDiffs.py +++ b/utils/analyzer/SATestUpdateDiffs.py @@ -3,7 +3,7 @@ """ Update reference results for static analyzer. """ -from __future__ import print_function +from __future__ import absolute_import, division, print_function import SATestBuild diff --git a/utils/analyzer/SumTimerInfo.py b/utils/analyzer/SumTimerInfo.py index b3219b00c7..36e519adbf 100644 --- a/utils/analyzer/SumTimerInfo.py +++ b/utils/analyzer/SumTimerInfo.py @@ -6,7 +6,7 @@ Script to Summarize statistics in the scan-build output. Statistics are enabled by passing '-internal-stats' option to scan-build (or '-analyzer-stats' to the analyzer). """ -from __future__ import print_function +from __future__ import absolute_import, division, print_function import sys diff --git a/utils/check_cfc/check_cfc.py b/utils/check_cfc/check_cfc.py index aea9bdd638..4ad88c8b75 100755 --- a/utils/check_cfc/check_cfc.py +++ b/utils/check_cfc/check_cfc.py @@ -47,7 +47,7 @@ To add a new check: subclass. """ -from __future__ import print_function +from __future__ import absolute_import, division, print_function import imp import os diff --git a/utils/check_cfc/obj_diff.py b/utils/check_cfc/obj_diff.py index 61b9118df8..1302834432 100755 --- a/utils/check_cfc/obj_diff.py +++ b/utils/check_cfc/obj_diff.py @@ -1,6 +1,6 @@ #!/usr/bin/env python2.7 -from __future__ import print_function +from __future__ import absolute_import, division, print_function import argparse import difflib diff --git a/utils/check_cfc/setup.py b/utils/check_cfc/setup.py index 6005f6f411..64f07d5dcc 100644 --- a/utils/check_cfc/setup.py +++ b/utils/check_cfc/setup.py @@ -1,7 +1,7 @@ """For use on Windows. Run with: python.exe setup.py py2exe """ -from __future__ import print_function +from __future__ import absolute_import, division, print_function from distutils.core import setup try: import py2exe diff --git a/utils/clangdiag.py b/utils/clangdiag.py index a9656c55d8..6baf65a876 100755 --- a/utils/clangdiag.py +++ b/utils/clangdiag.py @@ -9,7 +9,7 @@ # (lldb) command script import /path/to/clandiag.py #---------------------------------------------------------------------- -from __future__ import print_function +from __future__ import absolute_import, division, print_function import lldb import argparse import shlex diff --git a/utils/hmaptool/hmaptool b/utils/hmaptool/hmaptool index 2b1ca7436c..58baab2f77 100755 --- a/utils/hmaptool/hmaptool +++ b/utils/hmaptool/hmaptool @@ -1,5 +1,5 @@ #!/usr/bin/env python -from __future__ import print_function +from __future__ import absolute_import, division, print_function import json import optparse diff --git a/utils/modfuzz.py b/utils/modfuzz.py index 4dc25e8469..61ca3272ac 100644 --- a/utils/modfuzz.py +++ b/utils/modfuzz.py @@ -4,7 +4,7 @@ # 1) Update the 'decls' list below with your fuzzing configuration. # 2) Run with the clang binary as the command-line argument. -from __future__ import print_function +from __future__ import absolute_import, division, print_function import random import subprocess import sys diff --git a/utils/perf-training/perf-helper.py b/utils/perf-training/perf-helper.py index 6337a9b19a..72b4b4e5a0 100644 --- a/utils/perf-training/perf-helper.py +++ b/utils/perf-training/perf-helper.py @@ -7,7 +7,7 @@ # #===------------------------------------------------------------------------===# -from __future__ import print_function +from __future__ import absolute_import, division, print_function import sys import os diff --git a/utils/token-delta.py b/utils/token-delta.py index 9fc5646bb7..62b4eb3c77 100755 --- a/utils/token-delta.py +++ b/utils/token-delta.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -from __future__ import print_function +from __future__ import absolute_import, division, print_function import os import re import subprocess -- cgit v1.2.3 From 9f23440e30534272b51431c3997db504e7eae860 Mon Sep 17 00:00:00 2001 From: Erich Keane Date: Tue, 18 Dec 2018 16:22:21 +0000 Subject: [NFC] Fix usage of Builder.insert(new Bitcast...)in CodeGenFunction This is exactly a "CreateBitCast", so refactor this to get rid of a 'new'. Note that this slightly changes the test, as the Builder is now seemingly smart enough to fold one of the bitcasts into the annotation call. Change-Id: I1733fb1fdf91f5c9d88651067130b9a4e7b5ab67 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349506 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CodeGenFunction.cpp | 2 +- test/CodeGen/annotations-field.c | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp index f012384f3d..123ece2cac 100644 --- a/lib/CodeGen/CodeGenFunction.cpp +++ b/lib/CodeGen/CodeGenFunction.cpp @@ -2243,7 +2243,7 @@ Address CodeGenFunction::EmitFieldAnnotations(const FieldDecl *D, // annotation on the first field of a struct and annotation on the struct // itself. if (VTy != CGM.Int8PtrTy) - V = Builder.Insert(new llvm::BitCastInst(V, CGM.Int8PtrTy)); + V = Builder.CreateBitCast(V, CGM.Int8PtrTy); V = EmitAnnotationCall(F, V, I->getAnnotation(), D->getLocation()); V = Builder.CreateBitCast(V, VTy); } diff --git a/test/CodeGen/annotations-field.c b/test/CodeGen/annotations-field.c index 02bae15a2b..27e64de7bb 100644 --- a/test/CodeGen/annotations-field.c +++ b/test/CodeGen/annotations-field.c @@ -21,7 +21,6 @@ int main(int argc, char **argv) { // CHECK-NEXT: call i8* @llvm.ptr.annotation.p0i8({{.*}}str{{.*}}str{{.*}}i32 8) // CHECK-NEXT: bitcast i8* {{.*}} to i32* gf.v = argc; -// CHECK: bitcast i32* getelementptr inbounds (%struct.foo, %struct.foo* @gf, i32 0, i32 0) to i8* -// CHECK-NEXT: call i8* @llvm.ptr.annotation.p0i8({{.*}}str{{.*}}str{{.*}}i32 8) +// CHECK: call i8* @llvm.ptr.annotation.p0i8(i8* bitcast (%struct.foo* @gf to i8*), {{.*}}str{{.*}}str{{.*}}i32 8) return 0; } -- cgit v1.2.3 From a23457455f1a9a9d0a955a3e2dedc476d8ba9f71 Mon Sep 17 00:00:00 2001 From: Pierre Gousseau Date: Tue, 18 Dec 2018 17:03:35 +0000 Subject: [Driver][PS4] Do not implicitly link against asan or ubsan if -nostdlib or -nodefaultlibs on PS4. NFC for targets other than PS4. Respect -nostdlib and -nodefaultlibs when enabling asan or ubsan. Differential Revision: https://reviews.llvm.org/D55712 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349508 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Driver/ToolChains/Clang.cpp | 3 ++- lib/Driver/ToolChains/PS4CPU.cpp | 6 ++++-- test/Driver/fsanitize.c | 4 ++++ test/Driver/sanitizer-ld.c | 7 +++++++ 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/lib/Driver/ToolChains/Clang.cpp b/lib/Driver/ToolChains/Clang.cpp index 5b74ffa96c..1f267e68f1 100644 --- a/lib/Driver/ToolChains/Clang.cpp +++ b/lib/Driver/ToolChains/Clang.cpp @@ -4097,7 +4097,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, ABICompatArg->render(Args, CmdArgs); // Add runtime flag for PS4 when PGO, coverage, or sanitizers are enabled. - if (RawTriple.isPS4CPU()) { + if (RawTriple.isPS4CPU() && + !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) { PS4cpu::addProfileRTArgs(TC, Args, CmdArgs); PS4cpu::addSanitizerArgs(TC, CmdArgs); } diff --git a/lib/Driver/ToolChains/PS4CPU.cpp b/lib/Driver/ToolChains/PS4CPU.cpp index a4b74d4923..0708d25fe4 100644 --- a/lib/Driver/ToolChains/PS4CPU.cpp +++ b/lib/Driver/ToolChains/PS4CPU.cpp @@ -121,7 +121,8 @@ static void ConstructPS4LinkJob(const Tool &T, Compilation &C, assert(Output.isNothing() && "Invalid output."); } - AddPS4SanitizerArgs(ToolChain, CmdArgs); + if(!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) + AddPS4SanitizerArgs(ToolChain, CmdArgs); Args.AddAllArgs(CmdArgs, options::OPT_L); Args.AddAllArgs(CmdArgs, options::OPT_T_Group); @@ -190,7 +191,8 @@ static void ConstructGoldLinkJob(const Tool &T, Compilation &C, assert(Output.isNothing() && "Invalid output."); } - AddPS4SanitizerArgs(ToolChain, CmdArgs); + if(!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) + AddPS4SanitizerArgs(ToolChain, CmdArgs); if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) { const char *crt1 = nullptr; diff --git a/test/Driver/fsanitize.c b/test/Driver/fsanitize.c index 9411b68dab..0a82174aaa 100644 --- a/test/Driver/fsanitize.c +++ b/test/Driver/fsanitize.c @@ -753,6 +753,10 @@ // CHECK-ASAN-PS4: --dependent-lib=libSceDbgAddressSanitizer_stub_weak.a // CHECK-ASAN-PS4-NOT: {{(\.(o|bc)"? |-l).*-lSceDbgAddressSanitizer_stub_weak}} // CHECK-ASAN-PS4: -lSceDbgAddressSanitizer_stub_weak +// RUN: %clang -target x86_64-scei-ps4 -fsanitize=address -nostdlib %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-NOLIB-PS4 +// RUN: %clang -target x86_64-scei-ps4 -fsanitize=address -nodefaultlibs %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-NOLIB-PS4 +// RUN: %clang -target x86_64-scei-ps4 -fsanitize=address -nodefaultlibs -nostdlib %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-NOLIB-PS4 +// CHECK-ASAN-NOLIB-PS4-NOT: SceDbgAddressSanitizer_stub_weak // RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-minimal-runtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-MINIMAL // CHECK-ASAN-MINIMAL: error: invalid argument '-fsanitize-minimal-runtime' not allowed with '-fsanitize=address' diff --git a/test/Driver/sanitizer-ld.c b/test/Driver/sanitizer-ld.c index 9ce05996fd..db699410f7 100644 --- a/test/Driver/sanitizer-ld.c +++ b/test/Driver/sanitizer-ld.c @@ -673,6 +673,13 @@ // CHECK-AUBSAN-PS4: "{{.*}}ld{{(.gold)?(.exe)?}}" // CHECK-AUBSAN-PS4: -lSceDbgAddressSanitizer_stub_weak +// RUN: %clang -fsanitize=address,undefined %s -### -o %t.o 2>&1 \ +// RUN: -target x86_64-scei-ps4 -fuse-ld=ld \ +// RUN: -shared \ +// RUN: -nostdlib \ +// RUN: | FileCheck --check-prefix=CHECK-NOLIB-PS4 %s +// CHECK-NOLIB-PS4-NOT: SceDbgAddressSanitizer_stub_weak + // RUN: %clang -fsanitize=efficiency-cache-frag %s -### -o %t.o 2>&1 \ // RUN: -target x86_64-unknown-linux -fuse-ld=ld \ // RUN: | FileCheck --check-prefix=CHECK-ESAN-LINUX %s -- cgit v1.2.3 From ccfb6f1d2d2ec37c38a5583d63a8a7974d032c59 Mon Sep 17 00:00:00 2001 From: Alexey Bataev Date: Tue, 18 Dec 2018 19:20:15 +0000 Subject: [OPENMP][NVPTX]Added extra sync point to the inter-warp copy function. The parallel reduction operation requires an extra synchronization point in the inter-warp copy function to avoid divergence. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349525 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp | 5 +++++ test/OpenMP/nvptx_target_parallel_reduction_codegen.cpp | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp b/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp index b055132ef0..59086d219b 100644 --- a/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp +++ b/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp @@ -3089,6 +3089,7 @@ static void emitReductionListCopy( /// void inter_warp_copy_func(void* reduce_data, num_warps) /// shared smem[warp_size]; /// For all data entries D in reduce_data: +/// sync /// If (I am the first lane in each warp) /// Copy my local D to smem[warp_id] /// sync @@ -3203,6 +3204,10 @@ static llvm::Value *emitInterWarpCopyFunction(CodeGenModule &CGM, Bld.CreateCondBr(Cmp, BodyBB, ExitBB); CGF.EmitBlock(BodyBB); } + // kmpc_barrier. + CGM.getOpenMPRuntime().emitBarrierCall(CGF, Loc, OMPD_unknown, + /*EmitChecks=*/false, + /*ForceSimpleCall=*/true); llvm::BasicBlock *ThenBB = CGF.createBasicBlock("then"); llvm::BasicBlock *ElseBB = CGF.createBasicBlock("else"); llvm::BasicBlock *MergeBB = CGF.createBasicBlock("ifcont"); diff --git a/test/OpenMP/nvptx_target_parallel_reduction_codegen.cpp b/test/OpenMP/nvptx_target_parallel_reduction_codegen.cpp index dd93b0c1b9..34ad93b695 100644 --- a/test/OpenMP/nvptx_target_parallel_reduction_codegen.cpp +++ b/test/OpenMP/nvptx_target_parallel_reduction_codegen.cpp @@ -190,6 +190,7 @@ int bar(int n){ // CHECK: [[CNT:%.+]] = load i32, i32* [[CNT_ADDR]], // CHECK: [[DONE_COPY:%.+]] = icmp ult i32 [[CNT]], 2 // CHECK: br i1 [[DONE_COPY]], label + // CHECK: call void @__kmpc_barrier(%struct.ident_t* @ // CHECK: [[IS_WARP_MASTER:%.+]] = icmp eq i32 [[LANEID]], 0 // CHECK: br i1 [[IS_WARP_MASTER]], label {{%?}}[[DO_COPY:.+]], label {{%?}}[[COPY_ELSE:.+]] // @@ -427,6 +428,7 @@ int bar(int n){ // CHECK-DAG: [[LANEID:%.+]] = and i32 {{.+}}, 31 // CHECK-DAG: [[WARPID:%.+]] = ashr i32 {{.+}}, 5 // CHECK-DAG: [[RED_LIST:%.+]] = bitcast i8* {{.+}} to [[RLT]]* + // CHECK: call void @__kmpc_barrier(%struct.ident_t* @ // CHECK: [[IS_WARP_MASTER:%.+]] = icmp eq i32 [[LANEID]], 0 // CHECK: br i1 [[IS_WARP_MASTER]], label {{%?}}[[DO_COPY:.+]], label {{%?}}[[COPY_ELSE:.+]] // @@ -466,6 +468,7 @@ int bar(int n){ // // CHECK: [[READ_CONT]] // CHECK: call void @__kmpc_barrier(%struct.ident_t* @ + // CHECK: call void @__kmpc_barrier(%struct.ident_t* @ // CHECK: [[IS_WARP_MASTER:%.+]] = icmp eq i32 [[LANEID]], 0 // CHECK: br i1 [[IS_WARP_MASTER]], label {{%?}}[[DO_COPY:.+]], label {{%?}}[[COPY_ELSE:.+]] // @@ -740,6 +743,7 @@ int bar(int n){ // CHECK-DAG: [[LANEID:%.+]] = and i32 {{.+}}, 31 // CHECK-DAG: [[WARPID:%.+]] = ashr i32 {{.+}}, 5 // CHECK-DAG: [[RED_LIST:%.+]] = bitcast i8* {{.+}} to [[RLT]]* + // CHECK: call void @__kmpc_barrier(%struct.ident_t* @ // CHECK: [[IS_WARP_MASTER:%.+]] = icmp eq i32 [[LANEID]], 0 // CHECK: br i1 [[IS_WARP_MASTER]], label {{%?}}[[DO_COPY:.+]], label {{%?}}[[COPY_ELSE:.+]] // -- cgit v1.2.3 From 6682997445e8ad84b4fbab29270e016af5a31be3 Mon Sep 17 00:00:00 2001 From: Pete Cooper Date: Tue, 18 Dec 2018 20:33:00 +0000 Subject: Generate objc intrinsics instead of runtime calls as the ARC optimizer now works only on intrinsics Differential Revision: https://reviews.llvm.org/D55802 Reviewers: rjmccall git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349535 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGObjC.cpp | 165 ++++++----- lib/CodeGen/CodeGenModule.h | 4 + test/CodeGenObjC/arc-arm.m | 4 +- test/CodeGenObjC/arc-block-copy-escape.m | 4 +- test/CodeGenObjC/arc-blocks.m | 150 +++++----- test/CodeGenObjC/arc-bridged-cast.m | 16 +- test/CodeGenObjC/arc-exceptions.m | 8 +- test/CodeGenObjC/arc-foreach.m | 28 +- test/CodeGenObjC/arc-i386.m | 4 +- test/CodeGenObjC/arc-linetable-autorelease.m | 4 +- test/CodeGenObjC/arc-linetable.m | 10 +- test/CodeGenObjC/arc-literals.m | 60 ++-- test/CodeGenObjC/arc-loadweakretained-release.m | 12 +- test/CodeGenObjC/arc-no-runtime.m | 8 +- test/CodeGenObjC/arc-precise-lifetime.m | 54 ++-- test/CodeGenObjC/arc-property.m | 20 +- test/CodeGenObjC/arc-related-result-type.m | 8 +- test/CodeGenObjC/arc-ternary-op.m | 26 +- test/CodeGenObjC/arc-unbridged-cast.m | 2 +- test/CodeGenObjC/arc-unopt.m | 8 +- test/CodeGenObjC/arc-unoptimized-byref-var.m | 4 +- test/CodeGenObjC/arc-unsafeclaim.m | 44 +-- test/CodeGenObjC/arc-weak-property.m | 8 +- test/CodeGenObjC/arc-weak.m | 4 +- test/CodeGenObjC/arc-with-atthrow.m | 4 +- test/CodeGenObjC/arc.ll | 10 +- test/CodeGenObjC/arc.m | 322 ++++++++++----------- test/CodeGenObjC/autorelease.m | 6 +- test/CodeGenObjC/debug-info-block-line.m | 8 +- test/CodeGenObjC/empty-collection-literals.m | 12 +- test/CodeGenObjC/fragile-arc.m | 24 +- test/CodeGenObjC/mrc-weak.m | 40 +-- test/CodeGenObjC/noescape.m | 8 +- test/CodeGenObjC/ns_consume_null_check.m | 16 +- test/CodeGenObjC/nsvalue-objc-boxable-ios-arc.m | 24 +- test/CodeGenObjC/nsvalue-objc-boxable-mac-arc.m | 24 +- test/CodeGenObjC/objc-arc-container-subscripting.m | 6 +- test/CodeGenObjC/os_log.m | 8 +- test/CodeGenObjC/parameterized_classes.m | 6 +- test/CodeGenObjC/stret-lifetime.m | 2 +- test/CodeGenObjC/strong-in-c-struct.m | 20 +- test/CodeGenObjC/weak-in-c-struct.m | 20 +- test/CodeGenObjCXX/arc-attrs.mm | 8 +- test/CodeGenObjCXX/arc-blocks.mm | 22 +- test/CodeGenObjCXX/arc-constexpr.mm | 18 +- test/CodeGenObjCXX/arc-cxx11-init-list.mm | 10 +- test/CodeGenObjCXX/arc-exceptions.mm | 20 +- test/CodeGenObjCXX/arc-forwarded-lambda-call.mm | 8 +- test/CodeGenObjCXX/arc-globals.mm | 8 +- test/CodeGenObjCXX/arc-indirect.mm | 2 +- test/CodeGenObjCXX/arc-move.mm | 10 +- test/CodeGenObjCXX/arc-new-delete.mm | 28 +- test/CodeGenObjCXX/arc-pseudo-destructors.mm | 8 +- test/CodeGenObjCXX/arc-references.mm | 22 +- .../arc-returns-inner-reference-ptr.mm | 4 +- test/CodeGenObjCXX/arc-special-member-functions.mm | 20 +- test/CodeGenObjCXX/arc-weak.mm | 8 +- test/CodeGenObjCXX/arc.mm | 96 +++--- test/CodeGenObjCXX/block-nested-in-lambda.mm | 16 +- test/CodeGenObjCXX/destroy.mm | 4 +- test/CodeGenObjCXX/lambda-expressions.mm | 10 +- test/CodeGenObjCXX/literals.mm | 44 +-- .../CodeGenObjCXX/microsoft-abi-arc-param-order.mm | 4 +- test/CodeGenObjCXX/mrc-weak.mm | 40 +-- test/CodeGenObjCXX/objc-weak.mm | 14 +- test/SemaObjC/arc-objc-lifetime-conflict.m | 14 +- 66 files changed, 836 insertions(+), 817 deletions(-) diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp index cc582b926b..3747f4920a 100644 --- a/lib/CodeGen/CGObjC.cpp +++ b/lib/CodeGen/CGObjC.cpp @@ -1873,12 +1873,8 @@ void CodeGenFunction::EmitARCIntrinsicUse(ArrayRef values) { EmitNounwindRuntimeCall(fn, values); } - -static llvm::Constant *createARCRuntimeFunction(CodeGenModule &CGM, - llvm::FunctionType *FTy, - StringRef Name) { - llvm::Constant *RTF = CGM.CreateRuntimeFunction(FTy, Name); - +static void setARCRuntimeFunctionLinkage(CodeGenModule &CGM, + llvm::Constant *RTF) { if (auto *F = dyn_cast(RTF)) { // If the target runtime doesn't naturally support ARC, emit weak // references to the runtime support library. We don't really @@ -1886,14 +1882,8 @@ static llvm::Constant *createARCRuntimeFunction(CodeGenModule &CGM, if (!CGM.getLangOpts().ObjCRuntime.hasNativeARC() && !CGM.getTriple().isOSBinFormatCOFF()) { F->setLinkage(llvm::Function::ExternalWeakLinkage); - } else if (Name == "objc_retain" || Name == "objc_release") { - // If we have Native ARC, set nonlazybind attribute for these APIs for - // performance. - F->addFnAttr(llvm::Attribute::NonLazyBind); } } - - return RTF; } /// Perform an operation having the signature @@ -1903,15 +1893,14 @@ static llvm::Value *emitARCValueOperation(CodeGenFunction &CGF, llvm::Value *value, llvm::Type *returnType, llvm::Constant *&fn, - StringRef fnName, + llvm::Intrinsic::ID IntID, bool isTailCall = false) { if (isa(value)) return value; if (!fn) { - llvm::FunctionType *fnType = - llvm::FunctionType::get(CGF.Int8PtrTy, CGF.Int8PtrTy, false); - fn = createARCRuntimeFunction(CGF.CGM, fnType, fnName); + fn = CGF.CGM.getIntrinsic(IntID); + setARCRuntimeFunctionLinkage(CGF.CGM, fn); } // Cast the argument to 'id'. @@ -1932,11 +1921,10 @@ static llvm::Value *emitARCValueOperation(CodeGenFunction &CGF, static llvm::Value *emitARCLoadOperation(CodeGenFunction &CGF, Address addr, llvm::Constant *&fn, - StringRef fnName) { + llvm::Intrinsic::ID IntID) { if (!fn) { - llvm::FunctionType *fnType = - llvm::FunctionType::get(CGF.Int8PtrTy, CGF.Int8PtrPtrTy, false); - fn = createARCRuntimeFunction(CGF.CGM, fnType, fnName); + fn = CGF.CGM.getIntrinsic(IntID); + setARCRuntimeFunctionLinkage(CGF.CGM, fn); } // Cast the argument to 'id*'. @@ -1959,16 +1947,13 @@ static llvm::Value *emitARCStoreOperation(CodeGenFunction &CGF, Address addr, llvm::Value *value, llvm::Constant *&fn, - StringRef fnName, + llvm::Intrinsic::ID IntID, bool ignored) { assert(addr.getElementType() == value->getType()); if (!fn) { - llvm::Type *argTypes[] = { CGF.Int8PtrPtrTy, CGF.Int8PtrTy }; - - llvm::FunctionType *fnType - = llvm::FunctionType::get(CGF.Int8PtrTy, argTypes, false); - fn = createARCRuntimeFunction(CGF.CGM, fnType, fnName); + fn = CGF.CGM.getIntrinsic(IntID); + setARCRuntimeFunctionLinkage(CGF.CGM, fn); } llvm::Type *origType = value->getType(); @@ -1990,15 +1975,12 @@ static void emitARCCopyOperation(CodeGenFunction &CGF, Address dst, Address src, llvm::Constant *&fn, - StringRef fnName) { + llvm::Intrinsic::ID IntID) { assert(dst.getType() == src.getType()); if (!fn) { - llvm::Type *argTypes[] = { CGF.Int8PtrPtrTy, CGF.Int8PtrPtrTy }; - - llvm::FunctionType *fnType - = llvm::FunctionType::get(CGF.Builder.getVoidTy(), argTypes, false); - fn = createARCRuntimeFunction(CGF.CGM, fnType, fnName); + fn = CGF.CGM.getIntrinsic(IntID); + setARCRuntimeFunctionLinkage(CGF.CGM, fn); } llvm::Value *args[] = { @@ -2008,6 +1990,34 @@ static void emitARCCopyOperation(CodeGenFunction &CGF, CGF.EmitNounwindRuntimeCall(fn, args); } +/// Perform an operation having the signature +/// i8* (i8*) +/// where a null input causes a no-op and returns null. +static llvm::Value *emitObjCValueOperation(CodeGenFunction &CGF, + llvm::Value *value, + llvm::Type *returnType, + llvm::Constant *&fn, + StringRef fnName) { + if (isa(value)) + return value; + + if (!fn) { + llvm::FunctionType *fnType = + llvm::FunctionType::get(CGF.Int8PtrTy, CGF.Int8PtrTy, false); + fn = CGF.CGM.CreateRuntimeFunction(fnType, fnName); + } + + // Cast the argument to 'id'. + llvm::Type *origType = returnType ? returnType : value->getType(); + value = CGF.Builder.CreateBitCast(value, CGF.Int8PtrTy); + + // Call the function. + llvm::CallInst *call = CGF.EmitNounwindRuntimeCall(fn, value); + + // Cast the result back to the original type. + return CGF.Builder.CreateBitCast(call, origType); +} + /// Produce the code to do a retain. Based on the type, calls one of: /// call i8* \@objc_retain(i8* %value) /// call i8* \@objc_retainBlock(i8* %value) @@ -2023,7 +2033,7 @@ llvm::Value *CodeGenFunction::EmitARCRetain(QualType type, llvm::Value *value) { llvm::Value *CodeGenFunction::EmitARCRetainNonBlock(llvm::Value *value) { return emitARCValueOperation(*this, value, nullptr, CGM.getObjCEntrypoints().objc_retain, - "objc_retain"); + llvm::Intrinsic::objc_retain); } /// Retain the given block, with _Block_copy semantics. @@ -2037,7 +2047,7 @@ llvm::Value *CodeGenFunction::EmitARCRetainBlock(llvm::Value *value, llvm::Value *result = emitARCValueOperation(*this, value, nullptr, CGM.getObjCEntrypoints().objc_retainBlock, - "objc_retainBlock"); + llvm::Intrinsic::objc_retainBlock); // If the copy isn't mandatory, add !clang.arc.copy_on_escape to // tell the optimizer that it doesn't need to do this copy if the @@ -2107,7 +2117,7 @@ CodeGenFunction::EmitARCRetainAutoreleasedReturnValue(llvm::Value *value) { emitAutoreleasedReturnValueMarker(*this); return emitARCValueOperation(*this, value, nullptr, CGM.getObjCEntrypoints().objc_retainAutoreleasedReturnValue, - "objc_retainAutoreleasedReturnValue"); + llvm::Intrinsic::objc_retainAutoreleasedReturnValue); } /// Claim a possibly-autoreleased return value at +0. This is only @@ -2122,7 +2132,7 @@ CodeGenFunction::EmitARCUnsafeClaimAutoreleasedReturnValue(llvm::Value *value) { emitAutoreleasedReturnValueMarker(*this); return emitARCValueOperation(*this, value, nullptr, CGM.getObjCEntrypoints().objc_unsafeClaimAutoreleasedReturnValue, - "objc_unsafeClaimAutoreleasedReturnValue"); + llvm::Intrinsic::objc_unsafeClaimAutoreleasedReturnValue); } /// Release the given object. @@ -2133,9 +2143,8 @@ void CodeGenFunction::EmitARCRelease(llvm::Value *value, llvm::Constant *&fn = CGM.getObjCEntrypoints().objc_release; if (!fn) { - llvm::FunctionType *fnType = - llvm::FunctionType::get(Builder.getVoidTy(), Int8PtrTy, false); - fn = createARCRuntimeFunction(CGM, fnType, "objc_release"); + fn = CGM.getIntrinsic(llvm::Intrinsic::objc_release); + setARCRuntimeFunctionLinkage(CGM, fn); } // Cast the argument to 'id'. @@ -2180,10 +2189,8 @@ llvm::Value *CodeGenFunction::EmitARCStoreStrongCall(Address addr, llvm::Constant *&fn = CGM.getObjCEntrypoints().objc_storeStrong; if (!fn) { - llvm::Type *argTypes[] = { Int8PtrPtrTy, Int8PtrTy }; - llvm::FunctionType *fnType - = llvm::FunctionType::get(Builder.getVoidTy(), argTypes, false); - fn = createARCRuntimeFunction(CGM, fnType, "objc_storeStrong"); + fn = CGM.getIntrinsic(llvm::Intrinsic::objc_storeStrong); + setARCRuntimeFunctionLinkage(CGM, fn); } llvm::Value *args[] = { @@ -2237,7 +2244,7 @@ llvm::Value *CodeGenFunction::EmitARCStoreStrong(LValue dst, llvm::Value *CodeGenFunction::EmitARCAutorelease(llvm::Value *value) { return emitARCValueOperation(*this, value, nullptr, CGM.getObjCEntrypoints().objc_autorelease, - "objc_autorelease"); + llvm::Intrinsic::objc_autorelease); } /// Autorelease the given object. @@ -2246,7 +2253,7 @@ llvm::Value * CodeGenFunction::EmitARCAutoreleaseReturnValue(llvm::Value *value) { return emitARCValueOperation(*this, value, nullptr, CGM.getObjCEntrypoints().objc_autoreleaseReturnValue, - "objc_autoreleaseReturnValue", + llvm::Intrinsic::objc_autoreleaseReturnValue, /*isTailCall*/ true); } @@ -2256,7 +2263,7 @@ llvm::Value * CodeGenFunction::EmitARCRetainAutoreleaseReturnValue(llvm::Value *value) { return emitARCValueOperation(*this, value, nullptr, CGM.getObjCEntrypoints().objc_retainAutoreleaseReturnValue, - "objc_retainAutoreleaseReturnValue", + llvm::Intrinsic::objc_retainAutoreleaseReturnValue, /*isTailCall*/ true); } @@ -2285,7 +2292,7 @@ llvm::Value * CodeGenFunction::EmitARCRetainAutoreleaseNonBlock(llvm::Value *value) { return emitARCValueOperation(*this, value, nullptr, CGM.getObjCEntrypoints().objc_retainAutorelease, - "objc_retainAutorelease"); + llvm::Intrinsic::objc_retainAutorelease); } /// i8* \@objc_loadWeak(i8** %addr) @@ -2293,14 +2300,14 @@ CodeGenFunction::EmitARCRetainAutoreleaseNonBlock(llvm::Value *value) { llvm::Value *CodeGenFunction::EmitARCLoadWeak(Address addr) { return emitARCLoadOperation(*this, addr, CGM.getObjCEntrypoints().objc_loadWeak, - "objc_loadWeak"); + llvm::Intrinsic::objc_loadWeak); } /// i8* \@objc_loadWeakRetained(i8** %addr) llvm::Value *CodeGenFunction::EmitARCLoadWeakRetained(Address addr) { return emitARCLoadOperation(*this, addr, CGM.getObjCEntrypoints().objc_loadWeakRetained, - "objc_loadWeakRetained"); + llvm::Intrinsic::objc_loadWeakRetained); } /// i8* \@objc_storeWeak(i8** %addr, i8* %value) @@ -2310,7 +2317,7 @@ llvm::Value *CodeGenFunction::EmitARCStoreWeak(Address addr, bool ignored) { return emitARCStoreOperation(*this, addr, value, CGM.getObjCEntrypoints().objc_storeWeak, - "objc_storeWeak", ignored); + llvm::Intrinsic::objc_storeWeak, ignored); } /// i8* \@objc_initWeak(i8** %addr, i8* %value) @@ -2330,7 +2337,7 @@ void CodeGenFunction::EmitARCInitWeak(Address addr, llvm::Value *value) { emitARCStoreOperation(*this, addr, value, CGM.getObjCEntrypoints().objc_initWeak, - "objc_initWeak", /*ignored*/ true); + llvm::Intrinsic::objc_initWeak, /*ignored*/ true); } /// void \@objc_destroyWeak(i8** %addr) @@ -2338,9 +2345,8 @@ void CodeGenFunction::EmitARCInitWeak(Address addr, llvm::Value *value) { void CodeGenFunction::EmitARCDestroyWeak(Address addr) { llvm::Constant *&fn = CGM.getObjCEntrypoints().objc_destroyWeak; if (!fn) { - llvm::FunctionType *fnType = - llvm::FunctionType::get(Builder.getVoidTy(), Int8PtrPtrTy, false); - fn = createARCRuntimeFunction(CGM, fnType, "objc_destroyWeak"); + fn = CGM.getIntrinsic(llvm::Intrinsic::objc_destroyWeak); + setARCRuntimeFunctionLinkage(CGM, fn); } // Cast the argument to 'id*'. @@ -2355,7 +2361,7 @@ void CodeGenFunction::EmitARCDestroyWeak(Address addr) { void CodeGenFunction::EmitARCMoveWeak(Address dst, Address src) { emitARCCopyOperation(*this, dst, src, CGM.getObjCEntrypoints().objc_moveWeak, - "objc_moveWeak"); + llvm::Intrinsic::objc_moveWeak); } /// void \@objc_copyWeak(i8** %dest, i8** %src) @@ -2364,7 +2370,7 @@ void CodeGenFunction::EmitARCMoveWeak(Address dst, Address src) { void CodeGenFunction::EmitARCCopyWeak(Address dst, Address src) { emitARCCopyOperation(*this, dst, src, CGM.getObjCEntrypoints().objc_copyWeak, - "objc_copyWeak"); + llvm::Intrinsic::objc_copyWeak); } void CodeGenFunction::emitARCCopyAssignWeak(QualType Ty, Address DstAddr, @@ -2387,9 +2393,8 @@ void CodeGenFunction::emitARCMoveAssignWeak(QualType Ty, Address DstAddr, llvm::Value *CodeGenFunction::EmitObjCAutoreleasePoolPush() { llvm::Constant *&fn = CGM.getObjCEntrypoints().objc_autoreleasePoolPush; if (!fn) { - llvm::FunctionType *fnType = - llvm::FunctionType::get(Int8PtrTy, false); - fn = createARCRuntimeFunction(CGM, fnType, "objc_autoreleasePoolPush"); + fn = CGM.getIntrinsic(llvm::Intrinsic::objc_autoreleasePoolPush); + setARCRuntimeFunctionLinkage(CGM, fn); } return EmitNounwindRuntimeCall(fn); @@ -2400,18 +2405,28 @@ llvm::Value *CodeGenFunction::EmitObjCAutoreleasePoolPush() { void CodeGenFunction::EmitObjCAutoreleasePoolPop(llvm::Value *value) { assert(value->getType() == Int8PtrTy); - llvm::Constant *&fn = CGM.getObjCEntrypoints().objc_autoreleasePoolPop; - if (!fn) { - llvm::FunctionType *fnType = - llvm::FunctionType::get(Builder.getVoidTy(), Int8PtrTy, false); + if (getInvokeDest()) { + // Call the runtime method not the intrinsic if we are handling exceptions + llvm::Constant *&fn = + CGM.getObjCEntrypoints().objc_autoreleasePoolPopInvoke; + if (!fn) { + llvm::FunctionType *fnType = + llvm::FunctionType::get(Builder.getVoidTy(), Int8PtrTy, false); + fn = CGM.CreateRuntimeFunction(fnType, "objc_autoreleasePoolPop"); + setARCRuntimeFunctionLinkage(CGM, fn); + } - // We don't want to use a weak import here; instead we should not - // fall into this path. - fn = createARCRuntimeFunction(CGM, fnType, "objc_autoreleasePoolPop"); - } + // objc_autoreleasePoolPop can throw. + EmitRuntimeCallOrInvoke(fn, value); + } else { + llvm::Constant *&fn = CGM.getObjCEntrypoints().objc_autoreleasePoolPop; + if (!fn) { + fn = CGM.getIntrinsic(llvm::Intrinsic::objc_autoreleasePoolPop); + setARCRuntimeFunctionLinkage(CGM, fn); + } - // objc_autoreleasePoolPop can throw. - EmitRuntimeCallOrInvoke(fn, value); + EmitRuntimeCall(fn, value); + } } /// Produce the code to do an MRR version objc_autoreleasepool_push. @@ -2446,18 +2461,18 @@ llvm::Value *CodeGenFunction::EmitObjCMRRAutoreleasePoolPush() { /// call i8* \@objc_alloc(i8* %value) llvm::Value *CodeGenFunction::EmitObjCAlloc(llvm::Value *value, llvm::Type *resultType) { - return emitARCValueOperation(*this, value, resultType, - CGM.getObjCEntrypoints().objc_alloc, - "objc_alloc"); + return emitObjCValueOperation(*this, value, resultType, + CGM.getObjCEntrypoints().objc_alloc, + "objc_alloc"); } /// Allocate the given objc object. /// call i8* \@objc_allocWithZone(i8* %value) llvm::Value *CodeGenFunction::EmitObjCAllocWithZone(llvm::Value *value, llvm::Type *resultType) { - return emitARCValueOperation(*this, value, resultType, - CGM.getObjCEntrypoints().objc_allocWithZone, - "objc_allocWithZone"); + return emitObjCValueOperation(*this, value, resultType, + CGM.getObjCEntrypoints().objc_allocWithZone, + "objc_allocWithZone"); } /// Produce the code to do a primitive release. diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h index 0f6c3bec9e..f0d72af3ad 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -128,6 +128,10 @@ struct ObjCEntrypoints { /// void objc_autoreleasePoolPop(void*); llvm::Constant *objc_autoreleasePoolPop; + /// void objc_autoreleasePoolPop(void*); + /// Note this method is used when we are using exception handling + llvm::Constant *objc_autoreleasePoolPopInvoke; + /// void *objc_autoreleasePoolPush(void); llvm::Constant *objc_autoreleasePoolPush; diff --git a/test/CodeGenObjC/arc-arm.m b/test/CodeGenObjC/arc-arm.m index 63c861f289..b46f956bc6 100644 --- a/test/CodeGenObjC/arc-arm.m +++ b/test/CodeGenObjC/arc-arm.m @@ -14,9 +14,9 @@ void test1(void) { extern id test1_helper(void); // CHECK: [[T0:%.*]] = call [[CC]]i8* @test1_helper() // CHECK-NEXT: call void asm sideeffect "mov\09{{fp, fp|r7, r7}}\09\09// marker for objc_retainAutoreleaseReturnValue" - // CHECK-NEXT: [[T1:%.*]] = call [[CC]]i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]]) + // CHECK-NEXT: [[T1:%.*]] = call [[CC]]i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) // CHECK-NEXT: store i8* [[T1]], - // CHECK-NEXT: call [[CC]]void @objc_storeStrong( + // CHECK-NEXT: call [[CC]]void @llvm.objc.storeStrong( // CHECK-NEXT: ret void id x = test1_helper(); } diff --git a/test/CodeGenObjC/arc-block-copy-escape.m b/test/CodeGenObjC/arc-block-copy-escape.m index 16a75a0d31..3823a95d6a 100644 --- a/test/CodeGenObjC/arc-block-copy-escape.m +++ b/test/CodeGenObjC/arc-block-copy-escape.m @@ -9,14 +9,14 @@ void use_int(int); void test0(int i) { block_t block = ^{ use_int(i); }; // CHECK-LABEL: define {{.*}}void @test0( - // CHECK: call {{.*}}i8* @objc_retainBlock(i8* {{%.*}}) [[NUW:#[0-9]+]], !clang.arc.copy_on_escape + // CHECK: call {{.*}}i8* @llvm.objc.retainBlock(i8* {{%.*}}) [[NUW:#[0-9]+]], !clang.arc.copy_on_escape // CHECK: ret void } void test1(int i) { id block = ^{ use_int(i); }; // CHECK-LABEL: define {{.*}}void @test1( - // CHECK: call {{.*}}i8* @objc_retainBlock(i8* {{%.*}}) [[NUW]] + // CHECK: call {{.*}}i8* @llvm.objc.retainBlock(i8* {{%.*}}) [[NUW]] // CHECK-NOT: !clang.arc.copy_on_escape // CHECK: ret void } diff --git a/test/CodeGenObjC/arc-blocks.m b/test/CodeGenObjC/arc-blocks.m index 89317ab113..9181d21311 100644 --- a/test/CodeGenObjC/arc-blocks.m +++ b/test/CodeGenObjC/arc-blocks.m @@ -19,10 +19,10 @@ int (^test1(int x))(void) { // CHECK-NEXT: store i32 {{%.*}}, i32* [[X]] // CHECK: [[T0:%.*]] = bitcast [[BLOCK_T]]* [[BLOCK]] to i32 ()* // CHECK-NEXT: [[T1:%.*]] = bitcast i32 ()* [[T0]] to i8* - // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainBlock(i8* [[T1]]) [[NUW:#[0-9]+]] + // CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainBlock(i8* [[T1]]) [[NUW:#[0-9]+]] // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to i32 ()* // CHECK-NEXT: [[T4:%.*]] = bitcast i32 ()* [[T3]] to i8* - // CHECK-NEXT: [[T5:%.*]] = tail call i8* @objc_autoreleaseReturnValue(i8* [[T4]]) [[NUW]] + // CHECK-NEXT: [[T5:%.*]] = tail call i8* @llvm.objc.autoreleaseReturnValue(i8* [[T4]]) [[NUW]] // CHECK-NEXT: [[T6:%.*]] = bitcast i8* [[T5]] to i32 ()* // CHECK-NEXT: ret i32 ()* [[T6]] return ^{ return x; }; @@ -32,19 +32,19 @@ void test2(id x) { // CHECK-LABEL: define void @test2( // CHECK: [[X:%.*]] = alloca i8*, // CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]], -// CHECK-NEXT: [[PARM:%.*]] = call i8* @objc_retain(i8* {{%.*}}) +// CHECK-NEXT: [[PARM:%.*]] = call i8* @llvm.objc.retain(i8* {{%.*}}) // CHECK-NEXT: store i8* [[PARM]], i8** [[X]] // CHECK-NEXT: [[SLOTREL:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5 // CHECK: [[SLOT:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5 // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[X]], -// CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[T0]]) +// CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retain(i8* [[T0]]) // CHECK-NEXT: store i8* [[T1]], i8** [[SLOT]], // CHECK-NEXT: bitcast // CHECK-NEXT: call void @test2_helper( // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[SLOTREL]] -// CHECK-NEXT: call void @objc_release(i8* [[T0]]) [[NUW]], !clang.imprecise_release +// CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) [[NUW]], !clang.imprecise_release // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[X]] -// CHECK-NEXT: call void @objc_release(i8* [[T0]]) [[NUW]], !clang.imprecise_release +// CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) [[NUW]], !clang.imprecise_release // CHECK-NEXT: ret void extern void test2_helper(id (^)(void)); test2_helper(^{ return x; }); @@ -56,7 +56,7 @@ void test2(id x) { // CHECK-NEXT: [[DST:%.*]] = bitcast i8* [[T0]] to [[BLOCK_T]]* // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[SRC]], i32 0, i32 5 // CHECK-NEXT: [[T1:%.*]] = load i8*, i8** [[T0]] -// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retain(i8* [[T1]]) [[NUW]] +// CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retain(i8* [[T1]]) [[NUW]] // CHECK-NEXT: ret void @@ -65,7 +65,7 @@ void test2(id x) { // CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[BLOCK_T]]* // CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[T1]], i32 0, i32 5 // CHECK-NEXT: [[T3:%.*]] = load i8*, i8** [[T2]] -// CHECK-NEXT: call void @objc_release(i8* [[T3]]) +// CHECK-NEXT: call void @llvm.objc.release(i8* [[T3]]) // CHECK-NEXT: ret void } @@ -78,7 +78,7 @@ void test3(void (^sink)(id*)) { // CHECK-NEXT: [[STRONG:%.*]] = alloca i8* // CHECK-NEXT: [[TEMP:%.*]] = alloca i8* // CHECK-NEXT: bitcast void (i8**)* {{%.*}} to i8* - // CHECK-NEXT: call i8* @objc_retain( + // CHECK-NEXT: call i8* @llvm.objc.retain( // CHECK-NEXT: bitcast i8* // CHECK-NEXT: store void (i8**)* {{%.*}}, void (i8**)** [[SINK]] // CHECK-NEXT: [[STRONGPTR1:%.*]] = bitcast i8** [[STRONG]] to i8* @@ -95,20 +95,20 @@ void test3(void (^sink)(id*)) { // CHECK-NEXT: [[F1:%.*]] = bitcast i8* [[F0]] to void (i8*, i8**)* // CHECK-NEXT: call void [[F1]](i8* [[BLOCK]], i8** [[TEMP]]) // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[TEMP]] - // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[T0]]) + // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retain(i8* [[T0]]) // CHECK-NEXT: call void (...) @clang.arc.use(i8* [[V]]) [[NUW]] // CHECK-NEXT: [[T2:%.*]] = load i8*, i8** [[STRONG]] // CHECK-NEXT: store i8* [[T1]], i8** [[STRONG]] - // CHECK-NEXT: call void @objc_release(i8* [[T2]]) + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T2]]) // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[STRONG]] - // CHECK-NEXT: call void @objc_release(i8* [[T0]]) + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) // CHECK-NEXT: [[STRONGPTR2:%.*]] = bitcast i8** [[STRONG]] to i8* // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[STRONGPTR2]]) // CHECK-NEXT: load void (i8**)*, void (i8**)** [[SINK]] // CHECK-NEXT: bitcast - // CHECK-NEXT: call void @objc_release + // CHECK-NEXT: call void @llvm.objc.release // CHECK-NEXT: ret void } @@ -127,7 +127,7 @@ void test4(void) { // CHECK-NEXT: store i32 838860800, i32* [[T0]] // CHECK: [[SLOT:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[VAR]], i32 0, i32 6 // CHECK-NEXT: [[T0:%.*]] = call i8* @test4_source() - // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]]) + // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) // CHECK-NEXT: store i8* [[T1]], i8** [[SLOT]] // CHECK-NEXT: [[SLOT:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[VAR]], i32 0, i32 6 // 0x42800000 - has signature, copy/dispose helpers, as well as BLOCK_HAS_EXTENDED_LAYOUT @@ -138,7 +138,7 @@ void test4(void) { // CHECK: [[T0:%.*]] = bitcast [[BYREF_T]]* [[VAR]] to i8* // CHECK-NEXT: call void @_Block_object_dispose(i8* [[T0]], i32 8) // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[SLOT]] - // CHECK-NEXT: call void @objc_release(i8* [[T0]]) + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) // CHECK: ret void // CHECK-LABEL: define internal void @__Block_byref_object_copy_(i8*, i8*) #{{[0-9]+}} { @@ -153,13 +153,13 @@ void test4(void) { // CHECK-LABEL: define internal void @__Block_byref_object_dispose_(i8*) #{{[0-9]+}} { // CHECK: [[T0:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* {{%.*}}, i32 0, i32 6 // CHECK-NEXT: [[T1:%.*]] = load i8*, i8** [[T0]] - // CHECK-NEXT: call void @objc_release(i8* [[T1]]) + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) // CHECK-LABEL: define internal void @__test4_block_invoke // CHECK: [[SLOT:%.*]] = getelementptr inbounds {{.*}}, i32 0, i32 6 // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[SLOT]], align 8 // CHECK-NEXT: store i8* null, i8** [[SLOT]], - // CHECK-NEXT: call void @objc_release(i8* [[T0]]) + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) // CHECK-NEXT: ret void // CHECK-LABEL: define linkonce_odr hidden void @__copy_helper_block_8_32r(i8*, i8*) unnamed_addr #{{[0-9]+}} { @@ -181,9 +181,9 @@ void test5(void) { // CHECK-NEXT: [[VARPTR1:%.*]] = bitcast i8** [[VAR]] to i8* // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[VARPTR1]]) // CHECK: [[T0:%.*]] = call i8* @test5_source() - // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]]) + // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) // CHECK-NEXT: store i8* [[T1]], i8** [[VAR]], - // CHECK-NEXT: call void @objc_release(i8* [[T1]]) + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) // 0x40800000 - has signature but no copy/dispose, as well as BLOCK_HAS_EXTENDED_LAYOUT // CHECK: store i32 -1073741824, i32* // CHECK: [[CAPTURE:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5 @@ -212,9 +212,9 @@ void test6(void) { // CHECK-NEXT: store i32 1107296256, i32* [[T0]] // CHECK: [[SLOT:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[VAR]], i32 0, i32 6 // CHECK-NEXT: [[T0:%.*]] = call i8* @test6_source() - // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]]) - // CHECK-NEXT: call i8* @objc_initWeak(i8** [[SLOT]], i8* [[T1]]) - // CHECK-NEXT: call void @objc_release(i8* [[T1]]) + // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) + // CHECK-NEXT: call i8* @llvm.objc.initWeak(i8** [[SLOT]], i8* [[T1]]) + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) // CHECK-NEXT: [[SLOT:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[VAR]], i32 0, i32 6 // 0x42800000 - has signature, copy/dispose helpers, as well as BLOCK_HAS_EXTENDED_LAYOUT // CHECK: store i32 -1040187392, @@ -225,7 +225,7 @@ void test6(void) { // CHECK: call void @test6_helper( // CHECK: [[T0:%.*]] = bitcast [[BYREF_T]]* [[VAR]] to i8* // CHECK-NEXT: call void @_Block_object_dispose(i8* [[T0]], i32 8) - // CHECK-NEXT: call void @objc_destroyWeak(i8** [[SLOT]]) + // CHECK-NEXT: call void @llvm.objc.destroyWeak(i8** [[SLOT]]) // CHECK-NEXT: [[VARPTR2:%.*]] = bitcast [[BYREF_T]]* [[VAR]] to i8* // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 48, i8* [[VARPTR2]]) // CHECK-NEXT: ret void @@ -235,15 +235,15 @@ void test6(void) { // CHECK-NEXT: load i8*, i8** // CHECK-NEXT: bitcast i8* {{%.*}} to [[BYREF_T]]* // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* {{%.*}}, i32 0, i32 6 - // CHECK-NEXT: call void @objc_moveWeak(i8** [[T0]], i8** [[T1]]) + // CHECK-NEXT: call void @llvm.objc.moveWeak(i8** [[T0]], i8** [[T1]]) // CHECK-LABEL: define internal void @__Block_byref_object_dispose_.{{[0-9]+}}(i8*) #{{[0-9]+}} { // CHECK: [[T0:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* {{%.*}}, i32 0, i32 6 - // CHECK-NEXT: call void @objc_destroyWeak(i8** [[T0]]) + // CHECK-NEXT: call void @llvm.objc.destroyWeak(i8** [[T0]]) // CHECK-LABEL: define internal void @__test6_block_invoke // CHECK: [[SLOT:%.*]] = getelementptr inbounds {{.*}}, i32 0, i32 6 - // CHECK-NEXT: call i8* @objc_storeWeak(i8** [[SLOT]], i8* null) + // CHECK-NEXT: call i8* @llvm.objc.storeWeak(i8** [[SLOT]], i8* null) // CHECK-NEXT: ret void } @@ -258,33 +258,33 @@ void test7(void) { // CHECK: [[VAR:%.*]] = alloca i8*, // CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]], // CHECK: [[T0:%.*]] = call i8* @test7_source() - // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]]) - // CHECK-NEXT: call i8* @objc_initWeak(i8** [[VAR]], i8* [[T1]]) - // CHECK-NEXT: call void @objc_release(i8* [[T1]]) + // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) + // CHECK-NEXT: call i8* @llvm.objc.initWeak(i8** [[VAR]], i8* [[T1]]) + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) // 0x42800000 - has signature, copy/dispose helpers, as well as BLOCK_HAS_EXTENDED_LAYOUT // CHECK: store i32 -1040187392, // CHECK: [[SLOT:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5 - // CHECK-NEXT: call void @objc_copyWeak(i8** [[SLOT]], i8** [[VAR]]) + // CHECK-NEXT: call void @llvm.objc.copyWeak(i8** [[SLOT]], i8** [[VAR]]) // CHECK: call void @test7_helper( - // CHECK-NEXT: call void @objc_destroyWeak(i8** {{%.*}}) - // CHECK-NEXT: call void @objc_destroyWeak(i8** [[VAR]]) + // CHECK-NEXT: call void @llvm.objc.destroyWeak(i8** {{%.*}}) + // CHECK-NEXT: call void @llvm.objc.destroyWeak(i8** [[VAR]]) // CHECK: ret void // CHECK-LABEL: define internal void @__test7_block_invoke // CHECK: [[SLOT:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* {{%.*}}, i32 0, i32 5 - // CHECK-NEXT: [[T0:%.*]] = call i8* @objc_loadWeakRetained(i8** [[SLOT]]) + // CHECK-NEXT: [[T0:%.*]] = call i8* @llvm.objc.loadWeakRetained(i8** [[SLOT]]) // CHECK-NEXT: call void @test7_consume(i8* [[T0]]) - // CHECK-NEXT: call void @objc_release(i8* [[T0]]) + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) // CHECK: ret void // CHECK-LABEL: define linkonce_odr hidden void @__copy_helper_block_8_32w(i8*, i8*) unnamed_addr #{{[0-9]+}} { // CHECK: getelementptr // CHECK-NEXT: getelementptr - // CHECK-NEXT: call void @objc_copyWeak( + // CHECK-NEXT: call void @llvm.objc.copyWeak( // CHECK-LABEL: define linkonce_odr hidden void @__destroy_helper_block_8_32w(i8*) unnamed_addr #{{[0-9]+}} { // CHECK: getelementptr - // CHECK-NEXT: call void @objc_destroyWeak( + // CHECK-NEXT: call void @llvm.objc.destroyWeak( } @interface Test8 @end @@ -323,11 +323,11 @@ id test9(void) { // CHECK: load i8*, i8** getelementptr // CHECK-NEXT: bitcast i8* // CHECK-NEXT: call i8* -// CHECK-NEXT: tail call i8* @objc_autoreleaseReturnValue +// CHECK-NEXT: tail call i8* @llvm.objc.autoreleaseReturnValue // CHECK-NEXT: ret i8* // CHECK: call i8* @test9_produce() -// CHECK-NEXT: call i8* @objc_retain +// CHECK-NEXT: call i8* @llvm.objc.retain // CHECK-NEXT: ret i8* } @@ -345,7 +345,7 @@ void test10a(void) { // Run the initializer as an assignment. // CHECK: [[T0:%.*]] = bitcast void ()* {{%.*}} to i8* - // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainBlock(i8* [[T0]]) + // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retainBlock(i8* [[T0]]) // CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[T1]] to void ()* // CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[BYREF]], i32 0, i32 1 // CHECK-NEXT: [[T4:%.*]] = load [[BYREF_T]]*, [[BYREF_T]]** [[T3]] @@ -353,7 +353,7 @@ void test10a(void) { // CHECK-NEXT: [[T6:%.*]] = load void ()*, void ()** [[T5]], align 8 // CHECK-NEXT: store void ()* {{%.*}}, void ()** [[T5]], align 8 // CHECK-NEXT: [[T7:%.*]] = bitcast void ()* [[T6]] to i8* - // CHECK-NEXT: call void @objc_release(i8* [[T7]]) + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T7]]) // Destroy at end of function. // CHECK-NEXT: [[SLOT:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[BYREF]], i32 0, i32 6 @@ -361,7 +361,7 @@ void test10a(void) { // CHECK-NEXT: call void @_Block_object_dispose(i8* [[T0]], i32 8) // CHECK-NEXT: [[T1:%.*]] = load void ()*, void ()** [[SLOT]] // CHECK-NEXT: [[T2:%.*]] = bitcast void ()* [[T1]] to i8* - // CHECK-NEXT: call void @objc_release(i8* [[T2]]) + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T2]]) // CHECK: ret void } @@ -379,7 +379,7 @@ void test10a(void) { // CHECK-NEXT: [[S2:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[S1]], i32 0, i32 6 // CHECK-NEXT: [[T0:%.*]] = load void ()*, void ()** [[S2]], align 8 // CHECK-NEXT: [[T1:%.*]] = bitcast void ()* [[T0]] to i8* -// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainBlock(i8* [[T1]]) +// CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainBlock(i8* [[T1]]) // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to void ()* // CHECK-NEXT: store void ()* [[T3]], void ()** [[D2]], align 8 // CHECK: ret void @@ -390,7 +390,7 @@ void test10a(void) { // CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[T1]], i32 0, i32 6 // CHECK-NEXT: [[T3:%.*]] = load void ()*, void ()** [[T2]] // CHECK-NEXT: [[T4:%.*]] = bitcast void ()* [[T3]] to i8* -// CHECK-NEXT: call void @objc_release(i8* [[T4]]) +// CHECK-NEXT: call void @llvm.objc.release(i8* [[T4]]) // CHECK-NEXT: ret void // Test that we correctly assign to __block variables when the @@ -410,7 +410,7 @@ void test10b(void) { // The assignment. // CHECK: [[T0:%.*]] = bitcast void ()* {{%.*}} to i8* - // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainBlock(i8* [[T0]]) + // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retainBlock(i8* [[T0]]) // CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[T1]] to void ()* // CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[BYREF]], i32 0, i32 1 // CHECK-NEXT: [[T4:%.*]] = load [[BYREF_T]]*, [[BYREF_T]]** [[T3]] @@ -418,14 +418,14 @@ void test10b(void) { // CHECK-NEXT: [[T6:%.*]] = load void ()*, void ()** [[T5]], align 8 // CHECK-NEXT: store void ()* {{%.*}}, void ()** [[T5]], align 8 // CHECK-NEXT: [[T7:%.*]] = bitcast void ()* [[T6]] to i8* - // CHECK-NEXT: call void @objc_release(i8* [[T7]]) + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T7]]) // Destroy at end of function. // CHECK-NEXT: [[T0:%.*]] = bitcast [[BYREF_T]]* [[BYREF]] to i8* // CHECK-NEXT: call void @_Block_object_dispose(i8* [[T0]], i32 8) // CHECK-NEXT: [[T1:%.*]] = load void ()*, void ()** [[SLOT]] // CHECK-NEXT: [[T2:%.*]] = bitcast void ()* [[T1]] to i8* - // CHECK-NEXT: call void @objc_release(i8* [[T2]]) + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T2]]) // CHECK: ret void } @@ -440,12 +440,12 @@ void test11a(void) { // CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]], align 8 // CHECK: [[T0:%.*]] = bitcast [[BLOCK_T]]* [[BLOCK]] to void ()* // CHECK-NEXT: [[T1:%.*]] = bitcast void ()* [[T0]] to i8* - // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainBlock(i8* [[T1]]) + // CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainBlock(i8* [[T1]]) // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to void ()* // CHECK-NEXT: [[T4:%.*]] = bitcast void ()* [[T3]] to i8* // CHECK-NEXT: call void @test11_helper(i8* [[T4]]) // CHECK-NEXT: [[T5:%.*]] = bitcast void ()* [[T3]] to i8* - // CHECK-NEXT: call void @objc_release(i8* [[T5]]) + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T5]]) // CHECK: ret void } void test11b(void) { @@ -458,12 +458,12 @@ void test11b(void) { // CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]], align 8 // CHECK: [[T0:%.*]] = bitcast [[BLOCK_T]]* [[BLOCK]] to void ()* // CHECK-NEXT: [[T1:%.*]] = bitcast void ()* [[T0]] to i8* - // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainBlock(i8* [[T1]]) + // CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainBlock(i8* [[T1]]) // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to void ()* // CHECK-NEXT: [[T4:%.*]] = bitcast void ()* [[T3]] to i8* // CHECK-NEXT: store i8* [[T4]], i8** [[B]], align 8 // CHECK-NEXT: [[T5:%.*]] = load i8*, i8** [[B]] - // CHECK-NEXT: call void @objc_release(i8* [[T5]]) + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T5]]) // CHECK: ret void } @@ -500,7 +500,7 @@ void test13(id x) { // CHECK-NEXT: [[B:%.*]] = alloca void ()*, align 8 // CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:.*]], align 8 // CHECK-NEXT: [[CLEANUP_ACTIVE:%.*]] = alloca i1 - // CHECK-NEXT: [[T0:%.*]] = call i8* @objc_retain(i8* {{%.*}}) + // CHECK-NEXT: [[T0:%.*]] = call i8* @llvm.objc.retain(i8* {{%.*}}) // CHECK-NEXT: store i8* [[T0]], i8** [[X]], align 8 // CHECK-NEXT: [[BPTR1:%.*]] = bitcast void ()** [[B]] to i8* // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[BPTR1]]) @@ -513,7 +513,7 @@ void test13(id x) { // CHECK-NOT: br // CHECK: [[CAPTURE:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5 // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[X]], align 8 - // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[T0]]) + // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retain(i8* [[T0]]) // CHECK-NEXT: store i8* [[T1]], i8** [[CAPTURE]], align 8 // CHECK-NEXT: store i1 true, i1* [[CLEANUP_ACTIVE]] // CHECK-NEXT: bitcast [[BLOCK_T]]* [[BLOCK]] to void ()* @@ -521,25 +521,25 @@ void test13(id x) { // CHECK: br label // CHECK: [[T0:%.*]] = phi void ()* // CHECK-NEXT: [[T1:%.*]] = bitcast void ()* [[T0]] to i8* - // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainBlock(i8* [[T1]]) + // CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainBlock(i8* [[T1]]) // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to void ()* // CHECK-NEXT: store void ()* [[T3]], void ()** [[B]], align 8 // CHECK-NEXT: [[T0:%.*]] = load void ()*, void ()** [[B]], align 8 // CHECK-NEXT: call void @test13_use(void ()* [[T0]]) // CHECK-NEXT: [[T0:%.*]] = load void ()*, void ()** [[B]] // CHECK-NEXT: [[T1:%.*]] = bitcast void ()* [[T0]] to i8* - // CHECK-NEXT: call void @objc_release(i8* [[T1]]) + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) // CHECK-NEXT: [[T0:%.*]] = load i1, i1* [[CLEANUP_ACTIVE]] // CHECK-NEXT: br i1 [[T0]] // CHECK: [[T0:%.*]] = load i8*, i8** [[CLEANUP_ADDR]] - // CHECK-NEXT: call void @objc_release(i8* [[T0]]) + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) // CHECK-NEXT: br label // CHECK: [[BPTR2:%.*]] = bitcast void ()** [[B]] to i8* // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[BPTR2]]) // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[X]] - // CHECK-NEXT: call void @objc_release(i8* [[T0]]) + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) // CHECK-NEXT: ret void } @@ -586,7 +586,7 @@ id (^test17(id self, int which))(void) { // CHECK-NEXT: [[SELF:%.*]] = alloca i8*, // CHECK: [[B0:%.*]] = alloca [[BLOCK:<.*>]], align // CHECK: [[B1:%.*]] = alloca [[BLOCK]], align -// CHECK: [[T0:%.*]] = call i8* @objc_retain(i8* +// CHECK: [[T0:%.*]] = call i8* @llvm.objc.retain(i8* // CHECK-NEXT: store i8* [[T0]], i8** [[SELF]], align // CHECK-NOT: objc_retain // CHECK-NOT: objc_release @@ -595,15 +595,15 @@ id (^test17(id self, int which))(void) { // CHECK-NOT: objc_release // CHECK: [[T0:%.*]] = getelementptr inbounds [[BLOCK]], [[BLOCK]]* [[B0]], i32 0, i32 5 // CHECK-NEXT: [[T1:%.*]] = load i8*, i8** [[SELF]], align -// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retain(i8* [[T1]]) +// CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retain(i8* [[T1]]) // CHECK-NEXT: store i8* [[T2]], i8** [[T0]], // CHECK-NEXT: [[T0:%.*]] = bitcast [[BLOCK]]* [[B0]] to i8* ()* // CHECK-NEXT: [[T1:%.*]] = bitcast i8* ()* [[T0]] to i8* -// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainBlock(i8* [[T1]]) +// CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainBlock(i8* [[T1]]) // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to i8* ()* // CHECK-NEXT: store i8* ()* [[T3]], i8* ()** [[RET]] // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[DESTROY]] -// CHECK-NEXT: call void @objc_release(i8* [[T0]]) +// CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) // CHECK-NEXT: store i32 // CHECK-NEXT: br label // CHECK-NOT: objc_retain @@ -613,15 +613,15 @@ id (^test17(id self, int which))(void) { // CHECK-NOT: objc_release // CHECK: [[T0:%.*]] = getelementptr inbounds [[BLOCK]], [[BLOCK]]* [[B1]], i32 0, i32 5 // CHECK-NEXT: [[T1:%.*]] = load i8*, i8** [[SELF]], align -// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retain(i8* [[T1]]) +// CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retain(i8* [[T1]]) // CHECK-NEXT: store i8* [[T2]], i8** [[T0]], // CHECK-NEXT: [[T0:%.*]] = bitcast [[BLOCK]]* [[B1]] to i8* ()* // CHECK-NEXT: [[T1:%.*]] = bitcast i8* ()* [[T0]] to i8* -// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainBlock(i8* [[T1]]) +// CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainBlock(i8* [[T1]]) // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to i8* ()* // CHECK-NEXT: store i8* ()* [[T3]], i8* ()** [[RET]] // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[DESTROY]] -// CHECK-NEXT: call void @objc_release(i8* [[T0]]) +// CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) // CHECK-NEXT: store i32 // CHECK-NEXT: br label @@ -630,18 +630,18 @@ void test18(id x) { // CHECK-UNOPT: [[X:%.*]] = alloca i8*, // CHECK-UNOPT-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]], // CHECK-UNOPT-NEXT: store i8* null, i8** [[X]] -// CHECK-UNOPT-NEXT: call void @objc_storeStrong(i8** [[X]], +// CHECK-UNOPT-NEXT: call void @llvm.objc.storeStrong(i8** [[X]], // CHECK-UNOPT-NEXT: [[SLOTREL:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5 // CHECK-UNOPT: %[[BLOCK_DESCRIPTOR:.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[BLOCK]], i32 0, i32 4 // CHECK-UNOPT: store %[[STRUCT_BLOCK_DESCRIPTOR]]* bitcast ({ i64, i64, i8*, i8*, i8*, i64 }* @[[BLOCK_DESCRIPTOR_TMP44]] to %[[STRUCT_BLOCK_DESCRIPTOR]]*), %[[STRUCT_BLOCK_DESCRIPTOR]]** %[[BLOCK_DESCRIPTOR]], align 8 // CHECK-UNOPT: [[SLOT:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5 // CHECK-UNOPT-NEXT: [[T0:%.*]] = load i8*, i8** [[X]], -// CHECK-UNOPT-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[T0]]) +// CHECK-UNOPT-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retain(i8* [[T0]]) // CHECK-UNOPT-NEXT: store i8* [[T1]], i8** [[SLOT]], // CHECK-UNOPT-NEXT: bitcast // CHECK-UNOPT-NEXT: call void @test18_helper( -// CHECK-UNOPT-NEXT: call void @objc_storeStrong(i8** [[SLOTREL]], i8* null) [[NUW:#[0-9]+]] -// CHECK-UNOPT-NEXT: call void @objc_storeStrong(i8** [[X]], i8* null) [[NUW]] +// CHECK-UNOPT-NEXT: call void @llvm.objc.storeStrong(i8** [[SLOTREL]], i8* null) [[NUW:#[0-9]+]] +// CHECK-UNOPT-NEXT: call void @llvm.objc.storeStrong(i8** [[X]], i8* null) [[NUW]] // CHECK-UNOPT-NEXT: ret void extern void test18_helper(id (^)(void)); test18_helper(^{ return x; }); @@ -669,7 +669,7 @@ void test19(void (^b)(void)) { // CHECK: [[B:%.*]] = alloca void ()*, // CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]], // CHECK-NEXT: [[T0:%.*]] = bitcast void ()* {{%.*}} to i8* -// CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[T0]]) +// CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retain(i8* [[T0]]) // CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[T1]] to void ()* // CHECK-NEXT: store void ()* [[T2]], void ()** [[B]] @@ -680,7 +680,7 @@ void test19(void (^b)(void)) { // CHECK: [[SLOT:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5 // CHECK-NEXT: [[T0:%.*]] = load void ()*, void ()** [[B]], // CHECK-NEXT: [[T1:%.*]] = bitcast void ()* [[T0]] to i8* -// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retain(i8* [[T1]]) +// CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retain(i8* [[T1]]) // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to void ()* // CHECK-NEXT: store void ()* [[T3]], void ()** [[SLOT]], // Call. @@ -692,12 +692,12 @@ void test19(void (^b)(void)) { // Block teardown. // CHECK-NEXT: [[T0:%.*]] = load void ()*, void ()** [[SLOTREL]] // CHECK-NEXT: [[T1:%.*]] = bitcast void ()* [[T0]] to i8* -// CHECK-NEXT: call void @objc_release(i8* [[T1]]) +// CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) // Local cleanup. // CHECK-NEXT: [[T0:%.*]] = load void ()*, void ()** [[B]] // CHECK-NEXT: [[T1:%.*]] = bitcast void ()* [[T0]] to i8* -// CHECK-NEXT: call void @objc_release(i8* [[T1]]) +// CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) // CHECK-NEXT: ret void } @@ -705,7 +705,7 @@ void test19(void (^b)(void)) { // CHECK-LABEL: define void @test20( // CHECK: [[XADDR:%.*]] = alloca i8* // CHECK-NEXT: [[BLOCK:%.*]] = alloca <[[BLOCKTY:.*]]> -// CHECK-NEXT: [[RETAINEDX:%.*]] = call i8* @objc_retain(i8* %{{.*}}) +// CHECK-NEXT: [[RETAINEDX:%.*]] = call i8* @llvm.objc.retain(i8* %{{.*}}) // CHECK-NEXT: store i8* [[RETAINEDX]], i8** [[XADDR]] // CHECK-NEXT: [[CAPTUREFIELD:%.*]] = getelementptr inbounds <[[BLOCKTY]]>, <[[BLOCKTY]]>* [[BLOCK]], i32 0, i32 5 // CHECK: [[BLOCKCAPTURED:%.*]] = getelementptr inbounds <[[BLOCKTY]]>, <[[BLOCKTY]]>* [[BLOCK]], i32 0, i32 5 @@ -714,7 +714,7 @@ void test19(void (^b)(void)) { // CHECK: [[CAPTURE:%.*]] = load i8*, i8** [[CAPTUREFIELD]] // CHECK-NEXT: call void (...) @clang.arc.use(i8* [[CAPTURE]]) // CHECK-NEXT: [[X:%.*]] = load i8*, i8** [[XADDR]] -// CHECK-NEXT: call void @objc_release(i8* [[X]]) +// CHECK-NEXT: call void @llvm.objc.release(i8* [[X]]) // CHECK-NEXT: ret void // CHECK-UNOPT-LABEL: define void @test20( @@ -723,9 +723,9 @@ void test19(void (^b)(void)) { // CHECK-UNOPT: [[CAPTUREFIELD:%.*]] = getelementptr inbounds <[[BLOCKTY]]>, <[[BLOCKTY]]>* [[BLOCK]], i32 0, i32 5 // CHECK-UNOPT: [[BLOCKCAPTURED:%.*]] = getelementptr inbounds <[[BLOCKTY]]>, <[[BLOCKTY]]>* [[BLOCK]], i32 0, i32 5 // CHECK-UNOPT: [[CAPTURED:%.*]] = load i8*, i8** [[XADDR]] -// CHECK-UNOPT: [[RETAINED:%.*]] = call i8* @objc_retain(i8* [[CAPTURED]]) +// CHECK-UNOPT: [[RETAINED:%.*]] = call i8* @llvm.objc.retain(i8* [[CAPTURED]]) // CHECK-UNOPT: store i8* [[RETAINED]], i8** [[BLOCKCAPTURED]] -// CHECK-UNOPT: call void @objc_storeStrong(i8** [[CAPTUREFIELD]], i8* null) +// CHECK-UNOPT: call void @llvm.objc.storeStrong(i8** [[CAPTUREFIELD]], i8* null) void test20_callee(void (^)()); void test20(const id x) { diff --git a/test/CodeGenObjC/arc-bridged-cast.m b/test/CodeGenObjC/arc-bridged-cast.m index 42795d5d80..db01894496 100644 --- a/test/CodeGenObjC/arc-bridged-cast.m +++ b/test/CodeGenObjC/arc-bridged-cast.m @@ -27,10 +27,10 @@ void bridge_transfer_from_cf(int *i) { // CHECK-NOT: retain // CHECK: store i32 13 (void)(__bridge_transfer id)CFCreateSomething(), *i = 13; - // CHECK: call void @objc_release + // CHECK: call void @llvm.objc.release // CHECK: store i32 17 *i = 17; - // CHECK: call void @objc_release + // CHECK: call void @llvm.objc.release // CHECK-NEXT: bitcast // CHECK-NEXT: call void @llvm.lifetime.end // CHECK-NEXT: ret void @@ -42,7 +42,7 @@ void bridge_from_cf(int *i) { *i = 7; // CHECK: call i8* @CFCreateSomething() id obj1 = (__bridge id)CFCreateSomething(); - // CHECK: objc_retainAutoreleasedReturnValue + // CHECK: llvm.objc.retainAutoreleasedReturnValue // CHECK: store i32 11 *i = 11; // CHECK: call i8* @CFCreateSomething() @@ -51,7 +51,7 @@ void bridge_from_cf(int *i) { (void)(__bridge id)CFCreateSomething(), *i = 13; // CHECK: store i32 17 *i = 17; - // CHECK: call void @objc_release + // CHECK: call void @llvm.objc.release // CHECK-NEXT: bitcast // CHECK-NEXT: call void @llvm.lifetime.end // CHECK-NEXT: ret void @@ -62,12 +62,12 @@ void bridge_retained_of_cf(int *i) { *i = 7; // CHECK: call i8* @CreateSomething() CFTypeRef cf1 = (__bridge_retained CFTypeRef)CreateSomething(); - // CHECK-NEXT: call i8* @objc_retainAutoreleasedReturnValue + // CHECK-NEXT: call i8* @llvm.objc.retainAutoreleasedReturnValue // CHECK: store i32 11 *i = 11; // CHECK: call i8* @CreateSomething() (__bridge_retained CFTypeRef)CreateSomething(), *i = 13; - // CHECK-NEXT: call i8* @objc_retainAutoreleasedReturnValue + // CHECK-NEXT: call i8* @llvm.objc.retainAutoreleasedReturnValue // CHECK: store i32 13 // CHECK: store i32 17 *i = 17; @@ -99,8 +99,8 @@ void bridge_of_cf(int *i) { // CHECK-LABEL: define %struct.__CFString* @bridge_of_paren_expr() CFStringRef bridge_of_paren_expr() { - // CHECK-NOT: call i8* @objc_retainAutoreleasedReturnValue( - // CHECK-NOT: call void @objc_release( + // CHECK-NOT: call i8* @llvm.objc.retainAutoreleasedReturnValue( + // CHECK-NOT: call void @llvm.objc.release( CFStringRef r = (__bridge CFStringRef)(CreateNSString()); r = (__bridge CFStringRef)((NSString *)(CreateNSString())); return r; diff --git a/test/CodeGenObjC/arc-exceptions.m b/test/CodeGenObjC/arc-exceptions.m index dafffd81f5..b8fb47057e 100644 --- a/test/CodeGenObjC/arc-exceptions.m +++ b/test/CodeGenObjC/arc-exceptions.m @@ -17,11 +17,11 @@ void test0(void) { // CHECK: [[T0:%.*]] = call i8* @objc_begin_catch( // CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[ETY]]* // CHECK-NEXT: [[T2:%.*]] = bitcast [[ETY]]* [[T1]] to i8* -// CHECK-NEXT: [[T3:%.*]] = call i8* @objc_retain(i8* [[T2]]) [[NUW:#[0-9]+]] +// CHECK-NEXT: [[T3:%.*]] = call i8* @llvm.objc.retain(i8* [[T2]]) [[NUW:#[0-9]+]] // CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to [[ETY]]* // CHECK-NEXT: store [[ETY]]* [[T4]], [[ETY]]** [[E]] // CHECK-NEXT: [[T0:%.*]] = bitcast [[ETY]]** [[E]] to i8** -// CHECK-NEXT: call void @objc_storeStrong(i8** [[T0]], i8* null) [[NUW]] +// CHECK-NEXT: call void @llvm.objc.storeStrong(i8** [[T0]], i8* null) [[NUW]] // CHECK-NEXT: call void @objc_end_catch() [[NUW]] void test1_helper(void); @@ -38,9 +38,9 @@ void test1(void) { // CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[ETY]]* // CHECK-NEXT: [[T2:%.*]] = bitcast [[ETY]]** [[E]] to i8** // CHECK-NEXT: [[T3:%.*]] = bitcast [[ETY]]* [[T1]] to i8* -// CHECK-NEXT: call i8* @objc_initWeak(i8** [[T2]], i8* [[T3]]) [[NUW]] +// CHECK-NEXT: call i8* @llvm.objc.initWeak(i8** [[T2]], i8* [[T3]]) [[NUW]] // CHECK-NEXT: [[T0:%.*]] = bitcast [[ETY]]** [[E]] to i8** -// CHECK-NEXT: call void @objc_destroyWeak(i8** [[T0]]) [[NUW]] +// CHECK-NEXT: call void @llvm.objc.destroyWeak(i8** [[T0]]) [[NUW]] // CHECK-NEXT: call void @objc_end_catch() [[NUW]] // CHECK: attributes [[NUW]] = { nounwind } diff --git a/test/CodeGenObjC/arc-foreach.m b/test/CodeGenObjC/arc-foreach.m index ffeb37247b..65d517cc93 100644 --- a/test/CodeGenObjC/arc-foreach.m +++ b/test/CodeGenObjC/arc-foreach.m @@ -38,7 +38,7 @@ void test0(NSArray *array) { // CHECK-LP64-NEXT: store [[ARRAY_T]]* null, [[ARRAY_T]]** [[ARRAY]] // CHECK-LP64-NEXT: [[ZERO:%.*]] = bitcast [[ARRAY_T]]** [[ARRAY]] to i8** // CHECK-LP64-NEXT: [[ONE:%.*]] = bitcast [[ARRAY_T]]* {{%.*}} to i8* -// CHECK-LP64-NEXT: call void @objc_storeStrong(i8** [[ZERO]], i8* [[ONE]]) [[NUW:#[0-9]+]] +// CHECK-LP64-NEXT: call void @llvm.objc.storeStrong(i8** [[ZERO]], i8* [[ONE]]) [[NUW:#[0-9]+]] // Initialize the fast enumaration state. // CHECK-LP64-NEXT: [[T0:%.*]] = bitcast [[STATE_T]]* [[STATE]] to i8* @@ -47,7 +47,7 @@ void test0(NSArray *array) { // Evaluate the collection expression and retain. // CHECK-LP64-NEXT: [[T0:%.*]] = load [[ARRAY_T]]*, [[ARRAY_T]]** [[ARRAY]], align 8 // CHECK-LP64-NEXT: [[T1:%.*]] = bitcast [[ARRAY_T]]* [[T0]] to i8* -// CHECK-LP64-NEXT: [[T2:%.*]] = call i8* @objc_retain(i8* [[T1]]) +// CHECK-LP64-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retain(i8* [[T1]]) // CHECK-LP64-NEXT: [[SAVED_ARRAY:%.*]] = bitcast i8* [[T2]] to [[ARRAY_T]]* // Call the enumeration method. @@ -68,11 +68,11 @@ void test0(NSArray *array) { // CHECK-LP64: [[D0:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5 // CHECK-LP64: [[T0:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5 // CHECK-LP64-NEXT: [[T1:%.*]] = load i8*, i8** [[X]] -// CHECK-LP64-NEXT: [[T2:%.*]] = call i8* @objc_retain(i8* [[T1]]) +// CHECK-LP64-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retain(i8* [[T1]]) // CHECK-LP64-NEXT: store i8* [[T2]], i8** [[T0]] // CHECK-LP64-NEXT: [[BLOCK1:%.*]] = bitcast [[BLOCK_T]]* [[BLOCK]] // CHECK-LP64-NEXT: call void @use_block(void ()* [[BLOCK1]]) -// CHECK-LP64-NEXT: call void @objc_storeStrong(i8** [[D0]], i8* null) +// CHECK-LP64-NEXT: call void @llvm.objc.storeStrong(i8** [[D0]], i8* null) // CHECK-LP64-NOT: call void (...) @clang.arc.use(i8* [[CAPTURE]]) // CHECK-LP64-OPT: [[D0:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[BLOCK]], i64 0, i32 5 @@ -85,11 +85,11 @@ void test0(NSArray *array) { // Release the array. // CHECK-LP64: [[T0:%.*]] = bitcast [[ARRAY_T]]* [[SAVED_ARRAY]] to i8* -// CHECK-LP64-NEXT: call void @objc_release(i8* [[T0]]) +// CHECK-LP64-NEXT: call void @llvm.objc.release(i8* [[T0]]) // Destroy 'array'. // CHECK-LP64: [[T0:%.*]] = bitcast [[ARRAY_T]]** [[ARRAY]] to i8** -// CHECK-LP64-NEXT: call void @objc_storeStrong(i8** [[T0]], i8* null) +// CHECK-LP64-NEXT: call void @llvm.objc.storeStrong(i8** [[T0]], i8* null) // CHECK-LP64-NEXT: ret void // CHECK-LP64-LABEL: define internal void @__test0_block_invoke @@ -116,15 +116,15 @@ void test1(NSArray *array) { // CHECK-LP64-NEXT: [[T1:%.*]] = load i8**, i8*** [[T0]] // CHECK-LP64-NEXT: [[T2:%.*]] = getelementptr i8*, i8** [[T1]], i64 // CHECK-LP64-NEXT: [[T3:%.*]] = load i8*, i8** [[T2]] -// CHECK-LP64-NEXT: call i8* @objc_initWeak(i8** [[X]], i8* [[T3]]) +// CHECK-LP64-NEXT: call i8* @llvm.objc.initWeak(i8** [[X]], i8* [[T3]]) // CHECK-LP64: [[D0:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5 // CHECK-LP64: [[T0:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5 -// CHECK-LP64-NEXT: call void @objc_copyWeak(i8** [[T0]], i8** [[X]]) +// CHECK-LP64-NEXT: call void @llvm.objc.copyWeak(i8** [[T0]], i8** [[X]]) // CHECK-LP64-NEXT: [[T1:%.*]] = bitcast [[BLOCK_T]]* [[BLOCK]] to // CHECK-LP64: call void @use_block -// CHECK-LP64-NEXT: call void @objc_destroyWeak(i8** [[D0]]) -// CHECK-LP64-NEXT: call void @objc_destroyWeak(i8** [[X]]) +// CHECK-LP64-NEXT: call void @llvm.objc.destroyWeak(i8** [[D0]]) +// CHECK-LP64-NEXT: call void @llvm.objc.destroyWeak(i8** [[X]]) // rdar://problem/9817306 @interface Test2 @@ -139,7 +139,7 @@ void test2(Test2 *a) { // CHECK-LP64-LABEL: define void @test2( // CHECK-LP64: [[T0:%.*]] = call [[ARRAY_T]]* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to [[ARRAY_T]]* (i8*, i8*)*)( // CHECK-LP64-NEXT: [[T1:%.*]] = bitcast [[ARRAY_T]]* [[T0]] to i8* -// CHECK-LP64-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]]) +// CHECK-LP64-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]]) // CHECK-LP64-NEXT: [[COLL:%.*]] = bitcast i8* [[T2]] to [[ARRAY_T]]* // Make sure it's not immediately released before starting the iteration. @@ -157,7 +157,7 @@ void test2(Test2 *a) { // This bitcast is for the final release. // CHECK-LP64: [[T0:%.*]] = bitcast [[ARRAY_T]]* [[COLL]] to i8* -// CHECK-LP64-NEXT: call void @objc_release(i8* [[T0]]) +// CHECK-LP64-NEXT: call void @llvm.objc.release(i8* [[T0]]) // Check that the 'continue' label is positioned appropriately @@ -211,7 +211,7 @@ NSArray *array4; // CHECK-LP64: [[BC:%.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, [[TY]]* }>, <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, [[TY]]* }>* [[BLOCK]], i32 0, i32 5 // CHECK-LP64: [[T1:%.*]] = load [[TY]]*, [[TY]]** [[SELF_ADDR]] // CHECK-LP64: [[T2:%.*]] = bitcast [[TY]]* [[T1]] to i8* -// CHECK-LP64: call i8* @objc_retain(i8* [[T2]]) +// CHECK-LP64: call i8* @llvm.objc.retain(i8* [[T2]]) // CHECK-LP64-OPT-LABEL: define internal void @"\01-[I1 foo2]"( // CHECK-LP64-OPT: [[TY:%.*]]* %self @@ -219,7 +219,7 @@ NSArray *array4; // CHECK-LP64-OPT: [[T0:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[BLOCK]], i64 0, i32 5 // CHECK-LP64: [[T5:%.*]] = bitcast [[TY]]** [[T0]] to i8** -// CHECK-LP64: call void @objc_storeStrong(i8** [[T5]], i8* null) +// CHECK-LP64: call void @llvm.objc.storeStrong(i8** [[T5]], i8* null) // CHECK-LP64-NOT: call void (...) @clang.arc.use([[TY]]* [[T5]]) // CHECK-LP64: switch i32 {{%.*}}, label %[[UNREACHABLE:.*]] [ // CHECK-LP64-NEXT: i32 0, label %[[CLEANUP_CONT:.*]] diff --git a/test/CodeGenObjC/arc-i386.m b/test/CodeGenObjC/arc-i386.m index 7693a8f2b6..66b6ea8501 100644 --- a/test/CodeGenObjC/arc-i386.m +++ b/test/CodeGenObjC/arc-i386.m @@ -16,9 +16,9 @@ void test1(void) { extern id test1_helper(void); // CHECK: [[T0:%.*]] = call i8* @test1_helper() // CHECK-NEXT: call void asm sideeffect "mov - // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]]) + // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) // CHECK-NEXT: store i8* [[T1]], - // CHECK-NEXT: call void @objc_storeStrong( + // CHECK-NEXT: call void @llvm.objc.storeStrong( // CHECK-NEXT: ret void id x = test1_helper(); } diff --git a/test/CodeGenObjC/arc-linetable-autorelease.m b/test/CodeGenObjC/arc-linetable-autorelease.m index 6812e8a6de..0804b0700a 100644 --- a/test/CodeGenObjC/arc-linetable-autorelease.m +++ b/test/CodeGenObjC/arc-linetable-autorelease.m @@ -29,8 +29,8 @@ NSRect NSMakeRect(CGFloat x, CGFloat y, CGFloat w, CGFloat h); CGFloat pattern[2]; // CHECK: define {{.*}}_createBezierPathWithWidth // CHECK: load {{.*}} %path, align {{.*}}, !dbg ![[RET:[0-9]+]] - // CHECK: call void @objc_storeStrong{{.*}} !dbg ![[ARC:[0-9]+]] - // CHECK: call {{.*}} @objc_autoreleaseReturnValue{{.*}} !dbg ![[ARC]] + // CHECK: call void @llvm.objc.storeStrong{{.*}} !dbg ![[ARC:[0-9]+]] + // CHECK: call {{.*}} @llvm.objc.autoreleaseReturnValue{{.*}} !dbg ![[ARC]] // CHECK: ret {{.*}} !dbg ![[ARC]] // CHECK: ![[RET]] = !DILocation(line: [[@LINE+1]], scope: !{{.*}}) return path; diff --git a/test/CodeGenObjC/arc-linetable.m b/test/CodeGenObjC/arc-linetable.m index 531219d6d5..3883e0a3a9 100644 --- a/test/CodeGenObjC/arc-linetable.m +++ b/test/CodeGenObjC/arc-linetable.m @@ -3,8 +3,8 @@ // Legend: EXP = Return expression, RET = ret instruction // CHECK: define {{.*}}testNoSideEffect -// CHECK: call void @objc_storeStrong{{.*}} -// CHECK: call void @objc_storeStrong{{.*}} !dbg ![[RET1:[0-9]+]] +// CHECK: call void @llvm.objc.storeStrong{{.*}} +// CHECK: call void @llvm.objc.storeStrong{{.*}} !dbg ![[RET1:[0-9]+]] // CHECK: ret {{.*}} !dbg ![[RET1]] // CHECK: define {{.*}}testNoCleanup @@ -20,8 +20,8 @@ // CHECK: ret {{.*}} !dbg ![[RET4:[0-9]+]] // CHECK: define {{.*}}testVoid -// CHECK: call void @objc_storeStrong{{.*}} -// CHECK: call void @objc_storeStrong{{.*}} !dbg ![[RET5:[0-9]+]] +// CHECK: call void @llvm.objc.storeStrong{{.*}} +// CHECK: call void @llvm.objc.storeStrong{{.*}} !dbg ![[RET5:[0-9]+]] // CHECK: ret {{.*}} !dbg ![[RET5]] // CHECK: define {{.*}}testVoidNoReturn @@ -35,7 +35,7 @@ // CHECK: define {{.*}}testCleanupVoid // CHECK: icmp ne {{.*}}!dbg ![[SKIP1:[0-9]+]] // CHECK: store i32 0, i32* {{.*}}, !dbg ![[RET8:[0-9]+]] -// CHECK: @objc_storeStrong{{.*}}, !dbg ![[RET8]] +// CHECK: @llvm.objc.storeStrong{{.*}}, !dbg ![[RET8]] // CHECK: ret {{.*}} !dbg ![[RET8]] typedef signed char BOOL; diff --git a/test/CodeGenObjC/arc-literals.m b/test/CodeGenObjC/arc-literals.m index 74e231c765..3953787ea5 100644 --- a/test/CodeGenObjC/arc-literals.m +++ b/test/CodeGenObjC/arc-literals.m @@ -15,24 +15,24 @@ // CHECK-LABEL: define void @test_numeric() void test_numeric() { // CHECK: {{call.*objc_msgSend.*i32 17}} - // CHECK: call i8* @objc_retainAutoreleasedReturnValue + // CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue id ilit = @17; // CHECK: {{call.*objc_msgSend.*i32 25}} - // CHECK: call i8* @objc_retainAutoreleasedReturnValue + // CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue id ulit = @25u; // CHECK: {{call.*objc_msgSend.*i64 42}} - // CHECK: call i8* @objc_retainAutoreleasedReturnValue + // CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue id ulllit = @42ull; // CHECK: {{call.*objc_msgSend.*i8 signext 97}} - // CHECK: call i8* @objc_retainAutoreleasedReturnValue + // CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue id charlit = @'a'; - // CHECK: call void @objc_release + // CHECK: call void @llvm.objc.release // CHECK: call void @llvm.lifetime.end - // CHECK: call void @objc_release + // CHECK: call void @llvm.objc.release // CHECK: call void @llvm.lifetime.end - // CHECK: call void @objc_release + // CHECK: call void @llvm.objc.release // CHECK: call void @llvm.lifetime.end - // CHECK: call void @objc_release + // CHECK: call void @llvm.objc.release // CHECK: call void @llvm.lifetime.end // CHECK-NEXT: ret void } @@ -43,8 +43,8 @@ void test_array(id a, id b) { // CHECK: [[B:%.*]] = alloca i8*, // Retaining parameters - // CHECK: call i8* @objc_retain(i8* - // CHECK: call i8* @objc_retain(i8* + // CHECK: call i8* @llvm.objc.retain(i8* + // CHECK: call i8* @llvm.objc.retain(i8* // Constructing the array // CHECK: [[T0:%.*]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[OBJECTS:%[A-Za-z0-9]+]], i64 0, i64 0 @@ -59,13 +59,13 @@ void test_array(id a, id b) { // CHECK-NEXT: [[T1:%.*]] = bitcast [[CLASS_T]]* [[T0]] to i8* // CHECK-NEXT: [[T2:%.*]] = bitcast [2 x i8*]* [[OBJECTS]] to i8** // CHECK-NEXT: [[T3:%.*]] = call i8* bitcast ({{.*@objc_msgSend.*}})(i8* [[T1]], i8* [[SEL]], i8** [[T2]], i64 2) - // CHECK-NEXT: [[T4:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T3]]) + // CHECK-NEXT: [[T4:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T3]]) // CHECK: call void (...) @clang.arc.use(i8* [[V0]], i8* [[V1]]) id arr = @[a, b]; - // CHECK: call void @objc_release - // CHECK: call void @objc_release - // CHECK: call void @objc_release + // CHECK: call void @llvm.objc.release + // CHECK: call void @llvm.objc.release + // CHECK: call void @llvm.objc.release // CHECK-NEXT: ret void } @@ -77,10 +77,10 @@ void test_dictionary(id k1, id o1, id k2, id o2) { // CHECK: [[O2:%.*]] = alloca i8*, // Retaining parameters - // CHECK: call i8* @objc_retain(i8* - // CHECK: call i8* @objc_retain(i8* - // CHECK: call i8* @objc_retain(i8* - // CHECK: call i8* @objc_retain(i8* + // CHECK: call i8* @llvm.objc.retain(i8* + // CHECK: call i8* @llvm.objc.retain(i8* + // CHECK: call i8* @llvm.objc.retain(i8* + // CHECK: call i8* @llvm.objc.retain(i8* // Constructing the arrays // CHECK: [[T0:%.*]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[KEYS:%[A-Za-z0-9]+]], i64 0, i64 0 @@ -103,16 +103,16 @@ void test_dictionary(id k1, id o1, id k2, id o2) { // CHECK-NEXT: [[T2:%.*]] = bitcast [2 x i8*]* [[OBJECTS]] to i8** // CHECK-NEXT: [[T3:%.*]] = bitcast [2 x i8*]* [[KEYS]] to i8** // CHECK-NEXT: [[T4:%.*]] = call i8* bitcast ({{.*@objc_msgSend.*}})(i8* [[T1]], i8* [[SEL]], i8** [[T2]], i8** [[T3]], i64 2) - // CHECK-NEXT: [[T5:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T4]]) + // CHECK-NEXT: [[T5:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T4]]) // CHECK-NEXT: call void (...) @clang.arc.use(i8* [[V0]], i8* [[V1]], i8* [[V2]], i8* [[V3]]) id dict = @{ k1 : o1, k2 : o2 }; - // CHECK: call void @objc_release - // CHECK: call void @objc_release - // CHECK: call void @objc_release - // CHECK: call void @objc_release - // CHECK: call void @objc_release + // CHECK: call void @llvm.objc.release + // CHECK: call void @llvm.objc.release + // CHECK: call void @llvm.objc.release + // CHECK: call void @llvm.objc.release + // CHECK: call void @llvm.objc.release // CHECK-NEXT: ret void } @@ -126,7 +126,7 @@ void test_dictionary(id k1, id o1, id k2, id o2) { // CHECK-LABEL: define void @test_property void test_property(B *b) { // Retain parameter - // CHECK: call i8* @objc_retain + // CHECK: call i8* @llvm.objc.retain // CHECK: [[T0:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[OBJECTS:%.*]], i64 0, i64 0 @@ -135,7 +135,7 @@ void test_property(B *b) { // CHECK-NEXT: [[T1:%.*]] = bitcast // CHECK-NEXT: [[T2:%.*]] = call [[B:%.*]]* bitcast ({{.*}} @objc_msgSend to {{.*}})(i8* [[T1]], i8* [[SEL]]) // CHECK-NEXT: [[T3:%.*]] = bitcast [[B]]* [[T2]] to i8* - // CHECK-NEXT: [[T4:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T3]]) + // CHECK-NEXT: [[T4:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T3]]) // CHECK-NEXT: [[V0:%.*]] = bitcast i8* [[T4]] to [[B]]* // CHECK-NEXT: [[V1:%.*]] = bitcast [[B]]* [[V0]] to i8* @@ -148,7 +148,7 @@ void test_property(B *b) { // CHECK-NEXT: [[T1:%.*]] = bitcast [[CLASS_T]]* [[T0]] to i8* // CHECK-NEXT: [[T2:%.*]] = bitcast [1 x i8*]* [[OBJECTS]] to i8** // CHECK-NEXT: [[T3:%.*]] = call i8* bitcast ({{.*}} @objc_msgSend to {{.*}}(i8* [[T1]], i8* [[SEL]], i8** [[T2]], i64 1) - // CHECK-NEXT: call i8* @objc_retainAutoreleasedReturnValue(i8* [[T3]]) + // CHECK-NEXT: call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T3]]) // CHECK-NEXT: call void (...) @clang.arc.use(i8* [[V1]]) // CHECK-NEXT: bitcast // CHECK-NEXT: bitcast @@ -157,12 +157,12 @@ void test_property(B *b) { // Release b.prop // CHECK-NEXT: [[T0:%.*]] = bitcast [[B]]* [[V0]] to i8* - // CHECK-NEXT: call void @objc_release(i8* [[T0]]) + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) // Destroy arr - // CHECK: call void @objc_release + // CHECK: call void @llvm.objc.release // Destroy b - // CHECK: call void @objc_release + // CHECK: call void @llvm.objc.release // CHECK-NEXT: ret void } diff --git a/test/CodeGenObjC/arc-loadweakretained-release.m b/test/CodeGenObjC/arc-loadweakretained-release.m index 5392abdf8c..a35ee0187c 100644 --- a/test/CodeGenObjC/arc-loadweakretained-release.m +++ b/test/CodeGenObjC/arc-loadweakretained-release.m @@ -28,13 +28,13 @@ int main (int argc, const char * argv[]) { } } -// CHECK: [[SIXTEEN:%.*]] = call i8* @objc_loadWeakRetained(i8** {{%.*}}) +// CHECK: [[SIXTEEN:%.*]] = call i8* @llvm.objc.loadWeakRetained(i8** {{%.*}}) // CHECK-NEXT: [[SEVENTEEN:%.*]] = bitcast i8* [[SIXTEEN]] to {{%.*}} // CHECK-NEXT: [[EIGHTEEN:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_.6 // CHECK-NEXT: [[NINETEEN:%.*]] = bitcast %0* [[SEVENTEEN]] to i8* // CHECK-NEXT: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend // CHECK-NEXT: [[TWENTY:%.*]] = bitcast %0* [[SEVENTEEN]] to i8* -// CHECK-NEXT: call void @objc_release(i8* [[TWENTY]]) +// CHECK-NEXT: call void @llvm.objc.release(i8* [[TWENTY]]) void test1(int cond) { extern void test34_sink(id *); @@ -55,7 +55,7 @@ void test1(int cond) { // CHECK-NEXT: [[ICRARGUMENT:%.*]] = select i1 [[ICRISNULL]], i8** null, i8** [[INCRTEMP]] // CHECK-NEXT: store i1 false, i1* [[CONDCLEANUP]] // CHECK-NEXT: br i1 [[ICRISNULL]], label [[ICRCONT:%.*]], label [[ICRCOPY:%.*]] -// CHECK: [[ONE:%.*]] = call i8* @objc_loadWeakRetained( +// CHECK: [[ONE:%.*]] = call i8* @llvm.objc.loadWeakRetained( // CHECK-NEXT: store i8* [[ONE]], i8** [[CONDCLEANUPSAVE]] // CHECK-NEXT: store i1 true, i1* [[CONDCLEANUP]] // CHECK-NEXT: store i8* [[ONE]], i8** [[INCRTEMP]] @@ -65,13 +65,13 @@ void test1(int cond) { // CHECK-NEXT: [[ICRISNULL1:%.*]] = icmp eq i8** [[COND1]], null // CHECK-NEXT: br i1 [[ICRISNULL1]], label [[ICRDONE:%.*]], label [[ICRWRITEBACK:%.*]] // CHECK: [[TWO:%.*]] = load i8*, i8** [[INCRTEMP]] -// CHECK-NEXT: [[THREE:%.*]] = call i8* @objc_storeWeak( +// CHECK-NEXT: [[THREE:%.*]] = call i8* @llvm.objc.storeWeak( // CHECK-NEXT: br label [[ICRDONE]] // CHECK: [[CLEANUPISACTIVE:%.*]] = load i1, i1* [[CONDCLEANUP]] // CHECK-NEXT: br i1 [[CLEANUPISACTIVE]], label [[CLEASNUPACTION:%.*]], label [[CLEANUPDONE:%.*]] // CHECK: [[FOUR:%.*]] = load i8*, i8** [[CONDCLEANUPSAVE]] -// CHECK-NEXT: call void @objc_release(i8* [[FOUR]]) +// CHECK-NEXT: call void @llvm.objc.release(i8* [[FOUR]]) // CHECK-NEXT: br label -// CHECK: call void @objc_destroyWeak(i8** [[WEAK]]) +// CHECK: call void @llvm.objc.destroyWeak(i8** [[WEAK]]) // CHECK-NEXT: ret void diff --git a/test/CodeGenObjC/arc-no-runtime.m b/test/CodeGenObjC/arc-no-runtime.m index f5f5b90ea5..31f0ed8714 100644 --- a/test/CodeGenObjC/arc-no-runtime.m +++ b/test/CodeGenObjC/arc-no-runtime.m @@ -5,9 +5,9 @@ id make(void) __attribute__((ns_returns_retained)); void test0() { make(); id x = 0; - // CHECK: call void @objc_release( - // CHECK: call void @objc_storeStrong( + // CHECK: call void @llvm.objc.release( + // CHECK: call void @llvm.objc.storeStrong( } -// CHECK: declare extern_weak void @objc_release( -// CHECK: declare extern_weak void @objc_storeStrong( +// CHECK: declare extern_weak void @llvm.objc.release( +// CHECK: declare extern_weak void @llvm.objc.storeStrong( diff --git a/test/CodeGenObjC/arc-precise-lifetime.m b/test/CodeGenObjC/arc-precise-lifetime.m index a366c08bbb..4c563c5b84 100644 --- a/test/CodeGenObjC/arc-precise-lifetime.m +++ b/test/CodeGenObjC/arc-precise-lifetime.m @@ -14,11 +14,11 @@ void test0() { // CHECK-NEXT: [[T1:%.*]] = load i8*, i8** [[X]] // CHECK-NEXT: store i8* null, i8** [[X]] - // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW:#[0-9]+]] + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) [[NUW:#[0-9]+]] // CHECK-NOT: clang.imprecise_release // CHECK-NEXT: [[T1:%.*]] = load i8*, i8** [[X]] - // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW:#[0-9]+]] + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) [[NUW:#[0-9]+]] // CHECK-NOT: clang.imprecise_release // CHECK-NEXT: [[XPTR2:%.*]] = bitcast i8** [[X]] to i8* @@ -43,14 +43,14 @@ void test1a_message(void) { // CHECK: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PTRPTR1]]) // CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper() // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8* - // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]]) + // CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]]) // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]* // CHECK-NEXT: store [[TEST1]]* [[T3]] // CHECK-NEXT: [[CPTR1:%.*]] = bitcast i8** [[C]] to i8* // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[CPTR1]]) // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]** // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8* - // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutorelease(i8* [[T1]]) + // CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainAutorelease(i8* [[T1]]) // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]* // CHECK-NEXT: [[T4:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_ // CHECK-NEXT: [[T5:%.*]] = bitcast [[TEST1]]* [[T3]] to i8* @@ -60,7 +60,7 @@ void test1a_message(void) { // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[CPTR2]]) // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]** // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8* - // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW]], !clang.imprecise_release + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) [[NUW]], !clang.imprecise_release // CHECK-NEXT: [[PTRPTR2:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8* // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[PTRPTR2]]) // CHECK-NEXT: ret void @@ -77,14 +77,14 @@ void test1a_property(void) { // CHECK: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PTRPTR1]]) // CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper() // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8* - // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]]) + // CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]]) // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]* // CHECK-NEXT: store [[TEST1]]* [[T3]] // CHECK-NEXT: [[CPTR1:%.*]] = bitcast i8** [[C]] to i8* // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[CPTR1]]) // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]** // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8* - // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutorelease(i8* [[T1]]) + // CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainAutorelease(i8* [[T1]]) // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]* // CHECK-NEXT: [[T4:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_ // CHECK-NEXT: [[T5:%.*]] = bitcast [[TEST1]]* [[T3]] to i8* @@ -94,7 +94,7 @@ void test1a_property(void) { // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[CPTR2]]) // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]** // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8* - // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW]], !clang.imprecise_release + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) [[NUW]], !clang.imprecise_release // CHECK-NEXT: [[PTRPTR2:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8* // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[PTRPTR2]]) // CHECK-NEXT: ret void @@ -111,7 +111,7 @@ void test1b_message(void) { // CHECK: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PTRPTR1]]) // CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper() // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8* - // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]]) + // CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]]) // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]* // CHECK-NEXT: store [[TEST1]]* [[T3]] // CHECK-NEXT: [[CPTR1:%.*]] = bitcast i8** [[C]] to i8* @@ -125,7 +125,7 @@ void test1b_message(void) { // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[CPTR2]]) // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]** // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8* - // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW]] + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) [[NUW]] // CHECK-NOT: clang.imprecise_release // CHECK-NEXT: [[PTRPTR2:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8* // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[PTRPTR2]]) @@ -142,7 +142,7 @@ void test1b_property(void) { // CHECK: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PTRPTR1]]) // CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper() // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8* - // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]]) + // CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]]) // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]* // CHECK-NEXT: store [[TEST1]]* [[T3]] // CHECK-NEXT: [[CPTR1:%.*]] = bitcast i8** [[C]] to i8* @@ -156,7 +156,7 @@ void test1b_property(void) { // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[CPTR2]]) // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]** // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8* - // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW]] + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) [[NUW]] // CHECK-NOT: clang.imprecise_release // CHECK-NEXT: [[PTRPTR2:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8* // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[PTRPTR2]]) @@ -173,14 +173,14 @@ void test1c_message(void) { // CHECK: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PTRPTR1]]) // CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper() // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8* - // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]]) + // CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]]) // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]* // CHECK-NEXT: store [[TEST1]]* [[T3]] // CHECK-NEXT: [[PCPTR1:%.*]] = bitcast i8** [[PC]] to i8* // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PCPTR1]]) // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]** // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8* - // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutorelease(i8* [[T1]]) + // CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainAutorelease(i8* [[T1]]) // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]* // CHECK-NEXT: [[T4:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_ // CHECK-NEXT: [[T5:%.*]] = bitcast [[TEST1]]* [[T3]] to i8* @@ -190,7 +190,7 @@ void test1c_message(void) { // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[PCPTR2]]) // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]** // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8* - // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW]], !clang.imprecise_release + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) [[NUW]], !clang.imprecise_release // CHECK-NEXT: [[PTRPTR2:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8* // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[PTRPTR2]]) // CHECK-NEXT: ret void @@ -206,14 +206,14 @@ void test1c_property(void) { // CHECK: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PTRPTR1]]) // CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper() // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8* - // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]]) + // CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]]) // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]* // CHECK-NEXT: store [[TEST1]]* [[T3]] // CHECK-NEXT: [[PCPTR1:%.*]] = bitcast i8** [[PC]] to i8* // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PCPTR1]]) // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]** // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8* - // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutorelease(i8* [[T1]]) + // CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainAutorelease(i8* [[T1]]) // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]* // CHECK-NEXT: [[T4:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_ // CHECK-NEXT: [[T5:%.*]] = bitcast [[TEST1]]* [[T3]] to i8* @@ -223,7 +223,7 @@ void test1c_property(void) { // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[PCPTR2]]) // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]** // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8* - // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW]], !clang.imprecise_release + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) [[NUW]], !clang.imprecise_release // CHECK-NEXT: [[PTRPTR2:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8* // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[PTRPTR2]]) // CHECK-NEXT: ret void @@ -239,7 +239,7 @@ void test1d_message(void) { // CHECK: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PTRPTR1]]) // CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper() // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8* - // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]]) + // CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]]) // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]* // CHECK-NEXT: store [[TEST1]]* [[T3]] // CHECK-NEXT: [[PCPTR1:%.*]] = bitcast i8** [[PC]] to i8* @@ -253,7 +253,7 @@ void test1d_message(void) { // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[PCPTR2]]) // CHECK-NEXT: [[NINE:%.*]] = load [[TEST1]]*, [[TEST1]]** // CHECK-NEXT: [[TEN:%.*]] = bitcast [[TEST1]]* [[NINE]] to i8* - // CHECK-NEXT: call void @objc_release(i8* [[TEN]]) + // CHECK-NEXT: call void @llvm.objc.release(i8* [[TEN]]) // CHECK-NEXT: [[PTRPTR2:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8* // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[PTRPTR2]]) // CHECK-NEXT: ret void @@ -269,7 +269,7 @@ void test1d_property(void) { // CHECK: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PTRPTR1]]) // CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper() // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8* - // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]]) + // CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]]) // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]* // CHECK-NEXT: store [[TEST1]]* [[T3]] // CHECK-NEXT: [[PCPTR1:%.*]] = bitcast i8** [[PC]] to i8* @@ -283,7 +283,7 @@ void test1d_property(void) { // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[PCPTR2]]) // CHECK-NEXT: [[NINE:%.*]] = load [[TEST1]]*, [[TEST1]]** // CHECK-NEXT: [[TEN:%.*]] = bitcast [[TEST1]]* [[NINE]] to i8* - // CHECK-NEXT: call void @objc_release(i8* [[TEN]]) + // CHECK-NEXT: call void @llvm.objc.release(i8* [[TEN]]) // CHECK-NEXT: [[PTRPTR2:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8* // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[PTRPTR2]]) // CHECK-NEXT: ret void @@ -301,7 +301,7 @@ void test2(Test2 *x) { x->ivar = 0; // CHECK: [[X:%.*]] = alloca [[TEST2:%.*]]* // CHECK-NEXT: [[T0:%.*]] = bitcast [[TEST2]]* {{%.*}} to i8* - // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[T0]]) [[NUW]] + // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retain(i8* [[T0]]) [[NUW]] // CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[T1]] to [[TEST2]]* // CHECK-NEXT: store [[TEST2]]* [[T2]], [[TEST2]]** [[X]], @@ -312,12 +312,12 @@ void test2(Test2 *x) { // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to i8** // CHECK-NEXT: [[T4:%.*]] = load i8*, i8** [[T3]], // CHECK-NEXT: store i8* null, i8** [[T3]], - // CHECK-NEXT: call void @objc_release(i8* [[T4]]) [[NUW]] + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T4]]) [[NUW]] // CHECK-NOT: imprecise // CHECK-NEXT: [[T0:%.*]] = load [[TEST2]]*, [[TEST2]]** [[X]] // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST2]]* [[T0]] to i8* - // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW]], !clang.imprecise_release + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) [[NUW]], !clang.imprecise_release // CHECK-NEXT: ret void } @@ -325,11 +325,11 @@ void test2(Test2 *x) { // CHECK-LABEL: define void @test3(i8* void test3(PRECISE_LIFETIME id x) { // CHECK: [[X:%.*]] = alloca i8*, - // CHECK-NEXT: [[T0:%.*]] = call i8* @objc_retain(i8* {{%.*}}) [[NUW]] + // CHECK-NEXT: [[T0:%.*]] = call i8* @llvm.objc.retain(i8* {{%.*}}) [[NUW]] // CHECK-NEXT: store i8* [[T0]], i8** [[X]], // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[X]] - // CHECK-NEXT: call void @objc_release(i8* [[T0]]) [[NUW]] + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) [[NUW]] // CHECK-NOT: imprecise_release // CHECK-NEXT: ret void diff --git a/test/CodeGenObjC/arc-property.m b/test/CodeGenObjC/arc-property.m index edc4d1e853..b417f9505e 100644 --- a/test/CodeGenObjC/arc-property.m +++ b/test/CodeGenObjC/arc-property.m @@ -8,11 +8,11 @@ void test0(Test0 *t0, id value) { t0.value = value; } // CHECK-LABEL: define void @test0( -// CHECK: call void @objc_storeStrong -// CHECK: call void @objc_storeStrong +// CHECK: call void @llvm.objc.storeStrong +// CHECK: call void @llvm.objc.storeStrong // CHECK: @objc_msgSend -// CHECK: call void @objc_storeStrong( -// CHECK: call void @objc_storeStrong( +// CHECK: call void @llvm.objc.storeStrong( +// CHECK: call void @llvm.objc.storeStrong( struct S1 { Class isa; }; @interface Test1 @@ -62,7 +62,7 @@ static Class theGlobalClass; // CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST2]]* [[T1]] to i8* // CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8, i8* [[T2]], i64 [[OFFSET]] // CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to i8** -// CHECK-NEXT: call void @objc_storeStrong(i8** [[T4]], i8* [[T0]]) [[NUW:#[0-9]+]] +// CHECK-NEXT: call void @llvm.objc.storeStrong(i8** [[T4]], i8* [[T0]]) [[NUW:#[0-9]+]] // CHECK-NEXT: ret void // CHECK: define internal i8* @"\01-[Test2 theClass]"( @@ -83,7 +83,7 @@ static Class theGlobalClass; // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST2]]* [[T0]] to i8* // CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds i8, i8* [[T1]], i64 [[OFFSET]] // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to i8** -// CHECK-NEXT: call void @objc_storeStrong(i8** [[T3]], i8* null) [[NUW]] +// CHECK-NEXT: call void @llvm.objc.storeStrong(i8** [[T3]], i8* null) [[NUW]] // CHECK-NEXT: ret void // rdar://13115896 @@ -112,11 +112,11 @@ void test3(Test3 *t) { // CHECK-NEXT: [[T2:%.*]] = call i8* bitcast ({{.*}} @objc_msgSend to {{.*}})(i8* [[T1]], i8* [[SEL]]) // CHECK-NEXT: [[T3:%.*]] = load i8*, i8** [[X]], // CHECK-NEXT: store i8* [[T2]], i8** [[X]], -// CHECK-NEXT: call void @objc_release(i8* [[T3]]) +// CHECK-NEXT: call void @llvm.objc.release(i8* [[T3]]) // Epilogue. -// CHECK-NEXT: call void @objc_storeStrong(i8** [[X]], i8* null) +// CHECK-NEXT: call void @llvm.objc.storeStrong(i8** [[X]], i8* null) // CHECK-NEXT: [[T0:%.*]] = bitcast [[TEST3]]** [[T]] to i8** -// CHECK-NEXT: call void @objc_storeStrong(i8** [[T0]], i8* null) +// CHECK-NEXT: call void @llvm.objc.storeStrong(i8** [[T0]], i8* null) // CHECK-NEXT: ret void @implementation Test3 @@ -126,7 +126,7 @@ void test3(Test3 *t) { } // CHECK: define internal i8* @"\01-[Test3 copyMachine]"( // CHECK: [[T0:%.*]] = call i8* @test3_helper() -// CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]]) +// CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) // CHECK-NEXT: ret i8* [[T1]] - (void) setCopyMachine: (id) x {} @end diff --git a/test/CodeGenObjC/arc-related-result-type.m b/test/CodeGenObjC/arc-related-result-type.m index 02d380368b..ac69e0d9f6 100644 --- a/test/CodeGenObjC/arc-related-result-type.m +++ b/test/CodeGenObjC/arc-related-result-type.m @@ -12,17 +12,17 @@ void test0(Test0 *val) { // CHECK-NEXT: store [[TEST0]]* null // CHECK-NEXT: bitcast // CHECK-NEXT: bitcast -// CHECK-NEXT: call void @objc_storeStrong( +// CHECK-NEXT: call void @llvm.objc.storeStrong( // CHECK-NEXT: load [[TEST0]]*, [[TEST0]]** [[VAL]], // CHECK-NEXT: load // CHECK-NEXT: bitcast // CHECK-NEXT: [[T0:%.*]] = call i8* bitcast ( -// CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]]) +// CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) // CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[T1]] to [[TEST0]]* // CHECK-NEXT: store [[TEST0]]* [[T2]], [[TEST0]]** [[X]] // CHECK-NEXT: [[T0:%.*]] = bitcast [[TEST0]]** [[X]] to i8** -// CHECK-NEXT: call void @objc_storeStrong(i8** [[T0]], i8* null) +// CHECK-NEXT: call void @llvm.objc.storeStrong(i8** [[T0]], i8* null) // CHECK-NEXT: [[T0:%.*]] = bitcast [[TEST0]]** [[VAL]] to i8** -// CHECK-NEXT: call void @objc_storeStrong(i8** [[T0]], i8* null) +// CHECK-NEXT: call void @llvm.objc.storeStrong(i8** [[T0]], i8* null) // CHECK-NEXT: ret void } diff --git a/test/CodeGenObjC/arc-ternary-op.m b/test/CodeGenObjC/arc-ternary-op.m index 3488d2c538..91ba6c4505 100644 --- a/test/CodeGenObjC/arc-ternary-op.m +++ b/test/CodeGenObjC/arc-ternary-op.m @@ -22,15 +22,15 @@ void test0(_Bool cond) { // CHECK-NEXT: store i1 true, i1* [[RELCOND]] // CHECK-NEXT: br label // CHECK: [[T0:%.*]] = phi i8* [ null, {{%.*}} ], [ [[CALL]], {{%.*}} ] - // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[T0]]) [[NUW:#[0-9]+]] + // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retain(i8* [[T0]]) [[NUW:#[0-9]+]] // CHECK-NEXT: store i8* [[T1]], i8** [[X]], // CHECK-NEXT: [[REL:%.*]] = load i1, i1* [[RELCOND]] // CHECK-NEXT: br i1 [[REL]], // CHECK: [[T0:%.*]] = load i8*, i8** [[RELVAL]] - // CHECK-NEXT: call void @objc_release(i8* [[T0]]) [[NUW]] + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) [[NUW]] // CHECK-NEXT: br label // CHECK: [[T0:%.*]] = load i8*, i8** [[X]] - // CHECK-NEXT: call void @objc_release(i8* [[T0]]) [[NUW]] + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) [[NUW]] // CHECK-NEXT: [[XPTR2:%.*]] = bitcast i8** [[X]] to i8* // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[XPTR2]]) // CHECK-NEXT: ret void @@ -58,7 +58,7 @@ void test1(int cond) { // CHECK-NEXT: store i8* null, i8** [[STRONG]] // CHECK-NEXT: [[WEAKPTR1:%.*]] = bitcast i8** [[WEAK]] to i8* // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[WEAKPTR1]]) - // CHECK-NEXT: call i8* @objc_initWeak(i8** [[WEAK]], i8* null) + // CHECK-NEXT: call i8* @llvm.objc.initWeak(i8** [[WEAK]], i8* null) // CHECK-NEXT: [[T0:%.*]] = load i32, i32* [[COND]] // CHECK-NEXT: [[T1:%.*]] = icmp ne i32 [[T0]], 0 @@ -74,11 +74,11 @@ void test1(int cond) { // CHECK-NEXT: [[T0:%.*]] = icmp eq i8** [[ARG]], null // CHECK-NEXT: br i1 [[T0]], // CHECK: [[T0:%.*]] = load i8*, i8** [[TEMP1]] - // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[T0]]) + // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retain(i8* [[T0]]) // CHECK-NEXT: call void (...) @clang.arc.use(i8* [[W]]) [[NUW]] // CHECK-NEXT: [[T2:%.*]] = load i8*, i8** [[ARG]] // CHECK-NEXT: store i8* [[T1]], i8** [[ARG]] - // CHECK-NEXT: call void @objc_release(i8* [[T2]]) + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T2]]) // CHECK-NEXT: br label // CHECK: [[T0:%.*]] = load i32, i32* [[COND]] @@ -88,7 +88,7 @@ void test1(int cond) { // CHECK-NEXT: [[T1:%.*]] = select i1 [[T0]], i8** null, i8** [[TEMP2]] // CHECK-NEXT: store i1 false, i1* [[CONDCLEANUP]] // CHECK-NEXT: br i1 [[T0]], - // CHECK: [[T0:%.*]] = call i8* @objc_loadWeakRetained(i8** [[ARG]]) + // CHECK: [[T0:%.*]] = call i8* @llvm.objc.loadWeakRetained(i8** [[ARG]]) // CHECK-NEXT: store i8* [[T0]], i8** [[CONDCLEANUPSAVE]] // CHECK-NEXT: store i1 true, i1* [[CONDCLEANUP]] // CHECK-NEXT: store i8* [[T0]], i8** [[TEMP2]] @@ -97,10 +97,10 @@ void test1(int cond) { // CHECK-NEXT: [[T0:%.*]] = icmp eq i8** [[ARG]], null // CHECK-NEXT: br i1 [[T0]], // CHECK: [[T0:%.*]] = load i8*, i8** [[TEMP2]] - // CHECK-NEXT: call i8* @objc_storeWeak(i8** [[ARG]], i8* [[T0]]) + // CHECK-NEXT: call i8* @llvm.objc.storeWeak(i8** [[ARG]], i8* [[T0]]) // CHECK-NEXT: br label - // CHECK: call void @objc_destroyWeak(i8** [[WEAK]]) + // CHECK: call void @llvm.objc.destroyWeak(i8** [[WEAK]]) // CHECK: [[WEAKPTR2:%.*]] = bitcast i8** [[WEAK]] to i8* // CHECK: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[WEAKPTR2]]) // CHECK: [[STRONGPTR2:%.*]] = bitcast i8** [[STRONG]] to i8* @@ -130,21 +130,21 @@ void test2(int cond) { // CHECK-NEXT: br i1 // Within true branch, cleanup enabled. // CHECK: [[T0:%.*]] = call i8* @test2_producer() - // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]]) + // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) // CHECK-NEXT: store i8* [[T1]], i8** [[CLEANUP_SAVE]] // CHECK-NEXT: store i1 true, i1* [[RUN_CLEANUP]] // CHECK-NEXT: br label // Join point for conditional operator; retain immediately. // CHECK: [[T0:%.*]] = phi i8* [ [[T1]], {{%.*}} ], [ null, {{%.*}} ] - // CHECK-NEXT: [[RESULT:%.*]] = call i8* @objc_retain(i8* [[T0]]) + // CHECK-NEXT: [[RESULT:%.*]] = call i8* @llvm.objc.retain(i8* [[T0]]) // Leaving full-expression; run conditional cleanup. // CHECK-NEXT: [[T0:%.*]] = load i1, i1* [[RUN_CLEANUP]] // CHECK-NEXT: br i1 [[T0]] // CHECK: [[T0:%.*]] = load i8*, i8** [[CLEANUP_SAVE]] - // CHECK-NEXT: call void @objc_release(i8* [[T0]]) + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) // CHECK-NEXT: br label // And way down at the end of the loop: - // CHECK: call void @objc_release(i8* [[RESULT]]) + // CHECK: call void @llvm.objc.release(i8* [[RESULT]]) } // CHECK: attributes [[NUW]] = { nounwind } diff --git a/test/CodeGenObjC/arc-unbridged-cast.m b/test/CodeGenObjC/arc-unbridged-cast.m index 5ab5d02fff..72b7b01bb7 100644 --- a/test/CodeGenObjC/arc-unbridged-cast.m +++ b/test/CodeGenObjC/arc-unbridged-cast.m @@ -32,4 +32,4 @@ id MMM() return 0; } -// CHECK-NOT: call i8* @objc_retainAutoreleasedReturnValue +// CHECK-NOT: call i8* @llvm.objc.retainAutoreleasedReturnValue diff --git a/test/CodeGenObjC/arc-unopt.m b/test/CodeGenObjC/arc-unopt.m index f80514d6e4..4354cb61c4 100644 --- a/test/CodeGenObjC/arc-unopt.m +++ b/test/CodeGenObjC/arc-unopt.m @@ -9,7 +9,7 @@ Test0 *test0(void) { // CHECK: [[LD:%.*]] = load [[TEST0:%.*]]*, [[TEST0:%.*]]** @test0_helper // CHECK-NEXT: [[T0:%.*]] = bitcast [[TEST0]]* [[LD]] to i8* - // CHECK-NEXT: [[T1:%.*]] = tail call i8* @objc_retainAutoreleaseReturnValue(i8* [[T0]]) + // CHECK-NEXT: [[T1:%.*]] = tail call i8* @llvm.objc.retainAutoreleaseReturnValue(i8* [[T0]]) // CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[T1]] to [[TEST0]]* // CHECK-NEXT: ret [[TEST0]]* [[T2]] } @@ -19,14 +19,14 @@ id test1(void) { return test1_helper; // CHECK: [[LD:%.*]] = load i8*, i8** @test1_helper - // CHECK-NEXT: [[T0:%.*]] = tail call i8* @objc_retainAutoreleaseReturnValue(i8* [[LD]]) + // CHECK-NEXT: [[T0:%.*]] = tail call i8* @llvm.objc.retainAutoreleaseReturnValue(i8* [[LD]]) // CHECK-NEXT: ret i8* [[T0]] } void test2(void) { // CHECK: [[X:%.*]] = alloca i8* // CHECK-NEXT: store i8* null, i8** [[X]] - // CHECK-NEXT: call void @objc_destroyWeak(i8** [[X]]) + // CHECK-NEXT: call void @llvm.objc.destroyWeak(i8** [[X]]) // CHECK-NEXT: ret void __weak id x; } @@ -63,7 +63,7 @@ void test5(void) { // CHECK-NEXT: [[T0:%.*]] = load [[TEST5]]*, [[TEST5]]** [[Y]], // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST5]]** [[X]] to i8** // CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST5]]* [[T0]] to i8* -// CHECK-NEXT: call void @objc_storeStrong(i8** [[T1]], i8* [[T2]]) +// CHECK-NEXT: call void @llvm.objc.storeStrong(i8** [[T1]], i8* [[T2]]) // CHECK-NEXT: [[T3:%.*]] = icmp ne [[TEST5]]* [[T0]], null // CHECK-NEXT: br i1 [[T3]], } diff --git a/test/CodeGenObjC/arc-unoptimized-byref-var.m b/test/CodeGenObjC/arc-unoptimized-byref-var.m index ffc73a44d4..bd57335d6e 100644 --- a/test/CodeGenObjC/arc-unoptimized-byref-var.m +++ b/test/CodeGenObjC/arc-unoptimized-byref-var.m @@ -9,8 +9,8 @@ void test19() { // CHECK-UNOPT: [[X2:%.*]] = getelementptr inbounds [[BYREF_T:%.*]], [[BYREF_T:%.*]]* [[VAR1:%.*]], i32 0, i32 6 // CHECK-UNOPT-NEXT: [[SIX:%.*]] = load i8*, i8** [[X2]], align 8 // CHECK-UNOPT-NEXT: store i8* null, i8** [[X]], align 8 -// CHECK-UNOPT-NEXT: call void @objc_storeStrong(i8** [[X]], i8* [[SIX]]) [[NUW:#[0-9]+]] -// CHECK-UNOPT-NEXT: call void @objc_storeStrong(i8** [[X2]], i8* null) [[NUW]] +// CHECK-UNOPT-NEXT: call void @llvm.objc.storeStrong(i8** [[X]], i8* [[SIX]]) [[NUW:#[0-9]+]] +// CHECK-UNOPT-NEXT: call void @llvm.objc.storeStrong(i8** [[X2]], i8* null) [[NUW]] // CHECK-UNOPT-NEXT: ret void } diff --git a/test/CodeGenObjC/arc-unsafeclaim.m b/test/CodeGenObjC/arc-unsafeclaim.m index 01329df0f7..fd063bfccf 100644 --- a/test/CodeGenObjC/arc-unsafeclaim.m +++ b/test/CodeGenObjC/arc-unsafeclaim.m @@ -29,7 +29,7 @@ void test_assign() { // CHECK: [[T0:%.*]] = call [[A:.*]]* @makeA() // CHECK-MARKED-NEXT: call void asm sideeffect // CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8* -// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_unsafeClaimAutoreleasedReturnValue(i8* [[T1]]) +// CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.unsafeClaimAutoreleasedReturnValue(i8* [[T1]]) // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[A]]* // CHECK-NEXT: [[T4:%.*]] = bitcast [[A]]* [[T3]] to i8* // CHECK-NEXT: store i8* [[T4]], i8** [[X]] @@ -41,7 +41,7 @@ void test_assign() { // DISABLED: [[T0:%.*]] = call [[A:.*]]* @makeA() // DISABLED-MARKED-NEXT: call void asm sideeffect // DISABLED-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8* -// DISABLED-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]]) +// DISABLED-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]]) void test_assign_assign() { __unsafe_unretained id x, y; @@ -53,7 +53,7 @@ void test_assign_assign() { // CHECK: [[T0:%.*]] = call [[A]]* @makeA() // CHECK-MARKED-NEXT: call void asm sideeffect // CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8* -// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_unsafeClaimAutoreleasedReturnValue(i8* [[T1]]) +// CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.unsafeClaimAutoreleasedReturnValue(i8* [[T1]]) // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[A]]* // CHECK-NEXT: [[T4:%.*]] = bitcast [[A]]* [[T3]] to i8* // CHECK-NEXT: store i8* [[T4]], i8** [[Y]] @@ -75,18 +75,18 @@ void test_strong_assign_assign() { // CHECK: [[T0:%.*]] = call [[A]]* @makeA() // CHECK-MARKED-NEXT: call void asm sideeffect // CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8* -// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]]) +// CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]]) // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[A]]* // CHECK-NEXT: [[T4:%.*]] = bitcast [[A]]* [[T3]] to i8* // CHECK-NEXT: store i8* [[T4]], i8** [[Y]] // CHECK-NEXT: [[OLD:%.*]] = load i8*, i8** [[X]] // CHECK-NEXT: store i8* [[T4]], i8** [[X]] -// CHECK-NEXT: call void @objc_release(i8* [[OLD]] +// CHECK-NEXT: call void @llvm.objc.release(i8* [[OLD]] // CHECK-OPTIMIZED-NEXT: bitcast // CHECK-OPTIMIZED-NEXT: lifetime.end -// CHECK-UNOPTIMIZED-NEXT: call void @objc_storeStrong(i8** [[X]], i8* null) +// CHECK-UNOPTIMIZED-NEXT: call void @llvm.objc.storeStrong(i8** [[X]], i8* null) // CHECK-OPTIMIZED-NEXT: [[T0:%.*]] = load i8*, i8** [[X]] -// CHECK-OPTIMIZED-NEXT: call void @objc_release(i8* [[T0]]) +// CHECK-OPTIMIZED-NEXT: call void @llvm.objc.release(i8* [[T0]]) // CHECK-OPTIMIZED-NEXT: bitcast // CHECK-OPTIMIZED-NEXT: lifetime.end // CHECK-NEXT: ret void @@ -102,16 +102,16 @@ void test_assign_strong_assign() { // CHECK: [[T0:%.*]] = call [[A]]* @makeA() // CHECK-MARKED-NEXT: call void asm sideeffect // CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8* -// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]]) +// CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]]) // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[A]]* // CHECK-NEXT: [[T4:%.*]] = bitcast [[A]]* [[T3]] to i8* // CHECK-NEXT: [[OLD:%.*]] = load i8*, i8** [[Y]] // CHECK-NEXT: store i8* [[T4]], i8** [[Y]] -// CHECK-NEXT: call void @objc_release(i8* [[OLD]] +// CHECK-NEXT: call void @llvm.objc.release(i8* [[OLD]] // CHECK-NEXT: store i8* [[T4]], i8** [[X]] -// CHECK-UNOPTIMIZED-NEXT: call void @objc_storeStrong(i8** [[Y]], i8* null) +// CHECK-UNOPTIMIZED-NEXT: call void @llvm.objc.storeStrong(i8** [[Y]], i8* null) // CHECK-OPTIMIZED-NEXT: [[T0:%.*]] = load i8*, i8** [[Y]] -// CHECK-OPTIMIZED-NEXT: call void @objc_release(i8* [[T0]]) +// CHECK-OPTIMIZED-NEXT: call void @llvm.objc.release(i8* [[T0]]) // CHECK-OPTIMIZED-NEXT: bitcast // CHECK-OPTIMIZED-NEXT: lifetime.end // CHECK-OPTIMIZED-NEXT: bitcast @@ -126,7 +126,7 @@ void test_init() { // CHECK: [[T0:%.*]] = call [[A]]* @makeA() // CHECK-MARKED-NEXT: call void asm sideeffect // CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8* -// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_unsafeClaimAutoreleasedReturnValue(i8* [[T1]]) +// CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.unsafeClaimAutoreleasedReturnValue(i8* [[T1]]) // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[A]]* // CHECK-NEXT: [[T4:%.*]] = bitcast [[A]]* [[T3]] to i8* // CHECK-NEXT: store i8* [[T4]], i8** [[X]] @@ -144,7 +144,7 @@ void test_init_assignment() { // CHECK: [[T0:%.*]] = call [[A]]* @makeA() // CHECK-MARKED-NEXT: call void asm sideeffect // CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8* -// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_unsafeClaimAutoreleasedReturnValue(i8* [[T1]]) +// CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.unsafeClaimAutoreleasedReturnValue(i8* [[T1]]) // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[A]]* // CHECK-NEXT: [[T4:%.*]] = bitcast [[A]]* [[T3]] to i8* // CHECK-NEXT: store i8* [[T4]], i8** [[X]] @@ -165,14 +165,14 @@ void test_strong_init_assignment() { // CHECK: [[T0:%.*]] = call [[A]]* @makeA() // CHECK-MARKED-NEXT: call void asm sideeffect // CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8* -// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]]) +// CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]]) // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[A]]* // CHECK-NEXT: [[T4:%.*]] = bitcast [[A]]* [[T3]] to i8* // CHECK-NEXT: store i8* [[T4]], i8** [[X]] // CHECK-NEXT: store i8* [[T4]], i8** [[Y]] -// CHECK-UNOPTIMIZED-NEXT: call void @objc_storeStrong(i8** [[Y]], i8* null) +// CHECK-UNOPTIMIZED-NEXT: call void @llvm.objc.storeStrong(i8** [[Y]], i8* null) // CHECK-OPTIMIZED-NEXT: [[T0:%.*]] = load i8*, i8** [[Y]] -// CHECK-OPTIMIZED-NEXT: call void @objc_release(i8* [[T0]]) +// CHECK-OPTIMIZED-NEXT: call void @llvm.objc.release(i8* [[T0]]) // CHECK-OPTIMIZED-NEXT: bitcast // CHECK-OPTIMIZED-NEXT: lifetime.end // CHECK-OPTIMIZED-NEXT: bitcast @@ -189,18 +189,18 @@ void test_init_strong_assignment() { // CHECK: [[T0:%.*]] = call [[A]]* @makeA() // CHECK-MARKED-NEXT: call void asm sideeffect // CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8* -// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]]) +// CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]]) // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[A]]* // CHECK-NEXT: [[T4:%.*]] = bitcast [[A]]* [[T3]] to i8* // CHECK-NEXT: [[OLD:%.*]] = load i8*, i8** [[X]] // CHECK-NEXT: store i8* [[T4]], i8** [[X]] -// CHECK-NEXT: call void @objc_release(i8* [[OLD]]) +// CHECK-NEXT: call void @llvm.objc.release(i8* [[OLD]]) // CHECK-NEXT: store i8* [[T4]], i8** [[Y]] // CHECK-OPTIMIZED-NEXT: bitcast // CHECK-OPTIMIZED-NEXT: lifetime.end -// CHECK-UNOPTIMIZED-NEXT: call void @objc_storeStrong(i8** [[X]], i8* null) +// CHECK-UNOPTIMIZED-NEXT: call void @llvm.objc.storeStrong(i8** [[X]], i8* null) // CHECK-OPTIMIZED-NEXT: [[T0:%.*]] = load i8*, i8** [[X]] -// CHECK-OPTIMIZED-NEXT: call void @objc_release(i8* [[T0]]) +// CHECK-OPTIMIZED-NEXT: call void @llvm.objc.release(i8* [[T0]]) // CHECK-OPTIMIZED-NEXT: bitcast // CHECK-OPTIMIZED-NEXT: lifetime.end // CHECK-NEXT: ret void @@ -212,7 +212,7 @@ void test_ignored() { // CHECK: [[T0:%.*]] = call [[A]]* @makeA() // CHECK-MARKED-NEXT: call void asm sideeffect // CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8* -// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_unsafeClaimAutoreleasedReturnValue(i8* [[T1]]) +// CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.unsafeClaimAutoreleasedReturnValue(i8* [[T1]]) // CHECK-NEXT: bitcast i8* [[T2]] to [[A]]* // CHECK-NEXT: ret void @@ -223,7 +223,7 @@ void test_cast_to_void() { // CHECK: [[T0:%.*]] = call [[A]]* @makeA() // CHECK-MARKED-NEXT: call void asm sideeffect // CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8* -// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_unsafeClaimAutoreleasedReturnValue(i8* [[T1]]) +// CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.unsafeClaimAutoreleasedReturnValue(i8* [[T1]]) // CHECK-NEXT: bitcast i8* [[T2]] to [[A]]* // CHECK-NEXT: ret void diff --git a/test/CodeGenObjC/arc-weak-property.m b/test/CodeGenObjC/arc-weak-property.m index d04032bc0d..8b50a0c209 100644 --- a/test/CodeGenObjC/arc-weak-property.m +++ b/test/CodeGenObjC/arc-weak-property.m @@ -21,8 +21,8 @@ // CHECK-NEXT: [[T2:%.*]] = bitcast [[WPT]]* [[T0]] to i8* // CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8, i8* [[T2]], i64 [[T1]] // CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to i8** -// CHECK-NEXT: [[T5:%.*]] = call i8* @objc_loadWeakRetained(i8** [[T4]]) -// CHECK-NEXT: [[T6:%.*]] = tail call i8* @objc_autoreleaseReturnValue(i8* [[T5]]) +// CHECK-NEXT: [[T5:%.*]] = call i8* @llvm.objc.loadWeakRetained(i8** [[T4]]) +// CHECK-NEXT: [[T6:%.*]] = tail call i8* @llvm.objc.autoreleaseReturnValue(i8* [[T5]]) // CHECK-NEXT: ret i8* [[T6]] // CHECK: define internal void @"\01-[WeakPropertyTest setPROP:]" @@ -38,7 +38,7 @@ // CHECK-NEXT: [[T2:%.*]] = bitcast [[WPT]]* [[T0]] to i8* // CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8, i8* [[T2]], i64 [[T1]] // CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to i8** -// CHECK-NEXT: call i8* @objc_storeWeak(i8** [[T4]], i8* [[V]]) +// CHECK-NEXT: call i8* @llvm.objc.storeWeak(i8** [[T4]], i8* [[V]]) // CHECK-NEXT: ret void // CHECK: define internal void @"\01-[WeakPropertyTest .cxx_destruct]" @@ -51,5 +51,5 @@ // CHECK-NEXT: [[T2:%.*]] = bitcast [[WPT]]* [[T0]] to i8* // CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8, i8* [[T2]], i64 [[T1]] // CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to i8** -// CHECK-NEXT: call void @objc_destroyWeak(i8** [[T4]]) +// CHECK-NEXT: call void @llvm.objc.destroyWeak(i8** [[T4]]) // CHECK-NEXT: ret void diff --git a/test/CodeGenObjC/arc-weak.m b/test/CodeGenObjC/arc-weak.m index 59f8d1d693..a976402f54 100644 --- a/test/CodeGenObjC/arc-weak.m +++ b/test/CodeGenObjC/arc-weak.m @@ -15,6 +15,6 @@ void test0(__weak B **src) { // CHECK-NEXT: [[T1:%.*]] = bitcast [[B]]** [[T0]] to [[A]]** // CHECK-NEXT: [[T2:%.*]] = bitcast [[A]]** [[DEST]] to i8** // CHECK-NEXT: [[T3:%.*]] = bitcast [[A]]** [[T1]] to i8** -// CHECK-NEXT: call void @objc_copyWeak(i8** [[T2]], i8** [[T3]]) +// CHECK-NEXT: call void @llvm.objc.copyWeak(i8** [[T2]], i8** [[T3]]) // CHECK-NEXT: [[T0:%.*]] = bitcast [[A]]** [[DEST]] to i8** -// CHECK: call void @objc_destroyWeak(i8** [[T0]]) +// CHECK: call void @llvm.objc.destroyWeak(i8** [[T0]]) diff --git a/test/CodeGenObjC/arc-with-atthrow.m b/test/CodeGenObjC/arc-with-atthrow.m index e5295159ce..93fa228c8b 100644 --- a/test/CodeGenObjC/arc-with-atthrow.m +++ b/test/CodeGenObjC/arc-with-atthrow.m @@ -11,8 +11,8 @@ void test() { // CHECK-LABEL: define void @test() // CHECK: [[T0:%.*]] = call i8* @make() -// CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]]) -// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_autorelease(i8* [[T1]]) +// CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) +// CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.autorelease(i8* [[T1]]) // CHECK-NEXT: call void @objc_exception_throw(i8* [[T2]]) [[NR:#[0-9]+]] // CHECK-NEXT: unreachable diff --git a/test/CodeGenObjC/arc.ll b/test/CodeGenObjC/arc.ll index caafcff052..f23c656c34 100644 --- a/test/CodeGenObjC/arc.ll +++ b/test/CodeGenObjC/arc.ll @@ -2,8 +2,8 @@ target triple = "x86_64-apple-darwin10" -declare i8* @objc_retain(i8*) -declare void @objc_release(i8*) +declare i8* @llvm.objc.retain(i8*) +declare void @llvm.objc.release(i8*) ; CHECK-LABEL: define void @test( ; CHECK-NOT: @objc_ @@ -13,15 +13,15 @@ entry: br label %loop loop: - call i8* @objc_retain(i8* %x) + call i8* @llvm.objc.retain(i8* %x) %q = load i1, i1* %p br i1 %q, label %loop.more, label %exit loop.more: - call void @objc_release(i8* %x) + call void @llvm.objc.release(i8* %x) br label %loop exit: - call void @objc_release(i8* %x) + call void @llvm.objc.release(i8* %x) ret void } diff --git a/test/CodeGenObjC/arc.m b/test/CodeGenObjC/arc.m index 3243952a36..fec6da56bd 100644 --- a/test/CodeGenObjC/arc.m +++ b/test/CodeGenObjC/arc.m @@ -6,39 +6,39 @@ // RUN: %clang_cc1 -fobjc-runtime=macosx-10.6.0 -triple x86_64-apple-darwin10 -Wno-objc-root-class -Wno-incompatible-pointer-types -Wno-arc-unsafe-retained-assign -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -o - %s | FileCheck -check-prefix=ARC-ALIEN %s // RUN: %clang_cc1 -fobjc-runtime=macosx-10.7.0 -triple x86_64-apple-darwin11 -Wno-objc-root-class -Wno-incompatible-pointer-types -Wno-arc-unsafe-retained-assign -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -o - %s | FileCheck -check-prefix=ARC-NATIVE %s -// ARC-ALIEN: declare extern_weak void @objc_storeStrong(i8**, i8*) -// ARC-ALIEN: declare extern_weak i8* @objc_retain(i8*) -// ARC-ALIEN: declare extern_weak i8* @objc_autoreleaseReturnValue(i8*) +// ARC-ALIEN: declare extern_weak void @llvm.objc.storeStrong(i8**, i8*) +// ARC-ALIEN: declare extern_weak i8* @llvm.objc.retain(i8*) +// ARC-ALIEN: declare extern_weak i8* @llvm.objc.autoreleaseReturnValue(i8*) // ARC-ALIEN: declare i8* @objc_msgSend(i8*, i8*, ...) [[NLB:#[0-9]+]] -// ARC-ALIEN: declare extern_weak void @objc_release(i8*) -// ARC-ALIEN: declare extern_weak i8* @objc_retainAutoreleasedReturnValue(i8*) -// ARC-ALIEN: declare extern_weak i8* @objc_initWeak(i8**, i8*) -// ARC-ALIEN: declare extern_weak i8* @objc_storeWeak(i8**, i8*) -// ARC-ALIEN: declare extern_weak i8* @objc_loadWeakRetained(i8**) -// ARC-ALIEN: declare extern_weak void @objc_destroyWeak(i8**) -// ARC-ALIEN: declare extern_weak i8* @objc_autorelease(i8*) -// ARC-ALIEN: declare extern_weak i8* @objc_retainAutorelease(i8*) - -// ARC-NATIVE: declare void @objc_storeStrong(i8**, i8*) -// ARC-NATIVE: declare i8* @objc_retain(i8*) [[NLB:#[0-9]+]] -// ARC-NATIVE: declare i8* @objc_autoreleaseReturnValue(i8*) -// ARC-NATIVE: declare i8* @objc_msgSend(i8*, i8*, ...) [[NLB]] -// ARC-NATIVE: declare void @objc_release(i8*) [[NLB]] -// ARC-NATIVE: declare i8* @objc_retainAutoreleasedReturnValue(i8*) -// ARC-NATIVE: declare i8* @objc_initWeak(i8**, i8*) -// ARC-NATIVE: declare i8* @objc_storeWeak(i8**, i8*) -// ARC-NATIVE: declare i8* @objc_loadWeakRetained(i8**) -// ARC-NATIVE: declare void @objc_destroyWeak(i8**) -// ARC-NATIVE: declare i8* @objc_autorelease(i8*) -// ARC-NATIVE: declare i8* @objc_retainAutorelease(i8*) +// ARC-ALIEN: declare extern_weak void @llvm.objc.release(i8*) +// ARC-ALIEN: declare extern_weak i8* @llvm.objc.retainAutoreleasedReturnValue(i8*) +// ARC-ALIEN: declare extern_weak i8* @llvm.objc.initWeak(i8**, i8*) +// ARC-ALIEN: declare extern_weak i8* @llvm.objc.storeWeak(i8**, i8*) +// ARC-ALIEN: declare extern_weak i8* @llvm.objc.loadWeakRetained(i8**) +// ARC-ALIEN: declare extern_weak void @llvm.objc.destroyWeak(i8**) +// ARC-ALIEN: declare extern_weak i8* @llvm.objc.autorelease(i8*) +// ARC-ALIEN: declare extern_weak i8* @llvm.objc.retainAutorelease(i8*) + +// ARC-NATIVE: declare void @llvm.objc.storeStrong(i8**, i8*) +// ARC-NATIVE: declare i8* @llvm.objc.retain(i8*) +// ARC-NATIVE: declare i8* @llvm.objc.autoreleaseReturnValue(i8*) +// ARC-NATIVE: declare i8* @objc_msgSend(i8*, i8*, ...) [[NLB:#[0-9]+]] +// ARC-NATIVE: declare void @llvm.objc.release(i8*) +// ARC-NATIVE: declare i8* @llvm.objc.retainAutoreleasedReturnValue(i8*) +// ARC-NATIVE: declare i8* @llvm.objc.initWeak(i8**, i8*) +// ARC-NATIVE: declare i8* @llvm.objc.storeWeak(i8**, i8*) +// ARC-NATIVE: declare i8* @llvm.objc.loadWeakRetained(i8**) +// ARC-NATIVE: declare void @llvm.objc.destroyWeak(i8**) +// ARC-NATIVE: declare i8* @llvm.objc.autorelease(i8*) +// ARC-NATIVE: declare i8* @llvm.objc.retainAutorelease(i8*) // CHECK-LABEL: define void @test0 void test0(id x) { // CHECK: [[X:%.*]] = alloca i8* - // CHECK-NEXT: [[PARM:%.*]] = call i8* @objc_retain(i8* {{.*}}) + // CHECK-NEXT: [[PARM:%.*]] = call i8* @llvm.objc.retain(i8* {{.*}}) // CHECK-NEXT: store i8* [[PARM]], i8** [[X]] // CHECK-NEXT: [[TMP:%.*]] = load i8*, i8** [[X]] - // CHECK-NEXT: call void @objc_release(i8* [[TMP]]) + // CHECK-NEXT: call void @llvm.objc.release(i8* [[TMP]]) // CHECK-NEXT: ret void } @@ -46,20 +46,20 @@ void test0(id x) { id test1(id x) { // CHECK: [[X:%.*]] = alloca i8* // CHECK-NEXT: [[Y:%.*]] = alloca i8* - // CHECK-NEXT: [[PARM:%.*]] = call i8* @objc_retain(i8* {{%.*}}) + // CHECK-NEXT: [[PARM:%.*]] = call i8* @llvm.objc.retain(i8* {{%.*}}) // CHECK-NEXT: store i8* [[PARM]], i8** [[X]] // CHECK-NEXT: [[YPTR1:%.*]] = bitcast i8** [[Y]] to i8* // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[YPTR1]]) // CHECK-NEXT: store i8* null, i8** [[Y]] // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[Y]] - // CHECK-NEXT: [[RET:%.*]] = call i8* @objc_retain(i8* [[T0]]) + // CHECK-NEXT: [[RET:%.*]] = call i8* @llvm.objc.retain(i8* [[T0]]) // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[Y]] - // CHECK-NEXT: call void @objc_release(i8* [[T0]]) + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) // CHECK-NEXT: [[YPTR2:%.*]] = bitcast i8** [[Y]] to i8* // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[YPTR2]]) // CHECK-NEXT: [[T1:%.*]] = load i8*, i8** [[X]] - // CHECK-NEXT: call void @objc_release(i8* [[T1]]) - // CHECK-NEXT: [[T1:%.*]] = tail call i8* @objc_autoreleaseReturnValue(i8* [[RET]]) + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) + // CHECK-NEXT: [[T1:%.*]] = tail call i8* @llvm.objc.autoreleaseReturnValue(i8* [[RET]]) // CHECK-NEXT: ret i8* [[T1]] id y; return y; @@ -113,19 +113,19 @@ void test3_unelided() { // CHECK-NEXT: [[ALLOC:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend // CHECK-NEXT: bitcast // CHECK-NEXT: bitcast - // CHECK-NEXT: call void @objc_release(i8* + // CHECK-NEXT: call void @llvm.objc.release(i8* [Test3 alloc]; // CHECK-NEXT: [[T0:%.*]] = load [[TEST3]]*, [[TEST3]]** [[X]] // CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_ // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST3]]* [[T0]] to i8* // CHECK-NEXT: [[COPY:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend {{.*}})(i8* [[T1]], - // CHECK-NEXT: call void @objc_release(i8* [[COPY]]) [[NUW:#[0-9]+]] + // CHECK-NEXT: call void @llvm.objc.release(i8* [[COPY]]) [[NUW:#[0-9]+]] [x copy]; // CHECK-NEXT: [[T0:%.*]] = load [[TEST3]]*, [[TEST3]]** [[X]] // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST3]]* [[T0]] to i8* - // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW]] + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) [[NUW]] // CHECK-NEXT: [[XPTR2:%.*]] = bitcast [[TEST3]]** [[X]] to i8* // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[XPTR2]]) // CHECK-NEXT: ret void @@ -163,13 +163,13 @@ void test3() { // Assignment to x. // CHECK-NEXT: [[TMP:%.*]] = load i8*, i8** [[X]] // CHECK-NEXT: store i8* [[COPY]], i8** [[X]] - // CHECK-NEXT: call void @objc_release(i8* [[TMP]]) [[NUW]] + // CHECK-NEXT: call void @llvm.objc.release(i8* [[TMP]]) [[NUW]] x = [x copy]; // Cleanup for x. // CHECK-NEXT: [[TMP:%.*]] = load i8*, i8** [[X]] - // CHECK-NEXT: call void @objc_release(i8* [[TMP]]) [[NUW]] + // CHECK-NEXT: call void @llvm.objc.release(i8* [[TMP]]) [[NUW]] // CHECK-NEXT: [[XPTR2:%.*]] = bitcast i8** [[X]] to i8* // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[XPTR2]]) // CHECK-NEXT: ret void @@ -193,7 +193,7 @@ id test4() { // Retain/release elided. // CHECK-NEXT: bitcast // CHECK-NEXT: [[INIT:%.*]] = bitcast - // CHECK-NEXT: [[RET:%.*]] = tail call i8* @objc_autoreleaseReturnValue(i8* [[INIT]]) + // CHECK-NEXT: [[RET:%.*]] = tail call i8* @llvm.objc.autoreleaseReturnValue(i8* [[INIT]]) // CHECK-NEXT: ret i8* [[RET]] @@ -212,10 +212,10 @@ void test5(Test5 *x, id y) { // CHECK: [[X:%.*]] = alloca [[TEST5:%.*]]*, // CHECK-NEXT: [[Y:%.*]] = alloca i8* // CHECK-NEXT: bitcast [[TEST5]]* {{%.*}} to i8* - // CHECK-NEXT: call i8* @objc_retain + // CHECK-NEXT: call i8* @llvm.objc.retain // CHECK-NEXT: [[PARMX:%.*]] = bitcast i8* {{%.*}} to [[TEST5]]* // CHECK-NEXT: store [[TEST5]]* [[PARMX]], [[TEST5]]** [[X]] - // CHECK-NEXT: call i8* @objc_retain + // CHECK-NEXT: call i8* @llvm.objc.retain // CHECK-NEXT: store // CHECK-NEXT: load [[TEST5]]*, [[TEST5]]** [[X]] @@ -225,7 +225,7 @@ void test5(Test5 *x, id y) { // CHECK-NEXT: [[VAR:%.*]] = bitcast // CHECK-NEXT: [[TMP:%.*]] = load i8*, i8** [[VAR]] // CHECK-NEXT: store i8* null, i8** [[VAR]] - // CHECK-NEXT: call void @objc_release(i8* [[TMP]]) [[NUW]] + // CHECK-NEXT: call void @llvm.objc.release(i8* [[TMP]]) [[NUW]] x->var = 0; // CHECK-NEXT: [[YVAL:%.*]] = load i8*, i8** [[Y]] @@ -234,18 +234,18 @@ void test5(Test5 *x, id y) { // CHECK-NEXT: bitcast // CHECK-NEXT: getelementptr // CHECK-NEXT: [[VAR:%.*]] = bitcast - // CHECK-NEXT: [[T0:%.*]] = call i8* @objc_retain(i8* [[YVAL]]) [[NUW]] + // CHECK-NEXT: [[T0:%.*]] = call i8* @llvm.objc.retain(i8* [[YVAL]]) [[NUW]] // CHECK-NEXT: [[TMP:%.*]] = load i8*, i8** [[VAR]] // CHECK-NEXT: store i8* [[T0]], i8** [[VAR]] - // CHECK-NEXT: call void @objc_release(i8* [[TMP]]) [[NUW]] + // CHECK-NEXT: call void @llvm.objc.release(i8* [[TMP]]) [[NUW]] x->var = y; // Epilogue. // CHECK-NEXT: [[TMP:%.*]] = load i8*, i8** [[Y]] - // CHECK-NEXT: call void @objc_release(i8* [[TMP]]) [[NUW]] + // CHECK-NEXT: call void @llvm.objc.release(i8* [[TMP]]) [[NUW]] // CHECK-NEXT: [[T0:%.*]] = load [[TEST5]]*, [[TEST5]]** [[X]] // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST5]]* [[T0]] to i8* - // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW]] + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) [[NUW]] // CHECK-NEXT: ret void } @@ -258,7 +258,7 @@ void test6() { // CHECK-NEXT: [[CALL:%.*]] = call i8* @test6_helper() // CHECK-NEXT: store i8* [[CALL]], i8** [[X]] // CHECK-NEXT: [[T1:%.*]] = load i8*, i8** [[X]] - // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW]], !clang.imprecise_release + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) [[NUW]], !clang.imprecise_release // CHECK-NEXT: [[XPTR2:%.*]] = bitcast i8** [[X]] to i8* // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[XPTR2]]) // CHECK-NEXT: ret void @@ -273,10 +273,10 @@ void test7() { // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[XPTR1]]) // CHECK-NEXT: store i8* null, i8** [[X]] // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[X]] - // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[T0]]) [[NUW]] + // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retain(i8* [[T0]]) [[NUW]] // CHECK-NEXT: call void @test7_helper(i8* [[T1]]) // CHECK-NEXT: [[T1:%.*]] = load i8*, i8** [[X]] - // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW]], !clang.imprecise_release + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) [[NUW]], !clang.imprecise_release // CHECK-NEXT: [[XPTR2:%.*]] = bitcast i8** [[X]] to i8* // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[XPTR2]]) // CHECK-NEXT: ret void @@ -292,7 +292,7 @@ void test8() { // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[XPTR1]]) // CHECK-NEXT: [[T0:%.*]] = call i8* @test8_helper() // CHECK-NEXT: store i8* [[T0]], i8** [[X]] - // CHECK-NEXT: call void @objc_release(i8* [[T0]]) [[NUW]], !clang.imprecise_release + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) [[NUW]], !clang.imprecise_release // CHECK-NEXT: [[XPTR2:%.*]] = bitcast i8** [[X]] to i8* // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[XPTR2]]) // CHECK-NEXT: ret void @@ -318,25 +318,25 @@ void test10() { // CHECK-NEXT: bitcast // CHECK-NEXT: [[T0:%.*]] = call [[TEST10]]* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST10]]* [[T0]] to i8* - // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]]) + // CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]]) // CHECK-NEXT: [[V:%.*]] = bitcast i8* [[T2]] to [[TEST10]]* // CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_{{[0-9]*}} // CHECK-NEXT: bitcast // CHECK-NEXT: [[T0:%.*]] = call [[TEST10]]* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST10]]* [[T0]] to i8* - // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]]) + // CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]]) // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST10]]* // CHECK-NEXT: [[T4:%.*]] = bitcast [[TEST10]]* [[T3]] to i8* // CHECK-NEXT: store i8* [[T4]], i8** [[Y]] // CHECK-NEXT: [[T0:%.*]] = bitcast [[TEST10]]* [[V]] to i8* - // CHECK-NEXT: call void @objc_release(i8* [[T0]]) + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[Y]] - // CHECK-NEXT: call void @objc_release(i8* [[T0]]) + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) // CHECK-NEXT: [[YPTR2:%.*]] = bitcast i8** [[Y]] to i8* // CHECK-NEXT: void @llvm.lifetime.end.p0i8(i64 8, i8* [[YPTR2]]) // CHECK-NEXT: [[T0:%.*]] = load [[TEST10]]*, [[TEST10]]** [[X]] // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST10]]* [[T0]] to i8* - // CHECK-NEXT: call void @objc_release(i8* [[T1]]) + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) // CHECK-NEXT: [[XPTR2:%.*]] = bitcast [[TEST10]]** [[X]] to i8* // CHECK-NEXT: void @llvm.lifetime.end.p0i8(i64 8, i8* [[XPTR2]]) // CHECK-NEXT: ret void @@ -353,7 +353,7 @@ void test11(id (*f)(void) __attribute__((ns_returns_retained))) { // CHECK-NEXT: [[T1:%.*]] = call i8* [[T0]]() // CHECK-NEXT: store i8* [[T1]], i8** [[X]], align // CHECK-NEXT: [[T3:%.*]] = load i8*, i8** [[X]] - // CHECK-NEXT: call void @objc_release(i8* [[T3]]) [[NUW]], !clang.imprecise_release + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T3]]) [[NUW]], !clang.imprecise_release // CHECK-NEXT: [[XPTR2:%.*]] = bitcast i8** [[X]] to i8* // CHECK-NEXT: void @llvm.lifetime.end.p0i8(i64 8, i8* [[XPTR2]]) // CHECK-NEXT: ret void @@ -371,27 +371,27 @@ void test12(void) { // CHECK-NEXT: [[XPTR1:%.*]] = bitcast i8** [[X]] to i8* // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[XPTR1]]) // CHECK-NEXT: [[T0:%.*]] = call i8* @test12_helper() - // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]]) - // CHECK-NEXT: call i8* @objc_initWeak(i8** [[X]], i8* [[T1]]) - // CHECK-NEXT: call void @objc_release(i8* [[T1]]) + // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) + // CHECK-NEXT: call i8* @llvm.objc.initWeak(i8** [[X]], i8* [[T1]]) + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) x = test12_helper(); // CHECK-NEXT: [[T0:%.*]] = call i8* @test12_helper() - // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]]) - // CHECK-NEXT: call i8* @objc_storeWeak(i8** [[X]], i8* [[T1]]) - // CHECK-NEXT: call void @objc_release(i8* [[T1]]) + // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) + // CHECK-NEXT: call i8* @llvm.objc.storeWeak(i8** [[X]], i8* [[T1]]) + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) id y = x; // CHECK-NEXT: [[YPTR1:%.*]] = bitcast i8** [[Y]] to i8* // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[YPTR1]]) - // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_loadWeakRetained(i8** [[X]]) + // CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.loadWeakRetained(i8** [[X]]) // CHECK-NEXT: store i8* [[T2]], i8** [[Y]], align // CHECK-NEXT: [[T4:%.*]] = load i8*, i8** [[Y]] - // CHECK-NEXT: call void @objc_release(i8* [[T4]]) [[NUW]], !clang.imprecise_release + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T4]]) [[NUW]], !clang.imprecise_release // CHECK-NEXT: [[YPTR2:%.*]] = bitcast i8** [[Y]] to i8* // CHECK-NEXT: void @llvm.lifetime.end.p0i8(i64 8, i8* [[YPTR2]]) - // CHECK-NEXT: call void @objc_destroyWeak(i8** [[X]]) + // CHECK-NEXT: call void @llvm.objc.destroyWeak(i8** [[X]]) // CHECK-NEXT: [[XPTR2:%.*]] = bitcast i8** [[X]] to i8* // CHECK-NEXT: void @llvm.lifetime.end.p0i8(i64 8, i8* [[XPTR2]]) // CHECK: ret void @@ -410,7 +410,7 @@ void test13(void) { extern fnty *test13_func; // CHECK-NEXT: [[FN:%.*]] = load void (i8*)*, void (i8*)** @test13_func, align // CHECK-NEXT: [[X_VAL:%.*]] = load i8*, i8** [[X]], align - // CHECK-NEXT: [[X_TMP:%.*]] = call i8* @objc_retain(i8* [[X_VAL]]) [[NUW]] + // CHECK-NEXT: [[X_TMP:%.*]] = call i8* @llvm.objc.retain(i8* [[X_VAL]]) [[NUW]] // CHECK-NEXT: call void [[FN]](i8* [[X_TMP]]) test13_func(x); @@ -420,14 +420,14 @@ void test13(void) { // CHECK-NEXT: [[BLOCK_FN_PTR:%.*]] = getelementptr inbounds [[BLOCKTY]], [[BLOCKTY]]* [[BLOCK]], i32 0, i32 3 // CHECK-NEXT: [[BLOCK_OPAQUE:%.*]] = bitcast [[BLOCKTY]]* [[BLOCK]] to i8* // CHECK-NEXT: [[X_VAL:%.*]] = load i8*, i8** [[X]], align - // CHECK-NEXT: [[X_TMP:%.*]] = call i8* @objc_retain(i8* [[X_VAL]]) [[NUW]] + // CHECK-NEXT: [[X_TMP:%.*]] = call i8* @llvm.objc.retain(i8* [[X_VAL]]) [[NUW]] // CHECK-NEXT: [[BLOCK_FN_TMP:%.*]] = load i8*, i8** [[BLOCK_FN_PTR]] // CHECK-NEXT: [[BLOCK_FN:%.*]] = bitcast i8* [[BLOCK_FN_TMP]] to void (i8*, i8*)* // CHECK-NEXT: call void [[BLOCK_FN]](i8* [[BLOCK_OPAQUE]], i8* [[X_TMP]]) test13_block(x); // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[X]] - // CHECK-NEXT: call void @objc_release(i8* [[T0]]) [[NUW]] + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) [[NUW]] // CHECK-NEXT: [[XPTR2:%.*]] = bitcast i8** [[X]] to i8* // CHECK-NEXT: void @llvm.lifetime.end.p0i8(i64 8, i8* [[XPTR2]]) // CHECK-NEXT: ret void @@ -479,14 +479,14 @@ void test13(void) { // CHECK-NEXT: [[T0:%.*]] = bitcast [[TEST16]]* [[BASE]] to i8* // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8, i8* [[T0]], i64 [[Y_OFF]] // CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[T1]] to i8** - // CHECK-NEXT: call void @objc_storeStrong(i8** [[T2]], i8* null) [[NUW]] + // CHECK-NEXT: call void @llvm.objc.storeStrong(i8** [[T2]], i8* null) [[NUW]] // Destroy z. // CHECK-NEXT: [[Z_OFF:%.*]] = load i64, i64* @"OBJC_IVAR_$_Test16.z" // CHECK-NEXT: [[T0:%.*]] = bitcast [[TEST16]]* [[BASE]] to i8* // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8, i8* [[T0]], i64 [[Z_OFF]] // CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[T1]] to i8** - // CHECK-NEXT: call void @objc_storeStrong(i8** [[T2]], i8* null) [[NUW]] + // CHECK-NEXT: call void @llvm.objc.storeStrong(i8** [[T2]], i8* null) [[NUW]] // CHECK-NEXT: ret void @@ -514,11 +514,11 @@ void test19() { x[2] = test19_helper(); // CHECK-NEXT: [[CALL:%.*]] = call i8* @test19_helper() - // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[CALL]]) [[NUW]] + // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[CALL]]) [[NUW]] // CHECK-NEXT: [[SLOT:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[X]], i64 0, i64 2 // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[SLOT]] // CHECK-NEXT: store i8* [[T1]], i8** [[SLOT]] - // CHECK-NEXT: call void @objc_release(i8* [[T0]]) [[NUW]] + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) [[NUW]] // CHECK-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[X]], i32 0, i32 0 // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds i8*, i8** [[BEGIN]], i64 5 @@ -527,7 +527,7 @@ void test19() { // CHECK: [[AFTER:%.*]] = phi i8** [ [[END]], {{%.*}} ], [ [[NEXT:%.*]], {{%.*}} ] // CHECK-NEXT: [[CUR:%.*]] = getelementptr inbounds i8*, i8** [[AFTER]], i64 -1 // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[CUR]] - // CHECK-NEXT: call void @objc_release(i8* [[T0]]) [[NUW]], !clang.imprecise_release + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) [[NUW]], !clang.imprecise_release // CHECK-NEXT: [[EQ:%.*]] = icmp eq i8** [[CUR]], [[BEGIN]] // CHECK-NEXT: br i1 [[EQ]], @@ -570,7 +570,7 @@ void test20(unsigned n) { // CHECK: [[AFTER:%.*]] = phi i8** [ [[END]], {{%.*}} ], [ [[CUR:%.*]], {{%.*}} ] // CHECK-NEXT: [[CUR:%.*]] = getelementptr inbounds i8*, i8** [[AFTER]], i64 -1 // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[CUR]] - // CHECK-NEXT: call void @objc_release(i8* [[T0]]) [[NUW]], !clang.imprecise_release + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) [[NUW]], !clang.imprecise_release // CHECK-NEXT: [[EQ:%.*]] = icmp eq i8** [[CUR]], [[VLA]] // CHECK-NEXT: br i1 [[EQ]], @@ -620,7 +620,7 @@ void test21(unsigned n) { // CHECK: [[AFTER:%.*]] = phi i8** [ [[END]], {{%.*}} ], [ [[CUR:%.*]], {{%.*}} ] // CHECK-NEXT: [[CUR:%.*]] = getelementptr inbounds i8*, i8** [[AFTER]], i64 -1 // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[CUR]] - // CHECK-NEXT: call void @objc_release(i8* [[T0]]) [[NUW]], !clang.imprecise_release + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) [[NUW]], !clang.imprecise_release // CHECK-NEXT: [[EQ:%.*]] = icmp eq i8** [[CUR]], [[BEGIN]] // CHECK-NEXT: br i1 [[EQ]], @@ -656,7 +656,7 @@ void test21(unsigned n) { // CHECK-NEXT: br label // CHECK: [[PAST:%.*]] = phi i8** [ [[END]], {{%.*}} ], [ [[CUR:%.*]], {{%.*}} ] // CHECK-NEXT: [[CUR]] = getelementptr inbounds i8*, i8** [[PAST]], i64 -1 -// CHECK-NEXT: call void @objc_storeStrong(i8** [[CUR]], i8* null) +// CHECK-NEXT: call void @llvm.objc.storeStrong(i8** [[CUR]], i8* null) // CHECK-NEXT: [[ISDONE:%.*]] = icmp eq i8** [[CUR]], [[BEGIN]] // CHECK-NEXT: br i1 [[ISDONE]], // CHECK: ret void @@ -674,12 +674,12 @@ void test21(unsigned n) { // CHECK-NEXT: store i8* {{%.*}}, i8** [[CMD]] // CHECK-NEXT: [[T0:%.*]] = load [[TEST27]]*, [[TEST27]]** [[SELF]] // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST27]]* [[T0]] to i8* -// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retain(i8* [[T1]]) +// CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retain(i8* [[T1]]) // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST27]]* // CHECK-NEXT: [[RET:%.*]] = bitcast [[TEST27]]* [[T3]] to i8* // CHECK-NEXT: [[T0:%.*]] = load [[TEST27]]*, [[TEST27]]** [[SELF]] // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST27]]* [[T0]] to i8* -// CHECK-NEXT: call void @objc_release(i8* [[T1]]) +// CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) // CHECK-NEXT: ret i8* [[RET]] @end @@ -697,7 +697,7 @@ void test21(unsigned n) { // CHECK-NEXT: [[T0:%.*]] = bitcast [[TEST28]]* [[SELF]] to i8* // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8, i8* [[T0]], i64 [[OFFSET]] // CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[T1]] to i8** -// CHECK-NEXT: call void @objc_storeStrong(i8** [[T2]], i8* null) +// CHECK-NEXT: call void @llvm.objc.storeStrong(i8** [[T2]], i8* null) // CHECK-NEXT: ret void @interface Test29_super @@ -738,14 +738,14 @@ static id _test29_allocator = 0; // Return statement. // CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[CALL]] // CHECK-NEXT: [[CALL:%.*]] = bitcast -// CHECK-NEXT: [[T0:%.*]] = call i8* @objc_retain(i8* [[CALL]]) [[NUW]] +// CHECK-NEXT: [[T0:%.*]] = call i8* @llvm.objc.retain(i8* [[CALL]]) [[NUW]] // CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[TEST29]]* // CHECK-NEXT: [[RET:%.*]] = bitcast [[TEST29]]* [[T1]] to i8* // Cleanup. // CHECK-NEXT: [[T0:%.*]] = load [[TEST29]]*, [[TEST29]]** [[SELF]] // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST29]]* [[T0]] to i8* -// CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW]], !clang.imprecise_release +// CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) [[NUW]], !clang.imprecise_release // Return. // CHECK-NEXT: ret i8* [[RET]] @@ -759,7 +759,7 @@ static id _test29_allocator = 0; // CHECK-NEXT: alloca // CHECK-NEXT: store [[TEST29]]* {{%.*}}, [[TEST29]]** [[SELF]] // CHECK-NEXT: store i8* {{%.*}}, i8** [[CMD]] -// CHECK-NEXT: [[T0:%.*]] = call i8* @objc_retain(i8* {{%.*}}) +// CHECK-NEXT: [[T0:%.*]] = call i8* @llvm.objc.retain(i8* {{%.*}}) // CHECK-NEXT: store i8* [[T0]], i8** [[ALLOCATOR]] // Evaluate arguments. Note that the send argument is evaluated @@ -782,27 +782,27 @@ static id _test29_allocator = 0; // Assignment. // CHECK-NEXT: [[T0:%.*]] = bitcast i8* [[CALL]] to [[TEST29]]* // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST29]]* [[T0]] to i8* -// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retain(i8* [[T1]]) [[NUW]] +// CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retain(i8* [[T1]]) [[NUW]] // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST29]]* // CHECK-NEXT: [[T4:%.*]] = load [[TEST29]]*, [[TEST29]]** [[SELF]], align // CHECK-NEXT: store [[TEST29]]* [[T3]], [[TEST29]]** [[SELF]], align // CHECK-NEXT: [[T5:%.*]] = bitcast [[TEST29]]* [[T4]] to i8* -// CHECK-NEXT: call void @objc_release(i8* [[T5]]) +// CHECK-NEXT: call void @llvm.objc.release(i8* [[T5]]) // Return statement. // CHECK-NEXT: [[T0:%.*]] = load [[TEST29]]*, [[TEST29]]** [[SELF]] // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST29]]* [[T0]] to i8* -// CHECK-NEXT: [[T0:%.*]] = call i8* @objc_retain(i8* [[T1]]) [[NUW]] +// CHECK-NEXT: [[T0:%.*]] = call i8* @llvm.objc.retain(i8* [[T1]]) [[NUW]] // CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[TEST29]]* // CHECK-NEXT: [[RET:%.*]] = bitcast [[TEST29]]* [[T1]] to i8* // Cleanup. // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[ALLOCATOR]] -// CHECK-NEXT: call void @objc_release(i8* [[T0]]) [[NUW]], !clang.imprecise_release +// CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) [[NUW]], !clang.imprecise_release // CHECK-NEXT: [[T0:%.*]] = load [[TEST29]]*, [[TEST29]]** [[SELF]] // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST29]]* [[T0]] to i8* -// CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW]], !clang.imprecise_release +// CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) [[NUW]], !clang.imprecise_release // Return. // CHECK-NEXT: ret i8* [[RET]] @@ -840,21 +840,21 @@ char *helper; // CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8, i8* [[T2]], i64 [[IVAR]] // CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to i8** // CHECK-NEXT#: [[T5:%.*]] = load i8*, i8** [[T4]] -// CHECK-NEXT#: [[T6:%.*]] = call i8* @objc_retain(i8* [[T0]]) -// CHECK-NEXT#: call void @objc_release(i8* [[T5]]) +// CHECK-NEXT#: [[T6:%.*]] = call i8* @llvm.objc.retain(i8* [[T0]]) +// CHECK-NEXT#: call void @llvm.objc.release(i8* [[T5]]) // CHECK-NEXT: store i8* [[T0]], i8** [[T4]] // Return. // CHECK-NEXT: [[T0:%.*]] = load [[TEST30]]*, [[TEST30]]** [[SELF]] // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST30]]* [[T0]] to i8* -// CHECK-NEXT: [[T0:%.*]] = call i8* @objc_retain(i8* [[T1]]) +// CHECK-NEXT: [[T0:%.*]] = call i8* @llvm.objc.retain(i8* [[T1]]) // CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[TEST30]]* // CHECK-NEXT: [[RET:%.*]] = bitcast [[TEST30]]* [[T1]] to i8* // Cleanup. // CHECK-NEXT: [[T0:%.*]] = load [[TEST30]]*, [[TEST30]]** [[SELF]] // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST30]]* [[T0]] to i8* -// CHECK-NEXT: call void @objc_release(i8* [[T1]]) +// CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) // Epilogue. // CHECK-NEXT: ret i8* [[RET]] @@ -876,7 +876,7 @@ char *helper; __attribute__((ns_returns_retained)) id test32(void) { // CHECK-LABEL: define i8* @test32() // CHECK: [[CALL:%.*]] = call i8* @test32_helper() -// CHECK-NEXT: [[T0:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[CALL]]) +// CHECK-NEXT: [[T0:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[CALL]]) // CHECK-NEXT: ret i8* [[T0]] extern id test32_helper(void); return test32_helper(); @@ -905,7 +905,7 @@ void test33(Test33 *ptr) { // CHECK-NEXT: [[TEMP1:%.*]] = alloca [[A_T]]* // CHECK-NEXT: [[TEMP2:%.*]] = alloca [[A_T]]* // CHECK-NEXT: bitcast - // CHECK-NEXT: objc_retain + // CHECK-NEXT: llvm.objc.retain // CHECK-NEXT: bitcast // CHECK-NEXT: store // CHECK-NEXT: bitcast @@ -920,13 +920,13 @@ void test33(Test33 *ptr) { // CHECK-NEXT: objc_msgSend{{.*}}, [[A_T]]** [[TEMP0]]) // CHECK-NEXT: [[T0:%.*]] = load [[A_T]]*, [[A_T]]** [[TEMP0]] // CHECK-NEXT: [[T1:%.*]] = bitcast [[A_T]]* [[T0]] to i8* - // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retain(i8* [[T1]]) + // CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retain(i8* [[T1]]) // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[A_T]]* // CHECK-NEXT: call void (...) @clang.arc.use([[A_T]]* [[W0]]) [[NUW]] // CHECK-NEXT: [[T4:%.*]] = load [[A_T]]*, [[A_T]]** [[A]] // CHECK-NEXT: store [[A_T]]* [[T3]], [[A_T]]** [[A]] // CHECK-NEXT: [[T5:%.*]] = bitcast [[A_T]]* [[T4]] to i8* - // CHECK-NEXT: call void @objc_release(i8* [[T5]]) + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T5]]) // CHECK-NEXT: load [[TEST33]]*, [[TEST33]]** [[PTR]] // CHECK-NEXT: [[W0:%.*]] = load [[A_T]]*, [[A_T]]** [[A]] @@ -936,13 +936,13 @@ void test33(Test33 *ptr) { // CHECK-NEXT: objc_msgSend{{.*}}, [[A_T]]** [[TEMP1]]) // CHECK-NEXT: [[T0:%.*]] = load [[A_T]]*, [[A_T]]** [[TEMP1]] // CHECK-NEXT: [[T1:%.*]] = bitcast [[A_T]]* [[T0]] to i8* - // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retain(i8* [[T1]]) + // CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retain(i8* [[T1]]) // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[A_T]]* // CHECK-NEXT: call void (...) @clang.arc.use([[A_T]]* [[W0]]) [[NUW]] // CHECK-NEXT: [[T4:%.*]] = load [[A_T]]*, [[A_T]]** [[A]] // CHECK-NEXT: store [[A_T]]* [[T3]], [[A_T]]** [[A]] // CHECK-NEXT: [[T5:%.*]] = bitcast [[A_T]]* [[T4]] to i8* - // CHECK-NEXT: call void @objc_release(i8* [[T5]]) + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T5]]) // CHECK-NEXT: load [[TEST33]]*, [[TEST33]]** [[PTR]] // CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_ @@ -962,21 +962,21 @@ void test33(Test33 *ptr) { // CHECK-NEXT: objc_msgSend{{.*}}, [[A_T]]** [[TEMP2]]) // CHECK-NEXT: [[T0:%.*]] = load [[A_T]]*, [[A_T]]** [[TEMP2]] // CHECK-NEXT: [[T1:%.*]] = bitcast [[A_T]]* [[T0]] to i8* - // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retain(i8* [[T1]]) + // CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retain(i8* [[T1]]) // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[A_T]]* // CHECK-NEXT: [[T4:%.*]] = load [[A_T]]*, [[A_T]]** [[A]] // CHECK-NEXT: store [[A_T]]* [[T3]], [[A_T]]** [[A]] // CHECK-NEXT: [[T5:%.*]] = bitcast [[A_T]]* [[T4]] to i8* - // CHECK-NEXT: call void @objc_release(i8* [[T5]]) + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T5]]) // CHECK-NEXT: load // CHECK-NEXT: bitcast - // CHECK-NEXT: objc_release + // CHECK-NEXT: llvm.objc.release // CHECK-NEXT: bitcast // CHECK-NEXT: call void @llvm.lifetime.end // CHECK-NEXT: load // CHECK-NEXT: bitcast - // CHECK-NEXT: objc_release + // CHECK-NEXT: llvm.objc.release // CHECK-NEXT: ret void } @@ -985,21 +985,21 @@ void test33(Test33 *ptr) { void test36(id x) { // CHECK: [[X:%.*]] = alloca i8* - // CHECK: call i8* @objc_retain - // CHECK: call i8* @objc_retain - // CHECK: call i8* @objc_retain + // CHECK: call i8* @llvm.objc.retain + // CHECK: call i8* @llvm.objc.retain + // CHECK: call i8* @llvm.objc.retain id array[3] = { @"A", x, @"y" }; // CHECK: [[T0:%.*]] = load i8*, i8** [[X]] // CHECK-NEXT: store i8* null, i8** [[X]] - // CHECK-NEXT: call void @objc_release(i8* [[T0]]) + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) x = 0; // CHECK: br label - // CHECK: call void @objc_release + // CHECK: call void @llvm.objc.release // CHECK: br i1 - // CHECK: call void @objc_release + // CHECK: call void @llvm.objc.release // CHECK-NEXT: ret void } @@ -1023,17 +1023,17 @@ void test37(void) { // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[TEMP]] // CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[TEST37]]* // CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST37]]* [[T1]] to i8* - // CHECK-NEXT: [[T3:%.*]] = call i8* @objc_retain(i8* [[T2]]) + // CHECK-NEXT: [[T3:%.*]] = call i8* @llvm.objc.retain(i8* [[T2]]) // CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to [[TEST37]]* // CHECK-NEXT: call void (...) @clang.arc.use(i8* [[W1]]) [[NUW]] // CHECK-NEXT: [[T5:%.*]] = load [[TEST37]]*, [[TEST37]]** [[VAR]] // CHECK-NEXT: store [[TEST37]]* [[T4]], [[TEST37]]** [[VAR]] // CHECK-NEXT: [[T6:%.*]] = bitcast [[TEST37]]* [[T5]] to i8* - // CHECK-NEXT: call void @objc_release(i8* [[T6]]) + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T6]]) // CHECK-NEXT: [[T0:%.*]] = load [[TEST37]]*, [[TEST37]]** [[VAR]] // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST37]]* [[T0]] to i8* - // CHECK-NEXT: call void @objc_release(i8* [[T1]]) + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) // CHECK-NEXT: [[VARPTR2:%.*]] = bitcast [[TEST37]]** [[VAR]] to i8* // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[VARPTR2]]) // CHECK-NEXT: ret void @@ -1045,7 +1045,7 @@ void test37(void) { extern id test43_produce(void); return test43_produce(); // CHECK: call i8* @test43_produce() - // CHECK-NEXT: call i8* @objc_retainAutoreleasedReturnValue( + // CHECK-NEXT: call i8* @llvm.objc.retainAutoreleasedReturnValue( // CHECK-NEXT: ret } @end @@ -1067,21 +1067,21 @@ void test46(__weak id *wp, __weak volatile id *wvp) { // TODO: this is sub-optimal, we should retain at the actual call site. // CHECK: [[T0:%.*]] = call i8* @test46_helper() - // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]]) + // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) // CHECK-NEXT: [[T2:%.*]] = load i8**, i8*** {{%.*}}, align 8 - // CHECK-NEXT: [[T3:%.*]] = call i8* @objc_storeWeak(i8** [[T2]], i8* [[T1]]) - // CHECK-NEXT: [[T4:%.*]] = call i8* @objc_retain(i8* [[T3]]) + // CHECK-NEXT: [[T3:%.*]] = call i8* @llvm.objc.storeWeak(i8** [[T2]], i8* [[T1]]) + // CHECK-NEXT: [[T4:%.*]] = call i8* @llvm.objc.retain(i8* [[T3]]) // CHECK-NEXT: store i8* [[T4]], i8** - // CHECK-NEXT: call void @objc_release(i8* [[T1]]) + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) id x = *wp = test46_helper(); // CHECK: [[T0:%.*]] = call i8* @test46_helper() - // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]]) + // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) // CHECK-NEXT: [[T2:%.*]] = load i8**, i8*** {{%.*}}, align 8 - // CHECK-NEXT: [[T3:%.*]] = call i8* @objc_storeWeak(i8** [[T2]], i8* [[T1]]) - // CHECK-NEXT: [[T4:%.*]] = call i8* @objc_retain(i8* [[T3]]) + // CHECK-NEXT: [[T3:%.*]] = call i8* @llvm.objc.storeWeak(i8** [[T2]], i8* [[T1]]) + // CHECK-NEXT: [[T4:%.*]] = call i8* @llvm.objc.retain(i8* [[T3]]) // CHECK-NEXT: store i8* [[T4]], i8** - // CHECK-NEXT: call void @objc_release(i8* [[T1]]) + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) id y = *wvp = test46_helper(); } @@ -1096,16 +1096,16 @@ void test47(void) { // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[XPTR1]]) // CHECK-NEXT: store i8* null, i8** [[X]] // CHECK-NEXT: [[CALL:%.*]] = call i8* @test47_helper() - // CHECK-NEXT: [[T0:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[CALL]]) + // CHECK-NEXT: [[T0:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[CALL]]) // CHECK-NEXT: [[T1:%.*]] = load i8*, i8** [[X]] // CHECK-NEXT: store i8* [[T0]], i8** [[X]] - // CHECK-NEXT: call void @objc_release(i8* [[T1]]) - // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retain(i8* [[T0]]) + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) + // CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retain(i8* [[T0]]) // CHECK-NEXT: [[T3:%.*]] = load i8*, i8** [[X]] // CHECK-NEXT: store i8* [[T2]], i8** [[X]] - // CHECK-NEXT: call void @objc_release(i8* [[T3]]) + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T3]]) // CHECK-NEXT: [[T4:%.*]] = load i8*, i8** [[X]] - // CHECK-NEXT: call void @objc_release(i8* [[T4]]) + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T4]]) // CHECK-NEXT: [[XPTR2:%.*]] = bitcast i8** [[X]] to i8* // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[XPTR2]]) // CHECK-NEXT: ret void @@ -1118,13 +1118,13 @@ void test48(void) { // CHECK: [[X:%.*]] = alloca i8* // CHECK-NEXT: [[XPTR1:%.*]] = bitcast i8** [[X]] to i8* // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[XPTR1]]) - // CHECK-NEXT: [[T0:%.*]] = call i8* @objc_initWeak(i8** [[X]], i8* null) + // CHECK-NEXT: [[T0:%.*]] = call i8* @llvm.objc.initWeak(i8** [[X]], i8* null) // CHECK-NEXT: [[T1:%.*]] = call i8* @test48_helper() - // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]]) - // CHECK-NEXT: [[T3:%.*]] = call i8* @objc_storeWeak(i8** [[X]], i8* [[T2]]) - // CHECK-NEXT: [[T4:%.*]] = call i8* @objc_storeWeak(i8** [[X]], i8* [[T3]]) - // CHECK-NEXT: call void @objc_release(i8* [[T2]]) - // CHECK-NEXT: call void @objc_destroyWeak(i8** [[X]]) + // CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]]) + // CHECK-NEXT: [[T3:%.*]] = call i8* @llvm.objc.storeWeak(i8** [[X]], i8* [[T2]]) + // CHECK-NEXT: [[T4:%.*]] = call i8* @llvm.objc.storeWeak(i8** [[X]], i8* [[T3]]) + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T2]]) + // CHECK-NEXT: call void @llvm.objc.destroyWeak(i8** [[X]]) // CHECK-NEXT: [[XPTR2:%.*]] = bitcast i8** [[X]] to i8* // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[XPTR2]]) // CHECK-NEXT: ret void @@ -1139,10 +1139,10 @@ void test49(void) { // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[XPTR1]]) // CHECK-NEXT: store i8* null, i8** [[X]] // CHECK-NEXT: [[CALL:%.*]] = call i8* @test49_helper() - // CHECK-NEXT: [[T0:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[CALL]]) - // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_autorelease(i8* [[T0]]) + // CHECK-NEXT: [[T0:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[CALL]]) + // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.autorelease(i8* [[T0]]) // CHECK-NEXT: store i8* [[T2]], i8** [[X]] - // CHECK-NEXT: [[T3:%.*]] = call i8* @objc_retainAutorelease(i8* [[T1]]) + // CHECK-NEXT: [[T3:%.*]] = call i8* @llvm.objc.retainAutorelease(i8* [[T1]]) // CHECK-NEXT: store i8* [[T3]], i8** [[X]] // CHECK-NEXT: [[XPTR2:%.*]] = bitcast i8** [[X]] to i8* // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[XPTR2]]) @@ -1153,8 +1153,8 @@ void test49(void) { id x(); void test50(id y) { ({x();}); -// CHECK: [[T0:%.*]] = call i8* @objc_retain -// CHECK: call void @objc_release +// CHECK: [[T0:%.*]] = call i8* @llvm.objc.retain +// CHECK: call void @llvm.objc.release } @@ -1190,7 +1190,7 @@ id test52(void) { // CHECK-NEXT: [[XPTR2:%.*]] = bitcast i32* [[X]] to i8* // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[XPTR2]]) // CHECK-NEXT: [[T2:%.*]] = load i8*, i8** [[TMPALLOCA]] -// CHECK-NEXT: [[T3:%.*]] = tail call i8* @objc_autoreleaseReturnValue(i8* [[T2]]) +// CHECK-NEXT: [[T3:%.*]] = tail call i8* @llvm.objc.autoreleaseReturnValue(i8* [[T2]]) // CHECK-NEXT: ret i8* [[T3]] } @@ -1208,20 +1208,20 @@ void test53(void) { // CHECK-NEXT: [[YPTR1:%.*]] = bitcast i8** [[Y]] to i8* // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[YPTR1]]) // CHECK-NEXT: [[T0:%.*]] = call i8* @test53_helper() -// CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]]) +// CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) // CHECK-NEXT: store i8* [[T1]], i8** [[Y]], // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[Y]], -// CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[T0]]) +// CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retain(i8* [[T0]]) // CHECK-NEXT: store i8* [[T1]], i8** [[TMPALLOCA]] // CHECK-NEXT: [[T2:%.*]] = load i8*, i8** [[Y]] -// CHECK-NEXT: call void @objc_release(i8* [[T2]]) +// CHECK-NEXT: call void @llvm.objc.release(i8* [[T2]]) // CHECK-NEXT: [[YPTR2:%.*]] = bitcast i8** [[Y]] to i8* // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[YPTR2]]) // CHECK-NEXT: [[T3:%.*]] = load i8*, i8** [[TMPALLOCA]] // CHECK-NEXT: store i8* [[T3]], i8** [[X]], // CHECK-NEXT: load i8*, i8** [[X]], // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[X]] -// CHECK-NEXT: call void @objc_release(i8* [[T0]]) +// CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) // CHECK-NEXT: [[XPTR2:%.*]] = bitcast i8** [[X]] to i8* // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[XPTR2]]) // CHECK-NEXT: ret void @@ -1233,11 +1233,11 @@ void test54(int first, ...) { __builtin_va_list arglist; // CHECK: call void @llvm.va_start __builtin_va_start(arglist, first); - // CHECK: call i8* @objc_retain + // CHECK: call i8* @llvm.objc.retain id obj = __builtin_va_arg(arglist, id); // CHECK: call void @llvm.va_end __builtin_va_end(arglist); - // CHECK: call void @objc_release + // CHECK: call void @llvm.objc.release // CHECK: ret void } @@ -1261,7 +1261,7 @@ void test54(int first, ...) { + (id) make { extern id test56_helper(void); // CHECK: [[T0:%.*]] = call i8* @test56_helper() - // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]]) + // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) // CHECK-NEXT: ret i8* [[T1]] return test56_helper(); } @@ -1275,7 +1275,7 @@ void test56_test(void) { // CHECK: [[T0:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*)*)( // CHECK-NEXT: store i8* [[T0]], i8** [[X]] // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[X]] - // CHECK-NEXT: call void @objc_release(i8* [[T0]]) + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) // CHECK-NEXT: [[XPTR2:%.*]] = bitcast i8** [[X]] to i8* // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[XPTR2]]) // CHECK-NEXT: ret void @@ -1305,8 +1305,8 @@ void test56_test(void) { // CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST57]]* [[T0]] to i8* // CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8, i8* [[T2]], i64 [[T1]] // CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to i8** -// CHECK-NEXT: [[T5:%.*]] = call i8* @objc_loadWeakRetained(i8** [[T4]]) -// CHECK-NEXT: [[T6:%.*]] = tail call i8* @objc_autoreleaseReturnValue(i8* [[T5]]) +// CHECK-NEXT: [[T5:%.*]] = call i8* @llvm.objc.loadWeakRetained(i8** [[T4]]) +// CHECK-NEXT: [[T6:%.*]] = tail call i8* @llvm.objc.autoreleaseReturnValue(i8* [[T5]]) // CHECK-NEXT: ret i8* [[T6]] // CHECK: define internal i8* @"\01-[Test57 unsafe]"( @@ -1328,11 +1328,11 @@ void test59(void) { // CHECK-LABEL: define void @test59() // CHECK: [[T0:%.*]] = call i8* @test59_getlock() - // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]]) + // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) // CHECK-NEXT: call i32 @objc_sync_enter(i8* [[T1]]) // CHECK-NEXT: call void @test59_body() // CHECK-NEXT: call i32 @objc_sync_exit(i8* [[T1]]) - // CHECK-NEXT: call void @objc_release(i8* [[T1]]) + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) // CHECK-NEXT: ret void } @@ -1350,27 +1350,27 @@ void test61(void) { extern id test61_make(void); // CHECK-NEXT: [[T0:%.*]] = call i8* @test61_make() - // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]]) + // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) // CHECK-NEXT: [[T2:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_ // CHECK-NEXT: [[T3:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_ // CHECK-NEXT: [[T4:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*, i8*)*)(i8* [[T1]], i8* [[T3]], i8* [[T2]]) - // CHECK-NEXT: call void @objc_release(i8* [[T1]]) + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) [test61_make() performSelector: @selector(test61_void)]; // CHECK-NEXT: [[YPTR1:%.*]] = bitcast i8** [[Y]] to i8* // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[YPTR1]]) // CHECK-NEXT: [[T0:%.*]] = call i8* @test61_make() - // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]]) + // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) // CHECK-NEXT: [[T2:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_ // CHECK-NEXT: [[T3:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_ // CHECK-NEXT: [[T4:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*, i8*)*)(i8* [[T1]], i8* [[T3]], i8* [[T2]]) - // CHECK-NEXT: [[T5:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T4]]) + // CHECK-NEXT: [[T5:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T4]]) // CHECK-NEXT: store i8* [[T5]], i8** [[Y]] - // CHECK-NEXT: call void @objc_release(i8* [[T1]]) + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) id y = [test61_make() performSelector: @selector(test61_id)]; // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[Y]] - // CHECK-NEXT: call void @objc_release(i8* [[T0]]) + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) // CHECK-NEXT: [[YPTR2:%.*]] = bitcast i8** [[Y]] to i8* // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[YPTR2]]) // CHECK-NEXT: ret void @@ -1400,7 +1400,7 @@ void test62(void) { // CHECK-NEXT: store i1 false, i1* [[CLEANUP_REQUIRED]] // CHECK-NEXT: br i1 [[T1]], // CHECK: [[T0:%.*]] = call i8* @test62_make() - // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]]) + // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) // CHECK-NEXT: store i8* [[T1]], i8** [[CLEANUP_VALUE]] // CHECK-NEXT: store i1 true, i1* [[CLEANUP_REQUIRED]] // CHECK-NEXT: [[T2:%.*]] = icmp ne i8* [[T1]], null @@ -1409,7 +1409,7 @@ void test62(void) { // CHECK-NEXT: [[T0:%.*]] = load i1, i1* [[CLEANUP_REQUIRED]] // CHECK-NEXT: br i1 [[T0]], // CHECK: [[T0:%.*]] = load i8*, i8** [[CLEANUP_VALUE]] - // CHECK-NEXT: call void @objc_release(i8* [[T0]]) + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) // CHECK-NEXT: br label // CHECK: br i1 [[COND]] // CHECK: call void @test62_body() @@ -1455,20 +1455,20 @@ void test66(void) { // CHECK-LABEL: define void @test66() // CHECK: [[T0:%.*]] = call [[TEST66:%.*]]* @test66_receiver() // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST66]]* [[T0]] to i8* -// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]]) +// CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]]) // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST66]]* // CHECK-NEXT: [[T4:%.*]] = call i8* @test66_arg() -// CHECK-NEXT: [[T5:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T4]]) +// CHECK-NEXT: [[T5:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T4]]) // CHECK-NEXT: [[T6:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES // CHECK-NEXT: [[T7:%.*]] = bitcast [[TEST66]]* [[T3]] to i8* // CHECK-NEXT: [[SIX:%.*]] = icmp eq i8* [[T7]], null // CHECK-NEXT: br i1 [[SIX]], label [[NULINIT:%.*]], label [[CALL:%.*]] // CHECK: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, i8*)*)(i8* [[T7]], i8* [[T6]], i8* [[T5]]) // CHECK-NEXT: br label [[CONT:%.*]] -// CHECK: call void @objc_release(i8* [[T5]]) [[NUW]] +// CHECK: call void @llvm.objc.release(i8* [[T5]]) [[NUW]] // CHECK-NEXT: br label [[CONT:%.*]] // CHECK: [[T8:%.*]] = bitcast [[TEST66]]* [[T3]] to i8* -// CHECK-NEXT: call void @objc_release(i8* [[T8]]) +// CHECK-NEXT: call void @llvm.objc.release(i8* [[T8]]) // CHECK-NEXT: ret void // rdar://problem/9953540 @@ -1495,10 +1495,10 @@ void test68(void) { // CHECK-NEXT: [[CLPTR1:%.*]] = bitcast i8** [[CL]] to i8* // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[CLPTR1]]) // CHECK-NEXT: [[T0:%.*]] = call i8* @test67_helper() -// CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]]) +// CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) // CHECK-NEXT: store i8* [[T1]], i8** [[CL]], align 8 // CHECK-NEXT: [[T2:%.*]] = load i8*, i8** [[CL]] -// CHECK-NEXT: call void @objc_release(i8* [[T2]]) +// CHECK-NEXT: call void @llvm.objc.release(i8* [[T2]]) // CHECK-NEXT: [[CLPTR2:%.*]] = bitcast i8** [[CL]] to i8* // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[CLPTR2]]) // CHECK-NEXT: ret void @@ -1519,7 +1519,7 @@ void test70(id i) { // CHECK-LABEL: define void @test70 // CHECK: store i8* null, i8** // CHECK: store i8* null, i8** - // CHECK: [[ID:%.*]] = call i8* @objc_retain(i8* + // CHECK: [[ID:%.*]] = call i8* @llvm.objc.retain(i8* // CHECK: store i8* [[ID]], i8** id x[3] = { [2] = i diff --git a/test/CodeGenObjC/autorelease.m b/test/CodeGenObjC/autorelease.m index ab65f8088d..0677340eae 100644 --- a/test/CodeGenObjC/autorelease.m +++ b/test/CodeGenObjC/autorelease.m @@ -25,9 +25,9 @@ } @end -// CHECK: call i8* @objc_autoreleasePoolPush +// CHECK: call i8* @llvm.objc.autoreleasePoolPush // CHECK: [[T:%.*]] = load i8*, i8** [[A:%.*]] -// CHECK: call void @objc_autoreleasePoolPop +// CHECK: call void @llvm.objc.autoreleasePoolPop // rdar://13660038 int tryTo(int (*f)(void)) { @@ -41,7 +41,7 @@ int tryTo(int (*f)(void)) { } // CHECK-LABEL: define i32 @tryTo(i32 ()* // CHECK: [[RET:%.*]] = alloca i32, -// CHECK: [[T0:%.*]] = call i8* @objc_autoreleasePoolPush() +// CHECK: [[T0:%.*]] = call i8* @llvm.objc.autoreleasePoolPush() // CHECK-NEXT: [[T1:%.*]] = load i32 ()*, i32 ()** {{%.*}}, // CHECK-NEXT: [[T2:%.*]] = invoke i32 [[T1]]() // CHECK: store i32 [[T2]], i32* [[RET]] diff --git a/test/CodeGenObjC/debug-info-block-line.m b/test/CodeGenObjC/debug-info-block-line.m index d4c409411c..863912e5df 100644 --- a/test/CodeGenObjC/debug-info-block-line.m +++ b/test/CodeGenObjC/debug-info-block-line.m @@ -62,16 +62,16 @@ typedef enum : NSUInteger { TMap *map = [TMap mapForID:mapID]; // Make sure we do not map code generated for the block to the above line. // CHECK: define internal void @"__39-[TServer serverConnection:getCommand:]_block_invoke" -// CHECK: call void @objc_storeStrong(i8** [[ZERO:%.*]], i8* [[ONE:%.*]]) [[NUW:#[0-9]+]] -// CHECK: call void @objc_storeStrong(i8** [[TWO:%.*]], i8* [[THREE:%.*]]) [[NUW]] +// CHECK: call void @llvm.objc.storeStrong(i8** [[ZERO:%.*]], i8* [[ONE:%.*]]) [[NUW:#[0-9]+]] +// CHECK: call void @llvm.objc.storeStrong(i8** [[TWO:%.*]], i8* [[THREE:%.*]]) [[NUW]] // CHECK: call {{.*}}@objc_msgSend{{.*}}, !dbg ![[LINE_ABOVE:[0-9]+]] // CHECK: getelementptr // CHECK-NOT: !dbg, ![[LINE_ABOVE]] // CHECK: bitcast %5** [[TMP:%.*]] to i8** // CHECK-NOT: !dbg, ![[LINE_ABOVE]] -// CHECK: call void @objc_storeStrong(i8** [[VAL1:%.*]], i8* null) [[NUW]] +// CHECK: call void @llvm.objc.storeStrong(i8** [[VAL1:%.*]], i8* null) [[NUW]] // CHECK-NEXT: bitcast %4** [[TMP:%.*]] to i8** -// CHECK-NEXT: call void @objc_storeStrong(i8** [[VAL2:%.*]], i8* null) [[NUW]] +// CHECK-NEXT: call void @llvm.objc.storeStrong(i8** [[VAL2:%.*]], i8* null) [[NUW]] // CHECK-NEXT: ret // CHECK: attributes [[NUW]] = { nounwind } [map dataWithCompletionBlock:^(NSData *data, NSError *error) { diff --git a/test/CodeGenObjC/empty-collection-literals.m b/test/CodeGenObjC/empty-collection-literals.m index 4b1d7f6ebe..313c8c86c1 100644 --- a/test/CodeGenObjC/empty-collection-literals.m +++ b/test/CodeGenObjC/empty-collection-literals.m @@ -17,16 +17,16 @@ void test_empty_array() { // CHECK-WITHOUT-EMPTY-COLLECTIONS-NOT: ret void // CHECK-WITHOUT-EMPTY-COLLECTIONS: {{call.*objc_msgSend}} // CHECK-WITHOUT-EMPTY-COLLECTIONS-NOT: ret void - // CHECK-WITHOUT-EMPTY-COLLECTIONS: {{call.*objc_retainAutoreleasedReturnValue}} + // CHECK-WITHOUT-EMPTY-COLLECTIONS: {{call.*llvm.objc.retainAutoreleasedReturnValue}} // CHECK-WITHOUT-EMPTY-COLLECTIONS: ret void // CHECK-WITH-EMPTY-COLLECTIONS-LABEL: define void @test_empty_array // CHECK-WITH-EMPTY-COLLECTIONS-NOT: ret void // CHECK-WITH-EMPTY-COLLECTIONS: load {{.*}} @__NSArray0__ // CHECK-WITH-EMPTY-COLLECTIONS-NOT: ret void - // CHECK-WITH-EMPTY-COLLECTIONS: {{call.*objc_retain\(}} + // CHECK-WITH-EMPTY-COLLECTIONS: {{call.*llvm.objc.retain\(}} // CHECK-WITH-EMPTY-COLLECTIONS-NOT: ret void - // CHECK-WITH-EMPTY-COLLECTIONS: call void @objc_storeStrong + // CHECK-WITH-EMPTY-COLLECTIONS: call void @llvm.objc.storeStrong // CHECK-WITH-EMPTY-COLLECTIONS-NEXT: ret void NSArray *arr = @[]; } @@ -36,16 +36,16 @@ void test_empty_dictionary() { // CHECK-WITHOUT-EMPTY-COLLECTIONS-NOT: ret void // CHECK-WITHOUT-EMPTY-COLLECTIONS: {{call.*objc_msgSend}} // CHECK-WITHOUT-EMPTY-COLLECTIONS-NOT: ret void - // CHECK-WITHOUT-EMPTY-COLLECTIONS: {{call.*objc_retainAutoreleasedReturnValue}} + // CHECK-WITHOUT-EMPTY-COLLECTIONS: {{call.*llvm.objc.retainAutoreleasedReturnValue}} // CHECK-WITHOUT-EMPTY-COLLECTIONS: ret void // CHECK-WITH-EMPTY-COLLECTIONS-LABEL: define void @test_empty_dictionary // CHECK-WITH-EMPTY-COLLECTIONS-NOT: ret void // CHECK-WITH-EMPTY-COLLECTIONS: load {{.*}} @__NSDictionary0__{{.*}}!invariant.load // CHECK-WITH-EMPTY-COLLECTIONS-NOT: ret void - // CHECK-WITH-EMPTY-COLLECTIONS: {{call.*objc_retain\(}} + // CHECK-WITH-EMPTY-COLLECTIONS: {{call.*llvm.objc.retain\(}} // CHECK-WITH-EMPTY-COLLECTIONS-NOT: ret void - // CHECK-WITH-EMPTY-COLLECTIONS: call void @objc_storeStrong + // CHECK-WITH-EMPTY-COLLECTIONS: call void @llvm.objc.storeStrong // CHECK-WITH-EMPTY-COLLECTIONS-NEXT: ret void NSDictionary *dict = @{}; } diff --git a/test/CodeGenObjC/fragile-arc.m b/test/CodeGenObjC/fragile-arc.m index 98a60133e2..1320a147bb 100644 --- a/test/CodeGenObjC/fragile-arc.m +++ b/test/CodeGenObjC/fragile-arc.m @@ -37,7 +37,7 @@ // CHECK-NEXT: [[IVAR:%.*]] = bitcast i8* [[T1]] to [[OPAQUE]]** // CHECK-NEXT: [[T0:%.*]] = load [[OPAQUE]]*, [[OPAQUE]]** [[IVAR]] // CHECK-NEXT: [[T1:%.*]] = bitcast [[OPAQUE]]* [[T0]] to i8* -// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retain(i8* [[T1]]) +// CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retain(i8* [[T1]]) // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[OPAQUE]]* // CHECK-NEXT: store [[OPAQUE]]* [[T3]], [[OPAQUE]]** [[X]] Opaque *x = strong; @@ -48,10 +48,10 @@ // CHECK-NEXT: [[IVAR:%.*]] = bitcast i8* [[T1]] to [[OPAQUE]]** // CHECK-NEXT: [[T0:%.*]] = bitcast [[OPAQUE]]** [[IVAR]] to i8** // CHECK-NEXT: [[T1:%.*]] = bitcast [[OPAQUE]]* [[VALUE]] to i8* -// CHECK-NEXT: call void @objc_storeStrong(i8** [[T0]], i8* [[T1]]) +// CHECK-NEXT: call void @llvm.objc.storeStrong(i8** [[T0]], i8* [[T1]]) strong = x; // CHECK-NEXT: [[T0:%.*]] = bitcast [[OPAQUE]]** [[X]] to i8** -// CHECK-NEXT: call void @objc_storeStrong(i8** [[T0]], i8* null) +// CHECK-NEXT: call void @llvm.objc.storeStrong(i8** [[T0]], i8* null) // CHECK-NEXT: ret void } @@ -64,7 +64,7 @@ // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8, i8* [[T0]], i32 8 // CHECK-NEXT: [[IVAR:%.*]] = bitcast i8* [[T1]] to [[OPAQUE]]** // CHECK-NEXT: [[T0:%.*]] = bitcast [[OPAQUE]]** [[IVAR]] to i8** -// CHECK-NEXT: [[T1:%.*]] = call i8* @objc_loadWeakRetained(i8** [[T0]]) +// CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.loadWeakRetained(i8** [[T0]]) // CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[T1]] to [[OPAQUE]]* // CHECK-NEXT: store [[OPAQUE]]* [[T2]], [[OPAQUE]]** [[X]] Opaque *x = weak; @@ -75,10 +75,10 @@ // CHECK-NEXT: [[IVAR:%.*]] = bitcast i8* [[T1]] to [[OPAQUE]]** // CHECK-NEXT: [[T0:%.*]] = bitcast [[OPAQUE]]** [[IVAR]] to i8** // CHECK-NEXT: [[T1:%.*]] = bitcast [[OPAQUE]]* [[VALUE]] to i8* -// CHECK-NEXT: call i8* @objc_storeWeak(i8** [[T0]], i8* [[T1]]) +// CHECK-NEXT: call i8* @llvm.objc.storeWeak(i8** [[T0]], i8* [[T1]]) weak = x; // CHECK-NEXT: [[T0:%.*]] = bitcast [[OPAQUE]]** [[X]] to i8** -// CHECK-NEXT: call void @objc_storeStrong(i8** [[T0]], i8* null) +// CHECK-NEXT: call void @llvm.objc.storeStrong(i8** [[T0]], i8* null) // CHECK-NEXT: ret void } @@ -89,12 +89,12 @@ // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8, i8* [[T0]], i32 8 // CHECK-NEXT: [[IVAR:%.*]] = bitcast i8* [[T1]] to [[OPAQUE]]** // CHECK-NEXT: [[T0:%.*]] = bitcast [[OPAQUE]]** [[IVAR]] to i8** -// CHECK-NEXT: call void @objc_destroyWeak(i8** [[T0]]) +// CHECK-NEXT: call void @llvm.objc.destroyWeak(i8** [[T0]]) // CHECK-NEXT: [[T0:%.*]] = bitcast [[A]]* [[SELF]] to i8* // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8, i8* [[T0]], i32 4 // CHECK-NEXT: [[IVAR:%.*]] = bitcast i8* [[T1]] to [[OPAQUE]]** // CHECK-NEXT: [[T0:%.*]] = bitcast [[OPAQUE]]** [[IVAR]] to i8** -// CHECK-NEXT: call void @objc_storeStrong(i8** [[T0]], i8* null) +// CHECK-NEXT: call void @llvm.objc.storeStrong(i8** [[T0]], i8* null) // CHECK-NEXT: ret void @end @@ -151,17 +151,17 @@ void testBlockLayoutWeak(__weak id x) { // CHECK: br i1 // CHECK: [[T0:%.*]] = bitcast i8* [[EXN]] to [[A]]* // CHECK: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8* -// CHECK: [[T2:%.*]] = call i8* @objc_retain(i8* [[T1]]) +// CHECK: [[T2:%.*]] = call i8* @llvm.objc.retain(i8* [[T1]]) // CHECK: [[T3:%.*]] = bitcast i8* [[T2]] to [[A]]* // CHECK: store [[A]]* [[T3]], [[A]]** [[X]] // CHECK: call void @checkpoint(i32 1) // CHECK: [[T0:%.*]] = bitcast [[A]]** [[X]] to i8** -// CHECK: call void @objc_storeStrong(i8** [[T0]], i8* null) +// CHECK: call void @llvm.objc.storeStrong(i8** [[T0]], i8* null) // CHECK: br label -// CHECK: [[T0:%.*]] = call i8* @objc_retain(i8* [[EXN]]) +// CHECK: [[T0:%.*]] = call i8* @llvm.objc.retain(i8* [[EXN]]) // CHECK: store i8* [[T0]], i8** [[Y]] // CHECK: call void @checkpoint(i32 2) -// CHECK: call void @objc_storeStrong(i8** [[Y]], i8* null) +// CHECK: call void @llvm.objc.storeStrong(i8** [[Y]], i8* null) extern void checkpoint(int n); void testCatch() { @try { diff --git a/test/CodeGenObjC/mrc-weak.m b/test/CodeGenObjC/mrc-weak.m index f77b945617..3a8cd2fd75 100644 --- a/test/CodeGenObjC/mrc-weak.m +++ b/test/CodeGenObjC/mrc-weak.m @@ -46,15 +46,15 @@ @implementation Foo // CHECK-LABEL: define internal void @"\01-[Foo .cxx_destruct]" -// CHECK: call void @objc_destroyWeak +// CHECK: call void @llvm.objc.destroyWeak @end void test1(__weak id x) {} // CHECK-LABEL: define void @test1 // CHECK: [[X:%.*]] = alloca i8*, -// CHECK-NEXT: objc_initWeak -// CHECK-NEXT: objc_destroyWeak +// CHECK-NEXT: @llvm.objc.initWeak +// CHECK-NEXT: @llvm.objc.destroyWeak // CHECK-NEXT: ret void void test2(id y) { @@ -65,8 +65,8 @@ void test2(id y) { // CHECK-NEXT: [[Z:%.*]] = alloca i8*, // CHECK-NEXT: store // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[Y]] -// CHECK-NEXT: call i8* @objc_initWeak(i8** [[Z]], i8* [[T0]]) -// CHECK-NEXT: call void @objc_destroyWeak(i8** [[Z]]) +// CHECK-NEXT: call i8* @llvm.objc.initWeak(i8** [[Z]], i8* [[T0]]) +// CHECK-NEXT: call void @llvm.objc.destroyWeak(i8** [[Z]]) // CHECK-NEXT: ret void void test3(id y) { @@ -79,8 +79,8 @@ void test3(id y) { // CHECK-NEXT: store // CHECK-NEXT: store i8* null, i8** [[Z]] // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[Y]] -// CHECK-NEXT: call i8* @objc_storeWeak(i8** [[Z]], i8* [[T0]]) -// CHECK-NEXT: call void @objc_destroyWeak(i8** [[Z]]) +// CHECK-NEXT: call i8* @llvm.objc.storeWeak(i8** [[Z]], i8* [[T0]]) +// CHECK-NEXT: call void @llvm.objc.destroyWeak(i8** [[Z]]) // CHECK-NEXT: ret void void test4(__weak id *p) { @@ -91,7 +91,7 @@ void test4(__weak id *p) { // CHECK-NEXT: [[Y:%.*]] = alloca i8*, // CHECK-NEXT: store // CHECK-NEXT: [[T0:%.*]] = load i8**, i8*** [[P]] -// CHECK-NEXT: [[T1:%.*]] = call i8* @objc_loadWeak(i8** [[T0]]) +// CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.loadWeak(i8** [[T0]]) // CHECK-NEXT: store i8* [[T1]], i8** [[Y]] // CHECK-NEXT: ret void @@ -103,7 +103,7 @@ void test5(__weak id *p) { // CHECK-NEXT: [[Y:%.*]] = alloca i8*, // CHECK-NEXT: store // CHECK-NEXT: [[T0:%.*]] = load i8**, i8*** [[P]] -// CHECK-NEXT: [[T1:%.*]] = call i8* @objc_loadWeakRetained(i8** [[T0]]) +// CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.loadWeakRetained(i8** [[T0]]) // CHECK-NEXT: store i8* [[T1]], i8** [[Y]] // CHECK-NEXT: ret void @@ -116,7 +116,7 @@ void test6(__weak Foo **p) { // CHECK-NEXT: store // CHECK-NEXT: [[T0:%.*]] = load [[FOO]]**, [[FOO]]*** [[P]] // CHECK-NEXT: [[T1:%.*]] = bitcast [[FOO]]** [[T0]] to i8** -// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_loadWeakRetained(i8** [[T1]]) +// CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.loadWeakRetained(i8** [[T1]]) // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[FOO]]* // CHECK-NEXT: store [[FOO]]* [[T3]], [[FOO]]** [[Y]] // CHECK-NEXT: ret void @@ -134,32 +134,32 @@ void test7(void) { // CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[FOO]]* // CHECK-NEXT: [[T2:%.*]] = bitcast [[FOO]]** [[P]] to i8** // CHECK-NEXT: [[T3:%.*]] = bitcast [[FOO]]* [[T1]] to i8* -// CHECK-NEXT: call i8* @objc_initWeak(i8** [[T2]], i8* [[T3]]) -// CHECK: call void @objc_copyWeak +// CHECK-NEXT: call i8* @llvm.objc.initWeak(i8** [[T2]], i8* [[T3]]) +// CHECK: call void @llvm.objc.copyWeak // CHECK: call void @use_block -// CHECK: call void @objc_destroyWeak +// CHECK: call void @llvm.objc.destroyWeak // CHECK-LABEL: define linkonce_odr hidden void @__copy_helper_block -// CHECK: @objc_copyWeak +// CHECK: @llvm.objc.copyWeak // CHECK-LABEL: define linkonce_odr hidden void @__destroy_helper_block -// CHECK: @objc_destroyWeak +// CHECK: @llvm.objc.destroyWeak void test8(void) { __block __weak Foo *p = get_object(); use_block(^{ [p run ]; }); } // CHECK-LABEL: define void @test8 -// CHECK: call i8* @objc_initWeak -// CHECK-NOT: call void @objc_copyWeak +// CHECK: call i8* @llvm.objc.initWeak +// CHECK-NOT: call void @llvm.objc.copyWeak // CHECK: call void @use_block -// CHECK: call void @objc_destroyWeak +// CHECK: call void @llvm.objc.destroyWeak // CHECK-LABEL: define internal void @__Block_byref_object_copy -// CHECK: call void @objc_moveWeak +// CHECK: call void @llvm.objc.moveWeak // CHECK-LABEL: define internal void @__Block_byref_object_dispose -// CHECK: call void @objc_destroyWeak +// CHECK: call void @llvm.objc.destroyWeak // CHECK-LABEL: define void @test9_baseline() // CHECK: define linkonce_odr hidden void @__copy_helper diff --git a/test/CodeGenObjC/noescape.m b/test/CodeGenObjC/noescape.m index c7624f24fb..0c4f3ddddf 100644 --- a/test/CodeGenObjC/noescape.m +++ b/test/CodeGenObjC/noescape.m @@ -94,7 +94,7 @@ void test5(BlockTy2 b, int *p) { // CHECK: %[[BLOCK:.*]] = alloca <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8* }>, align 8 // CHECK-NOARC: store i8* %[[B]], i8** %[[B_ADDR]], align 8 // CHECK-ARC: store i8* null, i8** %[[B_ADDR]], align 8 -// CHECK-ARC: call void @objc_storeStrong(i8** %[[B_ADDR]], i8* %[[B]]) +// CHECK-ARC: call void @llvm.objc.storeStrong(i8** %[[B_ADDR]], i8* %[[B]]) // CHECK-ARC: %[[V0:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8* }>, <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8* }>* %[[BLOCK]], i32 0, i32 5 // CHECK: %[[BLOCK_ISA:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8* }>, <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8* }>* %[[BLOCK]], i32 0, i32 0 // CHECK: store i8* bitcast (i8** @_NSConcreteGlobalBlock to i8*), i8** %[[BLOCK_ISA]], align 8 @@ -106,11 +106,11 @@ void test5(BlockTy2 b, int *p) { // CHECK-NOARC: %[[V1:.*]] = load i8*, i8** %[[B_ADDR]], align 8 // CHECK-NOARC: store i8* %[[V1]], i8** %[[BLOCK_CAPTURED]], align 8 // CHECK-ARC: %[[V2:.*]] = load i8*, i8** %[[B_ADDR]], align 8 -// CHECK-ARC: %[[V3:.*]] = call i8* @objc_retain(i8* %[[V2]]) +// CHECK-ARC: %[[V3:.*]] = call i8* @llvm.objc.retain(i8* %[[V2]]) // CHECK-ARC: store i8* %[[V3]], i8** %[[BLOCK_CAPTURED]], align 8 // CHECK: call void @noescapeFunc0( -// CHECK-ARC: call void @objc_storeStrong(i8** %[[V0]], i8* null) -// CHECK-ARC: call void @objc_storeStrong(i8** %[[B_ADDR]], i8* null) +// CHECK-ARC: call void @llvm.objc.storeStrong(i8** %[[V0]], i8* null) +// CHECK-ARC: call void @llvm.objc.storeStrong(i8** %[[B_ADDR]], i8* null) // Non-escaping blocks don't need copy/dispose helper functions. diff --git a/test/CodeGenObjC/ns_consume_null_check.m b/test/CodeGenObjC/ns_consume_null_check.m index 777659f268..292dfeedb9 100644 --- a/test/CodeGenObjC/ns_consume_null_check.m +++ b/test/CodeGenObjC/ns_consume_null_check.m @@ -17,7 +17,7 @@ void test0(void) { [x isEqual : obj]; } // CHECK-LABEL: define void @test0() -// CHECK: [[FIVE:%.*]] = call i8* @objc_retain +// CHECK: [[FIVE:%.*]] = call i8* @llvm.objc.retain // CHECK-NEXT: [[SIX:%.*]] = bitcast // CHECK-NEXT: [[SEVEN:%.*]] = icmp eq i8* [[SIX]], null // CHECK-NEXT: br i1 [[SEVEN]], label [[NULLINIT:%.*]], label [[CALL_LABEL:%.*]] @@ -25,7 +25,7 @@ void test0(void) { // CHECK-NEXT: [[EIGHT:%.*]] = bitcast i8* [[FN]] // CHECK-NEXT: [[CALL:%.*]] = call signext i8 [[EIGHT]] // CHECK-NEXT: br label [[CONT:%.*]] -// CHECK: call void @objc_release(i8* [[FIVE]]) [[NUW:#[0-9]+]] +// CHECK: call void @llvm.objc.release(i8* [[FIVE]]) [[NUW:#[0-9]+]] // CHECK-NEXT: br label [[CONT]] // CHECK: phi i8 [ [[CALL]], {{%.*}} ], [ 0, {{%.*}} ] @@ -44,11 +44,11 @@ void test1(void) { // CHECK: [[T0:%.*]] = call i8* bitcast ( // CHECK-NEXT: store i8* [[T0]], i8** [[OBJ]] // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[OBJ]] -// CHECK-NEXT: call i8* @objc_initWeak(i8** [[WEAKOBJ]], i8* [[T0]]) [[NUW]] +// CHECK-NEXT: call i8* @llvm.objc.initWeak(i8** [[WEAKOBJ]], i8* [[T0]]) [[NUW]] // Okay, start the message-send. // CHECK-NEXT: [[T0:%.*]] = load [[MYOBJECT:%.*]]*, [[MYOBJECT:%.*]]** @x // CHECK-NEXT: [[ARG:%.*]] = load i8*, i8** [[OBJ]] -// CHECK-NEXT: [[ARG_RETAINED:%.*]] = call i8* @objc_retain(i8* [[ARG]]) +// CHECK-NEXT: [[ARG_RETAINED:%.*]] = call i8* @llvm.objc.retain(i8* [[ARG]]) // CHECK-NEXT: load i8*, i8** @ // CHECK-NEXT: [[SELF:%.*]] = bitcast [[MYOBJECT]]* [[T0]] to i8* // Null check. @@ -65,7 +65,7 @@ void test1(void) { // CHECK-NEXT: [[IMAGCALL:%.*]] = load float, float* [[T0]] // CHECK-NEXT: br label [[CONT:%.*]]{{$}} // Null path. -// CHECK: call void @objc_release(i8* [[ARG_RETAINED]]) [[NUW]] +// CHECK: call void @llvm.objc.release(i8* [[ARG_RETAINED]]) [[NUW]] // CHECK-NEXT: br label [[CONT]] // Join point. // CHECK: [[REAL:%.*]] = phi float [ [[REALCALL]], [[INVOKE_CONT]] ], [ 0.000000e+00, [[FORNULL]] ] @@ -75,11 +75,11 @@ void test1(void) { // CHECK-NEXT: store float [[REAL]], float* [[T0]] // CHECK-NEXT: store float [[IMAG]], float* [[T1]] // Epilogue. -// CHECK-NEXT: call void @objc_destroyWeak(i8** [[WEAKOBJ]]) [[NUW]] -// CHECK-NEXT: call void @objc_storeStrong(i8** [[OBJ]], i8* null) [[NUW]] +// CHECK-NEXT: call void @llvm.objc.destroyWeak(i8** [[WEAKOBJ]]) [[NUW]] +// CHECK-NEXT: call void @llvm.objc.storeStrong(i8** [[OBJ]], i8* null) [[NUW]] // CHECK-NEXT: ret void // Cleanup. // CHECK: landingpad -// CHECK: call void @objc_destroyWeak(i8** [[WEAKOBJ]]) [[NUW]] +// CHECK: call void @llvm.objc.destroyWeak(i8** [[WEAKOBJ]]) [[NUW]] // CHECK: attributes [[NUW]] = { nounwind } diff --git a/test/CodeGenObjC/nsvalue-objc-boxable-ios-arc.m b/test/CodeGenObjC/nsvalue-objc-boxable-ios-arc.m index bab6e27bb3..4ca5adf1ca 100644 --- a/test/CodeGenObjC/nsvalue-objc-boxable-ios-arc.m +++ b/test/CodeGenObjC/nsvalue-objc-boxable-ios-arc.m @@ -25,9 +25,9 @@ void doRange() { // CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8* NSRange ns_range = { .location = 0, .length = 42 }; // CHECK: call {{.*objc_msgSend.*}}(i8* [[RECV]], i8* [[SEL]], i8* [[PARAM_CAST]], i8* {{.*}}[[RANGE_STR]]{{.*}}) - // CHECK: call i8* @objc_retainAutoreleasedReturnValue + // CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue NSValue *range = @(ns_range); - // CHECK: call void @objc_release + // CHECK: call void @llvm.objc.release // CHECK: ret void } @@ -44,9 +44,9 @@ void doPoint() { // CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8* CGPoint cg_point = { .x = 42, .y = 24 }; // CHECK: call {{.*objc_msgSend.*}}(i8* [[RECV]], i8* [[SEL]], i8* [[PARAM_CAST]], i8* {{.*}}[[POINT_STR]]{{.*}}) - // CHECK: call i8* @objc_retainAutoreleasedReturnValue + // CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue NSValue *point = @(cg_point); - // CHECK: call void @objc_release + // CHECK: call void @llvm.objc.release // CHECK: ret void } @@ -63,9 +63,9 @@ void doSize() { // CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8* CGSize cg_size = { .width = 42, .height = 24 }; // CHECK: call {{.*objc_msgSend.*}}(i8* [[RECV]], i8* [[SEL]], i8* [[PARAM_CAST]], i8* {{.*}}[[SIZE_STR]]{{.*}}) - // CHECK: call i8* @objc_retainAutoreleasedReturnValue + // CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue NSValue *size = @(cg_size); - // CHECK: call void @objc_release + // CHECK: call void @llvm.objc.release // CHECK: ret void } @@ -84,9 +84,9 @@ void doRect() { CGSize cg_size = { .width = 42, .height = 24 }; CGRect cg_rect = { .origin = cg_point, .size = cg_size }; // CHECK: call {{.*objc_msgSend.*}}(i8* [[RECV]], i8* [[SEL]], i8* [[PARAM_CAST]], i8*{{.*}}[[RECT_STR]]{{.*}}) - // CHECK: call i8* @objc_retainAutoreleasedReturnValue + // CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue NSValue *rect = @(cg_rect); - // CHECK: call void @objc_release + // CHECK: call void @llvm.objc.release // CHECK: ret void } @@ -103,9 +103,9 @@ void doNSEdgeInsets() { // CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8* NSEdgeInsets ns_edge_insets; // CHECK: call {{.*objc_msgSend.*}}(i8* [[RECV]], i8* [[SEL]], i8* [[PARAM_CAST]], i8*{{.*}}[[EDGE_STR]]{{.*}}) - // CHECK: call i8* @objc_retainAutoreleasedReturnValue + // CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue NSValue *edge_insets = @(ns_edge_insets); - // CHECK: call void @objc_release + // CHECK: call void @llvm.objc.release // CHECK: ret void } @@ -118,9 +118,9 @@ void doRangeRValue() { // CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]] // CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8* // CHECK: call {{.*objc_msgSend.*}}(i8* [[RECV]], i8* [[SEL]], i8* [[COERCE_CAST]], i8* {{.*}}[[RANGE_STR]]{{.*}}) - // CHECK: call i8* @objc_retainAutoreleasedReturnValue + // CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue NSValue *range_rvalue = @(getRange()); - // CHECK: call void @objc_release + // CHECK: call void @llvm.objc.release // CHECK: ret void } diff --git a/test/CodeGenObjC/nsvalue-objc-boxable-mac-arc.m b/test/CodeGenObjC/nsvalue-objc-boxable-mac-arc.m index a2b4dfd6d9..041f03873b 100644 --- a/test/CodeGenObjC/nsvalue-objc-boxable-mac-arc.m +++ b/test/CodeGenObjC/nsvalue-objc-boxable-mac-arc.m @@ -25,9 +25,9 @@ void doRange() { // CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8* NSRange ns_range = { .location = 0, .length = 42 }; // CHECK: call {{.*objc_msgSend.*}}(i8* [[RECV]], i8* [[SEL]], i8* [[PARAM_CAST]], i8* {{.*}}[[RANGE_STR]]{{.*}}) - // CHECK: call i8* @objc_retainAutoreleasedReturnValue + // CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue NSValue *range = @(ns_range); - // CHECK: call void @objc_release + // CHECK: call void @llvm.objc.release // CHECK: ret void } @@ -44,9 +44,9 @@ void doPoint() { // CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8* NSPoint ns_point = { .x = 42, .y = 24 }; // CHECK: call {{.*objc_msgSend.*}}(i8* [[RECV]], i8* [[SEL]], i8* [[PARAM_CAST]], i8* {{.*}}[[POINT_STR]]{{.*}}) - // CHECK: call i8* @objc_retainAutoreleasedReturnValue + // CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue NSValue *point = @(ns_point); - // CHECK: call void @objc_release + // CHECK: call void @llvm.objc.release // CHECK: ret void } @@ -63,9 +63,9 @@ void doSize() { // CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8* NSSize ns_size = { .width = 42, .height = 24 }; // CHECK: call {{.*objc_msgSend.*}}(i8* [[RECV]], i8* [[SEL]], i8* [[PARAM_CAST]], i8* {{.*}}[[SIZE_STR]]{{.*}}) - // CHECK: call i8* @objc_retainAutoreleasedReturnValue + // CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue NSValue *size = @(ns_size); - // CHECK: call void @objc_release + // CHECK: call void @llvm.objc.release // CHECK: ret void } @@ -84,9 +84,9 @@ void doRect() { NSSize ns_size = { .width = 42, .height = 24 }; NSRect ns_rect = { .origin = ns_point, .size = ns_size }; // CHECK: call {{.*objc_msgSend.*}}(i8* [[RECV]], i8* [[SEL]], i8* [[PARAM_CAST]], i8*{{.*}}[[RECT_STR]]{{.*}}) - // CHECK: call i8* @objc_retainAutoreleasedReturnValue + // CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue NSValue *rect = @(ns_rect); - // CHECK: call void @objc_release + // CHECK: call void @llvm.objc.release // CHECK: ret void } @@ -103,9 +103,9 @@ void doNSEdgeInsets() { // CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8* NSEdgeInsets ns_edge_insets; // CHECK: call {{.*objc_msgSend.*}}(i8* [[RECV]], i8* [[SEL]], i8* [[PARAM_CAST]], i8*{{.*}}[[EDGE_STR]]{{.*}}) - // CHECK: call i8* @objc_retainAutoreleasedReturnValue + // CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue NSValue *edge_insets = @(ns_edge_insets); - // CHECK: call void @objc_release + // CHECK: call void @llvm.objc.release // CHECK: ret void } @@ -122,9 +122,9 @@ void doRangeRValue() { // CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]] // CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8* // CHECK: call {{.*objc_msgSend.*}}(i8* [[RECV]], i8* [[SEL]], i8* [[COERCE_CAST]], i8* {{.*}}[[RANGE_STR]]{{.*}}) - // CHECK: call i8* @objc_retainAutoreleasedReturnValue + // CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue NSValue *range_rvalue = @(getRange()); - // CHECK: call void @objc_release + // CHECK: call void @llvm.objc.release // CHECK: ret void } diff --git a/test/CodeGenObjC/objc-arc-container-subscripting.m b/test/CodeGenObjC/objc-arc-container-subscripting.m index 182456221c..339415e3c0 100644 --- a/test/CodeGenObjC/objc-arc-container-subscripting.m +++ b/test/CodeGenObjC/objc-arc-container-subscripting.m @@ -12,10 +12,10 @@ id func() { } // CHECK: [[call:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend -// CHECK: [[SIX:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[call]]) [[NUW:#[0-9]+]] +// CHECK: [[SIX:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[call]]) [[NUW:#[0-9]+]] // CHECK: [[ARRAY_CASTED:%.*]] = bitcast %0** {{%.*}} to i8** -// CHECK: call void @objc_storeStrong(i8** [[ARRAY_CASTED]], i8* null) -// CHECK: [[EIGHT:%.*]] = tail call i8* @objc_autoreleaseReturnValue(i8* [[SIX]]) [[NUW]] +// CHECK: call void @llvm.objc.storeStrong(i8** [[ARRAY_CASTED]], i8* null) +// CHECK: [[EIGHT:%.*]] = tail call i8* @llvm.objc.autoreleaseReturnValue(i8* [[SIX]]) [[NUW]] // CHECK: ret i8* [[EIGHT]] // CHECK: attributes [[NUW]] = { nounwind } diff --git a/test/CodeGenObjC/os_log.m b/test/CodeGenObjC/os_log.m index 1cf0c9f1f3..34b62c7c33 100644 --- a/test/CodeGenObjC/os_log.m +++ b/test/CodeGenObjC/os_log.m @@ -21,7 +21,7 @@ void *test_builtin_os_log(void *buf) { // CHECK: %[[CALL:.*]] = tail call %[[TY0:.*]]* (...) @GenString() // CHECK: %[[V0:.*]] = bitcast %[[TY0]]* %[[CALL]] to i8* - // CHECK: %[[V1:.*]] = tail call i8* @objc_retainAutoreleasedReturnValue(i8* %[[V0]]) + // CHECK: %[[V1:.*]] = tail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* %[[V0]]) // CHECK: %[[V2:.*]] = ptrtoint %[[TY0]]* %[[CALL]] to i64 // CHECK: store i8 2, i8* %[[BUF]], align 1 // CHECK: %[[NUMARGS_I:.*]] = getelementptr i8, i8* %[[BUF]], i64 1 @@ -34,7 +34,7 @@ void *test_builtin_os_log(void *buf) { // CHECK: %[[ARGDATACAST_I:.*]] = bitcast i8* %[[ARGDATA_I]] to i64* // CHECK: store i64 %[[V2]], i64* %[[ARGDATACAST_I]], align 1 // CHECK: tail call void (...) @clang.arc.use(%[[TY0]]* %[[CALL]]) - // CHECK: tail call void @objc_release(i8* %[[V0]]) + // CHECK: tail call void @llvm.objc.release(i8* %[[V0]]) // CHECK: ret i8* %[[BUF]] // clang.arc.use is used and removed in IR optimizations. At O0, we should not @@ -45,13 +45,13 @@ void *test_builtin_os_log(void *buf) { // CHECK-O0: %[[V0:.*]] = load i8*, i8** %[[BUF_ADDR]], align 8 // CHECK-O0: %[[CALL:.*]] = call %[[TY0:.*]]* (...) @GenString() // CHECK-O0: %[[V1:.*]] = bitcast %[[TY0]]* %[[CALL]] to i8* - // CHECK-O0: %[[V2:.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* %[[V1]]) + // CHECK-O0: %[[V2:.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* %[[V1]]) // CHECK-O0: %[[V3:.*]] = bitcast i8* %[[V2]] to %[[TY0]]* // CHECK-O0: %[[V4:.*]] = ptrtoint %[[TY0]]* %[[V3]] to i64 // CHECK-O0: call void @__os_log_helper_1_2_1_8_64(i8* %[[V0]], i64 %[[V4]]) // CHECK-O0: %[[V5:.*]] = bitcast %[[TY0]]* %[[V3]] to i8* // CHECK-O0-NOT call void (...) @clang.arc.use({{.*}} - // CHECK-O0: call void @objc_release(i8* %[[V5]]) + // CHECK-O0: call void @llvm.objc.release(i8* %[[V5]]) // CHECK-O0: ret i8* %[[V0]] } diff --git a/test/CodeGenObjC/parameterized_classes.m b/test/CodeGenObjC/parameterized_classes.m index 34aca35af3..c2ddb5b551 100644 --- a/test/CodeGenObjC/parameterized_classes.m +++ b/test/CodeGenObjC/parameterized_classes.m @@ -61,11 +61,11 @@ void printMe(NSString *name) { } // CHECK-LABEL: define void @blockTest void blockTest(NSMutableArray *array, NSString *name) { // CHECK-NOT: ret void - // CHECK: call i8* @objc_retainBlock + // CHECK: call i8* @llvm.objc.retainBlock [array addObject: ^ { printMe(name); }]; // CHECK-NOT: ret void array[0] = ^ { printMe(name); }; - // CHECK: call i8* @objc_retainBlock + // CHECK: call i8* @llvm.objc.retainBlock // CHECK: ret void } @@ -80,7 +80,7 @@ void blockTest(NSMutableArray *array, NSString *name) { // CHECK: %[[V5:.*]] = bitcast i8* %[[ADDPTR]] to %[[IVARTY]]** // CHECK: %[[V6:.*]] = bitcast %[[IVARTY]]** %[[V5]] to i8** // CHECK: %[[V7:.*]] = bitcast %[[IVARTY]]* %[[V2]] to i8* -// CHECK: call void @objc_storeStrong(i8** %[[V6]], i8* %[[V7]]) +// CHECK: call void @llvm.objc.storeStrong(i8** %[[V6]], i8* %[[V7]]) @interface Base : NSObject { DestType _destination; diff --git a/test/CodeGenObjC/stret-lifetime.m b/test/CodeGenObjC/stret-lifetime.m index d81ef34aee..837014d4e6 100644 --- a/test/CodeGenObjC/stret-lifetime.m +++ b/test/CodeGenObjC/stret-lifetime.m @@ -27,7 +27,7 @@ void foo(id o, id p) { // CHECK: @llvm.lifetime.end // ARC: br label - // ARC: call void @objc_release + // ARC: call void @llvm.objc.release // ARC: br label // CHECK-NOT: call void @llvm.memset diff --git a/test/CodeGenObjC/strong-in-c-struct.m b/test/CodeGenObjC/strong-in-c-struct.m index 494b3b26fb..999b89dd60 100644 --- a/test/CodeGenObjC/strong-in-c-struct.m +++ b/test/CodeGenObjC/strong-in-c-struct.m @@ -125,7 +125,7 @@ void func(Strong *); // CHECK: %[[V1:.*]] = bitcast i8** %[[V0]] to i8* // CHECK: %[[V2:.*]] = getelementptr inbounds i8, i8* %[[V1]], i64 24 // CHECK: %[[V3:.*]] = bitcast i8* %[[V2]] to i8** -// CHECK: call void @objc_storeStrong(i8** %[[V3]], i8* null) +// CHECK: call void @llvm.objc.storeStrong(i8** %[[V3]], i8* null) // CHECK: ret void // CHECK: define linkonce_odr hidden void @__destructor_8_s16(i8** %[[DST:.*]]) @@ -135,7 +135,7 @@ void func(Strong *); // CHECK: %[[V1:.*]] = bitcast i8** %[[V0]] to i8* // CHECK: %[[V2:.*]] = getelementptr inbounds i8, i8* %[[V1]], i64 16 // CHECK: %[[V3:.*]] = bitcast i8* %[[V2]] to i8** -// CHECK: call void @objc_storeStrong(i8** %[[V3]], i8* null) +// CHECK: call void @llvm.objc.storeStrong(i8** %[[V3]], i8* null) // CHECK: ret void void test_constructor_destructor_StrongOuter(void) { @@ -169,7 +169,7 @@ void test_constructor_destructor_StrongOuter(void) { // CHECK: %[[V6:.*]] = getelementptr inbounds i8, i8* %[[V5]], i64 24 // CHECK: %[[V7:.*]] = bitcast i8* %[[V6]] to i8** // CHECK: %[[V8:.*]] = load i8*, i8** %[[V7]], align 8 -// CHECK: %[[V9:.*]] = call i8* @objc_retain(i8* %[[V8]]) +// CHECK: %[[V9:.*]] = call i8* @llvm.objc.retain(i8* %[[V8]]) // CHECK: store i8* %[[V9]], i8** %[[V4]], align 8 // CHECK: %[[V10:.*]] = bitcast i8** %[[V0]] to i8* // CHECK: %[[V11:.*]] = getelementptr inbounds i8, i8* %[[V10]], i64 32 @@ -200,7 +200,7 @@ void test_constructor_destructor_StrongOuter(void) { // CHECK: %[[V8:.*]] = getelementptr inbounds i8, i8* %[[V7]], i64 16 // CHECK: %[[V9:.*]] = bitcast i8* %[[V8]] to i8** // CHECK: %[[V10:.*]] = load i8*, i8** %[[V9]], align 8 -// CHECK: %[[V11:.*]] = call i8* @objc_retain(i8* %[[V10]]) +// CHECK: %[[V11:.*]] = call i8* @llvm.objc.retain(i8* %[[V10]]) // CHECK: store i8* %[[V11]], i8** %[[V6]], align 8 // CHECK: ret void @@ -222,7 +222,7 @@ void test_copy_constructor_StrongOuter(StrongOuter *s) { // CHECK: %[[V6:.*]] = getelementptr inbounds i8, i8* %[[V5]], i64 24 // CHECK: %[[V7:.*]] = bitcast i8* %[[V6]] to i8** // CHECK: %[[V8:.*]] = load i8*, i8** %[[V7]], align 8 -// CHECK: call void @objc_storeStrong(i8** %[[V4]], i8* %[[V8]]) +// CHECK: call void @llvm.objc.storeStrong(i8** %[[V4]], i8* %[[V8]]) void test_copy_assignment_StrongOuter(StrongOuter *d, StrongOuter *s) { *d = *s; @@ -283,7 +283,7 @@ void test_move_constructor_StrongOuter(void) { // CHECK: store i8* null, i8** %[[V7]], align 8 // CHECK: %[[V9:.*]] = load i8*, i8** %[[V4]], align 8 // CHECK: store i8* %[[V8]], i8** %[[V4]], align 8 -// CHECK: call void @objc_release(i8* %[[V9]]) +// CHECK: call void @llvm.objc.release(i8* %[[V9]]) void test_move_assignment_StrongOuter(StrongOuter *p) { *p = getStrongOuter(); @@ -363,7 +363,7 @@ void test_destructor_ignored_result(void) { // CHECK: %[[V0:.*]] = load i8**, i8*** %[[DST_ADDR]], align 8 // CHECK: %[[V1:.*]] = load i8**, i8*** %[[SRC_ADDR]], align 8 // CHECK: %[[V2:.*]] = load i8*, i8** %[[V1]], align 8 -// CHECK: %[[V3:.*]] = call i8* @objc_retainBlock(i8* %[[V2]]) +// CHECK: %[[V3:.*]] = call i8* @llvm.objc.retainBlock(i8* %[[V2]]) // CHECK: store i8* %[[V3]], i8** %[[V0]], align 8 // CHECK: ret void @@ -382,10 +382,10 @@ void test_copy_constructor_StrongBlock(StrongBlock *s) { // CHECK: %[[V0:.*]] = load i8**, i8*** %[[DST_ADDR]], align 8 // CHECK: %[[V1:.*]] = load i8**, i8*** %[[SRC_ADDR]], align 8 // CHECK: %[[V2:.*]] = load i8*, i8** %[[V1]], align 8 -// CHECK: %[[V3:.*]] = call i8* @objc_retainBlock(i8* %[[V2]]) +// CHECK: %[[V3:.*]] = call i8* @llvm.objc.retainBlock(i8* %[[V2]]) // CHECK: %[[V4:.*]] = load i8*, i8** %[[V0]], align 8 // CHECK: store i8* %[[V3]], i8** %[[V0]], align 8 -// CHECK: call void @objc_release(i8* %[[V4]]) +// CHECK: call void @llvm.objc.release(i8* %[[V4]]) // CHECK: ret void void test_copy_assignment_StrongBlock(StrongBlock *d, StrongBlock *s) { @@ -398,7 +398,7 @@ void test_copy_assignment_StrongBlock(StrongBlock *d, StrongBlock *s) { // CHECK: define linkonce_odr hidden void @__copy_constructor_8_8_t0w4_sv8( // CHECK: %[[V8:.*]] = load volatile i8*, i8** %{{.*}}, align 8 -// CHECK: %[[V9:.*]] = call i8* @objc_retain(i8* %[[V8]]) +// CHECK: %[[V9:.*]] = call i8* @llvm.objc.retain(i8* %[[V8]]) // CHECK: store volatile i8* %[[V9]], i8** %{{.*}}, align 8 void test_copy_constructor_StrongVolatile0(StrongVolatile *s) { diff --git a/test/CodeGenObjC/weak-in-c-struct.m b/test/CodeGenObjC/weak-in-c-struct.m index b0f4c08510..1b2d860fc3 100644 --- a/test/CodeGenObjC/weak-in-c-struct.m +++ b/test/CodeGenObjC/weak-in-c-struct.m @@ -40,7 +40,7 @@ void calleeWeak(Weak); // ARM64: %[[V1:.*]] = bitcast i8** %[[V0]] to i8* // ARM64: %[[V2:.*]] = getelementptr inbounds i8, i8* %[[V1]], i64 8 // ARM64: %[[V3:.*]] = bitcast i8* %[[V2]] to i8** -// ARM64: call void @objc_destroyWeak(i8** %[[V3]]) +// ARM64: call void @llvm.objc.destroyWeak(i8** %[[V3]]) void test_constructor_destructor_Weak(void) { Weak t; @@ -67,7 +67,7 @@ void test_constructor_destructor_Weak(void) { // ARM64: %[[V8:.*]] = bitcast i8** %[[V1]] to i8* // ARM64: %[[V9:.*]] = getelementptr inbounds i8, i8* %[[V8]], i64 8 // ARM64: %[[V10:.*]] = bitcast i8* %[[V9]] to i8** -// ARM64: call void @objc_copyWeak(i8** %[[V7]], i8** %[[V10]]) +// ARM64: call void @llvm.objc.copyWeak(i8** %[[V7]], i8** %[[V10]]) void test_copy_constructor_Weak(Weak *s) { Weak t = *s; @@ -93,9 +93,9 @@ void test_copy_constructor_Weak(Weak *s) { // ARM64: %[[V8:.*]] = bitcast i8** %[[V1]] to i8* // ARM64: %[[V9:.*]] = getelementptr inbounds i8, i8* %[[V8]], i64 8 // ARM64: %[[V10:.*]] = bitcast i8* %[[V9]] to i8** -// ARM64: %[[V11:.*]] = call i8* @objc_loadWeakRetained(i8** %[[V10]]) -// ARM64: %[[V12:.*]] = call i8* @objc_storeWeak(i8** %[[V7]], i8* %[[V11]]) -// ARM64: call void @objc_release(i8* %[[V11]]) +// ARM64: %[[V11:.*]] = call i8* @llvm.objc.loadWeakRetained(i8** %[[V10]]) +// ARM64: %[[V12:.*]] = call i8* @llvm.objc.storeWeak(i8** %[[V7]], i8* %[[V11]]) +// ARM64: call void @llvm.objc.release(i8* %[[V11]]) void test_copy_assignment_Weak(Weak *d, Weak *s) { *d = *s; @@ -121,7 +121,7 @@ void test_copy_assignment_Weak(Weak *d, Weak *s) { // ARM64: %[[V8:.*]] = bitcast i8** %[[V1]] to i8* // ARM64: %[[V9:.*]] = getelementptr inbounds i8, i8* %[[V8]], i64 8 // ARM64: %[[V10:.*]] = bitcast i8* %[[V9]] to i8** -// ARM64: call void @objc_moveWeak(i8** %[[V7]], i8** %[[V10]]) +// ARM64: call void @llvm.objc.moveWeak(i8** %[[V7]], i8** %[[V10]]) void test_move_constructor_Weak(void) { __block Weak t; @@ -148,10 +148,10 @@ void test_move_constructor_Weak(void) { // ARM64: %[[V8:.*]] = bitcast i8** %[[V1]] to i8* // ARM64: %[[V9:.*]] = getelementptr inbounds i8, i8* %[[V8]], i64 8 // ARM64: %[[V10:.*]] = bitcast i8* %[[V9]] to i8** -// ARM64: %[[V11:.*]] = call i8* @objc_loadWeakRetained(i8** %[[V10]]) -// ARM64: %[[V12:.*]] = call i8* @objc_storeWeak(i8** %[[V7]], i8* %[[V11]]) -// ARM64: call void @objc_destroyWeak(i8** %[[V10]]) -// ARM64: call void @objc_release(i8* %[[V11]]) +// ARM64: %[[V11:.*]] = call i8* @llvm.objc.loadWeakRetained(i8** %[[V10]]) +// ARM64: %[[V12:.*]] = call i8* @llvm.objc.storeWeak(i8** %[[V7]], i8* %[[V11]]) +// ARM64: call void @llvm.objc.destroyWeak(i8** %[[V10]]) +// ARM64: call void @llvm.objc.release(i8* %[[V11]]) void test_move_assignment_Weak(Weak *p) { *p = getWeak(); diff --git a/test/CodeGenObjCXX/arc-attrs.mm b/test/CodeGenObjCXX/arc-attrs.mm index 0b64d77566..5ab7a69de2 100644 --- a/test/CodeGenObjCXX/arc-attrs.mm +++ b/test/CodeGenObjCXX/arc-attrs.mm @@ -15,7 +15,7 @@ void sanityTest() { // CHECK-NEXT: call void @_Z13releaseObjectP11objc_object(i8* [[OBJ2]]) releaseObject(makeObject2()); - // CHECK-NEXT: call void @objc_storeStrong(i8** [[X]], i8* null) + // CHECK-NEXT: call void @llvm.objc.storeStrong(i8** [[X]], i8* null) // CHECK-NEXT: ret void } @@ -43,7 +43,7 @@ void templateTest() { // CHECK-NEXT: call void @_Z14releaseObjectTIU8__strongP11objc_objectEvT_(i8* [[OBJ3]]) releaseObjectT(makeObject1()); - // CHECK-NEXT: call void @objc_storeStrong(i8** [[X]], i8* null) + // CHECK-NEXT: call void @llvm.objc.storeStrong(i8** [[X]], i8* null) // CHECK-NEXT: ret void } @@ -58,7 +58,7 @@ ForwardConsumed::ForwardConsumed(__attribute__((ns_consumed)) id x) {} // CHECK-NOT: objc_retain // CHECK: store i8* {{.*}}, i8** [[X:%.*]], // CHECK-NOT: [[X]] -// CHECK: call void @objc_storeStrong(i8** [[X]], i8* null) +// CHECK: call void @llvm.objc.storeStrong(i8** [[X]], i8* null) // CHECK: define void @_ZN15ForwardConsumedC1EP11objc_object( // CHECK-NOT: objc_retain @@ -66,4 +66,4 @@ ForwardConsumed::ForwardConsumed(__attribute__((ns_consumed)) id x) {} // CHECK: [[T0:%.*]] = load i8*, i8** [[X]], // CHECK-NEXT: store i8* null, i8** [[X]], // CHECK-NEXT: call void @_ZN15ForwardConsumedC2EP11objc_object({{.*}}, i8* [[T0]]) -// CHECK: call void @objc_storeStrong(i8** [[X]], i8* null) +// CHECK: call void @llvm.objc.storeStrong(i8** [[X]], i8* null) diff --git a/test/CodeGenObjCXX/arc-blocks.mm b/test/CodeGenObjCXX/arc-blocks.mm index 4791aff0b3..ec0c12456a 100644 --- a/test/CodeGenObjCXX/arc-blocks.mm +++ b/test/CodeGenObjCXX/arc-blocks.mm @@ -72,7 +72,7 @@ namespace test1 { // CHECK: %[[V10:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8*, i8*, i8*, %[[STRUCT_TEST1_S0]], %[[STRUCT_TEST1_S0]], %[[STRUCT_TRIVIAL_INTERNAL]] }>, <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8*, i8*, i8*, %[[STRUCT_TEST1_S0]], %[[STRUCT_TEST1_S0]], %[[STRUCT_TRIVIAL_INTERNAL]] }>* %[[BLOCK_DEST]], i32 0, i32 5 // CHECK: %[[BLOCKCOPY_SRC2:.*]] = load i8*, i8** %[[V9]], align 8 // CHECK: store i8* null, i8** %[[V10]], align 8 -// CHECK: call void @objc_storeStrong(i8** %[[V10]], i8* %[[BLOCKCOPY_SRC2]]) +// CHECK: call void @llvm.objc.storeStrong(i8** %[[V10]], i8* %[[BLOCKCOPY_SRC2]]) // CHECK: %[[V4:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8*, i8*, i8*, %[[STRUCT_TEST1_S0]], %[[STRUCT_TEST1_S0]], %[[STRUCT_TRIVIAL_INTERNAL]] }>, <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8*, i8*, i8*, %[[STRUCT_TEST1_S0]], %[[STRUCT_TEST1_S0]], %[[STRUCT_TRIVIAL_INTERNAL]] }>* %[[BLOCK_SOURCE]], i32 0, i32 6 // CHECK: %[[V5:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8*, i8*, i8*, %[[STRUCT_TEST1_S0]], %[[STRUCT_TEST1_S0]], %[[STRUCT_TRIVIAL_INTERNAL]] }>, <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8*, i8*, i8*, %[[STRUCT_TEST1_S0]], %[[STRUCT_TEST1_S0]], %[[STRUCT_TRIVIAL_INTERNAL]] }>* %[[BLOCK_DEST]], i32 0, i32 6 @@ -82,7 +82,7 @@ namespace test1 { // CHECK: %[[V7:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8*, i8*, i8*, %[[STRUCT_TEST1_S0]], %[[STRUCT_TEST1_S0]], %[[STRUCT_TRIVIAL_INTERNAL]] }>, <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8*, i8*, i8*, %[[STRUCT_TEST1_S0]], %[[STRUCT_TEST1_S0]], %[[STRUCT_TRIVIAL_INTERNAL]] }>* %[[BLOCK_SOURCE]], i32 0, i32 7 // CHECK: %[[V8:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8*, i8*, i8*, %[[STRUCT_TEST1_S0]], %[[STRUCT_TEST1_S0]], %[[STRUCT_TRIVIAL_INTERNAL]] }>, <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8*, i8*, i8*, %[[STRUCT_TEST1_S0]], %[[STRUCT_TEST1_S0]], %[[STRUCT_TRIVIAL_INTERNAL]] }>* %[[BLOCK_DEST]], i32 0, i32 7 -// CHECK: call void @objc_copyWeak(i8** %[[V8]], i8** %[[V7]]) +// CHECK: call void @llvm.objc.copyWeak(i8** %[[V8]], i8** %[[V7]]) // CHECK: %[[V11:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8*, i8*, i8*, %[[STRUCT_TEST1_S0]], %[[STRUCT_TEST1_S0]], %[[STRUCT_TRIVIAL_INTERNAL]] }>, <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8*, i8*, i8*, %[[STRUCT_TEST1_S0]], %[[STRUCT_TEST1_S0]], %[[STRUCT_TRIVIAL_INTERNAL]] }>* %[[BLOCK_SOURCE]], i32 0, i32 8 // CHECK: %[[V12:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8*, i8*, i8*, %[[STRUCT_TEST1_S0]], %[[STRUCT_TEST1_S0]], %[[STRUCT_TRIVIAL_INTERNAL]] }>, <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8*, i8*, i8*, %[[STRUCT_TEST1_S0]], %[[STRUCT_TEST1_S0]], %[[STRUCT_TRIVIAL_INTERNAL]] }>* %[[BLOCK_DEST]], i32 0, i32 8 @@ -109,10 +109,10 @@ namespace test1 { // CHECK: br label %[[EHCLEANUP]] // CHECK: [[EHCLEANUP]]: -// CHECK: call void @objc_destroyWeak(i8** %[[V8]]) +// CHECK: call void @llvm.objc.destroyWeak(i8** %[[V8]]) // CHECK: %[[V21:.*]] = load i8*, i8** %[[V5]], align 8 // CHECK: call void @_Block_object_dispose(i8* %[[V21]], i32 8) -// CHECK: call void @objc_storeStrong(i8** %[[V10]], i8* null) +// CHECK: call void @llvm.objc.storeStrong(i8** %[[V10]], i8* null) // CHECK: br label %[[EH_RESUME:.*]] // CHECK: [[EH_RESUME]]: @@ -122,7 +122,7 @@ namespace test1 { // CHECK: call void @__clang_call_terminate( // CHECK-O1-LABEL: define linkonce_odr hidden void @__copy_helper_block_ea8_32s40r48w56c15_ZTSN5test12S0E60c15_ZTSN5test12S0E( -// CHECK-O1: tail call void @objc_release({{.*}}) {{.*}} !clang.imprecise_release +// CHECK-O1: tail call void @llvm.objc.release({{.*}}) {{.*}} !clang.imprecise_release // CHECK-NOEXCP: define linkonce_odr hidden void @__copy_helper_block_8_32s40r48w56c15_ZTSN5test12S0E60c15_ZTSN5test12S0E( // CHECK: define linkonce_odr hidden void @__destroy_helper_block_ea8_32s40r48w56c15_ZTSN5test12S0E60c15_ZTSN5test12S0E( @@ -140,10 +140,10 @@ namespace test1 { // CHECK: to label %[[INVOKE_CONT2:.*]] unwind label %[[LPAD1:.*]] // CHECK: [[INVOKE_CONT2]]: -// CHECK: call void @objc_destroyWeak(i8** %[[V3]]) +// CHECK: call void @llvm.objc.destroyWeak(i8** %[[V3]]) // CHECK: %[[V7:.*]] = load i8*, i8** %[[V2]], align 8 // CHECK: call void @_Block_object_dispose(i8* %[[V7]], i32 8) -// CHECK: call void @objc_storeStrong(i8** %[[V4]], i8* null) +// CHECK: call void @llvm.objc.storeStrong(i8** %[[V4]], i8* null) // CHECK: ret void // CHECK: [[LPAD]]: @@ -157,10 +157,10 @@ namespace test1 { // CHECK: br label %[[EHCLEANUP]] // CHECK: [[EHCLEANUP]]: -// CHECK: call void @objc_destroyWeak(i8** %[[V3]]) +// CHECK: call void @llvm.objc.destroyWeak(i8** %[[V3]]) // CHECK: %[[V14:.*]] = load i8*, i8** %[[V2]], align 8 // CHECK: call void @_Block_object_dispose(i8* %[[V14]], i32 8) -// CHECK: call void @objc_storeStrong(i8** %[[V4]], i8* null) +// CHECK: call void @llvm.objc.storeStrong(i8** %[[V4]], i8* null) // CHECK: br label %[[EH_RESUME:.*]] // CHECK: [[EH_RESUME]]: @@ -170,8 +170,8 @@ namespace test1 { // CHECK: call void @__clang_call_terminate( // CHECK-O1-LABEL: define linkonce_odr hidden void @__destroy_helper_block_ea8_32s40r48w56c15_ZTSN5test12S0E60c15_ZTSN5test12S0E( -// CHECK-O1: tail call void @objc_release({{.*}}) {{.*}} !clang.imprecise_release -// CHECK-O1: tail call void @objc_release({{.*}}) {{.*}} !clang.imprecise_release +// CHECK-O1: tail call void @llvm.objc.release({{.*}}) {{.*}} !clang.imprecise_release +// CHECK-O1: tail call void @llvm.objc.release({{.*}}) {{.*}} !clang.imprecise_release // CHECK-NOEXCP: define linkonce_odr hidden void @__destroy_helper_block_8_32s40r48w56c15_ZTSN5test12S0E60c15_ZTSN5test12S0E( namespace { diff --git a/test/CodeGenObjCXX/arc-constexpr.mm b/test/CodeGenObjCXX/arc-constexpr.mm index b12ff57a06..42fafcf2a4 100644 --- a/test/CodeGenObjCXX/arc-constexpr.mm +++ b/test/CodeGenObjCXX/arc-constexpr.mm @@ -6,11 +6,11 @@ // CHECK-LABEL: define void @_Z5test1v // CHECK: %[[ALLOCA:[A-Z]+]] = alloca %[[TYPE]]* -// CHECK: %[[V0:[0-9]+]] = call i8* @objc_retain(i8* bitcast (%struct.__NSConstantString_tag* @[[CFSTRING]] +// CHECK: %[[V0:[0-9]+]] = call i8* @llvm.objc.retain(i8* bitcast (%struct.__NSConstantString_tag* @[[CFSTRING]] // CHECK: %[[V1:[0-9]+]] = bitcast i8* %[[V0]] to %[[TYPE]]* // CHECK: store %[[TYPE]]* %[[V1]], %[[TYPE]]** %[[ALLOCA]] // CHECK: %[[V2:[0-9]+]] = bitcast %[[TYPE]]** %[[ALLOCA]] -// CHECK: call void @objc_storeStrong(i8** %[[V2]], i8* null) +// CHECK: call void @llvm.objc.storeStrong(i8** %[[V2]], i8* null) void test1() { constexpr NSString *S = @"abc"; } @@ -18,16 +18,16 @@ void test1() { // CHECK-LABEL: define void @_Z5test2v // CHECK: %[[CONST:[a-zA-Z]+]] = alloca %[[TYPE]]* // CHECK: %[[REF_CONST:[a-zA-Z]+]] = alloca %[[TYPE]]* -// CHECK: %[[V0:[0-9]+]] = call i8* @objc_retain(i8* bitcast (%struct.__NSConstantString_tag* @[[CFSTRING]] +// CHECK: %[[V0:[0-9]+]] = call i8* @llvm.objc.retain(i8* bitcast (%struct.__NSConstantString_tag* @[[CFSTRING]] // CHECK-NEXT: %[[V1:[0-9]+]] = bitcast i8* %[[V0]] to %[[TYPE]]* // CHECK-NEXT: store %[[TYPE]]* %[[V1]], %[[TYPE]]** %[[CONST]] -// CHECK: %[[V2:[0-9]+]] = call i8* @objc_retain(i8* bitcast (%struct.__NSConstantString_tag* @[[CFSTRING]] +// CHECK: %[[V2:[0-9]+]] = call i8* @llvm.objc.retain(i8* bitcast (%struct.__NSConstantString_tag* @[[CFSTRING]] // CHECK-NEXT: %[[V3:[0-9]+]] = bitcast i8* %[[V2]] to %[[TYPE]]* // CHECK-NEXT: store %[[TYPE]]* %[[V3]], %[[TYPE]]** %[[REF_CONST]] // CHECK: %[[V4:[0-9]+]] = bitcast %[[TYPE]]** %[[REF_CONST]] -// CHECK-NEXT: call void @objc_storeStrong(i8** %[[V4]], i8* null) +// CHECK-NEXT: call void @llvm.objc.storeStrong(i8** %[[V4]], i8* null) // CHECK: %[[V5:[0-9]+]] = bitcast %[[TYPE]]** %[[CONST]] -// CHECK-NEXT: call void @objc_storeStrong(i8** %[[V5]], i8* null) +// CHECK-NEXT: call void @llvm.objc.storeStrong(i8** %[[V5]], i8* null) void test2() { constexpr NSString *Const = @"abc"; // In IR RefConst should be initialized with Const initializer instead of @@ -39,12 +39,12 @@ void test2() { // CHECK: %[[WEAK_CONST:[a-zA-Z]+]] = alloca %[[TYPE]]* // CHECK: %[[REF_WEAK_CONST:[a-zA-Z]+]] = alloca %[[TYPE]]* // CHECK: %[[V0:[0-9]+]] = bitcast %[[TYPE]]** %[[WEAK_CONST]] -// CHECK-NEXT: %[[V1:[0-9]+]] = call i8* @objc_initWeak(i8** %[[V0]], i8* bitcast (%struct.__NSConstantString_tag* @[[CFSTRING]] +// CHECK-NEXT: %[[V1:[0-9]+]] = call i8* @llvm.objc.initWeak(i8** %[[V0]], i8* bitcast (%struct.__NSConstantString_tag* @[[CFSTRING]] // CHECK: store %[[TYPE]]* bitcast (%struct.__NSConstantString_tag* @[[CFSTRING]] to %[[TYPE]]*), %[[TYPE]]** %[[REF_WEAK_CONST]] // CHECK: %[[V2:[0-9]+]] = bitcast %[[TYPE]]** %[[REF_WEAK_CONST]] -// CHECK-NEXT: call void @objc_storeStrong(i8** %[[V2]], i8* null) +// CHECK-NEXT: call void @llvm.objc.storeStrong(i8** %[[V2]], i8* null) // CHECK: %[[V3:[0-9]+]] = bitcast %[[TYPE]]** %[[WEAK_CONST]] -// CHECK-NEXT: call void @objc_destroyWeak(i8** %[[V3]]) +// CHECK-NEXT: call void @llvm.objc.destroyWeak(i8** %[[V3]]) void test3() { __weak constexpr NSString *WeakConst = @"abc"; NSString* RefWeakConst = WeakConst; diff --git a/test/CodeGenObjCXX/arc-cxx11-init-list.mm b/test/CodeGenObjCXX/arc-cxx11-init-list.mm index af607654e1..2c70f64d20 100644 --- a/test/CodeGenObjCXX/arc-cxx11-init-list.mm +++ b/test/CodeGenObjCXX/arc-cxx11-init-list.mm @@ -29,14 +29,14 @@ extern "C" void single() { function({ [I new] }); } // CHECK: [[INSTANCE:%.*]] = {{.*}} call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*)*)(i8* {{.*}}, i8* {{.*}}) // CHECK-NEXT: [[CAST:%.*]] = bitcast [{{[0-9]+}} x %0*]* %{{.*}} to i8** // CHECK-NEXT: store i8* [[INSTANCE]], i8** [[CAST]], -// CHECK: call void @objc_release(i8* {{.*}}) +// CHECK: call void @llvm.objc.release(i8* {{.*}}) extern "C" void multiple() { function({ [I new], [I new] }); } // CHECK: [[INSTANCE:%.*]] = {{.*}} call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*)*)(i8* {{.*}}, i8* {{.*}}) // CHECK-NEXT: [[CAST:%.*]] = bitcast [{{[0-9]+}} x %0*]* %{{.*}} to i8** // CHECK-NEXT: store i8* [[INSTANCE]], i8** [[CAST]], -// CHECK: call void @objc_release(i8* {{.*}}) +// CHECK: call void @llvm.objc.release(i8* {{.*}}) std::initializer_list foo1() { return {@"str0", @"str1"}; @@ -58,11 +58,11 @@ extern "C" void extended() { // CHECK: [[INSTANCE:%.*]] = {{.*}} call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*)*)(i8* {{.*}}, i8* {{.*}}) // CHECK: {{.*}} call void @_Z8externalv() -// CHECK: {{.*}} call void @objc_release(i8* {{.*}}) +// CHECK: {{.*}} call void @llvm.objc.release(i8* {{.*}}) std::initializer_list il = { [I new] }; -// CHECK: [[POOL:%.*]] = {{.*}} call i8* @objc_autoreleasePoolPush() +// CHECK: [[POOL:%.*]] = {{.*}} call i8* @llvm.objc.autoreleasePoolPush() // CHECK: [[INSTANCE:%.*]] = {{.*}} call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*)*)(i8* {{.*}}, i8* {{.*}}) // CHECK-NEXT: store i8* [[INSTANCE]], i8** bitcast ([1 x %0*]* @_ZGR2il_ to i8**) -// CHECK: {{.*}} call void @objc_autoreleasePoolPop(i8* [[POOL]]) +// CHECK: {{.*}} call void @llvm.objc.autoreleasePoolPop(i8* [[POOL]]) diff --git a/test/CodeGenObjCXX/arc-exceptions.mm b/test/CodeGenObjCXX/arc-exceptions.mm index 3d50461350..94e1374c83 100644 --- a/test/CodeGenObjCXX/arc-exceptions.mm +++ b/test/CodeGenObjCXX/arc-exceptions.mm @@ -17,11 +17,11 @@ void test0(void) { // CHECK: [[T0:%.*]] = call i8* @objc_begin_catch( // CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[ETY]]* // CHECK-NEXT: [[T2:%.*]] = bitcast [[ETY]]* [[T1]] to i8* -// CHECK-NEXT: [[T3:%.*]] = call i8* @objc_retain(i8* [[T2]]) [[NUW:#[0-9]+]] +// CHECK-NEXT: [[T3:%.*]] = call i8* @llvm.objc.retain(i8* [[T2]]) [[NUW:#[0-9]+]] // CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to [[ETY]]* // CHECK-NEXT: store [[ETY]]* [[T4]], [[ETY]]** [[E]] // CHECK-NEXT: [[T0:%.*]] = bitcast [[ETY]]** [[E]] to i8** -// CHECK-NEXT: call void @objc_storeStrong(i8** [[T0]], i8* null) [[NUW]] +// CHECK-NEXT: call void @llvm.objc.storeStrong(i8** [[T0]], i8* null) [[NUW]] // CHECK-NEXT: call void @objc_end_catch() [[NUW]] void test1_helper(void); @@ -38,9 +38,9 @@ void test1(void) { // CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[ETY]]* // CHECK-NEXT: [[T2:%.*]] = bitcast [[ETY]]** [[E]] to i8** // CHECK-NEXT: [[T3:%.*]] = bitcast [[ETY]]* [[T1]] to i8* -// CHECK-NEXT: call i8* @objc_initWeak(i8** [[T2]], i8* [[T3]]) [[NUW]] +// CHECK-NEXT: call i8* @llvm.objc.initWeak(i8** [[T2]], i8* [[T3]]) [[NUW]] // CHECK-NEXT: [[T0:%.*]] = bitcast [[ETY]]** [[E]] to i8** -// CHECK-NEXT: call void @objc_destroyWeak(i8** [[T0]]) [[NUW]] +// CHECK-NEXT: call void @llvm.objc.destroyWeak(i8** [[T0]]) [[NUW]] // CHECK-NEXT: call void @objc_end_catch() [[NUW]] void test2_helper(void); @@ -56,11 +56,11 @@ void test2(void) { // CHECK: [[T0:%.*]] = call i8* @__cxa_begin_catch( // CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[ETY]]* // CHECK-NEXT: [[T2:%.*]] = bitcast [[ETY]]* [[T1]] to i8* -// CHECK-NEXT: [[T3:%.*]] = call i8* @objc_retain(i8* [[T2]]) [[NUW]] +// CHECK-NEXT: [[T3:%.*]] = call i8* @llvm.objc.retain(i8* [[T2]]) [[NUW]] // CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to [[ETY]]* // CHECK-NEXT: store [[ETY]]* [[T4]], [[ETY]]** [[E]] // CHECK-NEXT: [[T0:%.*]] = bitcast [[ETY]]** [[E]] to i8** -// CHECK-NEXT: call void @objc_storeStrong(i8** [[T0]], i8* null) [[NUW]] +// CHECK-NEXT: call void @llvm.objc.storeStrong(i8** [[T0]], i8* null) [[NUW]] // CHECK-NEXT: call void @__cxa_end_catch() [[NUW]] void test3_helper(void); @@ -77,9 +77,9 @@ void test3(void) { // CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[ETY]]* // CHECK-NEXT: [[T2:%.*]] = bitcast [[ETY]]** [[E]] to i8** // CHECK-NEXT: [[T3:%.*]] = bitcast [[ETY]]* [[T1]] to i8* -// CHECK-NEXT: call i8* @objc_initWeak(i8** [[T2]], i8* [[T3]]) [[NUW]] +// CHECK-NEXT: call i8* @llvm.objc.initWeak(i8** [[T2]], i8* [[T3]]) [[NUW]] // CHECK-NEXT: [[T0:%.*]] = bitcast [[ETY]]** [[E]] to i8** -// CHECK-NEXT: call void @objc_destroyWeak(i8** [[T0]]) [[NUW]] +// CHECK-NEXT: call void @llvm.objc.destroyWeak(i8** [[T0]]) [[NUW]] // CHECK-NEXT: call void @__cxa_end_catch() [[NUW]] namespace test4 { @@ -112,11 +112,11 @@ namespace test4 { // CHECK-NEXT: br label // CHECK: [[AFTER:%.*]] = phi i8** [ [[ARRAYEND]], {{%.*}} ], [ [[ELT:%.*]], {{%.*}} ] // CHECK-NEXT: [[ELT]] = getelementptr inbounds i8*, i8** [[AFTER]], i64 -1 - // CHECK-NEXT: call void @objc_storeStrong(i8** [[ELT]], i8* null) [[NUW]] + // CHECK-NEXT: call void @llvm.objc.storeStrong(i8** [[ELT]], i8* null) [[NUW]] // CHECK-NEXT: [[DONE:%.*]] = icmp eq i8** [[ELT]], [[ARRAYBEGIN]] // CHECK-NEXT: br i1 [[DONE]], // - Next, destroy single. - // CHECK: call void @objc_storeStrong(i8** [[SINGLE]], i8* null) [[NUW]] + // CHECK: call void @llvm.objc.storeStrong(i8** [[SINGLE]], i8* null) [[NUW]] // CHECK: br label // CHECK: resume } diff --git a/test/CodeGenObjCXX/arc-forwarded-lambda-call.mm b/test/CodeGenObjCXX/arc-forwarded-lambda-call.mm index 0a575c7697..5a5cb42067 100644 --- a/test/CodeGenObjCXX/arc-forwarded-lambda-call.mm +++ b/test/CodeGenObjCXX/arc-forwarded-lambda-call.mm @@ -5,8 +5,8 @@ void test0(id x) { test0_helper([=]() { return x; }); // CHECK-LABEL: define internal i8* @___Z5test0P11objc_object_block_invoke // CHECK: [[T0:%.*]] = call i8* @"_ZZ5test0P11objc_objectENK3$_0clEv" - // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]]) - // CHECK-NEXT: [[T2:%.*]] = tail call i8* @objc_autoreleaseReturnValue(i8* [[T1]]) + // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) + // CHECK-NEXT: [[T2:%.*]] = tail call i8* @llvm.objc.autoreleaseReturnValue(i8* [[T1]]) // CHECK-NEXT: ret i8* [[T2]] } @@ -28,8 +28,8 @@ void test1() { test1_helper([](){ return test1_rv; }); // CHECK-LABEL: define internal i8* @"_ZZ5test1vEN3$_18__invokeEv" // CHECK: [[T0:%.*]] = call i8* @"_ZZ5test1vENK3$_1clEv" - // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]]) - // CHECK-NEXT: [[T2:%.*]] = tail call i8* @objc_autoreleaseReturnValue(i8* [[T1]]) + // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) + // CHECK-NEXT: [[T2:%.*]] = tail call i8* @llvm.objc.autoreleaseReturnValue(i8* [[T1]]) // CHECK-NEXT: ret i8* [[T2]] } diff --git a/test/CodeGenObjCXX/arc-globals.mm b/test/CodeGenObjCXX/arc-globals.mm index a03ac9948b..d5116ee96c 100644 --- a/test/CodeGenObjCXX/arc-globals.mm +++ b/test/CodeGenObjCXX/arc-globals.mm @@ -7,21 +7,21 @@ id getObject(); // CHECK-LABEL: define internal void @__cxx_global_var_init // CHECK: call i8* @_Z9getObjectv -// CHECK-NEXT: call i8* @objc_retainAutoreleasedReturnValue +// CHECK-NEXT: call i8* @llvm.objc.retainAutoreleasedReturnValue // CHECK-NEXT: {{store i8*.*@global_obj}} // CHECK-NEXT: ret void id global_obj = getObject(); // CHECK-LABEL: define internal void @__cxx_global_var_init // CHECK: call i8* @_Z9getObjectv -// CHECK-NEXT: call i8* @objc_retainAutoreleasedReturnValue +// CHECK-NEXT: call i8* @llvm.objc.retainAutoreleasedReturnValue // CHECK-NEXT: {{store i8*.*@global_obj2}} // CHECK-NEXT: ret void id global_obj2 = getObject(); // CHECK-LABEL: define internal void @_GLOBAL__sub_I_arc_globals.mm -// CHECK: call i8* @objc_autoreleasePoolPush() +// CHECK: call i8* @llvm.objc.autoreleasePoolPush() // CHECK-NEXT: call void @__cxx_global_var_init // CHECK-NEXT: call void @__cxx_global_var_init.1 -// CHECK-NEXT: call void @objc_autoreleasePoolPop( +// CHECK-NEXT: call void @llvm.objc.autoreleasePoolPop( // CHECK-NEXT: ret void diff --git a/test/CodeGenObjCXX/arc-indirect.mm b/test/CodeGenObjCXX/arc-indirect.mm index 6982bac041..49fdc51e46 100644 --- a/test/CodeGenObjCXX/arc-indirect.mm +++ b/test/CodeGenObjCXX/arc-indirect.mm @@ -19,4 +19,4 @@ struct S { // CHECK-DARWIN: define internal void @"\01-[C object:struct:]"(<{ %0*, i8*, i8*, %struct.S, [3 x i8] }>* inalloca) // CHECK: %obj = getelementptr inbounds <{ %0*, i8*, i8*, %struct.S, [3 x i8] }>, <{ %0*, i8*, i8*, %struct.S, [3 x i8] }>* %0, i32 0, i32 2 // CHECK: %[[INSTANCE:[0-9]+]] = load i8*, i8** %obj, align 4 -// CHECK: call void @objc_storeStrong(i8** %obj, i8* %[[INSTANCE]]) +// CHECK: call void @llvm.objc.storeStrong(i8** %obj, i8* %[[INSTANCE]]) diff --git a/test/CodeGenObjCXX/arc-move.mm b/test/CodeGenObjCXX/arc-move.mm index def2cea956..a43b9bc604 100644 --- a/test/CodeGenObjCXX/arc-move.mm +++ b/test/CodeGenObjCXX/arc-move.mm @@ -6,7 +6,7 @@ void simple_move(__strong id &x, __strong id &y) { // CHECK: store i8* null // CHECK: = load i8*, i8** // CHECK: store i8* - // CHECK-NEXT: call void @objc_release + // CHECK-NEXT: call void @llvm.objc.release x = static_cast<__strong id&&>(y); // CHECK-NEXT: ret void } @@ -39,7 +39,7 @@ void library_move(__strong id &x, __strong id &y) { // CHECK: load i8**, i8*** // CHECK-NEXT: load i8*, i8** // CHECK-NEXT: store i8* - // CHECK-NEXT: call void @objc_release + // CHECK-NEXT: call void @llvm.objc.release // CHECK-NEXT: ret void x = move(y); } @@ -66,7 +66,7 @@ void library_move(__strong id &y) { // CHECK-NEXT: [[IPTR2:%.*]] = bitcast i32* [[I]] to i8* // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[IPTR2]]) // CHECK-NEXT: [[OBJ:%[a-zA-Z0-9]+]] = load i8*, i8** [[X]] - // CHECK-NEXT: call void @objc_release(i8* [[OBJ]]) + // CHECK-NEXT: call void @llvm.objc.release(i8* [[OBJ]]) // CHECK-NEXT: [[XPTR2:%.*]] = bitcast i8** [[X]] to i8* // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[XPTR2]]) // CHECK-NEXT: ret void @@ -77,9 +77,9 @@ void const_move(const __strong id &x) { // CHECK: [[Y:%.*]] = alloca i8*, // CHECK: [[X:%.*]] = call dereferenceable({{[0-9]+}}) i8** @_Z4moveIRU8__strongKP11objc_objectEON16remove_referenceIT_E4typeEOS5_( // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[X]] - // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[T0]]) + // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retain(i8* [[T0]]) // CHECK-NEXT: store i8* [[T1]], i8** [[Y]] // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[Y]] - // CHECK-NEXT: call void @objc_release(i8* [[T0]]) + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) id y = move(x); } diff --git a/test/CodeGenObjCXX/arc-new-delete.mm b/test/CodeGenObjCXX/arc-new-delete.mm index 9fb5781990..0f66056be6 100644 --- a/test/CodeGenObjCXX/arc-new-delete.mm +++ b/test/CodeGenObjCXX/arc-new-delete.mm @@ -8,8 +8,8 @@ typedef __weak id weak_id; void test_new(id invalue) { // CHECK: [[INVALUEADDR:%.*]] = alloca i8* // UNOPT-NEXT: store i8* null, i8** [[INVALUEADDR]] - // UNOPT-NEXT: call void @objc_storeStrong(i8** [[INVALUEADDR]], i8* [[INVALUE:%.*]]) - // OPT-NEXT: [[T0:%.*]] = call i8* @objc_retain(i8* [[INVALUE:%.*]]) + // UNOPT-NEXT: call void @llvm.objc.storeStrong(i8** [[INVALUEADDR]], i8* [[INVALUE:%.*]]) + // OPT-NEXT: [[T0:%.*]] = call i8* @llvm.objc.retain(i8* [[INVALUE:%.*]]) // OPT-NEXT: store i8* [[T0]], i8** [[INVALUEADDR]] // CHECK: call i8* @_Znwm @@ -19,7 +19,7 @@ void test_new(id invalue) { // CHECK: call i8* @_Znwm // CHECK-NEXT: {{bitcast i8\*.*to i8\*\*}} // UNOPT-NEXT: store i8* null, i8** - // OPT-NEXT: call i8* @objc_initWeak(i8** {{.*}}, i8* null) + // OPT-NEXT: call i8* @llvm.objc.initWeak(i8** {{.*}}, i8* null) new weak_id; // CHECK: call i8* @_Znwm @@ -29,20 +29,20 @@ void test_new(id invalue) { // CHECK: call i8* @_Znwm // CHECK-NEXT: {{bitcast i8\*.*to i8\*\*}} // UNOPT-NEXT: store i8* null, i8** - // OPT-NEXT: call i8* @objc_initWeak(i8** {{.*}}, i8* null) + // OPT-NEXT: call i8* @llvm.objc.initWeak(i8** {{.*}}, i8* null) new __weak id; // CHECK: call i8* @_Znwm - // CHECK: call i8* @objc_retain + // CHECK: call i8* @llvm.objc.retain // CHECK: store i8* new __strong id(invalue); // CHECK: call i8* @_Znwm - // CHECK: call i8* @objc_initWeak + // CHECK: call i8* @llvm.objc.initWeak new __weak id(invalue); - // UNOPT: call void @objc_storeStrong - // OPT: call void @objc_release + // UNOPT: call void @llvm.objc.storeStrong + // OPT: call void @llvm.objc.release // CHECK: ret void } @@ -63,13 +63,13 @@ void test_array_new() { // CHECK-LABEL: define void @_Z11test_deletePU8__strongP11objc_objectPU6__weakS0_ void test_delete(__strong id *sptr, __weak id *wptr) { // CHECK: br i1 - // UNOPT: call void @objc_storeStrong(i8** {{.*}}, i8* null) + // UNOPT: call void @llvm.objc.storeStrong(i8** {{.*}}, i8* null) // OPT: load i8*, i8** - // OPT-NEXT: call void @objc_release + // OPT-NEXT: call void @llvm.objc.release // CHECK: call void @_ZdlPv delete sptr; - // CHECK: call void @objc_destroyWeak + // CHECK: call void @llvm.objc.destroyWeak // CHECK: call void @_ZdlPv delete wptr; @@ -84,9 +84,9 @@ void test_array_delete(__strong id *sptr, __weak id *wptr) { // CHECK-NEXT: icmp eq i8** [[BEGIN]], [[END]] // CHECK: [[PAST:%.*]] = phi i8** [ [[END]], {{%.*}} ], [ [[CUR:%.*]], // CHECK-NEXT: [[CUR]] = getelementptr inbounds i8*, i8** [[PAST]], i64 -1 - // UNOPT-NEXT: call void @objc_storeStrong(i8** [[CUR]], i8* null) + // UNOPT-NEXT: call void @llvm.objc.storeStrong(i8** [[CUR]], i8* null) // OPT-NEXT: [[T0:%.*]] = load i8*, i8** [[CUR]] - // OPT-NEXT: objc_release(i8* [[T0]]) + // OPT-NEXT: llvm.objc.release(i8* [[T0]]) // CHECK-NEXT: icmp eq i8** [[CUR]], [[BEGIN]] // CHECK: call void @_ZdaPv delete [] sptr; @@ -97,7 +97,7 @@ void test_array_delete(__strong id *sptr, __weak id *wptr) { // CHECK-NEXT: icmp eq i8** [[BEGIN]], [[END]] // CHECK: [[PAST:%.*]] = phi i8** [ [[END]], {{%.*}} ], [ [[CUR:%.*]], // CHECK-NEXT: [[CUR]] = getelementptr inbounds i8*, i8** [[PAST]], i64 -1 - // CHECK-NEXT: call void @objc_destroyWeak(i8** [[CUR]]) + // CHECK-NEXT: call void @llvm.objc.destroyWeak(i8** [[CUR]]) // CHECK-NEXT: icmp eq i8** [[CUR]], [[BEGIN]] // CHECK: call void @_ZdaPv delete [] wptr; diff --git a/test/CodeGenObjCXX/arc-pseudo-destructors.mm b/test/CodeGenObjCXX/arc-pseudo-destructors.mm index b79d9a3447..191712d79c 100644 --- a/test/CodeGenObjCXX/arc-pseudo-destructors.mm +++ b/test/CodeGenObjCXX/arc-pseudo-destructors.mm @@ -4,18 +4,18 @@ void test_objc_object_pseudo_dtor(__strong id *ptr, __weak id *wptr) { // CHECK: load i8**, i8*** // CHECK-NEXT: load i8*, i8** - // CHECK-NEXT: call void @objc_release + // CHECK-NEXT: call void @llvm.objc.release ptr->~id(); - // CHECK: call void @objc_destroyWeak(i8** {{%.*}}) + // CHECK: call void @llvm.objc.destroyWeak(i8** {{%.*}}) wptr->~id(); // CHECK: load i8**, i8*** // CHECK-NEXT: load i8*, i8** - // CHECK-NEXT: call void @objc_release + // CHECK-NEXT: call void @llvm.objc.release (*ptr).~id(); - // CHECK: call void @objc_destroyWeak(i8** {{%.*}}) + // CHECK: call void @llvm.objc.destroyWeak(i8** {{%.*}}) (*wptr).~id(); // CHECK: ret void } diff --git a/test/CodeGenObjCXX/arc-references.mm b/test/CodeGenObjCXX/arc-references.mm index 983b211dfb..aa0b85f2a0 100644 --- a/test/CodeGenObjCXX/arc-references.mm +++ b/test/CodeGenObjCXX/arc-references.mm @@ -10,17 +10,17 @@ void callee(); // CHECK-LABEL: define void @_Z5test0v() void test0() { // CHECK: call i8* @_Z9getObjectv - // CHECK-NEXT: call i8* @objc_retainAutoreleasedReturnValue + // CHECK-NEXT: call i8* @llvm.objc.retainAutoreleasedReturnValue const __strong id &ref1 = getObject(); // CHECK: call void @_Z6calleev callee(); // CHECK: call i8* @_Z9getObjectv - // CHECK-NEXT: call i8* @objc_retainAutoreleasedReturnValue - // CHECK-NEXT: call i8* @objc_autorelease + // CHECK-NEXT: call i8* @llvm.objc.retainAutoreleasedReturnValue + // CHECK-NEXT: call i8* @llvm.objc.autorelease const __autoreleasing id &ref2 = getObject(); // CHECK: call void @_Z6calleev callee(); - // CHECK: call void @objc_release + // CHECK: call void @llvm.objc.release // CHECK: ret } @@ -39,12 +39,12 @@ typedef __strong id strong_id; //CHECK: define void @_Z5test3v void test3() { // CHECK: [[REF:%.*]] = alloca i8**, align 8 - // CHECK: call i8* @objc_initWeak + // CHECK: call i8* @llvm.objc.initWeak // CHECK-NEXT: store i8** const __weak id &ref = strong_id(); // CHECK-NEXT: call void @_Z6calleev() callee(); - // CHECK-NEXT: call void @objc_destroyWeak + // CHECK-NEXT: call void @llvm.objc.destroyWeak // CHECK-NEXT: [[PTR:%.*]] = bitcast i8*** [[REF]] to i8* // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[PTR]]) // CHECK-NEXT: ret void @@ -52,11 +52,11 @@ void test3() { // CHECK-LABEL: define void @_Z5test4RU8__strongP11objc_object void test4(__strong id &x) { - // CHECK: call i8* @objc_retain + // CHECK: call i8* @llvm.objc.retain __strong A* const &ar = x; // CHECK: store i32 17, i32* int i = 17; - // CHECK: call void @objc_release( + // CHECK: call void @llvm.objc.release( // CHECK: ret void } @@ -66,14 +66,14 @@ void sink(__strong A* &&); void test5(__strong id &x) { // CHECK: [[REFTMP:%.*]] = alloca {{%.*}}*, align 8 // CHECK: [[I:%.*]] = alloca i32, align 4 - // CHECK: [[OBJ_ID:%.*]] = call i8* @objc_retain( + // CHECK: [[OBJ_ID:%.*]] = call i8* @llvm.objc.retain( // CHECK-NEXT: [[OBJ_A:%.*]] = bitcast i8* [[OBJ_ID]] to [[A:%[a-zA-Z0-9]+]]* // CHECK-NEXT: store [[A]]* [[OBJ_A]], [[A]]** [[REFTMP:%[a-zA-Z0-9]+]] // CHECK-NEXT: call void @_Z4sinkOU8__strongP1A sink(x); // CHECK-NEXT: [[OBJ_A:%[a-zA-Z0-9]+]] = load [[A]]*, [[A]]** [[REFTMP]] // CHECK-NEXT: [[OBJ_ID:%[a-zA-Z0-9]+]] = bitcast [[A]]* [[OBJ_A]] to i8* - // CHECK-NEXT: call void @objc_release + // CHECK-NEXT: call void @llvm.objc.release // CHECK-NEXT: [[IPTR1:%.*]] = bitcast i32* [[I]] to i8* // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[IPTR1]]) // CHECK-NEXT: store i32 17, i32 @@ -85,7 +85,7 @@ void test5(__strong id &x) { // CHECK-LABEL: define internal void @__cxx_global_var_init( // CHECK: call i8* @_Z9getObjectv -// CHECK-NEXT: call i8* @objc_retainAutoreleasedReturnValue +// CHECK-NEXT: call i8* @llvm.objc.retainAutoreleasedReturnValue const __strong id &global_ref = getObject(); // Note: we intentionally don't release the object. diff --git a/test/CodeGenObjCXX/arc-returns-inner-reference-ptr.mm b/test/CodeGenObjCXX/arc-returns-inner-reference-ptr.mm index c4ab34ea0e..fa9b4219f5 100644 --- a/test/CodeGenObjCXX/arc-returns-inner-reference-ptr.mm +++ b/test/CodeGenObjCXX/arc-returns-inner-reference-ptr.mm @@ -15,8 +15,8 @@ void foo() { // CHECK: [[T0:%.*]] = load {{%.*}} {{%.*}}, align 8 // CHECK: [[T1:%.*]] = bitcast {{%.*}} [[T0]] to i8* -// call i8* @objc_retainAutorelease(i8* [[T1]]) nounwind +// call i8* @llvm.objc.retainAutorelease(i8* [[T1]]) nounwind // CHECK: [[T2:%.*]] = load {{%.*}} {{%.*}}, align 8 // CHECK: [[T3:%.*]] = bitcast {{%.*}} [[T2]] to i8* -// call i8* @objc_retainAutorelease(i8* [[T3]]) nounwind +// call i8* @llvm.objc.retainAutorelease(i8* [[T3]]) nounwind diff --git a/test/CodeGenObjCXX/arc-special-member-functions.mm b/test/CodeGenObjCXX/arc-special-member-functions.mm index d620187d70..04ffbbe021 100644 --- a/test/CodeGenObjCXX/arc-special-member-functions.mm +++ b/test/CodeGenObjCXX/arc-special-member-functions.mm @@ -91,7 +91,7 @@ void test_ObjCMember_copy_assign(ObjCMember m1, ObjCMember m2) { // Implicitly-generated copy assignment operator for ObjCMember // CHECK: {{define linkonce_odr.*@_ZN10ObjCMemberaSERKS_}} -// CHECK: call void @objc_storeStrong +// CHECK: call void @llvm.objc.storeStrong // CHECK: ret // CHECK-LABEL: define void @_Z47test_ObjCArrayMember_default_construct_destructv @@ -120,7 +120,7 @@ void test_ObjCArrayMember_copy_assign(ObjCArrayMember m1, ObjCArrayMember m2) { // Implicitly-generated copy assignment operator for ObjCArrayMember // CHECK: {{define linkonce_odr.*@_ZN15ObjCArrayMemberaSERKS_}} -// CHECK: call void @objc_storeStrong +// CHECK: call void @llvm.objc.storeStrong // CHECK-NEXT: br label // CHECK: ret @@ -155,13 +155,13 @@ void test_ObjCBlockMember_copy_assign(ObjCBlockMember m1, ObjCBlockMember m2) { // CHECK: [[T0:%.*]] = getelementptr inbounds [[T:%.*]], [[T:%.*]]* {{%.*}}, i32 0, i32 0 // CHECK-NEXT: [[T1:%.*]] = load i32 (i32)*, i32 (i32)** [[T0]], align 8 // CHECK-NEXT: [[T2:%.*]] = bitcast i32 (i32)* [[T1]] to i8* -// CHECK-NEXT: [[T3:%.*]] = call i8* @objc_retainBlock(i8* [[T2]]) +// CHECK-NEXT: [[T3:%.*]] = call i8* @llvm.objc.retainBlock(i8* [[T2]]) // CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to i32 (i32)* // CHECK-NEXT: [[T5:%.*]] = getelementptr inbounds [[T]], [[T]]* {{%.*}}, i32 0, i32 0 // CHECK-NEXT: [[T6:%.*]] = load i32 (i32)*, i32 (i32)** [[T5]], align 8 // CHECK-NEXT: store i32 (i32)* [[T4]], i32 (i32)** [[T5]] // CHECK-NEXT: [[T7:%.*]] = bitcast i32 (i32)* [[T6]] to i8* -// CHECK-NEXT: call void @objc_release(i8* [[T7]]) +// CHECK-NEXT: call void @llvm.objc.release(i8* [[T7]]) // CHECK-NEXT: ret // Check that the Weak object passed to this constructor is not destructed after @@ -179,13 +179,13 @@ void test_ObjCBlockMember_copy_assign(ObjCBlockMember m1, ObjCBlockMember m2) { // Implicitly-generated destructor for ObjCMember // CHECK-LABEL: define linkonce_odr void @_ZN10ObjCMemberD2Ev -// CHECK: call void @objc_storeStrong +// CHECK: call void @llvm.objc.storeStrong // CHECK: ret void // Implicitly-generated copy constructor for ObjCMember // CHECK-LABEL: define linkonce_odr void @_ZN10ObjCMemberC2ERKS_ // CHECK-NOT: objc_release -// CHECK: call i8* @objc_retain +// CHECK: call i8* @llvm.objc.retain // CHECK-NEXT: store i8* // CHECK-NEXT: ret void @@ -201,14 +201,14 @@ void test_ObjCBlockMember_copy_assign(ObjCBlockMember m1, ObjCBlockMember m2) { // CHECK-NEXT: br label // CHECK: [[PAST:%.*]] = phi i8** [ [[END]], {{%.*}} ], [ [[CUR:%.*]], {{%.*}} ] // CHECK-NEXT: [[CUR]] = getelementptr inbounds i8*, i8** [[PAST]], i64 -1 -// CHECK-NEXT: call void @objc_storeStrong(i8** [[CUR]], i8* null) +// CHECK-NEXT: call void @llvm.objc.storeStrong(i8** [[CUR]], i8* null) // CHECK-NEXT: [[T1:%.*]] = icmp eq i8** [[CUR]], [[BEGIN]] // CHECK-NEXT: br i1 [[T1]], // CHECK: ret void // Implicitly-generated copy constructor for ObjCArrayMember // CHECK-LABEL: define linkonce_odr void @_ZN15ObjCArrayMemberC2ERKS_ -// CHECK: call i8* @objc_retain +// CHECK: call i8* @llvm.objc.retain // CHECK-NEXT: store i8* // CHECK: br i1 // CHECK: ret @@ -220,11 +220,11 @@ void test_ObjCBlockMember_copy_assign(ObjCBlockMember m1, ObjCBlockMember m2) { // Implicitly-generated destructor for ObjCBlockMember // CHECK-LABEL: define linkonce_odr void @_ZN15ObjCBlockMemberD2Ev -// CHECK: call void @objc_storeStrong(i8* +// CHECK: call void @llvm.objc.storeStrong(i8* // CHECK: ret // Implicitly-generated copy constructor for ObjCBlockMember // CHECK-LABEL: define linkonce_odr void @_ZN15ObjCBlockMemberC2ERKS_ -// CHECK: call i8* @objc_retainBlock +// CHECK: call i8* @llvm.objc.retainBlock // CHECK: ret diff --git a/test/CodeGenObjCXX/arc-weak.mm b/test/CodeGenObjCXX/arc-weak.mm index 8fd03379aa..cb1bc95c93 100644 --- a/test/CodeGenObjCXX/arc-weak.mm +++ b/test/CodeGenObjCXX/arc-weak.mm @@ -15,9 +15,9 @@ void test0(__weak B **src) { // CHECK-NEXT: [[T1:%.*]] = bitcast [[B]]** [[T0]] to [[A]]** // CHECK-NEXT: [[T2:%.*]] = bitcast [[A]]** [[DEST]] to i8** // CHECK-NEXT: [[T3:%.*]] = bitcast [[A]]** [[T1]] to i8** -// CHECK-NEXT: call void @objc_copyWeak(i8** [[T2]], i8** [[T3]]) +// CHECK-NEXT: call void @llvm.objc.copyWeak(i8** [[T2]], i8** [[T3]]) // CHECK-NEXT: [[T0:%.*]] = bitcast [[A]]** [[DEST]] to i8** -// CHECK: call void @objc_destroyWeak(i8** [[T0]]) +// CHECK: call void @llvm.objc.destroyWeak(i8** [[T0]]) void test1(__weak B **src) { __weak A *dest = static_cast<__weak B*&&>(*src); @@ -29,6 +29,6 @@ void test1(__weak B **src) { // CHECK-NEXT: [[T1:%.*]] = bitcast [[B]]** [[T0]] to [[A]]** // CHECK-NEXT: [[T2:%.*]] = bitcast [[A]]** [[DEST]] to i8** // CHECK-NEXT: [[T3:%.*]] = bitcast [[A]]** [[T1]] to i8** -// CHECK-NEXT: call void @objc_moveWeak(i8** [[T2]], i8** [[T3]]) +// CHECK-NEXT: call void @llvm.objc.moveWeak(i8** [[T2]], i8** [[T3]]) // CHECK-NEXT: [[T0:%.*]] = bitcast [[A]]** [[DEST]] to i8** -// CHECK: call void @objc_destroyWeak(i8** [[T0]]) +// CHECK: call void @llvm.objc.destroyWeak(i8** [[T0]]) diff --git a/test/CodeGenObjCXX/arc.mm b/test/CodeGenObjCXX/arc.mm index 5e66206ad5..b7f099d4e8 100644 --- a/test/CodeGenObjCXX/arc.mm +++ b/test/CodeGenObjCXX/arc.mm @@ -20,21 +20,21 @@ void test0(__weak id *wp, __weak volatile id *wvp) { // TODO: in the non-volatile case, we do not need to be reloading. // CHECK: [[T0:%.*]] = call i8* @_Z12test0_helperv() - // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]]) + // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) // CHECK-NEXT: [[T2:%.*]] = load i8**, i8*** {{%.*}}, align 8 - // CHECK-NEXT: [[T3:%.*]] = call i8* @objc_storeWeak(i8** [[T2]], i8* [[T1]]) - // CHECK-NEXT: [[T4:%.*]] = call i8* @objc_retain(i8* [[T3]]) + // CHECK-NEXT: [[T3:%.*]] = call i8* @llvm.objc.storeWeak(i8** [[T2]], i8* [[T1]]) + // CHECK-NEXT: [[T4:%.*]] = call i8* @llvm.objc.retain(i8* [[T3]]) // CHECK-NEXT: store i8* [[T4]], i8** - // CHECK-NEXT: call void @objc_release(i8* [[T1]]) + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) id x = *wp = test0_helper(); // CHECK: [[T0:%.*]] = call i8* @_Z12test0_helperv() - // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]]) + // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) // CHECK-NEXT: [[T2:%.*]] = load i8**, i8*** {{%.*}}, align 8 - // CHECK-NEXT: [[T3:%.*]] = call i8* @objc_storeWeak(i8** [[T2]], i8* [[T1]]) - // CHECK-NEXT: [[T4:%.*]] = call i8* @objc_loadWeakRetained(i8** [[T2]]) + // CHECK-NEXT: [[T3:%.*]] = call i8* @llvm.objc.storeWeak(i8** [[T2]], i8* [[T1]]) + // CHECK-NEXT: [[T4:%.*]] = call i8* @llvm.objc.loadWeakRetained(i8** [[T2]]) // CHECK-NEXT: store i8* [[T4]], i8** - // CHECK-NEXT: call void @objc_release(i8* [[T1]]) + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) id y = *wvp = test0_helper(); } @@ -69,7 +69,7 @@ void test34(int cond) { // CHECK-NEXT: store i8* null, i8** [[STRONG]] // CHECK-NEXT: [[WEAKP:%.*]] = bitcast i8** [[WEAK]] to i8* // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[WEAKP]]) - // CHECK-NEXT: call i8* @objc_initWeak(i8** [[WEAK]], i8* null) + // CHECK-NEXT: call i8* @llvm.objc.initWeak(i8** [[WEAK]], i8* null) // CHECK-NEXT: [[T0:%.*]] = load i32, i32* [[COND]] // CHECK-NEXT: [[T1:%.*]] = icmp ne i32 [[T0]], 0 @@ -85,11 +85,11 @@ void test34(int cond) { // CHECK-NEXT: [[T0:%.*]] = icmp eq i8** [[ARG]], null // CHECK-NEXT: br i1 [[T0]], // CHECK: [[T0:%.*]] = load i8*, i8** [[TEMP1]] - // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[T0]]) + // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retain(i8* [[T0]]) // CHECK-NEXT: call void (...) @clang.arc.use(i8* [[W0]]) // CHECK-NEXT: [[T2:%.*]] = load i8*, i8** [[ARG]] // CHECK-NEXT: store i8* [[T1]], i8** [[ARG]] - // CHECK-NEXT: call void @objc_release(i8* [[T2]]) + // CHECK-NEXT: call void @llvm.objc.release(i8* [[T2]]) // CHECK-NEXT: br label // CHECK: [[T0:%.*]] = load i32, i32* [[COND]] @@ -99,7 +99,7 @@ void test34(int cond) { // CHECK-NEXT: [[T1:%.*]] = select i1 [[T0]], i8** null, i8** [[TEMP2]] // CHECK-NEXT: store i1 false, i1* [[CONDCLEANUP]] // CHECK-NEXT: br i1 [[T0]], - // CHECK: [[T0:%.*]] = call i8* @objc_loadWeakRetained(i8** [[ARG]]) + // CHECK: [[T0:%.*]] = call i8* @llvm.objc.loadWeakRetained(i8** [[ARG]]) // CHECK-NEXT: store i8* [[T0]], i8** [[CONDCLEANUPSAVE]] // CHECK-NEXT: store i1 true, i1* [[CONDCLEANUP]] // CHECK-NEXT: store i8* [[T0]], i8** [[TEMP2]] @@ -108,10 +108,10 @@ void test34(int cond) { // CHECK-NEXT: [[T0:%.*]] = icmp eq i8** [[ARG]], null // CHECK-NEXT: br i1 [[T0]], // CHECK: [[T0:%.*]] = load i8*, i8** [[TEMP2]] - // CHECK-NEXT: call i8* @objc_storeWeak(i8** [[ARG]], i8* [[T0]]) + // CHECK-NEXT: call i8* @llvm.objc.storeWeak(i8** [[ARG]], i8* [[T0]]) // CHECK-NEXT: br label - // CHECK: call void @objc_destroyWeak(i8** [[WEAK]]) + // CHECK: call void @llvm.objc.destroyWeak(i8** [[WEAK]]) // CHECK: ret void } @@ -126,36 +126,36 @@ struct Test35_Helper { void test35(Test35_Helper x0, Test35_Helper *x0p) { // CHECK: call void @llvm.lifetime.start // CHECK: call i8* @_ZN13Test35_Helper11makeObject1Ev - // CHECK-NOT: call i8* @objc_retain + // CHECK-NOT: call i8* @llvm.objc.retain id obj1 = Test35_Helper::makeObject1(); // CHECK: call void @llvm.lifetime.start // CHECK: call i8* @_ZN13Test35_Helper11makeObject2Ev - // CHECK-NOT: call i8* @objc_retain + // CHECK-NOT: call i8* @llvm.objc.retain id obj2 = x0.makeObject2(); // CHECK: call void @llvm.lifetime.start // CHECK: call i8* @_ZN13Test35_Helper11makeObject2Ev - // CHECK-NOT: call i8* @objc_retain + // CHECK-NOT: call i8* @llvm.objc.retain id obj3 = x0p->makeObject2(); id (Test35_Helper::*pmf)() __attribute__((ns_returns_retained)) = &Test35_Helper::makeObject2; // CHECK: call void @llvm.lifetime.start // CHECK: call i8* % - // CHECK-NOT: call i8* @objc_retain + // CHECK-NOT: call i8* @llvm.objc.retain id obj4 = (x0.*pmf)(); // CHECK: call void @llvm.lifetime.start // CHECK: call i8* % - // CHECK-NOT: call i8* @objc_retain + // CHECK-NOT: call i8* @llvm.objc.retain id obj5 = (x0p->*pmf)(); - // CHECK: call void @objc_release + // CHECK: call void @llvm.objc.release // CHECK: call void @llvm.lifetime.end - // CHECK: call void @objc_release + // CHECK: call void @llvm.objc.release // CHECK: call void @llvm.lifetime.end - // CHECK: call void @objc_release + // CHECK: call void @llvm.objc.release // CHECK: call void @llvm.lifetime.end - // CHECK: call void @objc_release + // CHECK: call void @llvm.objc.release // CHECK: call void @llvm.lifetime.end - // CHECK: call void @objc_release + // CHECK: call void @llvm.objc.release // CHECK: call void @llvm.lifetime.end // CHECK-NEXT: ret void } @@ -164,36 +164,36 @@ void test35(Test35_Helper x0, Test35_Helper *x0p) { void test35b(Test35_Helper x0, Test35_Helper *x0p) { // CHECK: call void @llvm.lifetime.start // CHECK: call i8* @_ZN13Test35_Helper11makeObject3Ev - // CHECK: call i8* @objc_retain + // CHECK: call i8* @llvm.objc.retain id obj1 = Test35_Helper::makeObject3(); // CHECK: call void @llvm.lifetime.start // CHECK: call i8* @_ZN13Test35_Helper11makeObject4Ev - // CHECK: call i8* @objc_retain + // CHECK: call i8* @llvm.objc.retain id obj2 = x0.makeObject4(); // CHECK: call void @llvm.lifetime.start // CHECK: call i8* @_ZN13Test35_Helper11makeObject4Ev - // CHECK: call i8* @objc_retain + // CHECK: call i8* @llvm.objc.retain id obj3 = x0p->makeObject4(); id (Test35_Helper::*pmf)() = &Test35_Helper::makeObject4; // CHECK: call void @llvm.lifetime.start // CHECK: call i8* % - // CHECK: call i8* @objc_retain + // CHECK: call i8* @llvm.objc.retain id obj4 = (x0.*pmf)(); // CHECK: call void @llvm.lifetime.start // CHECK: call i8* % - // CHECK: call i8* @objc_retain + // CHECK: call i8* @llvm.objc.retain id obj5 = (x0p->*pmf)(); - // CHECK: call void @objc_release + // CHECK: call void @llvm.objc.release // CHECK: call void @llvm.lifetime.end - // CHECK: call void @objc_release + // CHECK: call void @llvm.objc.release // CHECK: call void @llvm.lifetime.end // CHECK: call void @llvm.lifetime.end - // CHECK: call void @objc_release + // CHECK: call void @llvm.objc.release // CHECK: call void @llvm.lifetime.end - // CHECK: call void @objc_release + // CHECK: call void @llvm.objc.release // CHECK: call void @llvm.lifetime.end - // CHECK: call void @objc_release + // CHECK: call void @llvm.objc.release // CHECK: call void @llvm.lifetime.end // CHECK-NEXT: ret void } @@ -201,10 +201,10 @@ void test35b(Test35_Helper x0, Test35_Helper *x0p) { // rdar://problem/9603128 // CHECK-LABEL: define i8* @_Z6test36P11objc_object( id test36(id z) { - // CHECK: objc_retain - // CHECK: objc_retain - // CHECK: objc_release - // CHECK: objc_autoreleaseReturnValue + // CHECK: llvm.objc.retain + // CHECK: llvm.objc.retain + // CHECK: llvm.objc.release + // CHECK: llvm.objc.autoreleaseReturnValue return z; } @@ -224,7 +224,7 @@ template void test37(Test37 *a); // CHECK-LABEL: define weak_odr void @_Z6test37I6Test37EvPT_( // CHECK: [[T0:%.*]] = call [[NSARRAY]]* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to [[NSARRAY]]* (i8*, i8*)*)( // CHECK-NEXT: [[T1:%.*]] = bitcast [[NSARRAY]]* [[T0]] to i8* -// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]]) +// CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]]) // CHECK-NEXT: [[COLL:%.*]] = bitcast i8* [[T2]] to [[NSARRAY]]* // Make sure it's not immediately released before starting the iteration. @@ -242,7 +242,7 @@ template void test37(Test37 *a); // This bitcast is for the final release. // CHECK: [[T0:%.*]] = bitcast [[NSARRAY]]* [[COLL]] to i8* -// CHECK-NEXT: call void @objc_release(i8* [[T0]]) +// CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) template void send_release() { @@ -252,10 +252,10 @@ void send_release() { // CHECK-LABEL: define weak_odr void @_Z12send_releaseIiEvv( // CHECK: call %0* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend // CHECK-NEXT: bitcast -// CHECK-NEXT: call i8* @objc_retainAutoreleasedReturnValue +// CHECK-NEXT: call i8* @llvm.objc.retainAutoreleasedReturnValue // CHECK-NEXT: bitcast // CHECK-NEXT: bitcast -// CHECK-NEXT: call void @objc_release +// CHECK-NEXT: call void @llvm.objc.release // CHECK-NEXT: ret void template void send_release(); @@ -268,9 +268,9 @@ Test37 *instantiate_init() { // CHECK-LABEL: define weak_odr %2* @_Z16instantiate_initIiEP6Test37v // CHECK: call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend // CHECK: call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend -// CHECK: call i8* @objc_retain -// CHECK: call void @objc_release -// CHECK: call i8* @objc_autoreleaseReturnValue +// CHECK: call i8* @llvm.objc.retain +// CHECK: call void @llvm.objc.release +// CHECK: call i8* @llvm.objc.autoreleaseReturnValue template Test37* instantiate_init(); // Just make sure that the AST invariants hold properly here, @@ -322,7 +322,7 @@ template void test40_helper(); // CHECK-NEXT: store i8* [[T0]], i8** [[TEMP]] // CHECK: @objc_msgSend // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[TEMP]] -// CHECK-NEXT: call i8* @objc_retain(i8* [[T0]]) +// CHECK-NEXT: call i8* @llvm.objc.retain(i8* [[T0]]) // Check that moves out of __weak variables are compiled to use objc_moveWeak. void test41(__weak id &&x) { @@ -332,5 +332,5 @@ void test41(__weak id &&x) { // CHECK: [[X:%.*]] = alloca i8** // CHECK: [[Y:%.*]] = alloca i8* // CHECK: [[T0:%.*]] = load i8**, i8*** [[X]] -// CHECK-NEXT: call void @objc_moveWeak(i8** [[Y]], i8** [[T0]]) -// CHECK-NEXT: call void @objc_destroyWeak(i8** [[Y]]) +// CHECK-NEXT: call void @llvm.objc.moveWeak(i8** [[Y]], i8** [[T0]]) +// CHECK-NEXT: call void @llvm.objc.destroyWeak(i8** [[Y]]) diff --git a/test/CodeGenObjCXX/block-nested-in-lambda.mm b/test/CodeGenObjCXX/block-nested-in-lambda.mm index a538d1bd2b..4122d89e8f 100644 --- a/test/CodeGenObjCXX/block-nested-in-lambda.mm +++ b/test/CodeGenObjCXX/block-nested-in-lambda.mm @@ -51,27 +51,27 @@ void test0() { // CHECK: store %[[STRUCT_BLOCK_DESCRIPTOR]]* bitcast ({ i64, i64, i8*, i8*, i8*, i64 }* @"__block_descriptor_56_8_32s40s_e5_v8@?0l" to %[[STRUCT_BLOCK_DESCRIPTOR]]*), %[[STRUCT_BLOCK_DESCRIPTOR]]** %[[BLOCK_DESCRIPTOR]], align 8 // CHECK-LABEL: define linkonce_odr hidden void @__copy_helper_block_8_32s40s( -// CHECK-NOT: call void @objc_storeStrong( +// CHECK-NOT: call void @llvm.objc.storeStrong( // CHECK: %[[V4:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8*, i8*, i8** }>, <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8*, i8*, i8** }>* %{{.*}}, i32 0, i32 5 // CHECK: %[[V5:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8*, i8*, i8** }>, <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8*, i8*, i8** }>* %{{.*}}, i32 0, i32 5 // CHECK: %[[BLOCKCOPY_SRC:.*]] = load i8*, i8** %[[V4]], align 8 // CHECK: store i8* null, i8** %[[V5]], align 8 -// CHECK: call void @objc_storeStrong(i8** %[[V5]], i8* %[[BLOCKCOPY_SRC]]) +// CHECK: call void @llvm.objc.storeStrong(i8** %[[V5]], i8* %[[BLOCKCOPY_SRC]]) // CHECK: %[[V6:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8*, i8*, i8** }>, <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8*, i8*, i8** }>* %{{.*}}, i32 0, i32 6 // CHECK: %[[V7:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8*, i8*, i8** }>, <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8*, i8*, i8** }>* %{{.*}}, i32 0, i32 6 // CHECK: %[[BLOCKCOPY_SRC2:.*]] = load i8*, i8** %[[V6]], align 8 // CHECK: store i8* null, i8** %[[V7]], align 8 -// CHECK: call void @objc_storeStrong(i8** %[[V7]], i8* %[[BLOCKCOPY_SRC2]]) -// CHECK-NOT: call void @objc_storeStrong( +// CHECK: call void @llvm.objc.storeStrong(i8** %[[V7]], i8* %[[BLOCKCOPY_SRC2]]) +// CHECK-NOT: call void @llvm.objc.storeStrong( // CHECK: ret void // CHECK-LABEL: define linkonce_odr hidden void @__destroy_helper_block_8_32s40s( // CHECK: %[[V2:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8*, i8*, i8** }>, <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8*, i8*, i8** }>* %{{.*}}, i32 0, i32 5 // CHECK: %[[V3:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8*, i8*, i8** }>, <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8*, i8*, i8** }>* %{{.*}}, i32 0, i32 6 -// CHECK-NOT: call void @objc_storeStrong( -// CHECK: call void @objc_storeStrong(i8** %[[V3]], i8* null) -// CHECK: call void @objc_storeStrong(i8** %[[V2]], i8* null) -// CHECK-NOT: call void @objc_storeStrong( +// CHECK-NOT: call void @llvm.objc.storeStrong( +// CHECK: call void @llvm.objc.storeStrong(i8** %[[V3]], i8* null) +// CHECK: call void @llvm.objc.storeStrong(i8** %[[V2]], i8* null) +// CHECK-NOT: call void @llvm.objc.storeStrong( // CHECK: ret void void test1() { diff --git a/test/CodeGenObjCXX/destroy.mm b/test/CodeGenObjCXX/destroy.mm index 371f729afa..4a0451ec94 100644 --- a/test/CodeGenObjCXX/destroy.mm +++ b/test/CodeGenObjCXX/destroy.mm @@ -44,7 +44,7 @@ void test4() { // CHECK: call void @_ZN8tderivedIiED1Ev // CHECK-LABEL: define linkonce_odr void @_ZN7derivedD2Ev -// CHECK: call void @objc_storeStrong(i8** {{.*}}, i8* null) +// CHECK: call void @llvm.objc.storeStrong(i8** {{.*}}, i8* null) // CHECK-LABEL: define linkonce_odr void @_ZN8tderivedIiED2Ev -// CHECK: call void @objc_storeStrong(i8** {{.*}}, i8* null) +// CHECK: call void @llvm.objc.storeStrong(i8** {{.*}}, i8* null) diff --git a/test/CodeGenObjCXX/lambda-expressions.mm b/test/CodeGenObjCXX/lambda-expressions.mm index f60655c61b..ff7450f206 100644 --- a/test/CodeGenObjCXX/lambda-expressions.mm +++ b/test/CodeGenObjCXX/lambda-expressions.mm @@ -20,8 +20,8 @@ fp f() { auto x = []{ return 3; }; return x; } // ARC-LABEL: define internal i32 ()* @"_ZZ1fvENK3$_0cvU13block_pointerFivEEv" // ARC: store i8* bitcast (i8** @_NSConcreteStackBlock to i8*) // ARC: store i8* bitcast (i32 (i8*)* @"___ZZ1fvENK3$_0cvU13block_pointerFivEEv_block_invoke" to i8*) -// ARC: call i8* @objc_retainBlock -// ARC: call i8* @objc_autoreleaseReturnValue +// ARC: call i8* @llvm.objc.retainBlock +// ARC: call i8* @llvm.objc.autoreleaseReturnValue typedef int (^fp)(); fp global; @@ -35,8 +35,8 @@ void f2() { global = []{ return 3; }; } // ARC: define void @_Z2f2v() [[NUW:#[0-9]+]] { // ARC: store i8* bitcast (i32 (i8*)* @___Z2f2v_block_invoke to i8*), -// ARC: call i8* @objc_retainBlock -// ARC: call void @objc_release +// ARC: call i8* @llvm.objc.retainBlock +// ARC: call void @llvm.objc.release // ARC-LABEL: define internal i32 @___Z2f2v_block_invoke // ARC: call i32 @"_ZZ2f2vENK3$_1clEv @@ -72,7 +72,7 @@ void take_block(void (^block)()) { block(); } // ARC: store i32 %{{.*}}, i32* %[[CAPTURE1]] // ARC-LABEL: define internal void @"_ZZ10-[Foo foo]ENK3$_4clEv"( -// ARC-NOT: @objc_storeStrong( +// ARC-NOT: @llvm.objc.storeStrong( // ARC: ret void // ARC: define internal void @"___ZZN13LambdaCapture4foo1ERiENK3$_3clEv_block_invoke" diff --git a/test/CodeGenObjCXX/literals.mm b/test/CodeGenObjCXX/literals.mm index a42070b00c..0a14d330bd 100644 --- a/test/CodeGenObjCXX/literals.mm +++ b/test/CodeGenObjCXX/literals.mm @@ -29,7 +29,7 @@ void test_array() { // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP_CAST]]) // CHECK-NEXT: call void @_ZN1XC1Ev({{.*}} [[TMPX]]) // CHECK-NEXT: [[OBJECT0:%[a-zA-Z0-9.]+]] = invoke i8* @_ZNK1XcvP11objc_objectEv - // CHECK: [[RET0:%[a-zA-Z0-9.]+]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[OBJECT0]]) + // CHECK: [[RET0:%[a-zA-Z0-9.]+]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[OBJECT0]]) // CHECK: store i8* [[RET0]], i8** [[ELEMENT0]] // Initializing the second element @@ -38,36 +38,36 @@ void test_array() { // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP_CAST]]) // CHECK-NEXT: invoke void @_ZN1YC1Ev({{.*}} [[TMPY]]) // CHECK: [[OBJECT1:%[a-zA-Z0-9.]+]] = invoke i8* @_ZNK1YcvP11objc_objectEv - // CHECK: [[RET1:%[a-zA-Z0-9.]+]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[OBJECT1]]) + // CHECK: [[RET1:%[a-zA-Z0-9.]+]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[OBJECT1]]) // CHECK: store i8* [[RET1]], i8** [[ELEMENT1]] // Build the array // CHECK: {{invoke.*@objc_msgSend}} - // CHECK: call i8* @objc_retainAutoreleasedReturnValue + // CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue id arr = @[ X(), Y() ]; // Destroy temporaries // CHECK-NOT: ret void - // CHECK: call void @objc_release + // CHECK: call void @llvm.objc.release // CHECK-NOT: ret void // CHECK: invoke void @_ZN1YD1Ev // CHECK-NOT: ret void - // CHECK: call void @objc_release + // CHECK: call void @llvm.objc.release // CHECK-NEXT: call void @_ZN1XD1Ev // CHECK-NOT: ret void - // CHECK: call void @objc_release + // CHECK: call void @llvm.objc.release // CHECK-NEXT: [[PTR2:%.*]] = bitcast i8** [[ARR]] to i8* // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[PTR2]]) // CHECK-NEXT: ret void // Check cleanups - // CHECK: call void @objc_release - // CHECK-NOT: call void @objc_release + // CHECK: call void @llvm.objc.release + // CHECK-NOT: call void @llvm.objc.release // CHECK: invoke void @_ZN1YD1Ev - // CHECK: call void @objc_release - // CHECK-NOT: call void @objc_release + // CHECK: call void @llvm.objc.release + // CHECK-NOT: call void @llvm.objc.release // CHECK: invoke void @_ZN1XD1Ev - // CHECK-NOT: call void @objc_release + // CHECK-NOT: call void @llvm.objc.release // CHECK: unreachable } @@ -83,43 +83,43 @@ void test_array_instantiation() { // CHECK: [[ELEMENT0:%[a-zA-Z0-9.]+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[OBJECTS]], i64 0, i64 0 // CHECK: call void @_ZN1XC1Ev // CHECK-NEXT: [[OBJECT0:%[a-zA-Z0-9.]+]] = invoke i8* @_ZNK1XcvP11objc_objectEv - // CHECK: [[RET0:%[a-zA-Z0-9.]+]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[OBJECT0]]) + // CHECK: [[RET0:%[a-zA-Z0-9.]+]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[OBJECT0]]) // CHECK: store i8* [[RET0]], i8** [[ELEMENT0]] // Initializing the second element // CHECK: [[ELEMENT1:%[a-zA-Z0-9.]+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[OBJECTS]], i64 0, i64 1 // CHECK: invoke void @_ZN1YC1Ev // CHECK: [[OBJECT1:%[a-zA-Z0-9.]+]] = invoke i8* @_ZNK1YcvP11objc_objectEv - // CHECK: [[RET1:%[a-zA-Z0-9.]+]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[OBJECT1]]) + // CHECK: [[RET1:%[a-zA-Z0-9.]+]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[OBJECT1]]) // CHECK: store i8* [[RET1]], i8** [[ELEMENT1]] // Build the array // CHECK: {{invoke.*@objc_msgSend}} - // CHECK: call i8* @objc_retainAutoreleasedReturnValue + // CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue id arr = @[ X(), Y() ]; // Destroy temporaries // CHECK-NOT: ret void - // CHECK: call void @objc_release + // CHECK: call void @llvm.objc.release // CHECK-NOT: ret void // CHECK: invoke void @_ZN1YD1Ev // CHECK-NOT: ret void - // CHECK: call void @objc_release + // CHECK: call void @llvm.objc.release // CHECK-NEXT: call void @_ZN1XD1Ev // CHECK-NOT: ret void - // CHECK: call void @objc_release + // CHECK: call void @llvm.objc.release // CHECK-NEXT: [[PTR2]] = bitcast i8** [[ARR]] to i8* // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[PTR2]]) // CHECK-NEXT: ret void // Check cleanups - // CHECK: call void @objc_release - // CHECK-NOT: call void @objc_release + // CHECK: call void @llvm.objc.release + // CHECK-NOT: call void @llvm.objc.release // CHECK: invoke void @_ZN1YD1Ev - // CHECK: call void @objc_release - // CHECK-NOT: call void @objc_release + // CHECK: call void @llvm.objc.release + // CHECK-NOT: call void @llvm.objc.release // CHECK: invoke void @_ZN1XD1Ev - // CHECK-NOT: call void @objc_release + // CHECK-NOT: call void @llvm.objc.release // CHECK: unreachable } diff --git a/test/CodeGenObjCXX/microsoft-abi-arc-param-order.mm b/test/CodeGenObjCXX/microsoft-abi-arc-param-order.mm index 910a7db734..50c2e4aa41 100644 --- a/test/CodeGenObjCXX/microsoft-abi-arc-param-order.mm +++ b/test/CodeGenObjCXX/microsoft-abi-arc-param-order.mm @@ -13,8 +13,8 @@ struct A { // CHECK: (<{ %struct.A, i8*, %struct.A, i8* }>* inalloca) void test_arc_order(A a, id __attribute__((ns_consumed)) b , A c, id __attribute__((ns_consumed)) d) { // CHECK: call x86_thiscallcc void @"??1A@@QAE@XZ"(%struct.A* %{{.*}}) - // CHECK: call void @objc_storeStrong(i8** %{{.*}}, i8* null) + // CHECK: call void @llvm.objc.storeStrong(i8** %{{.*}}, i8* null) // CHECK: call x86_thiscallcc void @"??1A@@QAE@XZ"(%struct.A* %{{.*}}) - // CHECK: call void @objc_storeStrong(i8** %{{.*}}, i8* null) + // CHECK: call void @llvm.objc.storeStrong(i8** %{{.*}}, i8* null) // CHECK: ret void } diff --git a/test/CodeGenObjCXX/mrc-weak.mm b/test/CodeGenObjCXX/mrc-weak.mm index 1cb191fe30..b89d76cf47 100644 --- a/test/CodeGenObjCXX/mrc-weak.mm +++ b/test/CodeGenObjCXX/mrc-weak.mm @@ -26,15 +26,15 @@ @implementation Foo // CHECK-LABEL: define internal void @"\01-[Foo .cxx_destruct]" -// CHECK: call void @objc_destroyWeak +// CHECK: call void @llvm.objc.destroyWeak @end void test1(__weak id x) {} // CHECK-LABEL: define void @_Z5test1P11objc_object( // CHECK: [[X:%.*]] = alloca i8*, -// CHECK-NEXT: objc_initWeak -// CHECK-NEXT: objc_destroyWeak +// CHECK-NEXT: llvm.objc.initWeak +// CHECK-NEXT: llvm.objc.destroyWeak // CHECK-NEXT: ret void void test2(id y) { @@ -45,8 +45,8 @@ void test2(id y) { // CHECK-NEXT: [[Z:%.*]] = alloca i8*, // CHECK-NEXT: store // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[Y]] -// CHECK-NEXT: call i8* @objc_initWeak(i8** [[Z]], i8* [[T0]]) -// CHECK-NEXT: call void @objc_destroyWeak(i8** [[Z]]) +// CHECK-NEXT: call i8* @llvm.objc.initWeak(i8** [[Z]], i8* [[T0]]) +// CHECK-NEXT: call void @llvm.objc.destroyWeak(i8** [[Z]]) // CHECK-NEXT: ret void void test3(id y) { @@ -59,8 +59,8 @@ void test3(id y) { // CHECK-NEXT: store // CHECK-NEXT: store i8* null, i8** [[Z]] // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[Y]] -// CHECK-NEXT: call i8* @objc_storeWeak(i8** [[Z]], i8* [[T0]]) -// CHECK-NEXT: call void @objc_destroyWeak(i8** [[Z]]) +// CHECK-NEXT: call i8* @llvm.objc.storeWeak(i8** [[Z]], i8* [[T0]]) +// CHECK-NEXT: call void @llvm.objc.destroyWeak(i8** [[Z]]) // CHECK-NEXT: ret void void test4(__weak id *p) { @@ -71,7 +71,7 @@ void test4(__weak id *p) { // CHECK-NEXT: [[Y:%.*]] = alloca i8*, // CHECK-NEXT: store // CHECK-NEXT: [[T0:%.*]] = load i8**, i8*** [[P]] -// CHECK-NEXT: [[T1:%.*]] = call i8* @objc_loadWeak(i8** [[T0]]) +// CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.loadWeak(i8** [[T0]]) // CHECK-NEXT: store i8* [[T1]], i8** [[Y]] // CHECK-NEXT: ret void @@ -83,7 +83,7 @@ void test5(__weak id *p) { // CHECK-NEXT: [[Y:%.*]] = alloca i8*, // CHECK-NEXT: store // CHECK-NEXT: [[T0:%.*]] = load i8**, i8*** [[P]] -// CHECK-NEXT: [[T1:%.*]] = call i8* @objc_loadWeakRetained(i8** [[T0]]) +// CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.loadWeakRetained(i8** [[T0]]) // CHECK-NEXT: store i8* [[T1]], i8** [[Y]] // CHECK-NEXT: ret void @@ -96,7 +96,7 @@ void test6(__weak Foo **p) { // CHECK-NEXT: store // CHECK-NEXT: [[T0:%.*]] = load [[FOO]]**, [[FOO]]*** [[P]] // CHECK-NEXT: [[T1:%.*]] = bitcast [[FOO]]** [[T0]] to i8** -// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_loadWeakRetained(i8** [[T1]]) +// CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.loadWeakRetained(i8** [[T1]]) // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[FOO]]* // CHECK-NEXT: store [[FOO]]* [[T3]], [[FOO]]** [[Y]] // CHECK-NEXT: ret void @@ -114,32 +114,32 @@ void test7(void) { // CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[FOO]]* // CHECK-NEXT: [[T2:%.*]] = bitcast [[FOO]]** [[P]] to i8** // CHECK-NEXT: [[T3:%.*]] = bitcast [[FOO]]* [[T1]] to i8* -// CHECK-NEXT: call i8* @objc_initWeak(i8** [[T2]], i8* [[T3]]) -// CHECK: call void @objc_copyWeak +// CHECK-NEXT: call i8* @llvm.objc.initWeak(i8** [[T2]], i8* [[T3]]) +// CHECK: call void @llvm.objc.copyWeak // CHECK: call void @use_block -// CHECK: call void @objc_destroyWeak +// CHECK: call void @llvm.objc.destroyWeak // CHECK-LABEL: define linkonce_odr hidden void @__copy_helper_block -// CHECK: @objc_copyWeak +// CHECK: @llvm.objc.copyWeak // CHECK-LABEL: define linkonce_odr hidden void @__destroy_helper_block -// CHECK: @objc_destroyWeak +// CHECK: @llvm.objc.destroyWeak void test8(void) { __block __weak Foo *p = get_object(); use_block(^{ [p run ]; }); } // CHECK-LABEL: define void @_Z5test8v -// CHECK: call i8* @objc_initWeak -// CHECK-NOT: call void @objc_copyWeak +// CHECK: call i8* @llvm.objc.initWeak +// CHECK-NOT: call void @llvm.objc.copyWeak // CHECK: call void @use_block -// CHECK: call void @objc_destroyWeak +// CHECK: call void @llvm.objc.destroyWeak // CHECK-LABEL: define internal void @__Block_byref_object_copy -// CHECK: call void @objc_moveWeak +// CHECK: call void @llvm.objc.moveWeak // CHECK-LABEL: define internal void @__Block_byref_object_dispose -// CHECK: call void @objc_destroyWeak +// CHECK: call void @llvm.objc.destroyWeak // CHECK-LABEL: define void @_Z14test9_baselinev() // CHECK: define linkonce_odr hidden void @__copy_helper diff --git a/test/CodeGenObjCXX/objc-weak.mm b/test/CodeGenObjCXX/objc-weak.mm index 68c2d46111..afccc81106 100644 --- a/test/CodeGenObjCXX/objc-weak.mm +++ b/test/CodeGenObjCXX/objc-weak.mm @@ -18,9 +18,9 @@ id test0() { // CHECK: [[THIS:%this.*]] = load [[A]]*, [[A]]** [[THISADDR]] // CHECK: [[OBJECT:%.*]] = load [[A]]*, [[A]]** [[OBJECTADDR]] // CHECK: [[T0:%.*]] = getelementptr inbounds [[A]], [[A]]* [[OBJECT]], i32 0, i32 0 -// CHECK-NEXT: [[T1:%.*]] = call i8* @objc_loadWeak(i8** [[T0]]) +// CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.loadWeak(i8** [[T0]]) // CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds [[A]], [[A]]* [[THIS]], i32 0, i32 0 -// CHECK-NEXT: [[T3:%.*]] = call i8* @objc_storeWeak(i8** [[T2]], i8* [[T1]]) +// CHECK-NEXT: [[T3:%.*]] = call i8* @llvm.objc.storeWeak(i8** [[T2]], i8* [[T1]]) // Move Assignment Operator // CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %struct.A* @_ZN1AaSEOS_( @@ -29,9 +29,9 @@ id test0() { // CHECK: [[THIS:%this.*]] = load [[A]]*, [[A]]** [[THISADDR]] // CHECK: [[OBJECT:%.*]] = load [[A]]*, [[A]]** [[OBJECTADDR]] // CHECK: [[T0:%.*]] = getelementptr inbounds [[A]], [[A]]* [[OBJECT]], i32 0, i32 0 -// CHECK-NEXT: [[T1:%.*]] = call i8* @objc_loadWeak(i8** [[T0]]) +// CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.loadWeak(i8** [[T0]]) // CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds [[A]], [[A]]* [[THIS]], i32 0, i32 0 -// CHECK-NEXT: [[T3:%.*]] = call i8* @objc_storeWeak(i8** [[T2]], i8* [[T1]]) +// CHECK-NEXT: [[T3:%.*]] = call i8* @llvm.objc.storeWeak(i8** [[T2]], i8* [[T1]]) // Default Constructor // CHECK-LABEL: define linkonce_odr void @_ZN1AC2Ev( @@ -48,7 +48,7 @@ id test0() { // CHECK: [[T0:%.*]] = getelementptr inbounds [[A]], [[A]]* [[THIS]], i32 0, i32 0 // CHECK-NEXT: [[OBJECT:%.*]] = load [[A]]*, [[A]]** [[OBJECTADDR]] // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[A]], [[A]]* [[OBJECT]], i32 0, i32 0 -// CHECK-NEXT: call void @objc_copyWeak(i8** [[T0]], i8** [[T1]]) +// CHECK-NEXT: call void @llvm.objc.copyWeak(i8** [[T0]], i8** [[T1]]) // Move Constructor // CHECK-LABEL: define linkonce_odr void @_ZN1AC2EOS_( @@ -58,12 +58,12 @@ id test0() { // CHECK: [[T0:%.*]] = getelementptr inbounds [[A]], [[A]]* [[THIS]], i32 0, i32 0 // CHECK-NEXT: [[OBJECT:%.*]] = load [[A]]*, [[A]]** [[OBJECTADDR]] // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[A]], [[A]]* [[OBJECT]], i32 0, i32 0 -// CHECK-NEXT: call void @objc_moveWeak(i8** [[T0]], i8** [[T1]]) +// CHECK-NEXT: call void @llvm.objc.moveWeak(i8** [[T0]], i8** [[T1]]) // Destructor // CHECK-LABEL: define linkonce_odr void @_ZN1AD2Ev( // CHECK: [[THISADDR:%this.*]] = alloca [[A:.*]]* // CHECK: [[THIS:%this.*]] = load [[A]]*, [[A]]** [[THISADDR]] // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[A]], [[A]]* [[THIS]], i32 0, i32 0 -// CHECK-NEXT: call void @objc_destroyWeak(i8** [[T0]]) +// CHECK-NEXT: call void @llvm.objc.destroyWeak(i8** [[T0]]) diff --git a/test/SemaObjC/arc-objc-lifetime-conflict.m b/test/SemaObjC/arc-objc-lifetime-conflict.m index 218950ca7b..e8064b110c 100644 --- a/test/SemaObjC/arc-objc-lifetime-conflict.m +++ b/test/SemaObjC/arc-objc-lifetime-conflict.m @@ -1,19 +1,19 @@ // RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fobjc-arc -fobjc-runtime-has-weak %s -emit-llvm -o - | FileCheck %s // CHECK: bitcast {{.*}} %self_weak_s_w_s -// CHECK-NEXT: objc_destroyWeak +// CHECK-NEXT: llvm.objc.destroyWeak // CHECK-NEXT: bitcast {{.*}} %self_strong_w_s -// CHECK-NEXT: objc_storeStrong +// CHECK-NEXT: llvm.objc.storeStrong // CHECK-NEXT: bitcast {{.*}} %self_weak_s -// CHECK-NEXT: objc_destroyWeak +// CHECK-NEXT: llvm.objc.destroyWeak // CHECK-NEXT: bitcast {{.*}} %self_weak_s3 -// CHECK-NEXT: objc_destroyWeak +// CHECK-NEXT: llvm.objc.destroyWeak // CHECK-NEXT: bitcast {{.*}} %self_strong3 -// CHECK-NEXT: objc_storeStrong +// CHECK-NEXT: llvm.objc.storeStrong // CHECK-NEXT: bitcast {{.*}} %self_strong2 -// CHECK-NEXT: objc_storeStrong +// CHECK-NEXT: llvm.objc.storeStrong // CHECK-NEXT: bitcast {{.*}} %self_strong -// CHECK-NEXT: objc_storeStrong +// CHECK-NEXT: llvm.objc.storeStrong @interface NSObject @end @interface A : NSObject -- cgit v1.2.3 From 2801c2a2b5db82d5dd1833bb3344f8411b42f5d2 Mon Sep 17 00:00:00 2001 From: Alexey Bataev Date: Tue, 18 Dec 2018 21:01:42 +0000 Subject: [OPENMP][NVPTX]Emit shared memory buffer for reduction as 128 bytes buffer. Seems to me, nvlink has a bug with the proper support of the weakly linked symbols. It does not allow to define several shared memory buffer with the different sizes even with the weak linkage. Instead we always use 128 bytes buffer to prevent nvlink from the error message emission. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349540 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp | 16 ++++++++++++++++ test/OpenMP/nvptx_data_sharing.cpp | 2 +- .../nvptx_distribute_parallel_generic_mode_codegen.cpp | 2 +- test/OpenMP/nvptx_parallel_codegen.cpp | 2 +- test/OpenMP/nvptx_parallel_for_codegen.cpp | 2 +- test/OpenMP/nvptx_target_codegen.cpp | 2 +- test/OpenMP/nvptx_target_teams_distribute_codegen.cpp | 2 +- ...vptx_target_teams_distribute_parallel_for_codegen.cpp | 2 +- ...target_teams_distribute_parallel_for_simd_codegen.cpp | 2 +- test/OpenMP/nvptx_teams_codegen.cpp | 4 ++-- test/OpenMP/nvptx_teams_reduction_codegen.cpp | 2 +- 11 files changed, 27 insertions(+), 11 deletions(-) diff --git a/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp b/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp index 59086d219b..5e2676bf16 100644 --- a/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp +++ b/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp @@ -4518,6 +4518,22 @@ void CGOpenMPRuntimeNVPTX::clear() { Records.UseSharedMemory->setInitializer( llvm::ConstantInt::get(CGM.Int16Ty, UseSharedMemory ? 1 : 0)); } + // Allocate SharedMemorySize buffer for the shared memory. + // FIXME: nvlink does not handle weak linkage correctly (object with the + // different size are reported as erroneous). + // Restore this code as sson as nvlink is fixed. + if (!SharedStaticRD->field_empty()) { + llvm::APInt ArySize(/*numBits=*/64, SharedMemorySize); + QualType SubTy = C.getConstantArrayType( + C.CharTy, ArySize, ArrayType::Normal, /*IndexTypeQuals=*/0); + auto *Field = FieldDecl::Create( + C, SharedStaticRD, SourceLocation(), SourceLocation(), nullptr, SubTy, + C.getTrivialTypeSourceInfo(SubTy, SourceLocation()), + /*BW=*/nullptr, /*Mutable=*/false, + /*InitStyle=*/ICIS_NoInit); + Field->setAccess(AS_public); + SharedStaticRD->addDecl(Field); + } SharedStaticRD->completeDefinition(); if (!SharedStaticRD->field_empty()) { QualType StaticTy = C.getRecordType(SharedStaticRD); diff --git a/test/OpenMP/nvptx_data_sharing.cpp b/test/OpenMP/nvptx_data_sharing.cpp index ed3c88b577..3baee007fa 100644 --- a/test/OpenMP/nvptx_data_sharing.cpp +++ b/test/OpenMP/nvptx_data_sharing.cpp @@ -26,7 +26,7 @@ void test_ds(){ } } } -// CK1: [[MEM_TY:%.+]] = type { [8 x i8] } +// CK1: [[MEM_TY:%.+]] = type { [128 x i8] } // CK1-DAG: [[SHARED_GLOBAL_RD:@.+]] = common addrspace(3) global [[MEM_TY]] zeroinitializer // CK1-DAG: [[KERNEL_PTR:@.+]] = internal addrspace(3) global i8* null // CK1-DAG: [[KERNEL_SIZE:@.+]] = internal unnamed_addr constant i64 8 diff --git a/test/OpenMP/nvptx_distribute_parallel_generic_mode_codegen.cpp b/test/OpenMP/nvptx_distribute_parallel_generic_mode_codegen.cpp index a84962c4d8..4e763bd139 100644 --- a/test/OpenMP/nvptx_distribute_parallel_generic_mode_codegen.cpp +++ b/test/OpenMP/nvptx_distribute_parallel_generic_mode_codegen.cpp @@ -21,7 +21,7 @@ int main(int argc, char **argv) { return 0; } -// CHECK: [[MEM_TY:%.+]] = type { [84 x i8] } +// CHECK: [[MEM_TY:%.+]] = type { [128 x i8] } // CHECK-DAG: [[SHARED_GLOBAL_RD:@.+]] = common addrspace(3) global [[MEM_TY]] zeroinitializer // CHECK-DAG: [[KERNEL_PTR:@.+]] = internal addrspace(3) global i8* null // CHECK-DAG: [[KERNEL_SIZE:@.+]] = internal unnamed_addr constant i{{64|32}} 84 diff --git a/test/OpenMP/nvptx_parallel_codegen.cpp b/test/OpenMP/nvptx_parallel_codegen.cpp index 3dcf330179..821897cc0f 100644 --- a/test/OpenMP/nvptx_parallel_codegen.cpp +++ b/test/OpenMP/nvptx_parallel_codegen.cpp @@ -72,7 +72,7 @@ int bar(int n){ return a; } -// CHECK: [[MEM_TY:%.+]] = type { [4 x i8] } +// CHECK: [[MEM_TY:%.+]] = type { [128 x i8] } // CHECK-DAG: [[SHARED_GLOBAL_RD:@.+]] = common addrspace(3) global [[MEM_TY]] zeroinitializer // CHECK-DAG: [[KERNEL_PTR:@.+]] = internal addrspace(3) global i8* null // CHECK-DAG: [[KERNEL_SIZE:@.+]] = internal unnamed_addr constant i{{64|32}} 4 diff --git a/test/OpenMP/nvptx_parallel_for_codegen.cpp b/test/OpenMP/nvptx_parallel_for_codegen.cpp index 25a7a15693..6a8601f3ae 100644 --- a/test/OpenMP/nvptx_parallel_for_codegen.cpp +++ b/test/OpenMP/nvptx_parallel_for_codegen.cpp @@ -30,7 +30,7 @@ int bar(int n){ return a; } -// CHECK: [[MEM_TY:%.+]] = type { [4 x i8] } +// CHECK: [[MEM_TY:%.+]] = type { [128 x i8] } // CHECK-DAG: [[SHARED_GLOBAL_RD:@.+]] = common addrspace(3) global [[MEM_TY]] zeroinitializer // CHECK-DAG: [[KERNEL_PTR:@.+]] = internal addrspace(3) global i8* null // CHECK-DAG: [[KERNEL_SIZE:@.+]] = internal unnamed_addr constant i{{64|32}} 4 diff --git a/test/OpenMP/nvptx_target_codegen.cpp b/test/OpenMP/nvptx_target_codegen.cpp index db608eff59..033ed1e684 100644 --- a/test/OpenMP/nvptx_target_codegen.cpp +++ b/test/OpenMP/nvptx_target_codegen.cpp @@ -18,7 +18,7 @@ // CHECK-DAG: {{@__omp_offloading_.+l362}}_exec_mode = weak constant i8 1 // CHECK-DAG: {{@__omp_offloading_.+l380}}_exec_mode = weak constant i8 1 // CHECK-DAG: {{@__omp_offloading_.+l345}}_exec_mode = weak constant i8 1 -// CHECK-DAG: [[MAP_TY:%.+]] = type { [{{8|4}} x i8] } +// CHECK-DAG: [[MAP_TY:%.+]] = type { [128 x i8] } // CHECK-DAG: [[GLOB_TY:%.+]] = type { i32* } __thread int id; diff --git a/test/OpenMP/nvptx_target_teams_distribute_codegen.cpp b/test/OpenMP/nvptx_target_teams_distribute_codegen.cpp index ba99d17bdc..a13762549c 100644 --- a/test/OpenMP/nvptx_target_teams_distribute_codegen.cpp +++ b/test/OpenMP/nvptx_target_teams_distribute_codegen.cpp @@ -8,7 +8,7 @@ #ifndef HEADER #define HEADER -// CHECK: [[MEM_TY:%.+]] = type { [4 x i8] } +// CHECK: [[MEM_TY:%.+]] = type { [128 x i8] } // CHECK-DAG: {{@__omp_offloading_.+}}_l19_exec_mode = weak constant i8 1 // CHECK-DAG: internal unnamed_addr constant i{{64|32}} 4 diff --git a/test/OpenMP/nvptx_target_teams_distribute_parallel_for_codegen.cpp b/test/OpenMP/nvptx_target_teams_distribute_parallel_for_codegen.cpp index 0c06a60e44..5f003dd6cc 100644 --- a/test/OpenMP/nvptx_target_teams_distribute_parallel_for_codegen.cpp +++ b/test/OpenMP/nvptx_target_teams_distribute_parallel_for_codegen.cpp @@ -67,7 +67,7 @@ int bar(int n){ return a; } -// CHECK-DAG: [[MEM_TY:%.+]] = type { [4 x i8] } +// CHECK-DAG: [[MEM_TY:%.+]] = type { [128 x i8] } // CHECK-DAG: [[SHARED_GLOBAL_RD:@.+]] = common addrspace(3) global [[MEM_TY]] zeroinitializer // CHECK-DAG: [[KERNEL_PTR:@.+]] = internal addrspace(3) global i8* null // CHECK-DAG: [[KERNEL_SIZE:@.+]] = internal unnamed_addr constant i{{64|32}} 4 diff --git a/test/OpenMP/nvptx_target_teams_distribute_parallel_for_simd_codegen.cpp b/test/OpenMP/nvptx_target_teams_distribute_parallel_for_simd_codegen.cpp index 5a828af687..c4db1bc579 100644 --- a/test/OpenMP/nvptx_target_teams_distribute_parallel_for_simd_codegen.cpp +++ b/test/OpenMP/nvptx_target_teams_distribute_parallel_for_simd_codegen.cpp @@ -62,7 +62,7 @@ int bar(int n){ return a; } -// CHECK-DAG: [[MEM_TY:%.+]] = type { [4 x i8] } +// CHECK-DAG: [[MEM_TY:%.+]] = type { [128 x i8] } // CHECK-DAG: [[SHARED_GLOBAL_RD:@.+]] = common addrspace(3) global [[MEM_TY]] zeroinitializer // CHECK-DAG: [[KERNEL_PTR:@.+]] = internal addrspace(3) global i8* null // CHECK-DAG: [[KERNEL_SIZE:@.+]] = internal unnamed_addr constant i{{64|32}} 4 diff --git a/test/OpenMP/nvptx_teams_codegen.cpp b/test/OpenMP/nvptx_teams_codegen.cpp index 4965a50781..b259a4b938 100644 --- a/test/OpenMP/nvptx_teams_codegen.cpp +++ b/test/OpenMP/nvptx_teams_codegen.cpp @@ -27,7 +27,7 @@ int main (int argc, char **argv) { return tmain(argv); } -// CK1: [[MEM_TY:%.+]] = type { [{{4|8}} x i8] } +// CK1: [[MEM_TY:%.+]] = type { [128 x i8] } // CK1-DAG: [[SHARED_GLOBAL_RD:@.+]] = common addrspace(3) global [[MEM_TY]] zeroinitializer // CK1-DAG: [[KERNEL_PTR:@.+]] = internal addrspace(3) global i8* null // CK1-DAG: [[KERNEL_SIZE1:@.+]] = internal unnamed_addr constant i{{64|32}} 4 @@ -114,7 +114,7 @@ int main (int argc, char **argv) { return tmain(argv); } -// CK2: [[MEM_TY:%.+]] = type { [{{4|8}} x i8] } +// CK2: [[MEM_TY:%.+]] = type { [128 x i8] } // CK2-DAG: [[SHARED_GLOBAL_RD:@.+]] = common addrspace(3) global [[MEM_TY]] zeroinitializer // CK2-DAG: [[KERNEL_PTR:@.+]] = internal addrspace(3) global i8* null // CK2-DAG: [[KERNEL_SIZE1:@.+]] = internal unnamed_addr constant i{{64|32}} 4 diff --git a/test/OpenMP/nvptx_teams_reduction_codegen.cpp b/test/OpenMP/nvptx_teams_reduction_codegen.cpp index 65c147bd92..818f0739b2 100644 --- a/test/OpenMP/nvptx_teams_reduction_codegen.cpp +++ b/test/OpenMP/nvptx_teams_reduction_codegen.cpp @@ -8,7 +8,7 @@ #ifndef HEADER #define HEADER -// CHECK: [[MAP_TY:%.+]] = type { [16 x i8] } +// CHECK: [[MAP_TY:%.+]] = type { [128 x i8] } // CHECK-DAG: [[KERNEL_PTR:@.+]] = internal addrspace(3) global i8* null // CHECK-DAG: [[KERNEL_SHARED1:@.+]] = internal unnamed_addr constant i16 1 -- cgit v1.2.3 From d3028ae838e70097df9b8b2a790d844d0668a498 Mon Sep 17 00:00:00 2001 From: Vedant Kumar Date: Tue, 18 Dec 2018 21:05:03 +0000 Subject: [CodeGen] Handle mixed-width ops in mixed-sign mul-with-overflow lowering The special lowering for __builtin_mul_overflow introduced in r320902 fixed an ICE seen when passing mixed-sign operands to the builtin. This patch extends the special lowering to cover mixed-width, mixed-sign operands. In a few common scenarios, calls to muloti4 will no longer be emitted. This should address the latest comments in PR34920 and work around the link failure seen in: https://bugzilla.redhat.com/show_bug.cgi?id=1657544 Testing: - check-clang - A/B output comparison with: https://gist.github.com/vedantk/3eb9c88f82e5c32f2e590555b4af5081 Differential Revision: https://reviews.llvm.org/D55843 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349542 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGBuiltin.cpp | 19 ++++++++++++++----- test/CodeGen/builtins-overflow.c | 21 +++++++++++++++++++++ 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp index eea9207a34..0f8daa6744 100644 --- a/lib/CodeGen/CGBuiltin.cpp +++ b/lib/CodeGen/CGBuiltin.cpp @@ -1235,7 +1235,7 @@ static bool isSpecialMixedSignMultiply(unsigned BuiltinID, WidthAndSignedness Op2Info, WidthAndSignedness ResultInfo) { return BuiltinID == Builtin::BI__builtin_mul_overflow && - Op1Info.Width == Op2Info.Width && Op1Info.Width >= ResultInfo.Width && + std::max(Op1Info.Width, Op2Info.Width) >= ResultInfo.Width && Op1Info.Signed != Op2Info.Signed; } @@ -1256,11 +1256,20 @@ EmitCheckedMixedSignMultiply(CodeGenFunction &CGF, const clang::Expr *Op1, const clang::Expr *UnsignedOp = Op1Info.Signed ? Op2 : Op1; llvm::Value *Signed = CGF.EmitScalarExpr(SignedOp); llvm::Value *Unsigned = CGF.EmitScalarExpr(UnsignedOp); + unsigned SignedOpWidth = Op1Info.Signed ? Op1Info.Width : Op2Info.Width; + unsigned UnsignedOpWidth = Op1Info.Signed ? Op2Info.Width : Op1Info.Width; + + // One of the operands may be smaller than the other. If so, [s|z]ext it. + if (SignedOpWidth < UnsignedOpWidth) + Signed = CGF.Builder.CreateSExt(Signed, Unsigned->getType(), "op.sext"); + if (UnsignedOpWidth < SignedOpWidth) + Unsigned = CGF.Builder.CreateZExt(Unsigned, Signed->getType(), "op.zext"); llvm::Type *OpTy = Signed->getType(); llvm::Value *Zero = llvm::Constant::getNullValue(OpTy); Address ResultPtr = CGF.EmitPointerWithAlignment(ResultArg); llvm::Type *ResTy = ResultPtr.getElementType(); + unsigned OpWidth = std::max(Op1Info.Width, Op2Info.Width); // Take the absolute value of the signed operand. llvm::Value *IsNegative = CGF.Builder.CreateICmpSLT(Signed, Zero); @@ -1278,8 +1287,8 @@ EmitCheckedMixedSignMultiply(CodeGenFunction &CGF, const clang::Expr *Op1, if (ResultInfo.Signed) { // Signed overflow occurs if the result is greater than INT_MAX or lesser // than INT_MIN, i.e when |Result| > (INT_MAX + IsNegative). - auto IntMax = llvm::APInt::getSignedMaxValue(ResultInfo.Width) - .zextOrSelf(Op1Info.Width); + auto IntMax = + llvm::APInt::getSignedMaxValue(ResultInfo.Width).zextOrSelf(OpWidth); llvm::Value *MaxResult = CGF.Builder.CreateAdd(llvm::ConstantInt::get(OpTy, IntMax), CGF.Builder.CreateZExt(IsNegative, OpTy)); @@ -1297,9 +1306,9 @@ EmitCheckedMixedSignMultiply(CodeGenFunction &CGF, const clang::Expr *Op1, llvm::Value *Underflow = CGF.Builder.CreateAnd( IsNegative, CGF.Builder.CreateIsNotNull(UnsignedResult)); Overflow = CGF.Builder.CreateOr(UnsignedOverflow, Underflow); - if (ResultInfo.Width < Op1Info.Width) { + if (ResultInfo.Width < OpWidth) { auto IntMax = - llvm::APInt::getMaxValue(ResultInfo.Width).zext(Op1Info.Width); + llvm::APInt::getMaxValue(ResultInfo.Width).zext(OpWidth); llvm::Value *TruncOverflow = CGF.Builder.CreateICmpUGT( UnsignedResult, llvm::ConstantInt::get(OpTy, IntMax)); Overflow = CGF.Builder.CreateOr(Overflow, TruncOverflow); diff --git a/test/CodeGen/builtins-overflow.c b/test/CodeGen/builtins-overflow.c index 57f90eb66a..79a3186b74 100644 --- a/test/CodeGen/builtins-overflow.c +++ b/test/CodeGen/builtins-overflow.c @@ -339,6 +339,27 @@ long long test_smulll_overflow(long long x, long long y) { return result; } +int test_mixed_sign_mul_overflow_sext_signed_op(int x, unsigned long long y) { +// CHECK: @test_mixed_sign_mul_overflow_sext_signed_op +// CHECK: [[SignedOp:%.*]] = sext i32 %0 to i64 +// CHECK: [[IsNeg:%.*]] = icmp slt i64 [[SignedOp]], 0 + int result; + if (__builtin_mul_overflow(x, y, &result)) + return LongErrorCode; + return result; +} + +int test_mixed_sign_mul_overflow_zext_unsigned_op(long long x, unsigned y) { +// CHECK: @test_mixed_sign_mul_overflow_zext_unsigned_op +// CHECK: [[UnsignedOp:%.*]] = zext i32 %1 to i64 +// CHECK: [[IsNeg:%.*]] = icmp slt i64 %0, 0 +// CHECK: @llvm.umul.with.overflow.i64({{.*}}, i64 [[UnsignedOp]]) + int result; + if (__builtin_mul_overflow(x, y, &result)) + return LongErrorCode; + return result; +} + int test_mixed_sign_mull_overflow(int x, unsigned y) { // CHECK: @test_mixed_sign_mull_overflow // CHECK: [[IsNeg:%.*]] = icmp slt i32 [[Op1:%.*]], 0 -- cgit v1.2.3 From cffb335614b6cd0b9ef4efcc4055d8bb815e489b Mon Sep 17 00:00:00 2001 From: Aaron Ballman Date: Tue, 18 Dec 2018 21:42:20 +0000 Subject: Fix errors with the Clang natvis file. This updates the FunctionProtoType visualizer to use the proper bits for determining parameter information and the DeclarationName visualizer to use the detail namespace. It also adds support for viewing newer special declaration names (like deduction guides). Patch with help of Bruno Ricci. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349547 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/ClangVisualizers/clang.natvis | 53 +++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 23 deletions(-) diff --git a/utils/ClangVisualizers/clang.natvis b/utils/ClangVisualizers/clang.natvis index 6e3ca96ffd..b59b62a7e2 100644 --- a/utils/ClangVisualizers/clang.natvis +++ b/utils/ClangVisualizers/clang.natvis @@ -171,17 +171,17 @@ For later versions of Visual Studio, no setup is required--> but the expansion has all parameters --> {ResultType,view(cpp)} - + {*(clang::QualType *)(this+1),view(cpp)}{*this,view(parm1)} - + , {*((clang::QualType *)(this+1)+1),view(cpp)}{*this,view(parm2)} - + , {*((clang::QualType *)(this+1)+2),view(cpp)}{*this,view(parm3)} - + , {*((clang::QualType *)(this+1)+3),view(cpp)}{*this,view(parm4)} - + , {*((clang::QualType *)(this+1)+4),view(cpp)}{*this,view(parm5)} - + , /* expand for more params */ {*this,view(retType)}({*this,view(parm0)}) @@ -190,7 +190,7 @@ For later versions of Visual Studio, no setup is required--> {*this,view(parm0)} - NumParams + FunctionTypeBits.NumParams (clang::QualType *)(this+1) @@ -395,22 +395,29 @@ For later versions of Visual Studio, no setup is required--> {{Identifier ({*(clang::IdentifierInfo *)(Ptr & ~PtrMask)})}} {{ObjC Zero Arg Selector (*{(clang::IdentifierInfo *)(Ptr & ~PtrMask)})}} {{ObjC One Arg Selector (*{(clang::IdentifierInfo *)(Ptr & ~PtrMask)})}} + C++ Constructor {{*(clang::detail::CXXSpecialNameExtra *)(Ptr & ~PtrMask)}} + C++ Destructor {{*(clang::detail::CXXSpecialNameExtra *)(Ptr & ~PtrMask)}} + C++ Conversion function {{*(clang::detail::CXXSpecialNameExtra *)(Ptr & ~PtrMask)}} + C++ Operator {{*(clang::detail::CXXOperatorIdName *)(Ptr & ~PtrMask)}} {*(clang::DeclarationNameExtra *)(Ptr & ~PtrMask),view(cpp)} - {{Extra ({*(clang::DeclarationNameExtra *)(Ptr & ~PtrMask)})}} + IncludeView="cpp">{*(clang::detail::DeclarationNameExtra *)(Ptr & ~PtrMask),view(cpp)} + {{Extra ({*(clang::detail::DeclarationNameExtra *)(Ptr & ~PtrMask)})}} *(clang::IdentifierInfo *)(Ptr & ~PtrMask) *(clang::IdentifierInfo *)(Ptr & ~PtrMask) *(clang::IdentifierInfo *)(Ptr & ~PtrMask) - (clang::DeclarationNameExtra *)(Ptr & ~PtrMask) + *(clang::detail::CXXSpecialNameExtra *)(Ptr & ~PtrMask) + *(clang::detail::CXXSpecialNameExtra *)(Ptr & ~PtrMask) + *(clang::detail::CXXSpecialNameExtra *)(Ptr & ~PtrMask) + *(clang::detail::CXXOperatorIdName *)(Ptr & ~PtrMask) + (clang::detail::DeclarationNameExtra *)(Ptr & ~PtrMask) - - {((clang::CXXSpecialName *)this)->Type,view(cpp)} - {(clang::DeclarationNameExtra::ExtraKind)ExtraKindOrNumArgs,en}{" ",sb}{*this,view(cpp)} + + C++ Deduction guide + C++ Literal operator + C++ Using directive + {(clang::detail::DeclarationNameExtra::ExtraKind)ExtraKindOrNumArgs,en}{" ",sb}{*this,view(cpp)} {(clang::tok::TokenKind)Kind,en} @@ -458,17 +465,17 @@ For later versions of Visual Studio, no setup is required--> {*(clang::FunctionProtoType *)((clang::ExtQualsTypeCommonBase *)(((uintptr_t)DeclType.Value.Value) & ~15))->BaseType,view(retType)} - + {*ParamInfo[0]}{*this,view(parm1)nd} - + , {*ParamInfo[1]}{*this,view(parm2)nd} - + , {*ParamInfo[2]}{*this,view(parm3)nd} - + , {*ParamInfo[3]}{*this,view(parm4)nd} - + , {*ParamInfo[4]}{*this,view(parm5)nd} - + , /* expand for more params */ {*this,view(retType)nd} {Name,view(cpp)nd}({*this,view(parm0)nd}) @@ -477,7 +484,7 @@ For later versions of Visual Studio, no setup is required--> {*this,view(parm0)nd} - ((clang::FunctionProtoType *)((clang::ExtQualsTypeCommonBase *)(((uintptr_t)DeclType.Value.Value) & ~15))->BaseType)->NumParams + ((clang::FunctionProtoType *)((clang::ExtQualsTypeCommonBase *)(((uintptr_t)DeclType.Value.Value) & ~15))->BaseType)->FunctionTypeBits.NumParams ParamInfo -- cgit v1.2.3 From d4d7233447c39b5af77a7bf8f73b60fb53d5e9fd Mon Sep 17 00:00:00 2001 From: Kelvin Li Date: Tue, 18 Dec 2018 22:18:41 +0000 Subject: [OPENMP] parsing and sema support for 'close' map-type-modifier A map clause with the close map-type-modifier is a hint to prefer that the variables are mapped using a copy into faster memory. Patch by Ahsan Saghir (saghir) Differential Revision: https://reviews.llvm.org/D55719 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349551 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/OpenMPClause.h | 91 +++++++++-- include/clang/Basic/DiagnosticParseKinds.td | 4 +- include/clang/Basic/DiagnosticSemaKinds.td | 2 + include/clang/Basic/OpenMPKinds.def | 11 +- include/clang/Basic/OpenMPKinds.h | 9 ++ include/clang/Parse/Parser.h | 6 +- include/clang/Sema/Sema.h | 7 +- lib/AST/OpenMPClause.cpp | 22 +-- lib/Basic/OpenMPKinds.cpp | 11 +- lib/CodeGen/CGOpenMPRuntime.cpp | 65 ++++---- lib/Parse/ParseOpenMP.cpp | 168 ++++++++++++--------- lib/Sema/SemaOpenMP.cpp | 43 ++++-- lib/Sema/TreeTransform.h | 16 +- lib/Serialization/ASTReader.cpp | 7 +- lib/Serialization/ASTWriter.cpp | 5 +- test/OpenMP/target_ast_print.cpp | 76 +++++++++- test/OpenMP/target_data_ast_print.cpp | 26 ++++ test/OpenMP/target_map_messages.cpp | 56 ++++++- test/OpenMP/target_parallel_for_map_messages.cpp | 4 +- .../target_parallel_for_simd_map_messages.cpp | 4 +- test/OpenMP/target_parallel_map_messages.cpp | 4 +- test/OpenMP/target_simd_map_messages.cpp | 4 +- .../target_teams_distribute_map_messages.cpp | 4 +- ..._teams_distribute_parallel_for_map_messages.cpp | 4 +- ...s_distribute_parallel_for_simd_map_messages.cpp | 4 +- .../target_teams_distribute_simd_map_messages.cpp | 4 +- test/OpenMP/target_teams_map_messages.cpp | 4 +- 27 files changed, 479 insertions(+), 182 deletions(-) diff --git a/include/clang/AST/OpenMPClause.h b/include/clang/AST/OpenMPClause.h index e93f7e2b3e..bdcdf74b26 100644 --- a/include/clang/AST/OpenMPClause.h +++ b/include/clang/AST/OpenMPClause.h @@ -4061,8 +4061,19 @@ class OMPMapClause final : public OMPMappableExprListClause, return getUniqueDeclarationsNum() + getTotalComponentListNum(); } - /// Map type modifier for the 'map' clause. - OpenMPMapClauseKind MapTypeModifier = OMPC_MAP_unknown; +public: + /// Number of allowed map-type-modifiers. + static constexpr unsigned NumberOfModifiers = + OMPC_MAP_MODIFIER_last - OMPC_MAP_MODIFIER_unknown - 1; + +private: + /// Map-type-modifiers for the 'map' clause. + OpenMPMapModifierKind MapTypeModifiers[NumberOfModifiers] = { + OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown + }; + + /// Location of map-type-modifiers for the 'map' clause. + SourceLocation MapTypeModifiersLoc[NumberOfModifiers]; /// Map type for the 'map' clause. OpenMPMapClauseKind MapType = OMPC_MAP_unknown; @@ -4080,7 +4091,8 @@ class OMPMapClause final : public OMPMappableExprListClause, /// NumUniqueDeclarations declarations, \a NumComponentLists total component /// lists, and \a NumComponents total expression components. /// - /// \param MapTypeModifier Map type modifier. + /// \param MapModifiers Map-type-modifiers. + /// \param MapModifiersLoc Locations of map-type-modifiers. /// \param MapType Map type. /// \param MapTypeIsImplicit Map type is inferred implicitly. /// \param MapLoc Location of the map type. @@ -4091,7 +4103,8 @@ class OMPMapClause final : public OMPMappableExprListClause, /// clause. /// \param NumComponentLists Number of component lists in this clause. /// \param NumComponents Total number of expression components in the clause. - explicit OMPMapClause(OpenMPMapClauseKind MapTypeModifier, + explicit OMPMapClause(ArrayRef MapModifiers, + ArrayRef MapModifiersLoc, OpenMPMapClauseKind MapType, bool MapTypeIsImplicit, SourceLocation MapLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, @@ -4100,8 +4113,17 @@ class OMPMapClause final : public OMPMappableExprListClause, : OMPMappableExprListClause(OMPC_map, StartLoc, LParenLoc, EndLoc, NumVars, NumUniqueDeclarations, NumComponentLists, NumComponents), - MapTypeModifier(MapTypeModifier), MapType(MapType), - MapTypeIsImplicit(MapTypeIsImplicit), MapLoc(MapLoc) {} + MapType(MapType), MapTypeIsImplicit(MapTypeIsImplicit), + MapLoc(MapLoc) { + assert(llvm::array_lengthof(MapTypeModifiers) == MapModifiers.size() + && "Unexpected number of map type modifiers."); + llvm::copy(MapModifiers, std::begin(MapTypeModifiers)); + + assert(llvm::array_lengthof(MapTypeModifiersLoc) == + MapModifiersLoc.size() && + "Unexpected number of map type modifier locations."); + llvm::copy(MapModifiersLoc, std::begin(MapTypeModifiersLoc)); + } /// Build an empty clause. /// @@ -4116,10 +4138,25 @@ class OMPMapClause final : public OMPMappableExprListClause, OMPC_map, SourceLocation(), SourceLocation(), SourceLocation(), NumVars, NumUniqueDeclarations, NumComponentLists, NumComponents) {} - /// Set type modifier for the clause. + /// Set map-type-modifier for the clause. /// - /// \param T Type Modifier for the clause. - void setMapTypeModifier(OpenMPMapClauseKind T) { MapTypeModifier = T; } + /// \param I index for map-type-modifier. + /// \param T map-type-modifier for the clause. + void setMapTypeModifier(unsigned I, OpenMPMapModifierKind T) { + assert(I < NumberOfModifiers && + "Unexpected index to store map type modifier, exceeds array size."); + MapTypeModifiers[I] = T; + } + + /// Set location for the map-type-modifier. + /// + /// \param I index for map-type-modifier location. + /// \param TLoc map-type-modifier location. + void setMapTypeModifierLoc(unsigned I, SourceLocation TLoc) { + assert(I < NumberOfModifiers && + "Index to store map type modifier location exceeds array size."); + MapTypeModifiersLoc[I] = TLoc; + } /// Set type for the clause. /// @@ -4143,7 +4180,8 @@ public: /// \param Vars The original expression used in the clause. /// \param Declarations Declarations used in the clause. /// \param ComponentLists Component lists used in the clause. - /// \param TypeModifier Map type modifier. + /// \param MapModifiers Map-type-modifiers. + /// \param MapModifiersLoc Location of map-type-modifiers. /// \param Type Map type. /// \param TypeIsImplicit Map type is inferred implicitly. /// \param TypeLoc Location of the map type. @@ -4152,7 +4190,8 @@ public: ArrayRef Vars, ArrayRef Declarations, MappableExprComponentListsRef ComponentLists, - OpenMPMapClauseKind TypeModifier, + ArrayRef MapModifiers, + ArrayRef MapModifiersLoc, OpenMPMapClauseKind Type, bool TypeIsImplicit, SourceLocation TypeLoc); @@ -4182,9 +4221,33 @@ public: /// messages for some target directives. bool isImplicitMapType() const LLVM_READONLY { return MapTypeIsImplicit; } - /// Fetches the map type modifier for the clause. - OpenMPMapClauseKind getMapTypeModifier() const LLVM_READONLY { - return MapTypeModifier; + /// Fetches the map-type-modifier at 'Cnt' index of array of modifiers. + /// + /// \param Cnt index for map-type-modifier. + OpenMPMapModifierKind getMapTypeModifier(unsigned Cnt) const LLVM_READONLY { + assert(Cnt < NumberOfModifiers && + "Requested modifier exceeds the total number of modifiers."); + return MapTypeModifiers[Cnt]; + } + + /// Fetches the map-type-modifier location at 'Cnt' index of array of + /// modifiers' locations. + /// + /// \param Cnt index for map-type-modifier location. + SourceLocation getMapTypeModifierLoc(unsigned Cnt) const LLVM_READONLY { + assert(Cnt < NumberOfModifiers && + "Requested modifier location exceeds total number of modifiers."); + return MapTypeModifiersLoc[Cnt]; + } + + /// Fetches ArrayRef of map-type-modifiers. + ArrayRef getMapTypeModifiers() const LLVM_READONLY { + return llvm::makeArrayRef(MapTypeModifiers); + } + + /// Fetches ArrayRef of location of map-type-modifiers. + ArrayRef getMapTypeModifiersLoc() const LLVM_READONLY { + return llvm::makeArrayRef(MapTypeModifiersLoc); } /// Fetches location of clause mapping kind. diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td index ec07bb5c4f..1e816bc5f2 100644 --- a/include/clang/Basic/DiagnosticParseKinds.td +++ b/include/clang/Basic/DiagnosticParseKinds.td @@ -1157,9 +1157,11 @@ def err_omp_decl_in_declare_simd : Error< def err_omp_unknown_map_type : Error< "incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'">; def err_omp_unknown_map_type_modifier : Error< - "incorrect map type modifier, expected 'always'">; + "incorrect map type modifier, expected 'always' or 'close'">; def err_omp_map_type_missing : Error< "missing map type">; +def err_omp_map_type_modifier_missing : Error< + "missing map type modifier">; def err_omp_declare_simd_inbranch_notinbranch : Error< "unexpected '%0' clause, '%1' is specified already">; def err_expected_end_declare_target : Error< diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 2e84f5fedf..9ab263fcfe 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -8725,6 +8725,8 @@ def err_omp_expected_access_to_data_field : Error< "expected access to data field">; def err_omp_multiple_array_items_in_map_clause : Error< "multiple array elements associated with the same variable are not allowed in map clauses of the same construct">; +def err_omp_duplicate_map_type_modifier : Error< + "same map type modifier has been specified more than once">; def err_omp_pointer_mapped_along_with_derived_section : Error< "pointer cannot be mapped along with a section derived from itself">; def err_omp_original_storage_is_shared_and_does_not_contain : Error< diff --git a/include/clang/Basic/OpenMPKinds.def b/include/clang/Basic/OpenMPKinds.def index eb9881115c..f86721b1b0 100644 --- a/include/clang/Basic/OpenMPKinds.def +++ b/include/clang/Basic/OpenMPKinds.def @@ -120,6 +120,9 @@ #ifndef OPENMP_MAP_KIND #define OPENMP_MAP_KIND(Name) #endif +#ifndef OPENMP_MAP_MODIFIER_KIND +#define OPENMP_MAP_MODIFIER_KIND(Name) +#endif #ifndef OPENMP_DIST_SCHEDULE_KIND #define OPENMP_DIST_SCHEDULE_KIND(Name) #endif @@ -559,14 +562,17 @@ OPENMP_ORDERED_CLAUSE(threads) OPENMP_ORDERED_CLAUSE(simd) OPENMP_ORDERED_CLAUSE(depend) -// Map types and map type modifier for 'map' clause. +// Map types for 'map' clause. OPENMP_MAP_KIND(alloc) OPENMP_MAP_KIND(to) OPENMP_MAP_KIND(from) OPENMP_MAP_KIND(tofrom) OPENMP_MAP_KIND(delete) OPENMP_MAP_KIND(release) -OPENMP_MAP_KIND(always) + +// Map-type-modifiers for 'map' clause. +OPENMP_MAP_MODIFIER_KIND(always) +OPENMP_MAP_MODIFIER_KIND(close) // Clauses allowed for OpenMP directive 'taskloop'. OPENMP_TASKLOOP_CLAUSE(if) @@ -919,6 +925,7 @@ OPENMP_TASKGROUP_CLAUSE(task_reduction) #undef OPENMP_FOR_CLAUSE #undef OPENMP_FOR_SIMD_CLAUSE #undef OPENMP_MAP_KIND +#undef OPENMP_MAP_MODIFIER_KIND #undef OPENMP_DISTRIBUTE_CLAUSE #undef OPENMP_DIST_SCHEDULE_KIND #undef OPENMP_DEFAULTMAP_KIND diff --git a/include/clang/Basic/OpenMPKinds.h b/include/clang/Basic/OpenMPKinds.h index b0fab5ab11..3e03a48cf6 100644 --- a/include/clang/Basic/OpenMPKinds.h +++ b/include/clang/Basic/OpenMPKinds.h @@ -96,6 +96,15 @@ enum OpenMPMapClauseKind { OMPC_MAP_unknown }; +/// OpenMP modifier kind for 'map' clause. +enum OpenMPMapModifierKind { + OMPC_MAP_MODIFIER_unknown = OMPC_MAP_unknown, +#define OPENMP_MAP_MODIFIER_KIND(Name) \ + OMPC_MAP_MODIFIER_##Name, +#include "clang/Basic/OpenMPKinds.def" + OMPC_MAP_MODIFIER_last +}; + /// OpenMP attributes for 'dist_schedule' clause. enum OpenMPDistScheduleClauseKind { #define OPENMP_DIST_SCHEDULE_KIND(Name) OMPC_DIST_SCHEDULE_##Name, diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index 09e81d22ae..46e4431913 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_PARSE_PARSER_H #define LLVM_CLANG_PARSE_PARSER_H +#include "clang/AST/OpenMPClause.h" #include "clang/AST/Availability.h" #include "clang/Basic/BitmaskEnum.h" #include "clang/Basic/OpenMPKinds.h" @@ -2876,7 +2877,10 @@ public: DeclarationNameInfo ReductionId; OpenMPDependClauseKind DepKind = OMPC_DEPEND_unknown; OpenMPLinearClauseKind LinKind = OMPC_LINEAR_val; - OpenMPMapClauseKind MapTypeModifier = OMPC_MAP_unknown; + SmallVector + MapTypeModifiers; + SmallVector + MapTypeModifiersLoc; OpenMPMapClauseKind MapType = OMPC_MAP_unknown; bool IsMapTypeImplicit = false; SourceLocation DepLinMapLoc; diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 4ddbf6caec..7685b3f74a 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -9233,7 +9233,9 @@ public: SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, OpenMPDependClauseKind DepKind, - OpenMPLinearClauseKind LinKind, OpenMPMapClauseKind MapTypeModifier, + OpenMPLinearClauseKind LinKind, + ArrayRef MapTypeModifiers, + ArrayRef MapTypeModifiersLoc, OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation DepLinMapLoc); /// Called on well-formed 'private' clause. @@ -9317,7 +9319,8 @@ public: SourceLocation EndLoc); /// Called on well-formed 'map' clause. OMPClause * - ActOnOpenMPMapClause(OpenMPMapClauseKind MapTypeModifier, + ActOnOpenMPMapClause(ArrayRef MapTypeModifiers, + ArrayRef MapTypeModifiersLoc, OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, SourceLocation ColonLoc, ArrayRef VarList, SourceLocation StartLoc, diff --git a/lib/AST/OpenMPClause.cpp b/lib/AST/OpenMPClause.cpp index 3124b0ff6f..76098f15bf 100644 --- a/lib/AST/OpenMPClause.cpp +++ b/lib/AST/OpenMPClause.cpp @@ -796,8 +796,10 @@ OMPMapClause::Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef Vars, ArrayRef Declarations, MappableExprComponentListsRef ComponentLists, - OpenMPMapClauseKind TypeModifier, OpenMPMapClauseKind Type, - bool TypeIsImplicit, SourceLocation TypeLoc) { + ArrayRef MapModifiers, + ArrayRef MapModifiersLoc, + OpenMPMapClauseKind Type, bool TypeIsImplicit, + SourceLocation TypeLoc) { unsigned NumVars = Vars.size(); unsigned NumUniqueDeclarations = getUniqueDeclarationsTotalNumber(Declarations); @@ -820,12 +822,12 @@ OMPMapClause::Create(const ASTContext &C, SourceLocation StartLoc, NumVars, NumUniqueDeclarations, NumUniqueDeclarations + NumComponentLists, NumComponents)); OMPMapClause *Clause = new (Mem) OMPMapClause( - TypeModifier, Type, TypeIsImplicit, TypeLoc, StartLoc, LParenLoc, EndLoc, - NumVars, NumUniqueDeclarations, NumComponentLists, NumComponents); + MapModifiers, MapModifiersLoc, Type, TypeIsImplicit, TypeLoc, StartLoc, + LParenLoc, EndLoc, NumVars, NumUniqueDeclarations, NumComponentLists, + NumComponents); Clause->setVarRefs(Vars); Clause->setClauseInfo(Declarations, ComponentLists); - Clause->setMapTypeModifier(TypeModifier); Clause->setMapType(Type); Clause->setMapLoc(TypeLoc); return Clause; @@ -1426,10 +1428,12 @@ void OMPClausePrinter::VisitOMPMapClause(OMPMapClause *Node) { if (!Node->varlist_empty()) { OS << "map("; if (Node->getMapType() != OMPC_MAP_unknown) { - if (Node->getMapTypeModifier() != OMPC_MAP_unknown) { - OS << getOpenMPSimpleClauseTypeName(OMPC_map, - Node->getMapTypeModifier()); - OS << ','; + for (unsigned I = 0; I < OMPMapClause::NumberOfModifiers; ++I) { + if (Node->getMapTypeModifier(I) != OMPC_MAP_MODIFIER_unknown) { + OS << getOpenMPSimpleClauseTypeName(OMPC_map, + Node->getMapTypeModifier(I)); + OS << ','; + } } OS << getOpenMPSimpleClauseTypeName(OMPC_map, Node->getMapType()); OS << ':'; diff --git a/lib/Basic/OpenMPKinds.cpp b/lib/Basic/OpenMPKinds.cpp index dcd36c456f..a5bfac86e6 100644 --- a/lib/Basic/OpenMPKinds.cpp +++ b/lib/Basic/OpenMPKinds.cpp @@ -108,8 +108,11 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, #include "clang/Basic/OpenMPKinds.def" .Default(OMPC_LINEAR_unknown); case OMPC_map: - return llvm::StringSwitch(Str) -#define OPENMP_MAP_KIND(Name) .Case(#Name, OMPC_MAP_##Name) + return llvm::StringSwitch(Str) +#define OPENMP_MAP_KIND(Name) \ + .Case(#Name, static_cast(OMPC_MAP_##Name)) +#define OPENMP_MAP_MODIFIER_KIND(Name) \ + .Case(#Name, static_cast(OMPC_MAP_MODIFIER_##Name)) #include "clang/Basic/OpenMPKinds.def" .Default(OMPC_MAP_unknown); case OMPC_dist_schedule: @@ -243,10 +246,14 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, case OMPC_map: switch (Type) { case OMPC_MAP_unknown: + case OMPC_MAP_MODIFIER_last: return "unknown"; #define OPENMP_MAP_KIND(Name) \ case OMPC_MAP_##Name: \ return #Name; +#define OPENMP_MAP_MODIFIER_KIND(Name) \ + case OMPC_MAP_MODIFIER_##Name: \ + return #Name; #include "clang/Basic/OpenMPKinds.def" default: break; diff --git a/lib/CodeGen/CGOpenMPRuntime.cpp b/lib/CodeGen/CGOpenMPRuntime.cpp index 66f0783e27..d7a0a72de1 100644 --- a/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/lib/CodeGen/CGOpenMPRuntime.cpp @@ -6645,17 +6645,17 @@ private: struct MapInfo { OMPClauseMappableExprCommon::MappableExprComponentListRef Components; OpenMPMapClauseKind MapType = OMPC_MAP_unknown; - OpenMPMapClauseKind MapTypeModifier = OMPC_MAP_unknown; + ArrayRef MapModifiers; bool ReturnDevicePointer = false; bool IsImplicit = false; MapInfo() = default; MapInfo( OMPClauseMappableExprCommon::MappableExprComponentListRef Components, - OpenMPMapClauseKind MapType, OpenMPMapClauseKind MapTypeModifier, + OpenMPMapClauseKind MapType, + ArrayRef MapModifiers, bool ReturnDevicePointer, bool IsImplicit) - : Components(Components), MapType(MapType), - MapTypeModifier(MapTypeModifier), + : Components(Components), MapType(MapType), MapModifiers(MapModifiers), ReturnDevicePointer(ReturnDevicePointer), IsImplicit(IsImplicit) {} }; @@ -6732,10 +6732,9 @@ private: /// a flag marking the map as a pointer if requested. Add a flag marking the /// map as the first one of a series of maps that relate to the same map /// expression. - OpenMPOffloadMappingFlags getMapTypeBits(OpenMPMapClauseKind MapType, - OpenMPMapClauseKind MapTypeModifier, - bool IsImplicit, bool AddPtrFlag, - bool AddIsTargetParamFlag) const { + OpenMPOffloadMappingFlags getMapTypeBits( + OpenMPMapClauseKind MapType, ArrayRef MapModifiers, + bool IsImplicit, bool AddPtrFlag, bool AddIsTargetParamFlag) const { OpenMPOffloadMappingFlags Bits = IsImplicit ? OMP_MAP_IMPLICIT : OMP_MAP_NONE; switch (MapType) { @@ -6758,7 +6757,6 @@ private: case OMPC_MAP_delete: Bits |= OMP_MAP_DELETE; break; - case OMPC_MAP_always: case OMPC_MAP_unknown: llvm_unreachable("Unexpected map type!"); } @@ -6766,7 +6764,8 @@ private: Bits |= OMP_MAP_PTR_AND_OBJ; if (AddIsTargetParamFlag) Bits |= OMP_MAP_TARGET_PARAM; - if (MapTypeModifier == OMPC_MAP_always) + if (llvm::find(MapModifiers, OMPC_MAP_MODIFIER_always) + != MapModifiers.end()) Bits |= OMP_MAP_ALWAYS; return Bits; } @@ -6815,7 +6814,8 @@ private: /// \a IsFirstComponent should be set to true if the provided set of /// components is the first associated with a capture. void generateInfoForComponentList( - OpenMPMapClauseKind MapType, OpenMPMapClauseKind MapTypeModifier, + OpenMPMapClauseKind MapType, + ArrayRef MapModifiers, OMPClauseMappableExprCommon::MappableExprComponentListRef Components, MapBaseValuesArrayTy &BasePointers, MapValuesArrayTy &Pointers, MapValuesArrayTy &Sizes, MapFlagsArrayTy &Types, @@ -7125,7 +7125,7 @@ private: // Emit data for non-overlapped data. OpenMPOffloadMappingFlags Flags = OMP_MAP_MEMBER_OF | - getMapTypeBits(MapType, MapTypeModifier, IsImplicit, + getMapTypeBits(MapType, MapModifiers, IsImplicit, /*AddPtrFlag=*/false, /*AddIsTargetParamFlag=*/false); LB = BP; @@ -7175,7 +7175,7 @@ private: // this map is the first one that relates with the current capture // (there is a set of entries for each capture). OpenMPOffloadMappingFlags Flags = getMapTypeBits( - MapType, MapTypeModifier, IsImplicit, + MapType, MapModifiers, IsImplicit, !IsExpressionFirstInfo || IsLink, IsCaptureFirstInfo && !IsLink); if (!IsExpressionFirstInfo) { @@ -7395,28 +7395,29 @@ public: auto &&InfoGen = [&Info]( const ValueDecl *D, OMPClauseMappableExprCommon::MappableExprComponentListRef L, - OpenMPMapClauseKind MapType, OpenMPMapClauseKind MapModifier, + OpenMPMapClauseKind MapType, + ArrayRef MapModifiers, bool ReturnDevicePointer, bool IsImplicit) { const ValueDecl *VD = D ? cast(D->getCanonicalDecl()) : nullptr; - Info[VD].emplace_back(L, MapType, MapModifier, ReturnDevicePointer, + Info[VD].emplace_back(L, MapType, MapModifiers, ReturnDevicePointer, IsImplicit); }; // FIXME: MSVC 2013 seems to require this-> to find member CurDir. for (const auto *C : this->CurDir.getClausesOfKind()) for (const auto &L : C->component_lists()) { - InfoGen(L.first, L.second, C->getMapType(), C->getMapTypeModifier(), + InfoGen(L.first, L.second, C->getMapType(), C->getMapTypeModifiers(), /*ReturnDevicePointer=*/false, C->isImplicit()); } for (const auto *C : this->CurDir.getClausesOfKind()) for (const auto &L : C->component_lists()) { - InfoGen(L.first, L.second, OMPC_MAP_to, OMPC_MAP_unknown, + InfoGen(L.first, L.second, OMPC_MAP_to, llvm::None, /*ReturnDevicePointer=*/false, C->isImplicit()); } for (const auto *C : this->CurDir.getClausesOfKind()) for (const auto &L : C->component_lists()) { - InfoGen(L.first, L.second, OMPC_MAP_from, OMPC_MAP_unknown, + InfoGen(L.first, L.second, OMPC_MAP_from, llvm::None, /*ReturnDevicePointer=*/false, C->isImplicit()); } @@ -7469,7 +7470,7 @@ public: // Nonetheless, generateInfoForComponentList must be called to take // the pointer into account for the calculation of the range of the // partial struct. - InfoGen(nullptr, L.second, OMPC_MAP_unknown, OMPC_MAP_unknown, + InfoGen(nullptr, L.second, OMPC_MAP_unknown, llvm::None, /*ReturnDevicePointer=*/false, C->isImplicit()); DeferredInfo[nullptr].emplace_back(IE, VD); } else { @@ -7503,7 +7504,7 @@ public: unsigned CurrentBasePointersIdx = CurBasePointers.size(); // FIXME: MSVC 2013 seems to require this-> to find the member method. this->generateInfoForComponentList( - L.MapType, L.MapTypeModifier, L.Components, CurBasePointers, + L.MapType, L.MapModifiers, L.Components, CurBasePointers, CurPointers, CurSizes, CurTypes, PartialStruct, IsFirstComponentList, L.IsImplicit); @@ -7662,7 +7663,7 @@ public: using MapData = std::tuple; + OpenMPMapClauseKind, ArrayRef, bool>; SmallVector DeclComponentLists; // FIXME: MSVC 2013 seems to require this-> to find member CurDir. for (const auto *C : this->CurDir.getClausesOfKind()) { @@ -7672,7 +7673,7 @@ public: assert(!L.second.empty() && "Not expecting declaration with no component lists."); DeclComponentLists.emplace_back(L.second, C->getMapType(), - C->getMapTypeModifier(), + C->getMapTypeModifiers(), C->isImplicit()); } } @@ -7688,13 +7689,13 @@ public: for (const MapData &L : DeclComponentLists) { OMPClauseMappableExprCommon::MappableExprComponentListRef Components; OpenMPMapClauseKind MapType; - OpenMPMapClauseKind MapTypeModifier; + ArrayRef MapModifiers; bool IsImplicit; - std::tie(Components, MapType, MapTypeModifier, IsImplicit) = L; + std::tie(Components, MapType, MapModifiers, IsImplicit) = L; ++Count; for (const MapData &L1 : makeArrayRef(DeclComponentLists).slice(Count)) { OMPClauseMappableExprCommon::MappableExprComponentListRef Components1; - std::tie(Components1, MapType, MapTypeModifier, IsImplicit) = L1; + std::tie(Components1, MapType, MapModifiers, IsImplicit) = L1; auto CI = Components.rbegin(); auto CE = Components.rend(); auto SI = Components1.rbegin(); @@ -7778,13 +7779,13 @@ public: const MapData &L = *Pair.getFirst(); OMPClauseMappableExprCommon::MappableExprComponentListRef Components; OpenMPMapClauseKind MapType; - OpenMPMapClauseKind MapTypeModifier; + ArrayRef MapModifiers; bool IsImplicit; - std::tie(Components, MapType, MapTypeModifier, IsImplicit) = L; + std::tie(Components, MapType, MapModifiers, IsImplicit) = L; ArrayRef OverlappedComponents = Pair.getSecond(); bool IsFirstComponentList = true; - generateInfoForComponentList(MapType, MapTypeModifier, Components, + generateInfoForComponentList(MapType, MapModifiers, Components, BasePointers, Pointers, Sizes, Types, PartialStruct, IsFirstComponentList, IsImplicit, OverlappedComponents); @@ -7794,12 +7795,12 @@ public: for (const MapData &L : DeclComponentLists) { OMPClauseMappableExprCommon::MappableExprComponentListRef Components; OpenMPMapClauseKind MapType; - OpenMPMapClauseKind MapTypeModifier; + ArrayRef MapModifiers; bool IsImplicit; - std::tie(Components, MapType, MapTypeModifier, IsImplicit) = L; + std::tie(Components, MapType, MapModifiers, IsImplicit) = L; auto It = OverlappedData.find(&L); if (It == OverlappedData.end()) - generateInfoForComponentList(MapType, MapTypeModifier, Components, + generateInfoForComponentList(MapType, MapModifiers, Components, BasePointers, Pointers, Sizes, Types, PartialStruct, IsFirstComponentList, IsImplicit); @@ -7828,7 +7829,7 @@ public: continue; StructRangeInfoTy PartialStruct; generateInfoForComponentList( - C->getMapType(), C->getMapTypeModifier(), L.second, BasePointers, + C->getMapType(), C->getMapTypeModifiers(), L.second, BasePointers, Pointers, Sizes, Types, PartialStruct, /*IsFirstComponentList=*/true, C->isImplicit()); assert(!PartialStruct.Base.isValid() && diff --git a/lib/Parse/ParseOpenMP.cpp b/lib/Parse/ParseOpenMP.cpp index 1fb52801a9..17c3fa3cf2 100644 --- a/lib/Parse/ParseOpenMP.cpp +++ b/lib/Parse/ParseOpenMP.cpp @@ -1774,6 +1774,79 @@ static bool ParseReductionId(Parser &P, CXXScopeSpec &ReductionIdScopeSpec, nullptr, nullptr, ReductionId); } +/// Checks if the token is a valid map-type-modifier. +static OpenMPMapModifierKind isMapModifier(Parser &P) { + Token Tok = P.getCurToken(); + if (!Tok.is(tok::identifier)) + return OMPC_MAP_MODIFIER_unknown; + + Preprocessor &PP = P.getPreprocessor(); + OpenMPMapModifierKind TypeModifier = static_cast( + getOpenMPSimpleClauseType(OMPC_map, PP.getSpelling(Tok))); + return TypeModifier; +} + +/// Parse map-type-modifiers in map clause. +/// map([ [map-type-modifier[,] [map-type-modifier[,] ...] map-type : ] list) +/// where, map-type-modifier ::= always | close +static void parseMapTypeModifiers(Parser &P, + Parser::OpenMPVarListDataTy &Data) { + Preprocessor &PP = P.getPreprocessor(); + while (P.getCurToken().isNot(tok::colon)) { + Token Tok = P.getCurToken(); + OpenMPMapModifierKind TypeModifier = isMapModifier(P); + if (TypeModifier == OMPC_MAP_MODIFIER_always || + TypeModifier == OMPC_MAP_MODIFIER_close) { + Data.MapTypeModifiers.push_back(TypeModifier); + Data.MapTypeModifiersLoc.push_back(Tok.getLocation()); + P.ConsumeToken(); + } else { + // For the case of unknown map-type-modifier or a map-type. + // Map-type is followed by a colon; the function returns when it + // encounters a token followed by a colon. + if (Tok.is(tok::comma)) { + P.Diag(Tok, diag::err_omp_map_type_modifier_missing); + P.ConsumeToken(); + continue; + } + // Potential map-type token as it is followed by a colon. + if (PP.LookAhead(0).is(tok::colon)) + return; + P.Diag(Tok, diag::err_omp_unknown_map_type_modifier); + P.ConsumeToken(); + } + if (P.getCurToken().is(tok::comma)) + P.ConsumeToken(); + } +} + +/// Checks if the token is a valid map-type. +static OpenMPMapClauseKind isMapType(Parser &P) { + Token Tok = P.getCurToken(); + // The map-type token can be either an identifier or the C++ delete keyword. + if (!Tok.isOneOf(tok::identifier, tok::kw_delete)) + return OMPC_MAP_unknown; + Preprocessor &PP = P.getPreprocessor(); + OpenMPMapClauseKind MapType = static_cast( + getOpenMPSimpleClauseType(OMPC_map, PP.getSpelling(Tok))); + return MapType; +} + +/// Parse map-type in map clause. +/// map([ [map-type-modifier[,] [map-type-modifier[,] ...] map-type : ] list) +/// where, map-type ::= to | from | tofrom | alloc | release | delete +static void parseMapType(Parser &P, Parser::OpenMPVarListDataTy &Data) { + Token Tok = P.getCurToken(); + if (Tok.is(tok::colon)) { + P.Diag(Tok, diag::err_omp_map_type_missing); + return; + } + Data.MapType = isMapType(P); + if (Data.MapType == OMPC_MAP_unknown) + P.Diag(Tok, diag::err_omp_unknown_map_type); + P.ConsumeToken(); +} + /// Parses clauses with list. bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, OpenMPClauseKind Kind, @@ -1852,82 +1925,27 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, // Handle map type for map clause. ColonProtectionRAIIObject ColonRAII(*this); - /// The map clause modifier token can be either a identifier or the C++ - /// delete keyword. - auto &&IsMapClauseModifierToken = [](const Token &Tok) -> bool { - return Tok.isOneOf(tok::identifier, tok::kw_delete); - }; - // The first identifier may be a list item, a map-type or a - // map-type-modifier. The map modifier can also be delete which has the same + // map-type-modifier. The map-type can also be delete which has the same // spelling of the C++ delete keyword. - Data.MapType = - IsMapClauseModifierToken(Tok) - ? static_cast( - getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok))) - : OMPC_MAP_unknown; Data.DepLinMapLoc = Tok.getLocation(); - if (IsMapClauseModifierToken(Tok)) { - if (PP.LookAhead(0).is(tok::colon)) { - if (Data.MapType == OMPC_MAP_unknown) - Diag(Tok, diag::err_omp_unknown_map_type); - else if (Data.MapType == OMPC_MAP_always) - Diag(Tok, diag::err_omp_map_type_missing); - ConsumeToken(); - } else if (PP.LookAhead(0).is(tok::comma)) { - if (IsMapClauseModifierToken(PP.LookAhead(1)) && - PP.LookAhead(2).is(tok::colon)) { - Data.MapTypeModifier = Data.MapType; - if (Data.MapTypeModifier != OMPC_MAP_always) { - Diag(Tok, diag::err_omp_unknown_map_type_modifier); - Data.MapTypeModifier = OMPC_MAP_unknown; - } - - ConsumeToken(); - ConsumeToken(); - - Data.MapType = - IsMapClauseModifierToken(Tok) - ? static_cast( - getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok))) - : OMPC_MAP_unknown; - if (Data.MapType == OMPC_MAP_unknown || - Data.MapType == OMPC_MAP_always) - Diag(Tok, diag::err_omp_unknown_map_type); - ConsumeToken(); - } else { - Data.MapType = OMPC_MAP_tofrom; - Data.IsMapTypeImplicit = true; - } - } else if (IsMapClauseModifierToken(PP.LookAhead(0))) { - if (PP.LookAhead(1).is(tok::colon)) { - Data.MapTypeModifier = Data.MapType; - if (Data.MapTypeModifier != OMPC_MAP_always) { - Diag(Tok, diag::err_omp_unknown_map_type_modifier); - Data.MapTypeModifier = OMPC_MAP_unknown; - } - - ConsumeToken(); - - Data.MapType = - IsMapClauseModifierToken(Tok) - ? static_cast( - getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok))) - : OMPC_MAP_unknown; - if (Data.MapType == OMPC_MAP_unknown || - Data.MapType == OMPC_MAP_always) - Diag(Tok, diag::err_omp_unknown_map_type); - ConsumeToken(); - } else { - Data.MapType = OMPC_MAP_tofrom; - Data.IsMapTypeImplicit = true; - } - } else { - Data.MapType = OMPC_MAP_tofrom; - Data.IsMapTypeImplicit = true; - } - } else { + // Check for presence of a colon in the map clause. + TentativeParsingAction TPA(*this); + bool ColonPresent = false; + if (SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end, + StopBeforeMatch)) { + if (Tok.is(tok::colon)) + ColonPresent = true; + } + TPA.Revert(); + // Only parse map-type-modifier[s] and map-type if a colon is present in + // the map clause. + if (ColonPresent) { + parseMapTypeModifiers(*this, Data); + parseMapType(*this, Data); + } + if (Data.MapType == OMPC_MAP_unknown) { Data.MapType = OMPC_MAP_tofrom; Data.IsMapTypeImplicit = true; } @@ -2025,7 +2043,7 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, /// depend-clause: /// 'depend' '(' in | out | inout : list | source ')' /// map-clause: -/// 'map' '(' [ [ always , ] +/// 'map' '(' [ [ always [,] ] [ close [,] ] /// to | from | tofrom | alloc | release | delete ':' ] list ')'; /// to-clause: /// 'to' '(' list ')' @@ -2056,7 +2074,7 @@ OMPClause *Parser::ParseOpenMPVarListClause(OpenMPDirectiveKind DKind, return Actions.ActOnOpenMPVarListClause( Kind, Vars, Data.TailExpr, Loc, LOpen, Data.ColonLoc, Data.RLoc, Data.ReductionIdScopeSpec, Data.ReductionId, Data.DepKind, Data.LinKind, - Data.MapTypeModifier, Data.MapType, Data.IsMapTypeImplicit, - Data.DepLinMapLoc); + Data.MapTypeModifiers, Data.MapTypeModifiersLoc, Data.MapType, + Data.IsMapTypeImplicit, Data.DepLinMapLoc); } diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp index 2daf45411e..38a329a1fd 100644 --- a/lib/Sema/SemaOpenMP.cpp +++ b/lib/Sema/SemaOpenMP.cpp @@ -3336,9 +3336,10 @@ StmtResult Sema::ActOnOpenMPExecutableDirective( } if (!ImplicitMaps.empty()) { if (OMPClause *Implicit = ActOnOpenMPMapClause( - OMPC_MAP_unknown, OMPC_MAP_tofrom, /*IsMapTypeImplicit=*/true, - SourceLocation(), SourceLocation(), ImplicitMaps, - SourceLocation(), SourceLocation(), SourceLocation())) { + llvm::None, llvm::None, OMPC_MAP_tofrom, + /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(), + ImplicitMaps, SourceLocation(), SourceLocation(), + SourceLocation())) { ClausesWithImplicit.emplace_back(Implicit); ErrorFound |= cast(Implicit)->varlist_size() != ImplicitMaps.size(); @@ -9535,7 +9536,9 @@ OMPClause *Sema::ActOnOpenMPVarListClause( SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, OpenMPDependClauseKind DepKind, - OpenMPLinearClauseKind LinKind, OpenMPMapClauseKind MapTypeModifier, + OpenMPLinearClauseKind LinKind, + ArrayRef MapTypeModifiers, + ArrayRef MapTypeModifiersLoc, OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation DepLinMapLoc) { OMPClause *Res = nullptr; @@ -9588,9 +9591,9 @@ OMPClause *Sema::ActOnOpenMPVarListClause( StartLoc, LParenLoc, EndLoc); break; case OMPC_map: - Res = ActOnOpenMPMapClause(MapTypeModifier, MapType, IsMapTypeImplicit, - DepLinMapLoc, ColonLoc, VarList, StartLoc, - LParenLoc, EndLoc); + Res = ActOnOpenMPMapClause(MapTypeModifiers, MapTypeModifiersLoc, MapType, + IsMapTypeImplicit, DepLinMapLoc, ColonLoc, + VarList, StartLoc, LParenLoc, EndLoc); break; case OMPC_to: Res = ActOnOpenMPToClause(VarList, StartLoc, LParenLoc, EndLoc); @@ -12957,7 +12960,8 @@ checkMappableExpressionList(Sema &SemaRef, DSAStackTy *DSAS, } OMPClause * -Sema::ActOnOpenMPMapClause(OpenMPMapClauseKind MapTypeModifier, +Sema::ActOnOpenMPMapClause(ArrayRef MapTypeModifiers, + ArrayRef MapTypeModifiersLoc, OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, SourceLocation ColonLoc, ArrayRef VarList, SourceLocation StartLoc, @@ -12966,12 +12970,31 @@ Sema::ActOnOpenMPMapClause(OpenMPMapClauseKind MapTypeModifier, checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, StartLoc, MapType, IsMapTypeImplicit); + OpenMPMapModifierKind Modifiers[] = { OMPC_MAP_MODIFIER_unknown, + OMPC_MAP_MODIFIER_unknown }; + SourceLocation ModifiersLoc[OMPMapClause::NumberOfModifiers]; + + // Process map-type-modifiers, flag errors for duplicate modifiers. + unsigned Count = 0; + for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) { + if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown && + llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) { + Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); + continue; + } + assert(Count < OMPMapClause::NumberOfModifiers && + "Modifiers exceed the allowed number of map type modifiers"); + Modifiers[Count] = MapTypeModifiers[I]; + ModifiersLoc[Count] = MapTypeModifiersLoc[I]; + ++Count; + } + // We need to produce a map clause even if we don't have variables so that // other diagnostics related with non-existing map clauses are accurate. return OMPMapClause::Create(Context, StartLoc, LParenLoc, EndLoc, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, - MVLI.VarComponents, MapTypeModifier, MapType, - IsMapTypeImplicit, MapLoc); + MVLI.VarComponents, Modifiers, ModifiersLoc, + MapType, IsMapTypeImplicit, MapLoc); } QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 3f4b21eb55..50ecd6d81f 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -1796,14 +1796,16 @@ public: /// By default, performs semantic analysis to build the new OpenMP clause. /// Subclasses may override this routine to provide different behavior. OMPClause * - RebuildOMPMapClause(OpenMPMapClauseKind MapTypeModifier, + RebuildOMPMapClause(ArrayRef MapTypeModifiers, + ArrayRef MapTypeModifiersLoc, OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, SourceLocation ColonLoc, ArrayRef VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { - return getSema().ActOnOpenMPMapClause(MapTypeModifier, MapType, - IsMapTypeImplicit, MapLoc, ColonLoc, - VarList, StartLoc, LParenLoc, EndLoc); + return getSema().ActOnOpenMPMapClause(MapTypeModifiers, MapTypeModifiersLoc, + MapType, IsMapTypeImplicit, MapLoc, + ColonLoc, VarList, StartLoc, + LParenLoc, EndLoc); } /// Build a new OpenMP 'num_teams' clause. @@ -8803,9 +8805,9 @@ OMPClause *TreeTransform::TransformOMPMapClause(OMPMapClause *C) { Vars.push_back(EVar.get()); } return getDerived().RebuildOMPMapClause( - C->getMapTypeModifier(), C->getMapType(), C->isImplicitMapType(), - C->getMapLoc(), C->getColonLoc(), Vars, C->getBeginLoc(), - C->getLParenLoc(), C->getEndLoc()); + C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(), C->getMapType(), + C->isImplicitMapType(), C->getMapLoc(), C->getColonLoc(), Vars, + C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc()); } template diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index 558100d45c..e0b2b24a0d 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -12284,8 +12284,11 @@ void OMPClauseReader::VisitOMPDeviceClause(OMPDeviceClause *C) { void OMPClauseReader::VisitOMPMapClause(OMPMapClause *C) { C->setLParenLoc(Record.readSourceLocation()); - C->setMapTypeModifier( - static_cast(Record.readInt())); + for (unsigned I = 0; I < OMPMapClause::NumberOfModifiers; ++I) { + C->setMapTypeModifier( + I, static_cast(Record.readInt())); + C->setMapTypeModifierLoc(I, Record.readSourceLocation()); + } C->setMapType( static_cast(Record.readInt())); C->setMapLoc(Record.readSourceLocation()); diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp index 45de91f76f..37adcb7064 100644 --- a/lib/Serialization/ASTWriter.cpp +++ b/lib/Serialization/ASTWriter.cpp @@ -6782,7 +6782,10 @@ void OMPClauseWriter::VisitOMPMapClause(OMPMapClause *C) { Record.push_back(C->getTotalComponentListNum()); Record.push_back(C->getTotalComponentsNum()); Record.AddSourceLocation(C->getLParenLoc()); - Record.push_back(C->getMapTypeModifier()); + for (unsigned I = 0; I < OMPMapClause::NumberOfModifiers; ++I) { + Record.push_back(C->getMapTypeModifier(I)); + Record.AddSourceLocation(C->getMapTypeModifierLoc(I)); + } Record.push_back(C->getMapType()); Record.AddSourceLocation(C->getMapLoc()); Record.AddSourceLocation(C->getColonLoc()); diff --git a/test/OpenMP/target_ast_print.cpp b/test/OpenMP/target_ast_print.cpp index 827d6a4e3d..2734294ff6 100644 --- a/test/OpenMP/target_ast_print.cpp +++ b/test/OpenMP/target_ast_print.cpp @@ -14,7 +14,7 @@ void foo() {} template T tmain(T argc, T *argv) { - T i, j, a[20], always; + T i, j, a[20], always, close; #pragma omp target foo(); #pragma omp target if (target:argc > 0) @@ -35,6 +35,14 @@ T tmain(T argc, T *argv) { {always++;} #pragma omp target map(always,i) {always++;i++;} +#pragma omp target map(close,alloc: i) + foo(); +#pragma omp target map(close from: i) + foo(); +#pragma omp target map(close) + {close++;} +#pragma omp target map(close,i) + {close++;i++;} #pragma omp target nowait foo(); #pragma omp target depend(in : argc, argv[i:argc], a[:]) @@ -71,6 +79,19 @@ T tmain(T argc, T *argv) { // CHECK-NEXT: always++; // CHECK-NEXT: i++; // CHECK-NEXT: } +// CHECK-NEXT: #pragma omp target map(close,alloc: i) +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target map(close,from: i) +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target map(tofrom: close) +// CHECK-NEXT: { +// CHECK-NEXT: close++; +// CHECK-NEXT: } +// CHECK-NEXT: #pragma omp target map(tofrom: close,i) +// CHECK-NEXT: { +// CHECK-NEXT: close++; +// CHECK-NEXT: i++; +// CHECK-NEXT: } // CHECK-NEXT: #pragma omp target nowait // CHECK-NEXT: foo() // CHECK-NEXT: #pragma omp target depend(in : argc,argv[i:argc],a[:]) @@ -104,6 +125,19 @@ T tmain(T argc, T *argv) { // CHECK-NEXT: always++; // CHECK-NEXT: i++; // CHECK-NEXT: } +// CHECK-NEXT: #pragma omp target map(close,alloc: i) +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target map(close,from: i) +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target map(tofrom: close) +// CHECK-NEXT: { +// CHECK-NEXT: close++; +// CHECK-NEXT: } +// CHECK-NEXT: #pragma omp target map(tofrom: close,i) +// CHECK-NEXT: { +// CHECK-NEXT: close++; +// CHECK-NEXT: i++; +// CHECK-NEXT: } // CHECK-NEXT: #pragma omp target nowait // CHECK-NEXT: foo() // CHECK-NEXT: #pragma omp target depend(in : argc,argv[i:argc],a[:]) @@ -137,6 +171,19 @@ T tmain(T argc, T *argv) { // CHECK-NEXT: always++; // CHECK-NEXT: i++; // CHECK-NEXT: } +// CHECK-NEXT: #pragma omp target map(close,alloc: i) +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target map(close,from: i) +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target map(tofrom: close) +// CHECK-NEXT: { +// CHECK-NEXT: close++; +// CHECK-NEXT: } +// CHECK-NEXT: #pragma omp target map(tofrom: close,i) +// CHECK-NEXT: { +// CHECK-NEXT: close++; +// CHECK-NEXT: i++; +// CHECK-NEXT: } // CHECK-NEXT: #pragma omp target nowait // CHECK-NEXT: foo() // CHECK-NEXT: #pragma omp target depend(in : argc,argv[i:argc],a[:]) @@ -146,7 +193,7 @@ T tmain(T argc, T *argv) { // CHECK-LABEL: int main(int argc, char **argv) { int main (int argc, char **argv) { - int i, j, a[20], always; + int i, j, a[20], always, close; // CHECK-NEXT: int i, j, a[20] #pragma omp target // CHECK-NEXT: #pragma omp target @@ -202,6 +249,31 @@ int main (int argc, char **argv) { // CHECK-NEXT: i++; // CHECK-NEXT: } +#pragma omp target map(close,alloc: i) +// CHECK-NEXT: #pragma omp target map(close,alloc: i) + foo(); +// CHECK-NEXT: foo(); + +#pragma omp target map(close from: i) +// CHECK-NEXT: #pragma omp target map(close,from: i) + foo(); +// CHECK-NEXT: foo(); + +#pragma omp target map(close) +// CHECK-NEXT: #pragma omp target map(tofrom: close) + {close++;} +// CHECK-NEXT: { +// CHECK-NEXT: close++; +// CHECK-NEXT: } + +#pragma omp target map(close,i) +// CHECK-NEXT: #pragma omp target map(tofrom: close,i) + {close++;i++;} +// CHECK-NEXT: { +// CHECK-NEXT: close++; +// CHECK-NEXT: i++; +// CHECK-NEXT: } + #pragma omp target nowait // CHECK-NEXT: #pragma omp target nowait foo(); diff --git a/test/OpenMP/target_data_ast_print.cpp b/test/OpenMP/target_data_ast_print.cpp index 17dace8bfa..fa67c1834a 100644 --- a/test/OpenMP/target_data_ast_print.cpp +++ b/test/OpenMP/target_data_ast_print.cpp @@ -40,11 +40,16 @@ T tmain(T argc, T *argv) { #pragma omp target data map(always,alloc: e) foo(); +#pragma omp target data map(close,alloc: e) + foo(); + // nesting a target region #pragma omp target data map(e) { #pragma omp target map(always, alloc: e) foo(); + #pragma omp target map(close, alloc: e) + foo(); } return 0; @@ -68,10 +73,14 @@ T tmain(T argc, T *argv) { // CHECK-NEXT: foo(); // CHECK-NEXT: #pragma omp target data map(always,alloc: e) // CHECK-NEXT: foo(); +// CHECK-NEXT: #pragma omp target data map(close,alloc: e) +// CHECK-NEXT: foo(); // CHECK-NEXT: #pragma omp target data map(tofrom: e) // CHECK-NEXT: { // CHECK-NEXT: #pragma omp target map(always,alloc: e) // CHECK-NEXT: foo(); +// CHECK-NEXT: #pragma omp target map(close,alloc: e) +// CHECK-NEXT: foo(); // CHECK: template<> int tmain(int argc, int *argv) { // CHECK-NEXT: int i, j, b, c, d, e, x[20]; // CHECK-NEXT: #pragma omp target data map(to: c) @@ -90,10 +99,14 @@ T tmain(T argc, T *argv) { // CHECK-NEXT: foo(); // CHECK-NEXT: #pragma omp target data map(always,alloc: e) // CHECK-NEXT: foo(); +// CHECK-NEXT: #pragma omp target data map(close,alloc: e) +// CHECK-NEXT: foo(); // CHECK-NEXT: #pragma omp target data map(tofrom: e) // CHECK-NEXT: { // CHECK-NEXT: #pragma omp target map(always,alloc: e) // CHECK-NEXT: foo(); +// CHECK-NEXT: #pragma omp target map(close,alloc: e) +// CHECK-NEXT: foo(); // CHECK: template<> char tmain(char argc, char *argv) { // CHECK-NEXT: char i, j, b, c, d, e, x[20]; // CHECK-NEXT: #pragma omp target data map(to: c) @@ -112,10 +125,14 @@ T tmain(T argc, T *argv) { // CHECK-NEXT: foo(); // CHECK-NEXT: #pragma omp target data map(always,alloc: e) // CHECK-NEXT: foo(); +// CHECK-NEXT: #pragma omp target data map(close,alloc: e) +// CHECK-NEXT: foo(); // CHECK-NEXT: #pragma omp target data map(tofrom: e) // CHECK-NEXT: { // CHECK-NEXT: #pragma omp target map(always,alloc: e) // CHECK-NEXT: foo(); +// CHECK-NEXT: #pragma omp target map(close,alloc: e) +// CHECK-NEXT: foo(); int main (int argc, char **argv) { int b = argc, c, d, e, f, g, x[20]; @@ -161,6 +178,11 @@ int main (int argc, char **argv) { foo(); // CHECK-NEXT: foo(); +#pragma omp target data map(close,alloc: e) +// CHECK-NEXT: #pragma omp target data map(close,alloc: e) + foo(); +// CHECK-NEXT: foo(); + // nesting a target region #pragma omp target data map(e) // CHECK-NEXT: #pragma omp target data map(tofrom: e) @@ -170,7 +192,11 @@ int main (int argc, char **argv) { // CHECK-NEXT: #pragma omp target map(always,alloc: e) foo(); // CHECK-NEXT: foo(); +#pragma omp target map(close, alloc: e) +// CHECK-NEXT: #pragma omp target map(close,alloc: e) + foo(); } + return tmain(argc, &argc) + tmain(argv[0][0], argv[0]); } diff --git a/test/OpenMP/target_map_messages.cpp b/test/OpenMP/target_map_messages.cpp index f9547baeef..e81e61eaab 100644 --- a/test/OpenMP/target_map_messages.cpp +++ b/test/OpenMP/target_map_messages.cpp @@ -74,6 +74,8 @@ struct SA { #pragma omp target map(b[:-1]) // expected-error {{section length is evaluated to a negative value -1}} {} + #pragma omp target map(: c,f) // expected-error {{missing map type}} + {} #pragma omp target map(always, tofrom: c,f) {} #pragma omp target map(always, tofrom: c[1:2],f) @@ -86,6 +88,42 @@ struct SA { {} #pragma omp target map(always) // expected-error {{use of undeclared identifier 'always'}} {} + #pragma omp target map(close, tofrom: c,f) + {} + #pragma omp target map(close, tofrom: c[1:2],f) + {} + #pragma omp target map(close, tofrom: c,f[1:2]) + {} + #pragma omp target map(close, tofrom: c[:],f) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} + {} + #pragma omp target map(close, tofrom: c,f[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} + {} + #pragma omp target map(close) // expected-error {{use of undeclared identifier 'close'}} + {} + #pragma omp target map(close, close, tofrom: a) // expected-error {{same map type modifier has been specified more than once}} + {} + #pragma omp target map(always, close, always, close, tofrom: a) // expected-error {{same map type modifier has been specified more than once}} expected-error {{same map type modifier has been specified more than once}} + {} + #pragma omp target map( , tofrom: a) // expected-error {{missing map type modifier}} + {} + #pragma omp target map( , , tofrom: a) // expected-error {{missing map type modifier}} expected-error {{missing map type modifier}} + {} + #pragma omp target map( , , : a) // expected-error {{missing map type modifier}} expected-error {{missing map type modifier}} expected-error {{missing map type}} + {} + #pragma omp target map( d, f, bf: a) // expected-error {{incorrect map type modifier, expected 'always' or 'close'}} expected-error {{incorrect map type modifier, expected 'always' or 'close'}} expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} + {} + #pragma omp target map( , f, : a) // expected-error {{missing map type modifier}} expected-error {{incorrect map type modifier, expected 'always' or 'close'}} expected-error {{missing map type}} + {} + #pragma omp target map(always close: a) // expected-error {{missing map type}} + {} + #pragma omp target map(always close bf: a) // expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} + {} + #pragma omp target map(always tofrom close: a) // expected-error {{incorrect map type modifier, expected 'always' or 'close'}} expected-error {{missing map type}} + {} + #pragma omp target map(tofrom from: a) // expected-error {{incorrect map type modifier, expected 'always' or 'close'}} + {} + #pragma omp target map(close bf: a) // expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} + {} return; } }; @@ -405,7 +443,7 @@ T tmain(T argc) { T *k = &j; T x; T y; - T to, tofrom, always; + T to, tofrom, always, close; const T (&l)[5] = da; #pragma omp target map // expected-error {{expected '(' after 'map'}} {} @@ -478,10 +516,16 @@ T tmain(T argc) { #pragma omp target data map(always, tofrom: x) #pragma omp target data map(always: x) // expected-error {{missing map type}} -#pragma omp target data map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always'}} expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} +#pragma omp target data map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always' or 'close'}} expected-error {{missing map type}} #pragma omp target data map(always, tofrom: always, tofrom, x) #pragma omp target map(tofrom j) // expected-error {{expected ',' or ')' in 'map' clause}} foo(); + +#pragma omp target data map(close, tofrom: x) +#pragma omp target data map(close: x) // expected-error {{missing map type}} +#pragma omp target data map(tofrom, close: x) // expected-error {{incorrect map type modifier, expected 'always' or 'close'}} expected-error {{missing map type}} +#pragma omp target data map(close, tofrom: close, tofrom, x) + foo(); return 0; } @@ -515,7 +559,7 @@ int main(int argc, char **argv) { S6 m; int x; int y; - int to, tofrom, always; + int to, tofrom, always, close; const int (&l)[5] = da; SC1 s; SC1 *p; @@ -569,10 +613,14 @@ int main(int argc, char **argv) { #pragma omp target data map(always, tofrom: x) #pragma omp target data map(always: x) // expected-error {{missing map type}} -#pragma omp target data map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always'}} expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} +#pragma omp target data map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always' or 'close'}} expected-error {{missing map type}} #pragma omp target data map(always, tofrom: always, tofrom, x) #pragma omp target map(tofrom j) // expected-error {{expected ',' or ')' in 'map' clause}} foo(); +#pragma omp target data map(close, tofrom: x) +#pragma omp target data map(close: x) // expected-error {{missing map type}} +#pragma omp target data map(tofrom, close: x) // expected-error {{incorrect map type modifier, expected 'always' or 'close'}} expected-error {{missing map type}} + foo(); #pragma omp target private(j) map(j) // expected-error {{private variable cannot be in a map clause in '#pragma omp target' directive}} expected-note {{defined as private}} {} #pragma omp target firstprivate(j) map(j) // expected-error {{firstprivate variable cannot be in a map clause in '#pragma omp target' directive}} expected-note {{defined as firstprivate}} diff --git a/test/OpenMP/target_parallel_for_map_messages.cpp b/test/OpenMP/target_parallel_for_map_messages.cpp index f4f98dfc49..6d82921603 100644 --- a/test/OpenMP/target_parallel_for_map_messages.cpp +++ b/test/OpenMP/target_parallel_for_map_messages.cpp @@ -163,7 +163,7 @@ T tmain(T argc) { for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for map(always: x) // expected-error {{missing map type}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target parallel for map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always'}} expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} +#pragma omp target parallel for map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always' or 'close'}} expected-error {{missing map type}} for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for map(always, tofrom: always, tofrom, x) for (i = 0; i < argc; ++i) foo(); @@ -271,7 +271,7 @@ int main(int argc, char **argv) { for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for map(always: x) // expected-error {{missing map type}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target parallel for map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always'}} expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} +#pragma omp target parallel for map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always' or 'close'}} expected-error {{missing map type}} for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for map(always, tofrom: always, tofrom, x) for (i = 0; i < argc; ++i) foo(); diff --git a/test/OpenMP/target_parallel_for_simd_map_messages.cpp b/test/OpenMP/target_parallel_for_simd_map_messages.cpp index 1cab598839..a5135559cc 100644 --- a/test/OpenMP/target_parallel_for_simd_map_messages.cpp +++ b/test/OpenMP/target_parallel_for_simd_map_messages.cpp @@ -163,7 +163,7 @@ T tmain(T argc) { for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for simd map(always: x) // expected-error {{missing map type}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target parallel for simd map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always'}} expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} +#pragma omp target parallel for simd map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always' or 'close'}} expected-error {{missing map type}} for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for simd map(always, tofrom: always, tofrom, x) for (i = 0; i < argc; ++i) foo(); @@ -271,7 +271,7 @@ int main(int argc, char **argv) { for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for simd map(always: x) // expected-error {{missing map type}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target parallel for simd map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always'}} expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} +#pragma omp target parallel for simd map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always' or 'close'}} expected-error {{missing map type}} for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for simd map(always, tofrom: always, tofrom, x) for (i = 0; i < argc; ++i) foo(); diff --git a/test/OpenMP/target_parallel_map_messages.cpp b/test/OpenMP/target_parallel_map_messages.cpp index 4bb14ea52f..056fd501ac 100644 --- a/test/OpenMP/target_parallel_map_messages.cpp +++ b/test/OpenMP/target_parallel_map_messages.cpp @@ -163,7 +163,7 @@ T tmain(T argc) { foo(); #pragma omp target parallel map(always: x) // expected-error {{missing map type}} foo(); -#pragma omp target parallel map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always'}} expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} +#pragma omp target parallel map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always' or 'close'}} expected-error {{missing map type}} foo(); #pragma omp target parallel map(always, tofrom: always, tofrom, x) foo(); @@ -270,7 +270,7 @@ int main(int argc, char **argv) { foo(); #pragma omp target parallel map(always: x) // expected-error {{missing map type}} foo(); -#pragma omp target parallel map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always'}} expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} +#pragma omp target parallel map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always' or 'close'}} expected-error {{missing map type}} foo(); #pragma omp target parallel map(always, tofrom: always, tofrom, x) foo(); diff --git a/test/OpenMP/target_simd_map_messages.cpp b/test/OpenMP/target_simd_map_messages.cpp index 3722ecb95a..acd6298808 100644 --- a/test/OpenMP/target_simd_map_messages.cpp +++ b/test/OpenMP/target_simd_map_messages.cpp @@ -159,7 +159,7 @@ T tmain(T argc) { for (i = 0; i < argc; ++i) foo(); #pragma omp target simd map(always: x) // expected-error {{missing map type}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target simd map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always'}} expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} +#pragma omp target simd map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always' or 'close'}} expected-error {{missing map type}} for (i = 0; i < argc; ++i) foo(); #pragma omp target simd map(always, tofrom: always, tofrom, x) for (i = 0; i < argc; ++i) foo(); @@ -263,7 +263,7 @@ int main(int argc, char **argv) { for (i = 0; i < argc; ++i) foo(); #pragma omp target simd map(always: x) // expected-error {{missing map type}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target simd map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always'}} expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} +#pragma omp target simd map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always' or 'close'}} expected-error {{missing map type}} for (i = 0; i < argc; ++i) foo(); #pragma omp target simd map(always, tofrom: always, tofrom, x) for (i = 0; i < argc; ++i) foo(); diff --git a/test/OpenMP/target_teams_distribute_map_messages.cpp b/test/OpenMP/target_teams_distribute_map_messages.cpp index 826a09dd76..bbfa7cde9a 100644 --- a/test/OpenMP/target_teams_distribute_map_messages.cpp +++ b/test/OpenMP/target_teams_distribute_map_messages.cpp @@ -163,7 +163,7 @@ T tmain(T argc) { for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute map(always: x) // expected-error {{missing map type}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always'}} expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} +#pragma omp target teams distribute map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always' or 'close'}} expected-error {{missing map type}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute map(always, tofrom: always, tofrom, x) for (i = 0; i < argc; ++i) foo(); @@ -271,7 +271,7 @@ int main(int argc, char **argv) { for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute map(always: x) // expected-error {{missing map type}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always'}} expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} +#pragma omp target teams distribute map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always' or 'close'}} expected-error {{missing map type}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute map(always, tofrom: always, tofrom, x) for (i = 0; i < argc; ++i) foo(); diff --git a/test/OpenMP/target_teams_distribute_parallel_for_map_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_map_messages.cpp index 5cba1e732d..f585d0a1ee 100644 --- a/test/OpenMP/target_teams_distribute_parallel_for_map_messages.cpp +++ b/test/OpenMP/target_teams_distribute_parallel_for_map_messages.cpp @@ -163,7 +163,7 @@ T tmain(T argc) { for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute parallel for map(always: x) // expected-error {{missing map type}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute parallel for map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always'}} expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} +#pragma omp target teams distribute parallel for map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always' or 'close'}} expected-error {{missing map type}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute parallel for map(always, tofrom: always, tofrom, x) for (i = 0; i < argc; ++i) foo(); @@ -271,7 +271,7 @@ int main(int argc, char **argv) { for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute parallel for map(always: x) // expected-error {{missing map type}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute parallel for map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always'}} expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} +#pragma omp target teams distribute parallel for map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always' or 'close'}} expected-error {{missing map type}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute parallel for map(always, tofrom: always, tofrom, x) for (i = 0; i < argc; ++i) foo(); diff --git a/test/OpenMP/target_teams_distribute_parallel_for_simd_map_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_simd_map_messages.cpp index 63d85ebc37..5cf0327895 100644 --- a/test/OpenMP/target_teams_distribute_parallel_for_simd_map_messages.cpp +++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_map_messages.cpp @@ -163,7 +163,7 @@ T tmain(T argc) { for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute parallel for simd map(always: x) // expected-error {{missing map type}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute parallel for simd map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always'}} expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} +#pragma omp target teams distribute parallel for simd map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always' or 'close'}} expected-error {{missing map type}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute parallel for simd map(always, tofrom: always, tofrom, x) for (i = 0; i < argc; ++i) foo(); @@ -271,7 +271,7 @@ int main(int argc, char **argv) { for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute parallel for simd map(always: x) // expected-error {{missing map type}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute parallel for simd map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always'}} expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} +#pragma omp target teams distribute parallel for simd map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always' or 'close'}} expected-error {{missing map type}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute parallel for simd map(always, tofrom: always, tofrom, x) for (i = 0; i < argc; ++i) foo(); diff --git a/test/OpenMP/target_teams_distribute_simd_map_messages.cpp b/test/OpenMP/target_teams_distribute_simd_map_messages.cpp index 73671d7284..99c633a45d 100644 --- a/test/OpenMP/target_teams_distribute_simd_map_messages.cpp +++ b/test/OpenMP/target_teams_distribute_simd_map_messages.cpp @@ -163,7 +163,7 @@ T tmain(T argc) { for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute simd map(always: x) // expected-error {{missing map type}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute simd map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always'}} expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} +#pragma omp target teams distribute simd map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always' or 'close'}} expected-error {{missing map type}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute simd map(always, tofrom: always, tofrom, x) for (i = 0; i < argc; ++i) foo(); @@ -271,7 +271,7 @@ int main(int argc, char **argv) { for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute simd map(always: x) // expected-error {{missing map type}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute simd map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always'}} expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} +#pragma omp target teams distribute simd map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always' or 'close'}} expected-error {{missing map type}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute simd map(always, tofrom: always, tofrom, x) for (i = 0; i < argc; ++i) foo(); diff --git a/test/OpenMP/target_teams_map_messages.cpp b/test/OpenMP/target_teams_map_messages.cpp index 57d9396394..4b2629ee33 100644 --- a/test/OpenMP/target_teams_map_messages.cpp +++ b/test/OpenMP/target_teams_map_messages.cpp @@ -454,7 +454,7 @@ T tmain(T argc) { #pragma omp target data map(always, tofrom: x) #pragma omp target data map(always: x) // expected-error {{missing map type}} -#pragma omp target data map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always'}} expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} +#pragma omp target data map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always' or 'close'}} expected-error {{missing map type}} #pragma omp target data map(always, tofrom: always, tofrom, x) #pragma omp target teams map(tofrom j) // expected-error {{expected ',' or ')' in 'map' clause}} foo(); @@ -529,7 +529,7 @@ int main(int argc, char **argv) { #pragma omp target data map(always, tofrom: x) #pragma omp target data map(always: x) // expected-error {{missing map type}} -#pragma omp target data map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always'}} expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} +#pragma omp target data map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always' or 'close'}} expected-error {{missing map type}} #pragma omp target data map(always, tofrom: always, tofrom, x) #pragma omp target teams map(tofrom j) // expected-error {{expected ',' or ')' in 'map' clause}} foo(); -- cgit v1.2.3 From d1840a054d43341f98b8a37f490248818c11fee4 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Tue, 18 Dec 2018 22:54:03 +0000 Subject: Emit ASM input in a constant context Summary: Some ASM input constraints (e.g., "i" and "n") require immediate values. At O0, very few code transformations are performed. So if we cannot resolve to an immediate when emitting the ASM input we shouldn't delay its processing. Reviewers: rsmith, efriedma Reviewed By: efriedma Subscribers: rehana, efriedma, craig.topper, jyknight, cfe-commits Differential Revision: https://reviews.llvm.org/D55616 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349561 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Basic/TargetInfo.cpp | 2 ++ lib/CodeGen/CGStmt.cpp | 7 +++++-- lib/Sema/SemaStmtAsm.cpp | 16 ++++++++-------- test/CodeGen/builtin-constant-p.c | 11 +++++++++++ 4 files changed, 26 insertions(+), 10 deletions(-) diff --git a/lib/Basic/TargetInfo.cpp b/lib/Basic/TargetInfo.cpp index 7b69cb097c..269fad38b8 100644 --- a/lib/Basic/TargetInfo.cpp +++ b/lib/Basic/TargetInfo.cpp @@ -685,7 +685,9 @@ bool TargetInfo::validateInputConstraint( // FIXME: Fail if % is used with the last operand. break; case 'i': // immediate integer. + break; case 'n': // immediate integer with a known value. + Info.setRequiresImmediate(); break; case 'I': // Various constant constraints with target-specific meanings. case 'J': diff --git a/lib/CodeGen/CGStmt.cpp b/lib/CodeGen/CGStmt.cpp index bc7a18af1e..0242b48659 100644 --- a/lib/CodeGen/CGStmt.cpp +++ b/lib/CodeGen/CGStmt.cpp @@ -1820,11 +1820,14 @@ llvm::Value* CodeGenFunction::EmitAsmInput( // If this can't be a register or memory, i.e., has to be a constant // (immediate or symbolic), try to emit it as such. if (!Info.allowsRegister() && !Info.allowsMemory()) { + if (Info.requiresImmediateConstant()) { + llvm::APSInt AsmConst = InputExpr->EvaluateKnownConstInt(getContext()); + return llvm::ConstantInt::get(getLLVMContext(), AsmConst); + } + Expr::EvalResult Result; if (InputExpr->EvaluateAsInt(Result, getContext())) return llvm::ConstantInt::get(getLLVMContext(), Result.Val.getInt()); - assert(!Info.requiresImmediateConstant() && - "Required-immediate inlineasm arg isn't constant?"); } if (Info.allowsRegister() || !Info.allowsMemory()) diff --git a/lib/Sema/SemaStmtAsm.cpp b/lib/Sema/SemaStmtAsm.cpp index d209266049..b10b3d852c 100644 --- a/lib/Sema/SemaStmtAsm.cpp +++ b/lib/Sema/SemaStmtAsm.cpp @@ -378,17 +378,17 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple, << InputExpr->getSourceRange()); } else if (Info.requiresImmediateConstant() && !Info.allowsRegister()) { if (!InputExpr->isValueDependent()) { - Expr::EvalResult EVResult; - if (!InputExpr->EvaluateAsInt(EVResult, Context)) + llvm::SmallVector Diags; + llvm::APSInt Result = InputExpr->EvaluateKnownConstInt(Context, &Diags); + if (!Diags.empty()) return StmtError( Diag(InputExpr->getBeginLoc(), diag::err_asm_immediate_expected) << Info.getConstraintStr() << InputExpr->getSourceRange()); - llvm::APSInt Result = EVResult.Val.getInt(); - if (!Info.isValidAsmImmediate(Result)) - return StmtError(Diag(InputExpr->getBeginLoc(), - diag::err_invalid_asm_value_for_constraint) - << Result.toString(10) << Info.getConstraintStr() - << InputExpr->getSourceRange()); + if (!Info.isValidAsmImmediate(Result)) + return StmtError(Diag(InputExpr->getBeginLoc(), + diag::err_invalid_asm_value_for_constraint) + << Result.toString(10) << Info.getConstraintStr() + << InputExpr->getSourceRange()); } } else { diff --git a/test/CodeGen/builtin-constant-p.c b/test/CodeGen/builtin-constant-p.c index 7f4e7d07cc..f1cd06ad4a 100644 --- a/test/CodeGen/builtin-constant-p.c +++ b/test/CodeGen/builtin-constant-p.c @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s -O2 | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s -O0 | FileCheck --check-prefix=O0 %s int a = 42; @@ -166,3 +167,13 @@ struct { const char *t; int a; } test15[] = { extern char test16_v; struct { int a; } test16 = { __builtin_constant_p(test16_v) }; + +extern unsigned long long test17_v; + +void test17() { + // O0: define void @test17 + // O0: call void asm sideeffect "", {{.*}}(i32 -1) + // CHECK: define void @test17 + // CHECK: call void asm sideeffect "", {{.*}}(i32 -1) + __asm__ __volatile__("" :: "n"( (__builtin_constant_p(test17_v) || 0) ? 1 : -1)); +} -- cgit v1.2.3 From a15d5e7b261cf4c41289242a7426eb366807acfc Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Tue, 18 Dec 2018 23:29:35 +0000 Subject: [Driver] Also obey -nostdlib++ when rewriting -lstdc++. Reviewers: pirama Reviewed By: pirama Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D55856 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349570 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Driver/Driver.cpp | 4 +++- test/Driver/nostdlibxx.cpp | 9 +++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp index 413956eb18..dfc0faac7b 100644 --- a/lib/Driver/Driver.cpp +++ b/lib/Driver/Driver.cpp @@ -303,6 +303,7 @@ DerivedArgList *Driver::TranslateInputArgs(const InputArgList &Args) const { DerivedArgList *DAL = new DerivedArgList(Args); bool HasNostdlib = Args.hasArg(options::OPT_nostdlib); + bool HasNostdlibxx = Args.hasArg(options::OPT_nostdlibxx); bool HasNodefaultlib = Args.hasArg(options::OPT_nodefaultlibs); for (Arg *A : Args) { // Unfortunately, we have to parse some forwarding options (-Xassembler, @@ -347,7 +348,8 @@ DerivedArgList *Driver::TranslateInputArgs(const InputArgList &Args) const { StringRef Value = A->getValue(); // Rewrite unless -nostdlib is present. - if (!HasNostdlib && !HasNodefaultlib && Value == "stdc++") { + if (!HasNostdlib && !HasNodefaultlib && !HasNostdlibxx && + Value == "stdc++") { DAL->AddFlagArg(A, Opts->getOption(options::OPT_Z_reserved_lib_stdcxx)); continue; } diff --git a/test/Driver/nostdlibxx.cpp b/test/Driver/nostdlibxx.cpp index 02bd62d96a..48d14e15a6 100644 --- a/test/Driver/nostdlibxx.cpp +++ b/test/Driver/nostdlibxx.cpp @@ -6,3 +6,12 @@ // CHECK-NOT: -lstdc++ // CHECK-NOT: -lc++ // CHECK: -lm + +// Make sure -lstdc++ isn't rewritten to the default stdlib when -nostdlib++ is +// used. +// +// RUN: %clangxx -target i686-pc-linux-gnu -### \ +// RUN: -nostdlib++ -stdlib=libc++ -lstdc++ %s 2> %t +// RUN: FileCheck --check-prefix=CHECK-RESERVED-LIB-REWRITE < %t %s +// CHECK-RESERVED-LIB-REWRITE: -lstdc++ +// CHECK-RESERVED-LIB-REWRITE-NOT: -lc++ -- cgit v1.2.3 From 4b80d338e3b88e070111fcccf78616904881e202 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Wed, 19 Dec 2018 04:36:42 +0000 Subject: Revert accidentally included code. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349603 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaStmtAsm.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/Sema/SemaStmtAsm.cpp b/lib/Sema/SemaStmtAsm.cpp index b10b3d852c..d209266049 100644 --- a/lib/Sema/SemaStmtAsm.cpp +++ b/lib/Sema/SemaStmtAsm.cpp @@ -378,17 +378,17 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple, << InputExpr->getSourceRange()); } else if (Info.requiresImmediateConstant() && !Info.allowsRegister()) { if (!InputExpr->isValueDependent()) { - llvm::SmallVector Diags; - llvm::APSInt Result = InputExpr->EvaluateKnownConstInt(Context, &Diags); - if (!Diags.empty()) + Expr::EvalResult EVResult; + if (!InputExpr->EvaluateAsInt(EVResult, Context)) return StmtError( Diag(InputExpr->getBeginLoc(), diag::err_asm_immediate_expected) << Info.getConstraintStr() << InputExpr->getSourceRange()); - if (!Info.isValidAsmImmediate(Result)) - return StmtError(Diag(InputExpr->getBeginLoc(), - diag::err_invalid_asm_value_for_constraint) - << Result.toString(10) << Info.getConstraintStr() - << InputExpr->getSourceRange()); + llvm::APSInt Result = EVResult.Val.getInt(); + if (!Info.isValidAsmImmediate(Result)) + return StmtError(Diag(InputExpr->getBeginLoc(), + diag::err_invalid_asm_value_for_constraint) + << Result.toString(10) << Info.getConstraintStr() + << InputExpr->getSourceRange()); } } else { -- cgit v1.2.3 From a1a49a7b666a6a9d9b55b52602f9773a9e00b4f5 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Wed, 19 Dec 2018 04:54:29 +0000 Subject: Use "EvaluateAsRValue" instead of as a known int, because if it's not a known integer we want to emit a diagnostic instead of asserting. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349604 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaStmtAsm.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/Sema/SemaStmtAsm.cpp b/lib/Sema/SemaStmtAsm.cpp index d209266049..9e084c99d0 100644 --- a/lib/Sema/SemaStmtAsm.cpp +++ b/lib/Sema/SemaStmtAsm.cpp @@ -379,16 +379,16 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple, } else if (Info.requiresImmediateConstant() && !Info.allowsRegister()) { if (!InputExpr->isValueDependent()) { Expr::EvalResult EVResult; - if (!InputExpr->EvaluateAsInt(EVResult, Context)) + if (!InputExpr->EvaluateAsRValue(EVResult, Context, true)) return StmtError( Diag(InputExpr->getBeginLoc(), diag::err_asm_immediate_expected) << Info.getConstraintStr() << InputExpr->getSourceRange()); llvm::APSInt Result = EVResult.Val.getInt(); - if (!Info.isValidAsmImmediate(Result)) - return StmtError(Diag(InputExpr->getBeginLoc(), - diag::err_invalid_asm_value_for_constraint) - << Result.toString(10) << Info.getConstraintStr() - << InputExpr->getSourceRange()); + if (!Info.isValidAsmImmediate(Result)) + return StmtError(Diag(InputExpr->getBeginLoc(), + diag::err_invalid_asm_value_for_constraint) + << Result.toString(10) << Info.getConstraintStr() + << InputExpr->getSourceRange()); } } else { -- cgit v1.2.3 From 879a28b425916cc86df61177d19b35632a1852e2 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Wed, 19 Dec 2018 13:44:41 +0000 Subject: [Index] Index paremeters in lambda expressions. Summary: This fixes clangd couldn't find references for lambda parameters. Reviewers: ilya-biryukov Subscribers: ioeric, arphaman, kadircet, cfe-commits Differential Revision: https://reviews.llvm.org/D55437 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349626 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Index/IndexBody.cpp | 11 +++++++++++ test/Index/cxx11-lambdas.cpp | 3 +++ 2 files changed, 14 insertions(+) diff --git a/lib/Index/IndexBody.cpp b/lib/Index/IndexBody.cpp index dd8a1c7b3f..54a6df2496 100644 --- a/lib/Index/IndexBody.cpp +++ b/lib/Index/IndexBody.cpp @@ -9,6 +9,7 @@ #include "IndexingContext.h" #include "clang/AST/RecursiveASTVisitor.h" +#include "clang/AST/ASTLambda.h" using namespace clang; using namespace clang::index; @@ -454,6 +455,16 @@ public: } return true; } + + bool VisitParmVarDecl(ParmVarDecl* D) { + // Index the parameters of lambda expression. + if (IndexCtx.shouldIndexFunctionLocalSymbols()) { + const auto *DC = D->getDeclContext(); + if (DC && isLambdaCallOperator(DC)) + IndexCtx.handleDecl(D); + } + return true; + } }; } // anonymous namespace diff --git a/test/Index/cxx11-lambdas.cpp b/test/Index/cxx11-lambdas.cpp index 66df09ad29..6d6cbb6312 100644 --- a/test/Index/cxx11-lambdas.cpp +++ b/test/Index/cxx11-lambdas.cpp @@ -7,6 +7,7 @@ struct X { auto lambda = [&localA, localB] (Integer x) -> Integer { return localA + localB + x; }; + auto lambda2 = [](Integer y) {}; } }; @@ -26,8 +27,10 @@ struct X { // RUN: env CINDEXTEST_INDEXLOCALSYMBOLS=1 c-index-test -index-file -std=c++11 %s | FileCheck -check-prefix=CHECK-INDEX %s // CHECK-INDEX: [indexEntityReference]: kind: variable | name: localA | USR: c:cxx11-lambdas.cpp@100@S@X@F@f#@localA | lang: C | cursor: VariableRef=localA:6:9 | loc: 7:21 // CHECK-INDEX: [indexEntityReference]: kind: variable | name: localB | USR: c:cxx11-lambdas.cpp@100@S@X@F@f#@localB | lang: C | cursor: VariableRef=localB:6:17 | loc: 7:29 +// CHECK-INDEX: [indexDeclaration]: kind: variable | name: x | USR: c:cxx11-lambdas.cpp@157@S@X@F@f#@Sa@F@operator()#I#1@x | lang: C | cursor: ParmDecl=x:7:46 (Definition) | loc: 7:46 // CHECK-INDEX: [indexEntityReference]: kind: typedef | name: Integer | USR: c:cxx11-lambdas.cpp@T@Integer | lang: C | cursor: TypeRef=Integer:3:13 | loc: 7:52 // CHECK-INDEX: [indexEntityReference]: kind: typedef | name: Integer | USR: c:cxx11-lambdas.cpp@T@Integer | lang: C | cursor: TypeRef=Integer:3:13 | loc: 7:38 // CHECK-INDEX: [indexEntityReference]: kind: variable | name: localA | USR: c:cxx11-lambdas.cpp@100@S@X@F@f#@localA | lang: C | cursor: DeclRefExpr=localA:6:9 | loc: 8:14 // CHECK-INDEX: [indexEntityReference]: kind: variable | name: localB | USR: c:cxx11-lambdas.cpp@100@S@X@F@f#@localB | lang: C | cursor: DeclRefExpr=localB:6:17 | loc: 8:23 // CHECK-INDEX: [indexEntityReference]: kind: variable | name: x | USR: c:cxx11-lambdas.cpp@157@S@X@F@f#@Sa@F@operator()#I#1@x | lang: C | cursor: DeclRefExpr=x:7:46 | loc: 8:32 +// CHECK-INDEX: [indexDeclaration]: kind: variable | name: y | USR: c:cxx11-lambdas.cpp@244@S@X@F@f#@Sa@F@operator()#I#1@y | lang: C | cursor: ParmDecl=y:10:31 (Definition) | loc: 10:31 \ No newline at end of file -- cgit v1.2.3 From c2b4b6e12fab0e96e4aecb21ba1e63ce9bce5e94 Mon Sep 17 00:00:00 2001 From: Serge Guelton Date: Wed, 19 Dec 2018 13:46:13 +0000 Subject: Portable Python script across Python version urllib2 as been renamed into urllib and the library layout has changed. Workaround that in a consistent manner. Differential Revision: https://reviews.llvm.org/D55199 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349627 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/tools/dump_ast_matchers.py | 7 +++++-- docs/tools/dump_format_style.py | 1 - tools/scan-view/bin/scan-view | 8 +++++--- tools/scan-view/share/ScanView.py | 15 ++++++++++----- 4 files changed, 20 insertions(+), 11 deletions(-) diff --git a/docs/tools/dump_ast_matchers.py b/docs/tools/dump_ast_matchers.py index cae27b20a9..c96c1ca27a 100755 --- a/docs/tools/dump_ast_matchers.py +++ b/docs/tools/dump_ast_matchers.py @@ -5,7 +5,10 @@ import collections import re -import urllib2 +try: + from urllib.request import urlopen +except ImportError: + from urllib2 import urlopen MATCHERS_FILE = '../../include/clang/ASTMatchers/ASTMatchers.h' @@ -42,7 +45,7 @@ def esc(text): if url not in doxygen_probes: try: print('Probing %s...' % url) - urllib2.urlopen(url) + urlopen(url) doxygen_probes[url] = True except: doxygen_probes[url] = False diff --git a/docs/tools/dump_format_style.py b/docs/tools/dump_format_style.py index f2682edc77..5feb793a4d 100755 --- a/docs/tools/dump_format_style.py +++ b/docs/tools/dump_format_style.py @@ -6,7 +6,6 @@ import collections import os import re -import urllib2 CLANG_DIR = os.path.join(os.path.dirname(__file__), '../..') FORMAT_STYLE_FILE = os.path.join(CLANG_DIR, 'include/clang/Format/Format.h') diff --git a/tools/scan-view/bin/scan-view b/tools/scan-view/bin/scan-view index e3abb1c834..6165432e7a 100755 --- a/tools/scan-view/bin/scan-view +++ b/tools/scan-view/bin/scan-view @@ -11,7 +11,10 @@ import os import posixpath import threading import time -import urllib +try: + from urllib.request import urlopen +except ImportError: + from urllib2 import urlopen import webbrowser # How long to wait for server to start. @@ -29,7 +32,7 @@ kMaxPortsToTry = 100 def url_is_up(url): try: - o = urllib.urlopen(url) + o = urlopen(url) except IOError: return False o.close() @@ -37,7 +40,6 @@ def url_is_up(url): def start_browser(port, options): - import urllib import webbrowser url = 'http://%s:%d' % (options.host, port) diff --git a/tools/scan-view/share/ScanView.py b/tools/scan-view/share/ScanView.py index b4227f4a28..da30f36187 100644 --- a/tools/scan-view/share/ScanView.py +++ b/tools/scan-view/share/ScanView.py @@ -6,7 +6,12 @@ except ImportError: from SimpleHTTPServer import SimpleHTTPRequestHandler import os import sys -import urllib, urlparse +try: + from urlparse import urlparse + from urllib import unquote +except ImportError: + from urllib.parse import urlparse, unquote + import posixpath import StringIO import re @@ -198,8 +203,8 @@ def parse_query(qs, fields=None): value = '' else: name, value = chunk.split('=', 1) - name = urllib.unquote(name.replace('+', ' ')) - value = urllib.unquote(value.replace('+', ' ')) + name = unquote(name.replace('+', ' ')) + value = unquote(value.replace('+', ' ')) item = fields.get(name) if item is None: fields[name] = [value] @@ -654,9 +659,9 @@ File Bug fields = {} self.fields = fields - o = urlparse.urlparse(self.path) + o = urlparse(self.path) self.fields = parse_query(o.query, fields) - path = posixpath.normpath(urllib.unquote(o.path)) + path = posixpath.normpath(unquote(o.path)) # Split the components and strip the root prefix. components = path.split('/')[1:] -- cgit v1.2.3 From 2d4a825aa47df7c19caabef365c2ca0c1f3903f7 Mon Sep 17 00:00:00 2001 From: Simon Pilgrim Date: Wed, 19 Dec 2018 14:43:47 +0000 Subject: [X86][SSE] Auto upgrade PADDUS/PSUBUS intrinsics to UADD_SAT/USUB_SAT generic intrinsics (clang) Sibling patch to D55855, this emits UADD_SAT/USUB_SAT generic intrinsics for the SSE saturated math intrinsics instead of expanding to a IR code sequence that could be difficult to reassemble. Differential Revision: https://reviews.llvm.org/D55879 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349631 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGBuiltin.cpp | 33 +++++--------------- test/CodeGen/avx2-builtins.c | 16 +++------- test/CodeGen/avx512bw-builtins.c | 48 +++++++--------------------- test/CodeGen/avx512vlbw-builtins.c | 64 ++++++++++---------------------------- test/CodeGen/sse2-builtins.c | 16 +++------- 5 files changed, 44 insertions(+), 133 deletions(-) diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp index 0f8daa6744..486e7d8ec3 100644 --- a/lib/CodeGen/CGBuiltin.cpp +++ b/lib/CodeGen/CGBuiltin.cpp @@ -9487,31 +9487,14 @@ static Value *EmitX86SExtMask(CodeGenFunction &CGF, Value *Op, return CGF.Builder.CreateSExt(Mask, DstTy, "vpmovm2"); } -// Emit addition or subtraction with saturation. -// Handles both signed and unsigned intrinsics. -static Value *EmitX86AddSubSatExpr(CodeGenFunction &CGF, const CallExpr *E, +// Emit addition or subtraction with unsigned saturation. +// TODO: Handle signed intrinsics. +static Value *EmitX86AddSubSatExpr(CodeGenFunction &CGF, SmallVectorImpl &Ops, bool IsAddition) { - - // Collect vector elements and type data. - llvm::Type *ResultType = CGF.ConvertType(E->getType()); - - Value *Res; - if (IsAddition) { - // ADDUS: a > (a+b) ? ~0 : (a+b) - // If Ops[0] > Add, overflow occurred. - Value *Add = CGF.Builder.CreateAdd(Ops[0], Ops[1]); - Value *ICmp = CGF.Builder.CreateICmp(ICmpInst::ICMP_UGT, Ops[0], Add); - Value *Max = llvm::Constant::getAllOnesValue(ResultType); - Res = CGF.Builder.CreateSelect(ICmp, Max, Add); - } else { - // SUBUS: max(a, b) - b - Value *ICmp = CGF.Builder.CreateICmp(ICmpInst::ICMP_UGT, Ops[0], Ops[1]); - Value *Select = CGF.Builder.CreateSelect(ICmp, Ops[0], Ops[1]); - Res = CGF.Builder.CreateSub(Select, Ops[1]); - } - - return Res; + Intrinsic::ID IID = IsAddition ? Intrinsic::uadd_sat : Intrinsic::usub_sat; + llvm::Function *F = CGF.CGM.getIntrinsic(IID, Ops[0]->getType()); + return CGF.Builder.CreateCall(F, {Ops[0], Ops[1]}); } Value *CodeGenFunction::EmitX86CpuIs(const CallExpr *E) { @@ -11382,14 +11365,14 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID, case X86::BI__builtin_ia32_paddusw256: case X86::BI__builtin_ia32_paddusb128: case X86::BI__builtin_ia32_paddusw128: - return EmitX86AddSubSatExpr(*this, E, Ops, true /* IsAddition */); + return EmitX86AddSubSatExpr(*this, Ops, true /* IsAddition */); case X86::BI__builtin_ia32_psubusb512: case X86::BI__builtin_ia32_psubusw512: case X86::BI__builtin_ia32_psubusb256: case X86::BI__builtin_ia32_psubusw256: case X86::BI__builtin_ia32_psubusb128: case X86::BI__builtin_ia32_psubusw128: - return EmitX86AddSubSatExpr(*this, E, Ops, false /* IsAddition */); + return EmitX86AddSubSatExpr(*this, Ops, false /* IsAddition */); } } diff --git a/test/CodeGen/avx2-builtins.c b/test/CodeGen/avx2-builtins.c index 7792ca85b2..c943796c12 100644 --- a/test/CodeGen/avx2-builtins.c +++ b/test/CodeGen/avx2-builtins.c @@ -69,18 +69,14 @@ __m256i test_mm256_adds_epi16(__m256i a, __m256i b) { __m256i test_mm256_adds_epu8(__m256i a, __m256i b) { // CHECK-LABEL: test_mm256_adds_epu8 // CHECK-NOT: call <32 x i8> @llvm.x86.avx2.paddus.b(<32 x i8> %{{.*}}, <32 x i8> %{{.*}}) - // CHECK: add <32 x i8> %{{.*}}, %{{.*}} - // CHECK: icmp ugt <32 x i8> %{{.*}}, %{{.*}} - // CHECK: select <32 x i1> %{{.*}}, <32 x i8> , <32 x i8> {{.*}} + // CHECK: call <32 x i8> @llvm.uadd.sat.v32i8(<32 x i8> %{{.*}}, <32 x i8> %{{.*}}) return _mm256_adds_epu8(a, b); } __m256i test_mm256_adds_epu16(__m256i a, __m256i b) { // CHECK-LABEL: test_mm256_adds_epu16 // CHECK-NOT: call <16 x i16> @llvm.x86.avx2.paddus.w(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}) - // CHECK: add <16 x i16> %{{.*}}, %{{.*}} - // CHECK: icmp ugt <16 x i16> %{{.*}}, %{{.*}} - // CHECK: select <16 x i1> %{{.*}}, <16 x i16> , <16 x i16> {{.*}} + // CHECK: call <16 x i16> @llvm.uadd.sat.v16i16(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}) return _mm256_adds_epu16(a, b); } @@ -1188,18 +1184,14 @@ __m256i test_mm256_subs_epi16(__m256i a, __m256i b) { __m256i test_mm256_subs_epu8(__m256i a, __m256i b) { // CHECK-LABEL: test_mm256_subs_epu8 // CHECK-NOT: call <32 x i8> @llvm.x86.avx2.psubus.b(<32 x i8> %{{.*}}, <32 x i8> %{{.*}}) - // CHECK: icmp ugt <32 x i8> {{.*}}, {{.*}} - // CHECK: select <32 x i1> {{.*}}, <32 x i8> {{.*}}, <32 x i8> {{.*}} - // CHECK: sub <32 x i8> {{.*}}, {{.*}} + // CHECK: call <32 x i8> @llvm.usub.sat.v32i8(<32 x i8> %{{.*}}, <32 x i8> %{{.*}}) return _mm256_subs_epu8(a, b); } __m256i test_mm256_subs_epu16(__m256i a, __m256i b) { // CHECK-LABEL: test_mm256_subs_epu16 // CHECK-NOT: call <16 x i16> @llvm.x86.avx2.psubus.w(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}) - // CHECK: icmp ugt <16 x i16> {{.*}}, {{.*}} - // CHECK: select <16 x i1> {{.*}}, <16 x i16> {{.*}}, <16 x i16> {{.*}} - // CHECK: sub <16 x i16> {{.*}}, {{.*}} + // CHECK: call <16 x i16> @llvm.usub.sat.v16i16(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}) return _mm256_subs_epu16(a, b); } diff --git a/test/CodeGen/avx512bw-builtins.c b/test/CodeGen/avx512bw-builtins.c index d22bc7b5a3..64204bf2e8 100644 --- a/test/CodeGen/avx512bw-builtins.c +++ b/test/CodeGen/avx512bw-builtins.c @@ -1027,52 +1027,40 @@ return _mm512_maskz_adds_epi16(__U,__A,__B); __m512i test_mm512_adds_epu8(__m512i __A, __m512i __B) { // CHECK-LABEL: @test_mm512_adds_epu8 // CHECK-NOT: @llvm.x86.avx512.mask.paddus.b.512 - // CHECK: add <64 x i8> %{{.*}}, %{{.*}} - // CHECK: icmp ugt <64 x i8> %{{.*}}, %{{.*}} - // CHECK: select <64 x i1> %{{.*}}, <64 x i8> , <64 x i8> {{.*}} + // CHECK: call <64 x i8> @llvm.uadd.sat.v64i8(<64 x i8> %{{.*}}, <64 x i8> %{{.*}}) return _mm512_adds_epu8(__A,__B); } __m512i test_mm512_mask_adds_epu8(__m512i __W, __mmask64 __U, __m512i __A, __m512i __B) { // CHECK-LABEL: @test_mm512_mask_adds_epu8 // CHECK-NOT: @llvm.x86.avx512.mask.paddus.b.512 - // CHECK: add <64 x i8> %{{.*}}, %{{.*}} - // CHECK: icmp ugt <64 x i8> %{{.*}}, %{{.*}} - // CHECK: select <64 x i1> %{{.*}}, <64 x i8> , <64 x i8> {{.*}} + // CHECK: call <64 x i8> @llvm.uadd.sat.v64i8(<64 x i8> %{{.*}}, <64 x i8> %{{.*}}) // CHECK: select <64 x i1> %{{.*}}, <64 x i8> %{{.*}}, <64 x i8> %{{.*}} return _mm512_mask_adds_epu8(__W,__U,__A,__B); } __m512i test_mm512_maskz_adds_epu8(__mmask64 __U, __m512i __A, __m512i __B) { // CHECK-LABEL: @test_mm512_maskz_adds_epu8 // CHECK-NOT: @llvm.x86.avx512.mask.paddus.b.512 - // CHECK: add <64 x i8> %{{.*}}, %{{.*}} - // CHECK: icmp ugt <64 x i8> %{{.*}}, %{{.*}} - // CHECK: select <64 x i1> %{{.*}}, <64 x i8> , <64 x i8> {{.*}} + // CHECK: call <64 x i8> @llvm.uadd.sat.v64i8(<64 x i8> %{{.*}}, <64 x i8> %{{.*}}) // CHECK: select <64 x i1> %{{.*}}, <64 x i8> %{{.*}}, <64 x i8> %{{.*}} return _mm512_maskz_adds_epu8(__U,__A,__B); } __m512i test_mm512_adds_epu16(__m512i __A, __m512i __B) { // CHECK-LABEL: @test_mm512_adds_epu16 // CHECK-NOT: @llvm.x86.avx512.mask.paddus.w.512 - // CHECK: add <32 x i16> %{{.*}}, %{{.*}} - // CHECK: icmp ugt <32 x i16> %{{.*}}, %{{.*}} - // CHECK: select <32 x i1> %{{.*}}, <32 x i16> , <32 x i16> {{.*}} + // CHECK: call <32 x i16> @llvm.uadd.sat.v32i16(<32 x i16> %{{.*}}, <32 x i16> %{{.*}}) return _mm512_adds_epu16(__A,__B); } __m512i test_mm512_mask_adds_epu16(__m512i __W, __mmask32 __U, __m512i __A, __m512i __B) { // CHECK-LABEL: @test_mm512_mask_adds_epu16 // CHECK-NOT: @llvm.x86.avx512.mask.paddus.w.512 - // CHECK: add <32 x i16> %{{.*}}, %{{.*}} - // CHECK: icmp ugt <32 x i16> %{{.*}}, %{{.*}} - // CHECK: select <32 x i1> %{{.*}}, <32 x i16> , <32 x i16> {{.*}} + // CHECK: call <32 x i16> @llvm.uadd.sat.v32i16(<32 x i16> %{{.*}}, <32 x i16> %{{.*}}) // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}} return _mm512_mask_adds_epu16(__W,__U,__A,__B); } __m512i test_mm512_maskz_adds_epu16(__mmask32 __U, __m512i __A, __m512i __B) { // CHECK-LABEL: @test_mm512_maskz_adds_epu16 // CHECK-NOT: @llvm.x86.avx512.mask.paddus.w.512 - // CHECK: add <32 x i16> %{{.*}}, %{{.*}} - // CHECK: icmp ugt <32 x i16> %{{.*}}, %{{.*}} - // CHECK: select <32 x i1> %{{.*}}, <32 x i16> , <32 x i16> {{.*}} + // CHECK: call <32 x i16> @llvm.uadd.sat.v32i16(<32 x i16> %{{.*}}, <32 x i16> %{{.*}}) // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}} return _mm512_maskz_adds_epu16(__U,__A,__B); } @@ -1362,52 +1350,40 @@ return _mm512_maskz_subs_epi16(__U,__A,__B); __m512i test_mm512_subs_epu8(__m512i __A, __m512i __B) { // CHECK-LABEL: @test_mm512_subs_epu8 // CHECK-NOT: @llvm.x86.avx512.mask.psubus.b.512 - // CHECK: icmp ugt <64 x i8> {{.*}}, {{.*}} - // CHECK: select <64 x i1> {{.*}}, <64 x i8> {{.*}}, <64 x i8> {{.*}} - // CHECK: sub <64 x i8> {{.*}}, {{.*}} + // CHECK: call <64 x i8> @llvm.usub.sat.v64i8(<64 x i8> %{{.*}}, <64 x i8> %{{.*}}) return _mm512_subs_epu8(__A,__B); } __m512i test_mm512_mask_subs_epu8(__m512i __W, __mmask64 __U, __m512i __A, __m512i __B) { // CHECK-LABEL: @test_mm512_mask_subs_epu8 // CHECK-NOT: @llvm.x86.avx512.mask.psubus.b.512 - // CHECK: icmp ugt <64 x i8> {{.*}}, {{.*}} - // CHECK: select <64 x i1> {{.*}}, <64 x i8> {{.*}}, <64 x i8> {{.*}} - // CHECK: sub <64 x i8> {{.*}}, {{.*}} + // CHECK: call <64 x i8> @llvm.usub.sat.v64i8(<64 x i8> %{{.*}}, <64 x i8> %{{.*}}) // CHECK: select <64 x i1> %{{.*}}, <64 x i8> %{{.*}}, <64 x i8> %{{.*}} return _mm512_mask_subs_epu8(__W,__U,__A,__B); } __m512i test_mm512_maskz_subs_epu8(__mmask64 __U, __m512i __A, __m512i __B) { // CHECK-LABEL: @test_mm512_maskz_subs_epu8 // CHECK-NOT: @llvm.x86.avx512.mask.psubus.b.512 - // CHECK: icmp ugt <64 x i8> {{.*}}, {{.*}} - // CHECK: select <64 x i1> {{.*}}, <64 x i8> {{.*}}, <64 x i8> {{.*}} - // CHECK: sub <64 x i8> {{.*}}, {{.*}} + // CHECK: call <64 x i8> @llvm.usub.sat.v64i8(<64 x i8> %{{.*}}, <64 x i8> %{{.*}}) // CHECK: select <64 x i1> %{{.*}}, <64 x i8> %{{.*}}, <64 x i8> %{{.*}} return _mm512_maskz_subs_epu8(__U,__A,__B); } __m512i test_mm512_subs_epu16(__m512i __A, __m512i __B) { // CHECK-LABEL: @test_mm512_subs_epu16 // CHECK-NOT: @llvm.x86.avx512.mask.psubus.w.512 - // CHECK: icmp ugt <32 x i16> {{.*}}, {{.*}} - // CHECK: select <32 x i1> {{.*}}, <32 x i16> {{.*}}, <32 x i16> {{.*}} - // CHECK: sub <32 x i16> {{.*}}, {{.*}} + // CHECK: call <32 x i16> @llvm.usub.sat.v32i16(<32 x i16> %{{.*}}, <32 x i16> %{{.*}}) return _mm512_subs_epu16(__A,__B); } __m512i test_mm512_mask_subs_epu16(__m512i __W, __mmask32 __U, __m512i __A, __m512i __B) { // CHECK-LABEL: @test_mm512_mask_subs_epu16 // CHECK-NOT: @llvm.x86.avx512.mask.psubus.w.512 - // CHECK: icmp ugt <32 x i16> {{.*}}, {{.*}} - // CHECK: select <32 x i1> {{.*}}, <32 x i16> {{.*}}, <32 x i16> {{.*}} - // CHECK: sub <32 x i16> {{.*}}, {{.*}} + // CHECK: call <32 x i16> @llvm.usub.sat.v32i16(<32 x i16> %{{.*}}, <32 x i16> %{{.*}}) // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}} return _mm512_mask_subs_epu16(__W,__U,__A,__B); } __m512i test_mm512_maskz_subs_epu16(__mmask32 __U, __m512i __A, __m512i __B) { // CHECK-LABEL: @test_mm512_maskz_subs_epu16 // CHECK-NOT: @llvm.x86.avx512.mask.psubus.w.512 - // CHECK: icmp ugt <32 x i16> {{.*}}, {{.*}} - // CHECK: select <32 x i1> {{.*}}, <32 x i16> {{.*}}, <32 x i16> {{.*}} - // CHECK: sub <32 x i16> {{.*}}, {{.*}} + // CHECK: call <32 x i16> @llvm.usub.sat.v32i16(<32 x i16> %{{.*}}, <32 x i16> %{{.*}}) // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}} return _mm512_maskz_subs_epu16(__U,__A,__B); } diff --git a/test/CodeGen/avx512vlbw-builtins.c b/test/CodeGen/avx512vlbw-builtins.c index 06a48b5b27..fb42ffc392 100644 --- a/test/CodeGen/avx512vlbw-builtins.c +++ b/test/CodeGen/avx512vlbw-builtins.c @@ -1124,72 +1124,56 @@ __m256i test_mm256_maskz_adds_epi16(__mmask16 __U, __m256i __A, __m256i __B) { __m128i test_mm_mask_adds_epu8(__m128i __W, __mmask16 __U, __m128i __A, __m128i __B) { // CHECK-LABEL: @test_mm_mask_adds_epu8 // CHECK-NOT: @llvm.x86.sse2.paddus.b - // CHECK: add <16 x i8> %{{.*}}, %{{.*}} - // CHECK: icmp ugt <16 x i8> %{{.*}}, %{{.*}} - // CHECK: select <16 x i1> %{{.*}}, <16 x i8> , <16 x i8> {{.*}} + // CHECK: call <16 x i8> @llvm.uadd.sat.v16i8(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) // CHECK: select <16 x i1> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}} return _mm_mask_adds_epu8(__W,__U,__A,__B); } __m128i test_mm_maskz_adds_epu8(__mmask16 __U, __m128i __A, __m128i __B) { // CHECK-LABEL: @test_mm_maskz_adds_epu8 // CHECK-NOT: @llvm.x86.sse2.paddus.b - // CHECK: add <16 x i8> %{{.*}}, %{{.*}} - // CHECK: icmp ugt <16 x i8> %{{.*}}, %{{.*}} - // CHECK: select <16 x i1> %{{.*}}, <16 x i8> , <16 x i8> {{.*}} + // CHECK: call <16 x i8> @llvm.uadd.sat.v16i8(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) // CHECK: select <16 x i1> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}} return _mm_maskz_adds_epu8(__U,__A,__B); } __m256i test_mm256_mask_adds_epu8(__m256i __W, __mmask32 __U, __m256i __A, __m256i __B) { // CHECK-LABEL: @test_mm256_mask_adds_epu8 // CHECK-NOT: @llvm.x86.avx2.paddus.b - // CHECK: add <32 x i8> %{{.*}}, %{{.*}} - // CHECK: icmp ugt <32 x i8> %{{.*}}, %{{.*}} - // CHECK: select <32 x i1> %{{.*}}, <32 x i8> , <32 x i8> {{.*}} + // CHECK: call <32 x i8> @llvm.uadd.sat.v32i8(<32 x i8> %{{.*}}, <32 x i8> %{{.*}}) // CHECK: select <32 x i1> %{{.*}}, <32 x i8> %{{.*}}, <32 x i8> %{{.*}} return _mm256_mask_adds_epu8(__W,__U,__A,__B); } __m256i test_mm256_maskz_adds_epu8(__mmask32 __U, __m256i __A, __m256i __B) { // CHECK-LABEL: @test_mm256_maskz_adds_epu8 // CHECK-NOT: @llvm.x86.avx2.paddus.b - // CHECK: add <32 x i8> %{{.*}}, %{{.*}} - // CHECK: icmp ugt <32 x i8> %{{.*}}, %{{.*}} - // CHECK: select <32 x i1> %{{.*}}, <32 x i8> , <32 x i8> {{.*}} + // CHECK: call <32 x i8> @llvm.uadd.sat.v32i8(<32 x i8> %{{.*}}, <32 x i8> %{{.*}}) // CHECK: select <32 x i1> %{{.*}}, <32 x i8> %{{.*}}, <32 x i8> %{{.*}} return _mm256_maskz_adds_epu8(__U,__A,__B); } __m128i test_mm_mask_adds_epu16(__m128i __W, __mmask8 __U, __m128i __A, __m128i __B) { // CHECK-LABEL: @test_mm_mask_adds_epu16 // CHECK-NOT: @llvm.x86.sse2.paddus.w - // CHECK: add <8 x i16> %{{.*}}, %{{.*}} - // CHECK: icmp ugt <8 x i16> %{{.*}}, %{{.*}} - // CHECK: select <8 x i1> %{{.*}}, <8 x i16> , <8 x i16> {{.*}} + // CHECK: call <8 x i16> @llvm.uadd.sat.v8i16(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) // CHECK: select <8 x i1> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}} return _mm_mask_adds_epu16(__W,__U,__A,__B); } __m128i test_mm_maskz_adds_epu16(__mmask8 __U, __m128i __A, __m128i __B) { // CHECK-LABEL: @test_mm_maskz_adds_epu16 // CHECK-NOT: @llvm.x86.sse2.paddus.w - // CHECK: add <8 x i16> %{{.*}}, %{{.*}} - // CHECK: icmp ugt <8 x i16> %{{.*}}, %{{.*}} - // CHECK: select <8 x i1> %{{.*}}, <8 x i16> , <8 x i16> {{.*}} + // CHECK: call <8 x i16> @llvm.uadd.sat.v8i16(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) // CHECK: select <8 x i1> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}} return _mm_maskz_adds_epu16(__U,__A,__B); } __m256i test_mm256_mask_adds_epu16(__m256i __W, __mmask16 __U, __m256i __A, __m256i __B) { // CHECK-LABEL: @test_mm256_mask_adds_epu16 // CHECK-NOT: @llvm.x86.avx2.paddus.w - // CHECK: add <16 x i16> %{{.*}}, %{{.*}} - // CHECK: icmp ugt <16 x i16> %{{.*}}, %{{.*}} - // CHECK: select <16 x i1> %{{.*}}, <16 x i16> , <16 x i16> {{.*}} + // CHECK: call <16 x i16> @llvm.uadd.sat.v16i16(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}) // CHECK: select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}} return _mm256_mask_adds_epu16(__W,__U,__A,__B); } __m256i test_mm256_maskz_adds_epu16(__mmask16 __U, __m256i __A, __m256i __B) { // CHECK-LABEL: @test_mm256_maskz_adds_epu16 // CHECK-NOT: @llvm.x86.avx2.paddus.w - // CHECK: add <16 x i16> %{{.*}}, %{{.*}} - // CHECK: icmp ugt <16 x i16> %{{.*}}, %{{.*}} - // CHECK: select <16 x i1> %{{.*}}, <16 x i16> , <16 x i16> {{.*}} + // CHECK: call <16 x i16> @llvm.uadd.sat.v16i16(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}) // CHECK: select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}} return _mm256_maskz_adds_epu16(__U,__A,__B); } @@ -1592,72 +1576,56 @@ __m256i test_mm256_maskz_subs_epi16(__mmask16 __U, __m256i __A, __m256i __B) { __m128i test_mm_mask_subs_epu8(__m128i __W, __mmask16 __U, __m128i __A, __m128i __B) { // CHECK-LABEL: @test_mm_mask_subs_epu8 // CHECK-NOT: @llvm.x86.sse2.psubus.b - // CHECK: icmp ugt <16 x i8> {{.*}}, {{.*}} - // CHECK: select <16 x i1> {{.*}}, <16 x i8> {{.*}}, <16 x i8> {{.*}} - // CHECK: sub <16 x i8> {{.*}}, {{.*}} + // CHECK: call <16 x i8> @llvm.usub.sat.v16i8(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) // CHECK: select <16 x i1> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}} return _mm_mask_subs_epu8(__W,__U,__A,__B); } __m128i test_mm_maskz_subs_epu8(__mmask16 __U, __m128i __A, __m128i __B) { // CHECK-LABEL: @test_mm_maskz_subs_epu8 // CHECK-NOT: @llvm.x86.sse2.psubus.b - // CHECK: icmp ugt <16 x i8> {{.*}}, {{.*}} - // CHECK: select <16 x i1> {{.*}}, <16 x i8> {{.*}}, <16 x i8> {{.*}} - // CHECK: sub <16 x i8> {{.*}}, {{.*}} + // CHECK: call <16 x i8> @llvm.usub.sat.v16i8(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) // CHECK: select <16 x i1> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}} return _mm_maskz_subs_epu8(__U,__A,__B); } __m256i test_mm256_mask_subs_epu8(__m256i __W, __mmask32 __U, __m256i __A, __m256i __B) { // CHECK-LABEL: @test_mm256_mask_subs_epu8 // CHECK-NOT: @llvm.x86.avx2.psubus.b - // CHECK: icmp ugt <32 x i8> {{.*}}, {{.*}} - // CHECK: select <32 x i1> {{.*}}, <32 x i8> {{.*}}, <32 x i8> {{.*}} - // CHECK: sub <32 x i8> {{.*}}, {{.*}} + // CHECK: call <32 x i8> @llvm.usub.sat.v32i8(<32 x i8> %{{.*}}, <32 x i8> %{{.*}}) // CHECK: select <32 x i1> %{{.*}}, <32 x i8> %{{.*}}, <32 x i8> %{{.*}} return _mm256_mask_subs_epu8(__W,__U,__A,__B); } __m256i test_mm256_maskz_subs_epu8(__mmask32 __U, __m256i __A, __m256i __B) { // CHECK-LABEL: @test_mm256_maskz_subs_epu8 // CHECK-NOT: @llvm.x86.avx2.psubus.b - // CHECK: icmp ugt <32 x i8> {{.*}}, {{.*}} - // CHECK: select <32 x i1> {{.*}}, <32 x i8> {{.*}}, <32 x i8> {{.*}} - // CHECK: sub <32 x i8> {{.*}}, {{.*}} + // CHECK: call <32 x i8> @llvm.usub.sat.v32i8(<32 x i8> %{{.*}}, <32 x i8> %{{.*}}) // CHECK: select <32 x i1> %{{.*}}, <32 x i8> %{{.*}}, <32 x i8> %{{.*}} return _mm256_maskz_subs_epu8(__U,__A,__B); } __m128i test_mm_mask_subs_epu16(__m128i __W, __mmask8 __U, __m128i __A, __m128i __B) { // CHECK-LABEL: @test_mm_mask_subs_epu16 // CHECK-NOT: @llvm.x86.sse2.psubus.w - // CHECK: icmp ugt <8 x i16> {{.*}}, {{.*}} - // CHECK: select <8 x i1> {{.*}}, <8 x i16> {{.*}}, <8 x i16> {{.*}} - // CHECK: sub <8 x i16> {{.*}}, {{.*}} + // CHECK: call <8 x i16> @llvm.usub.sat.v8i16(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) // CHECK: select <8 x i1> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}} return _mm_mask_subs_epu16(__W,__U,__A,__B); } __m128i test_mm_maskz_subs_epu16(__mmask8 __U, __m128i __A, __m128i __B) { // CHECK-LABEL: @test_mm_maskz_subs_epu16 // CHECK-NOT: @llvm.x86.sse2.psubus.w - // CHECK: icmp ugt <8 x i16> {{.*}}, {{.*}} - // CHECK: select <8 x i1> {{.*}}, <8 x i16> {{.*}}, <8 x i16> {{.*}} - // CHECK: sub <8 x i16> {{.*}}, {{.*}} + // CHECK: call <8 x i16> @llvm.usub.sat.v8i16(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) // CHECK: select <8 x i1> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}} return _mm_maskz_subs_epu16(__U,__A,__B); } __m256i test_mm256_mask_subs_epu16(__m256i __W, __mmask16 __U, __m256i __A, __m256i __B) { // CHECK-LABEL: @test_mm256_mask_subs_epu16 // CHECK-NOT: @llvm.x86.avx2.psubus.w - // CHECK: icmp ugt <16 x i16> {{.*}}, {{.*}} - // CHECK: select <16 x i1> {{.*}}, <16 x i16> {{.*}}, <16 x i16> {{.*}} - // CHECK: sub <16 x i16> {{.*}}, {{.*}} + // CHECK: call <16 x i16> @llvm.usub.sat.v16i16(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}) // CHECK: select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}} return _mm256_mask_subs_epu16(__W,__U,__A,__B); } __m256i test_mm256_maskz_subs_epu16(__mmask16 __U, __m256i __A, __m256i __B) { // CHECK-LABEL: @test_mm256_maskz_subs_epu16 // CHECK-NOT: @llvm.x86.avx2.psubus.w - // CHECK: icmp ugt <16 x i16> {{.*}}, {{.*}} - // CHECK: select <16 x i1> {{.*}}, <16 x i16> {{.*}}, <16 x i16> {{.*}} - // CHECK: sub <16 x i16> {{.*}}, {{.*}} + // CHECK: call <16 x i16> @llvm.usub.sat.v16i16(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}) // CHECK: select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}} return _mm256_maskz_subs_epu16(__U,__A,__B); } diff --git a/test/CodeGen/sse2-builtins.c b/test/CodeGen/sse2-builtins.c index 005bdfd917..942e86b28f 100644 --- a/test/CodeGen/sse2-builtins.c +++ b/test/CodeGen/sse2-builtins.c @@ -60,18 +60,14 @@ __m128i test_mm_adds_epi16(__m128i A, __m128i B) { __m128i test_mm_adds_epu8(__m128i A, __m128i B) { // CHECK-LABEL: test_mm_adds_epu8 // CHECK-NOT: call <16 x i8> @llvm.x86.sse2.paddus.b(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) - // CHECK: add <16 x i8> %{{.*}}, %{{.*}} - // CHECK: icmp ugt <16 x i8> %{{.*}}, %{{.*}} - // CHECK: select <16 x i1> %{{.*}}, <16 x i8> , <16 x i8> {{.*}} + // CHECK: call <16 x i8> @llvm.uadd.sat.v16i8(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) return _mm_adds_epu8(A, B); } __m128i test_mm_adds_epu16(__m128i A, __m128i B) { // CHECK-LABEL: test_mm_adds_epu16 // CHECK-NOT: call <8 x i16> @llvm.x86.sse2.paddus.w(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) - // CHECK: add <8 x i16> %{{.*}}, %{{.*}} - // CHECK: icmp ugt <8 x i16> %{{.*}}, %{{.*}} - // CHECK: select <8 x i1> %{{.*}}, <8 x i16> , <8 x i16> {{.*}} + // CHECK: call <8 x i16> @llvm.uadd.sat.v8i16(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) return _mm_adds_epu16(A, B); } @@ -1477,18 +1473,14 @@ __m128i test_mm_subs_epi16(__m128i A, __m128i B) { __m128i test_mm_subs_epu8(__m128i A, __m128i B) { // CHECK-LABEL: test_mm_subs_epu8 // CHECK-NOT: call <16 x i8> @llvm.x86.sse2.psubus.b(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) - // CHECK: icmp ugt <16 x i8> {{.*}}, {{.*}} - // CHECK: select <16 x i1> {{.*}}, <16 x i8> {{.*}}, <16 x i8> {{.*}} - // CHECK: sub <16 x i8> {{.*}}, {{.*}} + // CHECK: call <16 x i8> @llvm.usub.sat.v16i8(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) return _mm_subs_epu8(A, B); } __m128i test_mm_subs_epu16(__m128i A, __m128i B) { // CHECK-LABEL: test_mm_subs_epu16 // CHECK-NOT: call <8 x i16> @llvm.x86.sse2.psubus.w(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) - // CHECK: icmp ugt <8 x i16> {{.*}}, {{.*}} - // CHECK: select <8 x i1> {{.*}}, <8 x i16> {{.*}}, <8 x i16> {{.*}} - // CHECK: sub <8 x i16> {{.*}}, {{.*}} + // CHECK: call <8 x i16> @llvm.usub.sat.v8i16(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) return _mm_subs_epu16(A, B); } -- cgit v1.2.3 From 774a696710935afdbfde96f2f79f77aab2d1e9e5 Mon Sep 17 00:00:00 2001 From: "Joel E. Denny" Date: Wed, 19 Dec 2018 15:59:47 +0000 Subject: [OpenMP] Fix data sharing analysis in nested clause Without this patch, clang doesn't complain that X needs explicit data sharing attributes in the following: ``` #pragma omp target teams default(none) { #pragma omp parallel num_threads(X) ; } ``` However, clang does produce that complaint after the braces are removed. With this patch, clang complains in both cases. Reviewed By: ABataev Differential Revision: https://reviews.llvm.org/D55861 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349635 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaOpenMP.cpp | 10 +++------- test/OpenMP/target_teams_messages.cpp | 10 ++++++++++ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp index 38a329a1fd..c207ba9bd3 100644 --- a/lib/Sema/SemaOpenMP.cpp +++ b/lib/Sema/SemaOpenMP.cpp @@ -2390,13 +2390,9 @@ public: void VisitStmt(Stmt *S) { for (Stmt *C : S->children()) { if (C) { - if (auto *OED = dyn_cast(C)) { - // Check implicitly captured variables in the task-based directives to - // check if they must be firstprivatized. - VisitSubCaptures(OED); - } else { - Visit(C); - } + // Check implicitly captured variables in the task-based directives to + // check if they must be firstprivatized. + Visit(C); } } } diff --git a/test/OpenMP/target_teams_messages.cpp b/test/OpenMP/target_teams_messages.cpp index 3a367bfc7e..bc068f87b6 100644 --- a/test/OpenMP/target_teams_messages.cpp +++ b/test/OpenMP/target_teams_messages.cpp @@ -50,6 +50,16 @@ int main(int argc, char **argv) { #pragma omp target teams default(none) ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} +#pragma omp target teams default(none) +#pragma omp parallel num_threads(argc) // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} + ; + +#pragma omp target teams default(none) + { +#pragma omp parallel num_threads(argc) // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} + ; + } + goto L2; // expected-error {{use of undeclared label 'L2'}} #pragma omp target teams L2: -- cgit v1.2.3 From 0108c9637ee634011c8df83417eb281f44ff692a Mon Sep 17 00:00:00 2001 From: Michal Gorny Date: Wed, 19 Dec 2018 17:25:46 +0000 Subject: [Driver] Disable -faddrsig by default on NetBSD Avoid passing -faddrsig by default on NetBSD. This platform is still using old GNU binutils that crashes on executables containing those sections. Differential Revision: https://reviews.llvm.org/D55828 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349647 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Driver/ToolChains/Clang.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/Driver/ToolChains/Clang.cpp b/lib/Driver/ToolChains/Clang.cpp index 1f267e68f1..18a43a695d 100644 --- a/lib/Driver/ToolChains/Clang.cpp +++ b/lib/Driver/ToolChains/Clang.cpp @@ -5273,7 +5273,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (Args.hasFlag(options::OPT_faddrsig, options::OPT_fno_addrsig, (TC.getTriple().isOSBinFormatELF() || TC.getTriple().isOSBinFormatCOFF()) && - TC.useIntegratedAs())) + TC.useIntegratedAs() && + RawTriple.getOS() != llvm::Triple::NetBSD)) CmdArgs.push_back("-faddrsig"); // Finally add the compile command to the compilation. -- cgit v1.2.3 From 3abed4868be116112e8dc37558a15c7af5afad86 Mon Sep 17 00:00:00 2001 From: Michal Gorny Date: Wed, 19 Dec 2018 17:25:51 +0000 Subject: [Basic] Correct description of SanitizerSet.empty() Differential Revision: https://reviews.llvm.org/D55830 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349648 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/Sanitizers.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/clang/Basic/Sanitizers.h b/include/clang/Basic/Sanitizers.h index 2ecbde8215..fe9e76a1e3 100644 --- a/include/clang/Basic/Sanitizers.h +++ b/include/clang/Basic/Sanitizers.h @@ -66,7 +66,7 @@ struct SanitizerSet { /// Disable the sanitizers specified in \p K. void clear(SanitizerMask K = SanitizerKind::All) { Mask &= ~K; } - /// Returns true if at least one sanitizer is enabled. + /// Returns true if no sanitizers are enabled. bool empty() const { return Mask == 0; } /// Bitmask of enabled sanitizers. -- cgit v1.2.3 From 5b01cba101848240d513c2f58854c109bc50f2d3 Mon Sep 17 00:00:00 2001 From: Michal Gorny Date: Wed, 19 Dec 2018 17:25:55 +0000 Subject: [Driver] Add .hasAnySanitizer() to SanitizerArgs Add a simple method to query whether any sanitizer was enabled, via SanitizerArgs. This will be used in the NetBSD driver to pass additional definitions that are required by all sanitizers. Differential Revision: https://reviews.llvm.org/D55832 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349649 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Driver/SanitizerArgs.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/clang/Driver/SanitizerArgs.h b/include/clang/Driver/SanitizerArgs.h index 763a187d71..55c5826bfb 100644 --- a/include/clang/Driver/SanitizerArgs.h +++ b/include/clang/Driver/SanitizerArgs.h @@ -82,6 +82,7 @@ class SanitizerArgs { bool needsUnwindTables() const; bool linkCXXRuntimes() const { return LinkCXXRuntimes; } bool hasCrossDsoCfi() const { return CfiCrossDso; } + bool hasAnySanitizer() const { return !Sanitizers.empty(); } void addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, types::ID InputType) const; }; -- cgit v1.2.3 From c00ce7cec04125051b37d5ee9b9b91090e15da31 Mon Sep 17 00:00:00 2001 From: Michal Gorny Date: Wed, 19 Dec 2018 17:25:59 +0000 Subject: [Driver] [NetBSD] Add -D_REENTRANT when using sanitizers NetBSD intends to support only reentrant interfaces in interceptors. When -lpthread is used without _REENTRANT defined, things are not guaranteed to work. This is especially important for and sanitization of interfaces around FILE. Some APIs have alternative modes depending on the _REENTRANT definition, and NetBSD intends to support sanitization of the _REENTRANT ones. Differential Revision: https://reviews.llvm.org/D55654 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349650 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Driver/ToolChains/NetBSD.cpp | 8 ++++++++ lib/Driver/ToolChains/NetBSD.h | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/lib/Driver/ToolChains/NetBSD.cpp b/lib/Driver/ToolChains/NetBSD.cpp index 73e230b3ea..6dba5b1a59 100644 --- a/lib/Driver/ToolChains/NetBSD.cpp +++ b/lib/Driver/ToolChains/NetBSD.cpp @@ -457,3 +457,11 @@ SanitizerMask NetBSD::getSupportedSanitizers() const { } return Res; } + +void NetBSD::addClangTargetOptions(const ArgList &, + ArgStringList &CC1Args, + Action::OffloadKind) const { + const SanitizerArgs &SanArgs = getSanitizerArgs(); + if (SanArgs.hasAnySanitizer()) + CC1Args.push_back("-D_REENTRANT"); +} diff --git a/lib/Driver/ToolChains/NetBSD.h b/lib/Driver/ToolChains/NetBSD.h index 49e3a58d02..ae0865fd65 100644 --- a/lib/Driver/ToolChains/NetBSD.h +++ b/lib/Driver/ToolChains/NetBSD.h @@ -76,6 +76,10 @@ public: SanitizerMask getSupportedSanitizers() const override; + void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args, + Action::OffloadKind DeviceOffloadKind) const override; + protected: Tool *buildAssembler() const override; Tool *buildLinker() const override; -- cgit v1.2.3 From 30b70311b7df6275c2bb89844bae45e37977dca2 Mon Sep 17 00:00:00 2001 From: Ilya Biryukov Date: Wed, 19 Dec 2018 18:01:24 +0000 Subject: [CodeComplete] Properly determine qualifiers of 'this' in a lambda Summary: The clang used to pick up the qualifiers of the lamba's call operator (which is always const) and fail to show non-const methods of 'this' in completion results. Reviewers: kadircet Reviewed By: kadircet Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D55885 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349655 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaCodeComplete.cpp | 8 +++----- test/CodeCompletion/this-quals.cpp | 21 +++++++++++++++++++++ 2 files changed, 24 insertions(+), 5 deletions(-) create mode 100644 test/CodeCompletion/this-quals.cpp diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp index 773dd46ac4..f8d4e4bb0e 100644 --- a/lib/Sema/SemaCodeComplete.cpp +++ b/lib/Sema/SemaCodeComplete.cpp @@ -3737,11 +3737,9 @@ void Sema::CodeCompleteOrdinaryName(Scope *S, // If we are in a C++ non-static member function, check the qualifiers on // the member function to filter/prioritize the results list. - if (CXXMethodDecl *CurMethod = dyn_cast(CurContext)) { - if (CurMethod->isInstance()) { - Results.setObjectTypeQualifiers(CurMethod->getTypeQualifiers()); - } - } + auto ThisType = getCurrentThisType(); + if (!ThisType.isNull()) + Results.setObjectTypeQualifiers(ThisType->getPointeeType().getQualifiers()); CodeCompletionDeclConsumer Consumer(Results, CurContext); LookupVisibleDecls(S, LookupOrdinaryName, Consumer, diff --git a/test/CodeCompletion/this-quals.cpp b/test/CodeCompletion/this-quals.cpp new file mode 100644 index 0000000000..eeaed00aa8 --- /dev/null +++ b/test/CodeCompletion/this-quals.cpp @@ -0,0 +1,21 @@ +class foo { + void mut_func() { + [this]() { + + }(); + // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:4:1 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s + // CHECK-CC1: const_func + // CHECK-CC1: mut_func + } + + void const_func() const { + [this]() { + + }(); + // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:13:1 %s -o - | FileCheck -check-prefix=CHECK-CC2 %s + // CHECK-CC2-NOT: mut_func + // CHECK-CC2: const_func + }; +}; + + -- cgit v1.2.3 From 842e99f500dec2f96beb4a9b69cf5ce156578eef Mon Sep 17 00:00:00 2001 From: Alexey Bataev Date: Wed, 19 Dec 2018 18:16:37 +0000 Subject: [OPENMP]Mark the loop as started when initialized. Need to mark the loop as started when the initialization statement is found. It is required to prevent possible incorrect loop iteraton variable detection during template instantiation and fix the compiler crash during the codegen. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349657 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaOpenMP.cpp | 1 + .../nvptx_target_teams_distribute_parallel_for_codegen.cpp | 13 ++++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp index c207ba9bd3..4fe8d3dd59 100644 --- a/lib/Sema/SemaOpenMP.cpp +++ b/lib/Sema/SemaOpenMP.cpp @@ -4649,6 +4649,7 @@ void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); if (AssociatedLoops > 0 && isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { + DSAStack->loopStart(); OpenMPIterationSpaceChecker ISC(*this, ForLoc); if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { if (ValueDecl *D = ISC.getLoopDecl()) { diff --git a/test/OpenMP/nvptx_target_teams_distribute_parallel_for_codegen.cpp b/test/OpenMP/nvptx_target_teams_distribute_parallel_for_codegen.cpp index 5f003dd6cc..2ecb9ca0e2 100644 --- a/test/OpenMP/nvptx_target_teams_distribute_parallel_for_codegen.cpp +++ b/test/OpenMP/nvptx_target_teams_distribute_parallel_for_codegen.cpp @@ -53,6 +53,13 @@ tx ftemplate(int n) { } } +#pragma omp target teams distribute parallel for collapse(2) + for(int i = 0; i < n; i++) { + for(int j = 0; j < n; j++) { + c[i][j] = i + j; + } + } + #pragma omp target teams distribute parallel for map(a, v[:N]) for(int i = 0; i < n; i++) a[i] = v[i]; @@ -212,7 +219,11 @@ int bar(int n){ // CHECK: call void @__kmpc_for_static_fini( // CHECK: ret void -// CHECK: define weak void @__omp_offloading_{{.*}}_l56(i[[SZ:64|32]] %{{[^,]+}}, [1000 x i32]* dereferenceable{{.*}}, i32* %{{[^)]+}}) +// CHECK: define weak void @__omp_offloading_{{.*}}_l56(i[[SZ:64|32]] %{{[^,]+}}, [10 x [10 x i32]]* dereferenceable{{.*}}) +// CHECK: call void [[OUTLINED:@__omp_outlined.*]](i32* %{{.+}}, i32* %{{.+}}, i[[SZ]] %{{.*}}, i[[SZ]] %{{.*}}, i[[SZ]] %{{.*}}, [10 x [10 x i32]]* %{{.*}}) +// CHECK: define internal void [[OUTLINED]](i32* noalias %{{.*}}, i32* noalias %{{.*}} i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, [10 x [10 x i32]]* dereferenceable{{.*}}) + +// CHECK: define weak void @__omp_offloading_{{.*}}_l63(i[[SZ:64|32]] %{{[^,]+}}, [1000 x i32]* dereferenceable{{.*}}, i32* %{{[^)]+}}) // CHECK: call void [[OUTLINED:@__omp_outlined.*]](i32* %{{.+}}, i32* %{{.+}}, i[[SZ]] %{{.*}}, i[[SZ]] %{{.*}}, i[[SZ]] %{{.*}}, [1000 x i32]* %{{.*}}, i32* %{{.*}}) // CHECK: define internal void [[OUTLINED]](i32* noalias %{{.*}}, i32* noalias %{{.*}} i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, [1000 x i32]* dereferenceable{{.*}}, i32* %{{.*}}) -- cgit v1.2.3 From e4f56bec7bc91fa4437b8e7ce1ac6e5a017766d8 Mon Sep 17 00:00:00 2001 From: David Blaikie Date: Wed, 19 Dec 2018 19:33:35 +0000 Subject: PR40096: Forwards-compatible with C++20 rule regarding aggregates not having user-declared ctors Looks like these were in place to make these types move-only. That's generally not a feature that the type should prescribe (unless it's an inherent limitation) - instead leaving it up to the users of a type. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349669 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Tooling/Refactoring/ASTSelection.cpp | 2 -- tools/clang-refactor/TestSupport.h | 3 --- 2 files changed, 5 deletions(-) diff --git a/lib/Tooling/Refactoring/ASTSelection.cpp b/lib/Tooling/Refactoring/ASTSelection.cpp index 7123fc32ce..b8f996d821 100644 --- a/lib/Tooling/Refactoring/ASTSelection.cpp +++ b/lib/Tooling/Refactoring/ASTSelection.cpp @@ -250,8 +250,6 @@ static bool hasAnyDirectChildrenWithKind(const SelectedASTNode &Node, namespace { struct SelectedNodeWithParents { - SelectedNodeWithParents(SelectedNodeWithParents &&) = default; - SelectedNodeWithParents &operator=(SelectedNodeWithParents &&) = default; SelectedASTNode::ReferenceType Node; llvm::SmallVector Parents; diff --git a/tools/clang-refactor/TestSupport.h b/tools/clang-refactor/TestSupport.h index 61aa660733..779006b0c5 100644 --- a/tools/clang-refactor/TestSupport.h +++ b/tools/clang-refactor/TestSupport.h @@ -59,9 +59,6 @@ struct TestSelectionRangesInFile { }; std::vector GroupedRanges; - TestSelectionRangesInFile(TestSelectionRangesInFile &&) = default; - TestSelectionRangesInFile &operator=(TestSelectionRangesInFile &&) = default; - bool foreachRange(const SourceManager &SM, llvm::function_ref Callback) const; -- cgit v1.2.3 From b99a35b5aefdf2bb77e6a9522e3c7fada2b73fa7 Mon Sep 17 00:00:00 2001 From: Artem Dergachev Date: Wed, 19 Dec 2018 21:50:46 +0000 Subject: [analyzer] CStringChecker: Fix a crash on C++ overloads of standard functions. It turns out that it's not all that uncommon to have a C++ override of, say, memcpy that receives a structure (or two) by reference (or by value, if it's being copied from) and copies memory from it (or into it, if it's passed by reference). In this case the argument will be of structure type (recall that expressions of reference type do not exist: instead, C++ classifies expressions into prvalues and lvalues and xvalues). In this scenario we crash because we are trying to assume that, say, a memory region is equal to an empty CompoundValue (the non-lazy one; this is what makeZeroVal() return for compound types and it represents prvalue of an object that is initialized with an empty initializer list). Add defensive checks. Differential Revision: https://reviews.llvm.org/D55873 rdar://problem/45366551 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349682 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/StaticAnalyzer/Checkers/CStringChecker.cpp | 90 ++++++++++++++++---------- 1 file changed, 56 insertions(+), 34 deletions(-) diff --git a/lib/StaticAnalyzer/Checkers/CStringChecker.cpp b/lib/StaticAnalyzer/Checkers/CStringChecker.cpp index 9d0ccb0390..8bffada69b 100644 --- a/lib/StaticAnalyzer/Checkers/CStringChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/CStringChecker.cpp @@ -188,7 +188,7 @@ public: const Expr *Buf, const char *message = nullptr, bool WarnAboutSize = false) const { - // This is a convenience override. + // This is a convenience overload. return CheckBufferAccess(C, state, Size, Buf, nullptr, message, nullptr, WarnAboutSize); } @@ -2254,64 +2254,86 @@ static bool isCPPStdLibraryFunction(const FunctionDecl *FD, StringRef Name) { // The driver method, and other Checker callbacks. //===----------------------------------------------------------------------===// -bool CStringChecker::evalCall(const CallExpr *CE, CheckerContext &C) const { +static CStringChecker::FnCheck identifyCall(const CallExpr *CE, + CheckerContext &C) { const FunctionDecl *FDecl = C.getCalleeDecl(CE); - if (!FDecl) - return false; + return nullptr; + + // Pro-actively check that argument types are safe to do arithmetic upon. + // We do not want to crash if someone accidentally passes a structure + // into, say, a C++ overload of any of these functions. + if (isCPPStdLibraryFunction(FDecl, "copy")) { + if (CE->getNumArgs() < 3 || !CE->getArg(2)->getType()->isPointerType()) + return nullptr; + return &CStringChecker::evalStdCopy; + } else if (isCPPStdLibraryFunction(FDecl, "copy_backward")) { + if (CE->getNumArgs() < 3 || !CE->getArg(2)->getType()->isPointerType()) + return nullptr; + return &CStringChecker::evalStdCopyBackward; + } else { + // An umbrella check for all C library functions. + for (auto I: CE->arguments()) { + QualType T = I->getType(); + if (!T->isIntegralOrEnumerationType() && !T->isPointerType()) + return nullptr; + } + } // FIXME: Poorly-factored string switches are slow. - FnCheck evalFunction = nullptr; if (C.isCLibraryFunction(FDecl, "memcpy")) - evalFunction = &CStringChecker::evalMemcpy; + return &CStringChecker::evalMemcpy; else if (C.isCLibraryFunction(FDecl, "mempcpy")) - evalFunction = &CStringChecker::evalMempcpy; + return &CStringChecker::evalMempcpy; else if (C.isCLibraryFunction(FDecl, "memcmp")) - evalFunction = &CStringChecker::evalMemcmp; + return &CStringChecker::evalMemcmp; else if (C.isCLibraryFunction(FDecl, "memmove")) - evalFunction = &CStringChecker::evalMemmove; - else if (C.isCLibraryFunction(FDecl, "memset") || - C.isCLibraryFunction(FDecl, "explicit_memset")) - evalFunction = &CStringChecker::evalMemset; + return &CStringChecker::evalMemmove; + else if (C.isCLibraryFunction(FDecl, "memset") || + C.isCLibraryFunction(FDecl, "explicit_memset")) + return &CStringChecker::evalMemset; else if (C.isCLibraryFunction(FDecl, "strcpy")) - evalFunction = &CStringChecker::evalStrcpy; + return &CStringChecker::evalStrcpy; else if (C.isCLibraryFunction(FDecl, "strncpy")) - evalFunction = &CStringChecker::evalStrncpy; + return &CStringChecker::evalStrncpy; else if (C.isCLibraryFunction(FDecl, "stpcpy")) - evalFunction = &CStringChecker::evalStpcpy; + return &CStringChecker::evalStpcpy; else if (C.isCLibraryFunction(FDecl, "strlcpy")) - evalFunction = &CStringChecker::evalStrlcpy; + return &CStringChecker::evalStrlcpy; else if (C.isCLibraryFunction(FDecl, "strcat")) - evalFunction = &CStringChecker::evalStrcat; + return &CStringChecker::evalStrcat; else if (C.isCLibraryFunction(FDecl, "strncat")) - evalFunction = &CStringChecker::evalStrncat; + return &CStringChecker::evalStrncat; else if (C.isCLibraryFunction(FDecl, "strlcat")) - evalFunction = &CStringChecker::evalStrlcat; + return &CStringChecker::evalStrlcat; else if (C.isCLibraryFunction(FDecl, "strlen")) - evalFunction = &CStringChecker::evalstrLength; + return &CStringChecker::evalstrLength; else if (C.isCLibraryFunction(FDecl, "strnlen")) - evalFunction = &CStringChecker::evalstrnLength; + return &CStringChecker::evalstrnLength; else if (C.isCLibraryFunction(FDecl, "strcmp")) - evalFunction = &CStringChecker::evalStrcmp; + return &CStringChecker::evalStrcmp; else if (C.isCLibraryFunction(FDecl, "strncmp")) - evalFunction = &CStringChecker::evalStrncmp; + return &CStringChecker::evalStrncmp; else if (C.isCLibraryFunction(FDecl, "strcasecmp")) - evalFunction = &CStringChecker::evalStrcasecmp; + return &CStringChecker::evalStrcasecmp; else if (C.isCLibraryFunction(FDecl, "strncasecmp")) - evalFunction = &CStringChecker::evalStrncasecmp; + return &CStringChecker::evalStrncasecmp; else if (C.isCLibraryFunction(FDecl, "strsep")) - evalFunction = &CStringChecker::evalStrsep; + return &CStringChecker::evalStrsep; else if (C.isCLibraryFunction(FDecl, "bcopy")) - evalFunction = &CStringChecker::evalBcopy; + return &CStringChecker::evalBcopy; else if (C.isCLibraryFunction(FDecl, "bcmp")) - evalFunction = &CStringChecker::evalMemcmp; - else if (isCPPStdLibraryFunction(FDecl, "copy")) - evalFunction = &CStringChecker::evalStdCopy; - else if (isCPPStdLibraryFunction(FDecl, "copy_backward")) - evalFunction = &CStringChecker::evalStdCopyBackward; + return &CStringChecker::evalMemcmp; else if (C.isCLibraryFunction(FDecl, "bzero") || - C.isCLibraryFunction(FDecl, "explicit_bzero")) - evalFunction = &CStringChecker::evalBzero; + C.isCLibraryFunction(FDecl, "explicit_bzero")) + return &CStringChecker::evalBzero; + + return nullptr; +} + +bool CStringChecker::evalCall(const CallExpr *CE, CheckerContext &C) const { + + FnCheck evalFunction = identifyCall(CE, C); // If the callee isn't a string function, let another checker handle it. if (!evalFunction) -- cgit v1.2.3 From 2ac8dae2d6fcf14ef1b60e456eacd2a9eeb5a6ee Mon Sep 17 00:00:00 2001 From: Artem Dergachev Date: Wed, 19 Dec 2018 21:51:59 +0000 Subject: [analyzer] CStringChecker: Add the forgotten test file. Differential Revision: https://reviews.llvm.org/D55873 rdar://problem/45366551 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349683 91177308-0d34-0410-b5e6-96231b3b80d8 --- test/Analysis/string.cpp | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 test/Analysis/string.cpp diff --git a/test/Analysis/string.cpp b/test/Analysis/string.cpp new file mode 100644 index 0000000000..f86416da6e --- /dev/null +++ b/test/Analysis/string.cpp @@ -0,0 +1,28 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix -verify %s + +// expected-no-diagnostics + +// Test functions that are called "memcpy" but aren't the memcpy +// we're looking for. Unfortunately, this test cannot be put into +// a namespace. The out-of-class weird memcpy needs to be recognized +// as a normal C function for the test to make sense. +typedef __typeof(sizeof(int)) size_t; +void *memcpy(void *, const void *, size_t); + +struct S { + static S s1, s2; + + // A weird overload within the class that accepts a structure reference + // instead of a pointer. + void memcpy(void *, const S &, size_t); + void test_in_class_weird_memcpy() { + memcpy(this, s2, 1); // no-crash + } +}; + +// A similarly weird overload outside of the class. +void *memcpy(void *, const S &, size_t); + +void test_out_of_class_weird_memcpy() { + memcpy(&S::s1, S::s2, 1); // no-crash +} -- cgit v1.2.3 From a2c62be9195ddfa400c07810c03a11f9325f37e7 Mon Sep 17 00:00:00 2001 From: Douglas Yung Date: Wed, 19 Dec 2018 22:45:26 +0000 Subject: Disable -faddsig by default for PS4 target. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349691 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Driver/ToolChains/Clang.cpp | 1 + test/Driver/addrsig.c | 1 + 2 files changed, 2 insertions(+) diff --git a/lib/Driver/ToolChains/Clang.cpp b/lib/Driver/ToolChains/Clang.cpp index 18a43a695d..1efaf0b584 100644 --- a/lib/Driver/ToolChains/Clang.cpp +++ b/lib/Driver/ToolChains/Clang.cpp @@ -5273,6 +5273,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (Args.hasFlag(options::OPT_faddrsig, options::OPT_fno_addrsig, (TC.getTriple().isOSBinFormatELF() || TC.getTriple().isOSBinFormatCOFF()) && + !TC.getTriple().isPS4() && TC.useIntegratedAs() && RawTriple.getOS() != llvm::Triple::NetBSD)) CmdArgs.push_back("-faddrsig"); diff --git a/test/Driver/addrsig.c b/test/Driver/addrsig.c index 4eea415c01..739dcc35ff 100644 --- a/test/Driver/addrsig.c +++ b/test/Driver/addrsig.c @@ -4,6 +4,7 @@ // RUN: %clang -### -target x86_64-unknown-linux -fno-integrated-as -faddrsig -c %s 2>&1 | FileCheck -check-prefix=ADDRSIG %s // RUN: %clang -### -target x86_64-unknown-linux -fno-addrsig -c %s 2>&1 | FileCheck -check-prefix=NO-ADDRSIG %s // RUN: %clang -### -target x86_64-apple-darwin -c %s 2>&1 | FileCheck -check-prefix=NO-ADDRSIG %s +// RUN: %clang -### -target x86_64-scei-ps4 -c %s 2>&1 | FileCheck -check-prefix=NO-ADDRSIG %s // ADDRSIG: -faddrsig // NO-ADDRSIG-NOT: -faddrsig -- cgit v1.2.3 From 61c52cbbb1d80578ae77658f4049fda7c5b7edfd Mon Sep 17 00:00:00 2001 From: Artem Dergachev Date: Wed, 19 Dec 2018 23:14:06 +0000 Subject: [analyzer] Improve modeling for returning an object from the top frame with RVO. Static Analyzer processes the program function-by-function, sometimes diving into other functions ("inlining" them). When an object is returned from an inlined function, Return Value Optimization is modeled, and the returned object is constructed at its return location directly. When an object is returned from the function from which the analysis has started (the top stack frame of the analysis), the return location is unknown. Model it with a SymbolicRegion based on a conjured symbol that is specifically tagged for that purpose, because this is generally the correct way to symbolicate unknown locations in Static Analyzer. Fixes leak false positives when an object is returned from top frame in C++17: objects that are put into a SymbolicRegion-based memory region automatically "escape" and no longer get reported as leaks. This only applies to C++17 return values with destructors, because it produces a redundant CXXBindTemporaryExpr in the call site, which confuses our liveness analysis. The actual fix for liveness analysis is still pending, but it is no longer causing problems. Additionally, re-enable temporary destructor tests in C++17. Differential Revision: https://reviews.llvm.org/D55804 rdar://problem/46217550 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349696 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/StaticAnalyzer/Core/ExprEngineCXX.cpp | 31 +++++++--- test/Analysis/temporaries.cpp | 96 +++++++++++++++++++++++++++---- 2 files changed, 108 insertions(+), 19 deletions(-) diff --git a/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp b/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp index 1f64976a9f..6445b9df5a 100644 --- a/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp +++ b/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp @@ -113,7 +113,9 @@ SVal ExprEngine::makeZeroElementRegion(ProgramStateRef State, SVal LValue, std::pair ExprEngine::prepareForObjectConstruction( const Expr *E, ProgramStateRef State, const LocationContext *LCtx, const ConstructionContext *CC, EvalCallOptions &CallOpts) { - MemRegionManager &MRMgr = getSValBuilder().getRegionManager(); + SValBuilder &SVB = getSValBuilder(); + MemRegionManager &MRMgr = SVB.getRegionManager(); + ASTContext &ACtx = SVB.getContext(); // See if we're constructing an existing region by looking at the // current construction context. @@ -139,7 +141,7 @@ std::pair ExprEngine::prepareForObjectConstruction( assert(Init->isAnyMemberInitializer()); const CXXMethodDecl *CurCtor = cast(LCtx->getDecl()); Loc ThisPtr = - getSValBuilder().getCXXThis(CurCtor, LCtx->getStackFrame()); + SVB.getCXXThis(CurCtor, LCtx->getStackFrame()); SVal ThisVal = State->getSVal(ThisPtr); const ValueDecl *Field; @@ -199,12 +201,25 @@ std::pair ExprEngine::prepareForObjectConstruction( cast(SFC->getCallSite()), State, CallerLCtx, RTC->getConstructionContext(), CallOpts); } else { - // We are on the top frame of the analysis. - // TODO: What exactly happens when we are? Does the temporary object - // live long enough in the region store in this case? Would checkers - // think that this object immediately goes out of scope? - CallOpts.IsTemporaryCtorOrDtor = true; - SVal V = loc::MemRegionVal(MRMgr.getCXXTempObjectRegion(E, LCtx)); + // We are on the top frame of the analysis. We do not know where is the + // object returned to. Conjure a symbolic region for the return value. + // TODO: We probably need a new MemRegion kind to represent the storage + // of that SymbolicRegion, so that we cound produce a fancy symbol + // instead of an anonymous conjured symbol. + // TODO: Do we need to track the region to avoid having it dead + // too early? It does die too early, at least in C++17, but because + // putting anything into a SymbolicRegion causes an immediate escape, + // it doesn't cause any leak false positives. + const auto *RCC = cast(CC); + // Make sure that this doesn't coincide with any other symbol + // conjured for the returned expression. + static const int TopLevelSymRegionTag = 0; + const Expr *RetE = RCC->getReturnStmt()->getRetValue(); + assert(RetE && "Void returns should not have a construction context"); + QualType ReturnTy = RetE->getType(); + QualType RegionTy = ACtx.getPointerType(ReturnTy); + SVal V = SVB.conjureSymbolVal(&TopLevelSymRegionTag, RetE, SFC, + RegionTy, currBldrCtx->blockCount()); return std::make_pair(State, V); } llvm_unreachable("Unhandled return value construction context!"); diff --git a/test/Analysis/temporaries.cpp b/test/Analysis/temporaries.cpp index 7a6b8b0409..6191abfb4d 100644 --- a/test/Analysis/temporaries.cpp +++ b/test/Analysis/temporaries.cpp @@ -1,9 +1,25 @@ -// RUN: %clang_analyze_cc1 -Wno-non-pod-varargs -analyzer-checker=core,cplusplus,debug.ExprInspection -analyzer-config cfg-temporary-dtors=false -verify -w -std=c++03 -analyzer-config eagerly-assume=false %s -// RUN: %clang_analyze_cc1 -Wno-non-pod-varargs -analyzer-checker=core,cplusplus,debug.ExprInspection -analyzer-config cfg-temporary-dtors=false -verify -w -std=c++11 -analyzer-config eagerly-assume=false %s -// RUN: %clang_analyze_cc1 -Wno-non-pod-varargs -analyzer-checker=core,cplusplus,debug.ExprInspection -DTEMPORARY_DTORS -verify -w -analyzer-config cfg-temporary-dtors=true,c++-temp-dtor-inlining=true -analyzer-config eagerly-assume=false %s -std=c++11 -// RUN: %clang_analyze_cc1 -Wno-non-pod-varargs -analyzer-checker=core,cplusplus,debug.ExprInspection -DTEMPORARY_DTORS -w -analyzer-config cfg-temporary-dtors=true,c++-temp-dtor-inlining=true -analyzer-config eagerly-assume=false %s -std=c++17 +// RUN: %clang_analyze_cc1 -w -analyzer-checker=core,cplusplus\ +// RUN: -analyzer-checker debug.ExprInspection -Wno-non-pod-varargs\ +// RUN: -analyzer-config eagerly-assume=false -verify %s\ +// RUN: -std=c++03 -analyzer-config cfg-temporary-dtors=false + +// RUN: %clang_analyze_cc1 -w -analyzer-checker=core,cplusplus\ +// RUN: -analyzer-checker debug.ExprInspection -Wno-non-pod-varargs\ +// RUN: -analyzer-config eagerly-assume=false -verify %s\ +// RUN: -std=c++11 -analyzer-config cfg-temporary-dtors=false + +// RUN: %clang_analyze_cc1 -w -analyzer-checker=core,cplusplus\ +// RUN: -analyzer-checker debug.ExprInspection -Wno-non-pod-varargs\ +// RUN: -analyzer-config eagerly-assume=false -verify %s\ +// RUN: -std=c++11 -analyzer-config cfg-temporary-dtors=true\ +// RUN: -DTEMPORARY_DTORS + +// RUN: %clang_analyze_cc1 -w -analyzer-checker=core,cplusplus\ +// RUN: -analyzer-checker debug.ExprInspection -Wno-non-pod-varargs\ +// RUN: -analyzer-config eagerly-assume=false -verify %s\ +// RUN: -std=c++17 -analyzer-config cfg-temporary-dtors=true\ +// RUN: -DTEMPORARY_DTORS -// Note: The C++17 run-line doesn't -verify yet - it is a no-crash test. extern bool clang_analyzer_eval(bool); extern bool clang_analyzer_warnIfReached(); @@ -450,7 +466,16 @@ namespace destructors { } #if __cplusplus >= 201103L - CtorWithNoReturnDtor returnNoReturnDtor() { + struct CtorWithNoReturnDtor2 { + CtorWithNoReturnDtor2() = default; + + CtorWithNoReturnDtor2(int x) { + clang_analyzer_checkInlined(true); // expected-warning{{TRUE}} + } + + ~CtorWithNoReturnDtor2() __attribute__((noreturn)); + }; + CtorWithNoReturnDtor2 returnNoReturnDtor() { return {1}; // no-crash } #endif @@ -805,7 +830,12 @@ void test_ternary_temporary_with_copy(int coin) { // On each branch the variable is constructed directly. if (coin) { clang_analyzer_eval(x == 1); // expected-warning{{TRUE}} +#if __cplusplus < 201703L clang_analyzer_eval(y == 1); // expected-warning{{TRUE}} +#else + // FIXME: Destructor called twice in C++17? + clang_analyzer_eval(y == 2); // expected-warning{{TRUE}} +#endif clang_analyzer_eval(z == 0); // expected-warning{{TRUE}} clang_analyzer_eval(w == 0); // expected-warning{{TRUE}} @@ -813,7 +843,12 @@ void test_ternary_temporary_with_copy(int coin) { clang_analyzer_eval(x == 0); // expected-warning{{TRUE}} clang_analyzer_eval(y == 0); // expected-warning{{TRUE}} clang_analyzer_eval(z == 1); // expected-warning{{TRUE}} +#if __cplusplus < 201703L clang_analyzer_eval(w == 1); // expected-warning{{TRUE}} +#else + // FIXME: Destructor called twice in C++17? + clang_analyzer_eval(w == 2); // expected-warning{{TRUE}} +#endif } } } // namespace test_match_constructors_and_destructors @@ -865,9 +900,12 @@ class C { public: ~C() { glob = 1; + // FIXME: Why is destructor not inlined in C++17 clang_analyzer_checkInlined(true); #ifdef TEMPORARY_DTORS - // expected-warning@-2{{TRUE}} +#if __cplusplus < 201703L + // expected-warning@-3{{TRUE}} +#endif #endif } }; @@ -886,11 +924,16 @@ void test(int coin) { // temporaries returned from functions, so we took the wrong branch. coin && is(get()); // no-crash if (coin) { + // FIXME: Why is destructor not inlined in C++17 clang_analyzer_eval(glob); #ifdef TEMPORARY_DTORS - // expected-warning@-2{{TRUE}} +#if __cplusplus < 201703L + // expected-warning@-3{{TRUE}} +#else + // expected-warning@-5{{UNKNOWN}} +#endif #else - // expected-warning@-4{{UNKNOWN}} + // expected-warning@-8{{UNKNOWN}} #endif } else { // The destructor is not called on this branch. @@ -1012,11 +1055,16 @@ void foo(void (*bar4)(S)) { #endif bar2(S(2)); + // FIXME: Why are we losing information in C++17? clang_analyzer_eval(glob == 2); #ifdef TEMPORARY_DTORS - // expected-warning@-2{{TRUE}} +#if __cplusplus < 201703L + // expected-warning@-3{{TRUE}} #else - // expected-warning@-4{{UNKNOWN}} + // expected-warning@-5{{UNKNOWN}} +#endif +#else + // expected-warning@-8{{UNKNOWN}} #endif C *c = new D(); @@ -1172,3 +1220,29 @@ void test() { c.foo(); } } // namespace union_indirect_field_crash + +namespace return_from_top_frame { +struct S { + int *p; + S() { p = new int; } + S(S &&s) : p(s.p) { s.p = 0; } + ~S(); // Presumably releases 'p'. +}; + +S foo() { + S s; + return s; +} + +S bar1() { + return foo(); // no-warning +} + +S bar2() { + return S(); +} + +S bar3(int coin) { + return coin ? S() : foo(); // no-warning +} +} // namespace return_from_top_frame -- cgit v1.2.3 From 0dc8ad57609f3456774040a501d5b6658b956c25 Mon Sep 17 00:00:00 2001 From: Artem Dergachev Date: Wed, 19 Dec 2018 23:35:08 +0000 Subject: [analyzer] GenericTaint: Fix formatting to prepare for incoming improvements. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Patch by Gábor Borsik! Differential Revision: https://reviews.llvm.org/D54918 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349698 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Checkers/GenericTaintChecker.cpp | 214 ++++++++++----------- 1 file changed, 107 insertions(+), 107 deletions(-) diff --git a/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp b/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp index fbc8ff3512..32fed202d3 100644 --- a/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp @@ -28,10 +28,13 @@ using namespace clang; using namespace ento; namespace { -class GenericTaintChecker : public Checker< check::PostStmt, - check::PreStmt > { +class GenericTaintChecker + : public Checker, check::PreStmt> { public: - static void *getTag() { static int Tag; return &Tag; } + static void *getTag() { + static int Tag; + return &Tag; + } void checkPostStmt(const CallExpr *CE, CheckerContext &C) const; @@ -69,8 +72,8 @@ private: static Optional getPointedToSVal(CheckerContext &C, const Expr *Arg); /// Functions defining the attack surface. - typedef ProgramStateRef (GenericTaintChecker::*FnCheck)(const CallExpr *, - CheckerContext &C) const; + typedef ProgramStateRef (GenericTaintChecker::*FnCheck)( + const CallExpr *, CheckerContext &C) const; ProgramStateRef postScanf(const CallExpr *CE, CheckerContext &C) const; ProgramStateRef postSocket(const CallExpr *CE, CheckerContext &C) const; ProgramStateRef postRetTaint(const CallExpr *CE, CheckerContext &C) const; @@ -120,16 +123,15 @@ private: TaintPropagationRule() {} - TaintPropagationRule(unsigned SArg, - unsigned DArg, bool TaintRet = false) { + TaintPropagationRule(unsigned SArg, unsigned DArg, bool TaintRet = false) { SrcArgs.push_back(SArg); DstArgs.push_back(DArg); if (TaintRet) DstArgs.push_back(ReturnValueIndex); } - TaintPropagationRule(unsigned SArg1, unsigned SArg2, - unsigned DArg, bool TaintRet = false) { + TaintPropagationRule(unsigned SArg1, unsigned SArg2, unsigned DArg, + bool TaintRet = false) { SrcArgs.push_back(SArg1); SrcArgs.push_back(SArg2); DstArgs.push_back(DArg); @@ -139,18 +141,17 @@ private: /// Get the propagation rule for a given function. static TaintPropagationRule - getTaintPropagationRule(const FunctionDecl *FDecl, - StringRef Name, - CheckerContext &C); + getTaintPropagationRule(const FunctionDecl *FDecl, StringRef Name, + CheckerContext &C); inline void addSrcArg(unsigned A) { SrcArgs.push_back(A); } - inline void addDstArg(unsigned A) { DstArgs.push_back(A); } + inline void addDstArg(unsigned A) { DstArgs.push_back(A); } inline bool isNull() const { return SrcArgs.empty(); } inline bool isDestinationArgument(unsigned ArgNum) const { - return (std::find(DstArgs.begin(), - DstArgs.end(), ArgNum) != DstArgs.end()); + return (std::find(DstArgs.begin(), DstArgs.end(), ArgNum) != + DstArgs.end()); } static inline bool isTaintedOrPointsToTainted(const Expr *E, @@ -169,7 +170,6 @@ private: /// Pre-process a function which propagates taint according to the /// taint rule. ProgramStateRef process(const CallExpr *CE, CheckerContext &C) const; - }; }; @@ -177,17 +177,18 @@ const unsigned GenericTaintChecker::ReturnValueIndex; const unsigned GenericTaintChecker::InvalidArgIndex; const char GenericTaintChecker::MsgUncontrolledFormatString[] = - "Untrusted data is used as a format string " - "(CWE-134: Uncontrolled Format String)"; + "Untrusted data is used as a format string " + "(CWE-134: Uncontrolled Format String)"; const char GenericTaintChecker::MsgSanitizeSystemArgs[] = - "Untrusted data is passed to a system call " - "(CERT/STR02-C. Sanitize data passed to complex subsystems)"; + "Untrusted data is passed to a system call " + "(CERT/STR02-C. Sanitize data passed to complex subsystems)"; const char GenericTaintChecker::MsgTaintedBufferSize[] = - "Untrusted data is used to specify the buffer size " - "(CERT/STR31-C. Guarantee that storage for strings has sufficient space for " - "character data and the null terminator)"; + "Untrusted data is used to specify the buffer size " + "(CERT/STR31-C. Guarantee that storage for strings has sufficient space " + "for " + "character data and the null terminator)"; } // end of anonymous namespace @@ -199,33 +200,32 @@ REGISTER_SET_WITH_PROGRAMSTATE(TaintArgsOnPostVisit, unsigned) GenericTaintChecker::TaintPropagationRule GenericTaintChecker::TaintPropagationRule::getTaintPropagationRule( - const FunctionDecl *FDecl, - StringRef Name, - CheckerContext &C) { + const FunctionDecl *FDecl, StringRef Name, CheckerContext &C) { // TODO: Currently, we might lose precision here: we always mark a return // value as tainted even if it's just a pointer, pointing to tainted data. // Check for exact name match for functions without builtin substitutes. - TaintPropagationRule Rule = llvm::StringSwitch(Name) - .Case("atoi", TaintPropagationRule(0, ReturnValueIndex)) - .Case("atol", TaintPropagationRule(0, ReturnValueIndex)) - .Case("atoll", TaintPropagationRule(0, ReturnValueIndex)) - .Case("getc", TaintPropagationRule(0, ReturnValueIndex)) - .Case("fgetc", TaintPropagationRule(0, ReturnValueIndex)) - .Case("getc_unlocked", TaintPropagationRule(0, ReturnValueIndex)) - .Case("getw", TaintPropagationRule(0, ReturnValueIndex)) - .Case("toupper", TaintPropagationRule(0, ReturnValueIndex)) - .Case("tolower", TaintPropagationRule(0, ReturnValueIndex)) - .Case("strchr", TaintPropagationRule(0, ReturnValueIndex)) - .Case("strrchr", TaintPropagationRule(0, ReturnValueIndex)) - .Case("read", TaintPropagationRule(0, 2, 1, true)) - .Case("pread", TaintPropagationRule(InvalidArgIndex, 1, true)) - .Case("gets", TaintPropagationRule(InvalidArgIndex, 0, true)) - .Case("fgets", TaintPropagationRule(2, 0, true)) - .Case("getline", TaintPropagationRule(2, 0)) - .Case("getdelim", TaintPropagationRule(3, 0)) - .Case("fgetln", TaintPropagationRule(0, ReturnValueIndex)) - .Default(TaintPropagationRule()); + TaintPropagationRule Rule = + llvm::StringSwitch(Name) + .Case("atoi", TaintPropagationRule(0, ReturnValueIndex)) + .Case("atol", TaintPropagationRule(0, ReturnValueIndex)) + .Case("atoll", TaintPropagationRule(0, ReturnValueIndex)) + .Case("getc", TaintPropagationRule(0, ReturnValueIndex)) + .Case("fgetc", TaintPropagationRule(0, ReturnValueIndex)) + .Case("getc_unlocked", TaintPropagationRule(0, ReturnValueIndex)) + .Case("getw", TaintPropagationRule(0, ReturnValueIndex)) + .Case("toupper", TaintPropagationRule(0, ReturnValueIndex)) + .Case("tolower", TaintPropagationRule(0, ReturnValueIndex)) + .Case("strchr", TaintPropagationRule(0, ReturnValueIndex)) + .Case("strrchr", TaintPropagationRule(0, ReturnValueIndex)) + .Case("read", TaintPropagationRule(0, 2, 1, true)) + .Case("pread", TaintPropagationRule(InvalidArgIndex, 1, true)) + .Case("gets", TaintPropagationRule(InvalidArgIndex, 0, true)) + .Case("fgets", TaintPropagationRule(2, 0, true)) + .Case("getline", TaintPropagationRule(2, 0)) + .Case("getdelim", TaintPropagationRule(3, 0)) + .Case("fgetln", TaintPropagationRule(0, ReturnValueIndex)) + .Default(TaintPropagationRule()); if (!Rule.isNull()) return Rule; @@ -233,8 +233,8 @@ GenericTaintChecker::TaintPropagationRule::getTaintPropagationRule( // Check if it's one of the memory setting/copying functions. // This check is specialized but faster then calling isCLibraryFunction. unsigned BId = 0; - if ( (BId = FDecl->getMemoryFunctionKind()) ) - switch(BId) { + if ((BId = FDecl->getMemoryFunctionKind())) + switch (BId) { case Builtin::BImemcpy: case Builtin::BImemmove: case Builtin::BIstrncpy: @@ -305,7 +305,7 @@ void GenericTaintChecker::addSourcesPre(const CallExpr *CE, // First, try generating a propagation rule for this function. TaintPropagationRule Rule = - TaintPropagationRule::getTaintPropagationRule(FDecl, Name, C); + TaintPropagationRule::getTaintPropagationRule(FDecl, Name, C); if (!Rule.isNull()) { State = Rule.process(CE, C); if (!State) @@ -316,15 +316,14 @@ void GenericTaintChecker::addSourcesPre(const CallExpr *CE, // Otherwise, check if we have custom pre-processing implemented. FnCheck evalFunction = llvm::StringSwitch(Name) - .Case("fscanf", &GenericTaintChecker::preFscanf) - .Default(nullptr); + .Case("fscanf", &GenericTaintChecker::preFscanf) + .Default(nullptr); // Check and evaluate the call. if (evalFunction) State = (this->*evalFunction)(CE, C); if (!State) return; C.addTransition(State); - } bool GenericTaintChecker::propagateFromPre(const CallExpr *CE, @@ -338,9 +337,10 @@ bool GenericTaintChecker::propagateFromPre(const CallExpr *CE, if (TaintArgs.isEmpty()) return false; - for (llvm::ImmutableSet::iterator - I = TaintArgs.begin(), E = TaintArgs.end(); I != E; ++I) { - unsigned ArgNum = *I; + for (llvm::ImmutableSet::iterator I = TaintArgs.begin(), + E = TaintArgs.end(); + I != E; ++I) { + unsigned ArgNum = *I; // Special handling for the tainted return value. if (ArgNum == ReturnValueIndex) { @@ -352,7 +352,7 @@ bool GenericTaintChecker::propagateFromPre(const CallExpr *CE, // tainted after the call. if (CE->getNumArgs() < (ArgNum + 1)) return false; - const Expr* Arg = CE->getArg(ArgNum); + const Expr *Arg = CE->getArg(ArgNum); Optional V = getPointedToSVal(C, Arg); if (V) State = State->addTaint(*V); @@ -379,19 +379,20 @@ void GenericTaintChecker::addSourcesPost(const CallExpr *CE, StringRef Name = C.getCalleeName(FDecl); if (Name.empty()) return; - FnCheck evalFunction = llvm::StringSwitch(Name) - .Case("scanf", &GenericTaintChecker::postScanf) - // TODO: Add support for vfscanf & family. - .Case("getchar", &GenericTaintChecker::postRetTaint) - .Case("getchar_unlocked", &GenericTaintChecker::postRetTaint) - .Case("getenv", &GenericTaintChecker::postRetTaint) - .Case("fopen", &GenericTaintChecker::postRetTaint) - .Case("fdopen", &GenericTaintChecker::postRetTaint) - .Case("freopen", &GenericTaintChecker::postRetTaint) - .Case("getch", &GenericTaintChecker::postRetTaint) - .Case("wgetch", &GenericTaintChecker::postRetTaint) - .Case("socket", &GenericTaintChecker::postSocket) - .Default(nullptr); + FnCheck evalFunction = + llvm::StringSwitch(Name) + .Case("scanf", &GenericTaintChecker::postScanf) + // TODO: Add support for vfscanf & family. + .Case("getchar", &GenericTaintChecker::postRetTaint) + .Case("getchar_unlocked", &GenericTaintChecker::postRetTaint) + .Case("getenv", &GenericTaintChecker::postRetTaint) + .Case("fopen", &GenericTaintChecker::postRetTaint) + .Case("fdopen", &GenericTaintChecker::postRetTaint) + .Case("freopen", &GenericTaintChecker::postRetTaint) + .Case("getch", &GenericTaintChecker::postRetTaint) + .Case("wgetch", &GenericTaintChecker::postRetTaint) + .Case("socket", &GenericTaintChecker::postSocket) + .Default(nullptr); // If the callee isn't defined, it is not of security concern. // Check and evaluate the call. @@ -404,7 +405,8 @@ void GenericTaintChecker::addSourcesPost(const CallExpr *CE, C.addTransition(State); } -bool GenericTaintChecker::checkPre(const CallExpr *CE, CheckerContext &C) const{ +bool GenericTaintChecker::checkPre(const CallExpr *CE, + CheckerContext &C) const { if (checkUncontrolledFormatString(CE, C)) return true; @@ -458,8 +460,8 @@ GenericTaintChecker::TaintPropagationRule::process(const CallExpr *CE, // Check for taint in arguments. bool IsTainted = false; - for (ArgVector::const_iterator I = SrcArgs.begin(), - E = SrcArgs.end(); I != E; ++I) { + for (ArgVector::const_iterator I = SrcArgs.begin(), E = SrcArgs.end(); I != E; + ++I) { unsigned ArgNum = *I; if (ArgNum == InvalidArgIndex) { @@ -483,8 +485,8 @@ GenericTaintChecker::TaintPropagationRule::process(const CallExpr *CE, return State; // Mark the arguments which should be tainted after the function returns. - for (ArgVector::const_iterator I = DstArgs.begin(), - E = DstArgs.end(); I != E; ++I) { + for (ArgVector::const_iterator I = DstArgs.begin(), E = DstArgs.end(); I != E; + ++I) { unsigned ArgNum = *I; // Should we mark all arguments as tainted? @@ -498,8 +500,8 @@ GenericTaintChecker::TaintPropagationRule::process(const CallExpr *CE, // Process pointer argument. const Type *ArgTy = Arg->getType().getTypePtr(); QualType PType = ArgTy->getPointeeType(); - if ((!PType.isNull() && !PType.isConstQualified()) - || (ArgTy->isReferenceType() && !Arg->getType().isConstQualified())) + if ((!PType.isNull() && !PType.isConstQualified()) || + (ArgTy->isReferenceType() && !Arg->getType().isConstQualified())) State = State->add(i); } continue; @@ -519,11 +521,10 @@ GenericTaintChecker::TaintPropagationRule::process(const CallExpr *CE, return State; } - // If argument 0 (file descriptor) is tainted, all arguments except for arg 0 // and arg 1 should get taint. ProgramStateRef GenericTaintChecker::preFscanf(const CallExpr *CE, - CheckerContext &C) const { + CheckerContext &C) const { assert(CE->getNumArgs() >= 2); ProgramStateRef State = C.getState(); @@ -532,14 +533,13 @@ ProgramStateRef GenericTaintChecker::preFscanf(const CallExpr *CE, isStdin(CE->getArg(0), C)) { // All arguments except for the first two should get taint. for (unsigned int i = 2; i < CE->getNumArgs(); ++i) - State = State->add(i); + State = State->add(i); return State; } return nullptr; } - // If argument 0(protocol domain) is network, the return value should get taint. ProgramStateRef GenericTaintChecker::postSocket(const CallExpr *CE, CheckerContext &C) const { @@ -558,7 +558,7 @@ ProgramStateRef GenericTaintChecker::postSocket(const CallExpr *CE, } ProgramStateRef GenericTaintChecker::postScanf(const CallExpr *CE, - CheckerContext &C) const { + CheckerContext &C) const { ProgramStateRef State = C.getState(); if (CE->getNumArgs() < 2) return State; @@ -567,7 +567,7 @@ ProgramStateRef GenericTaintChecker::postScanf(const CallExpr *CE, for (unsigned int i = 1; i < CE->getNumArgs(); ++i) { // The arguments are pointer arguments. The data they are pointing at is // tainted after the call. - const Expr* Arg = CE->getArg(i); + const Expr *Arg = CE->getArg(i); Optional V = getPointedToSVal(C, Arg); if (V) State = State->addTaint(*V); @@ -593,7 +593,8 @@ bool GenericTaintChecker::isStdin(const Expr *E, CheckerContext &C) { return false; // Get it's symbol and find the declaration region it's pointing to. - const SymbolRegionValue *Sm =dyn_cast(SymReg->getSymbol()); + const SymbolRegionValue *Sm = + dyn_cast(SymReg->getSymbol()); if (!Sm) return false; const DeclRegion *DeclReg = dyn_cast_or_null(Sm->getRegion()); @@ -605,11 +606,11 @@ bool GenericTaintChecker::isStdin(const Expr *E, CheckerContext &C) { if (const VarDecl *D = dyn_cast_or_null(DeclReg->getDecl())) { D = D->getCanonicalDecl(); if ((D->getName().find("stdin") != StringRef::npos) && D->isExternC()) - if (const PointerType * PtrTy = + if (const PointerType *PtrTy = dyn_cast(D->getType().getTypePtr())) - if (PtrTy->getPointeeType().getCanonicalType() == - C.getASTContext().getFILEType().getCanonicalType()) - return true; + if (PtrTy->getPointeeType().getCanonicalType() == + C.getASTContext().getFILEType().getCanonicalType()) + return true; } return false; } @@ -625,8 +626,7 @@ static bool getPrintfFormatArgumentNum(const CallExpr *CE, return false; for (const auto *Format : FDecl->specific_attrs()) { ArgNum = Format->getFormatIdx() - 1; - if ((Format->getType()->getName() == "printf") && - CE->getNumArgs() > ArgNum) + if ((Format->getType()->getName() == "printf") && CE->getNumArgs() > ArgNum) return true; } @@ -667,36 +667,36 @@ bool GenericTaintChecker::generateReportIfTainted(const Expr *E, return false; } -bool GenericTaintChecker::checkUncontrolledFormatString(const CallExpr *CE, - CheckerContext &C) const{ +bool GenericTaintChecker::checkUncontrolledFormatString( + const CallExpr *CE, CheckerContext &C) const { // Check if the function contains a format string argument. unsigned int ArgNum = 0; if (!getPrintfFormatArgumentNum(CE, C, ArgNum)) return false; - // If either the format string content or the pointer itself are tainted, warn. + // If either the format string content or the pointer itself are tainted, + // warn. return generateReportIfTainted(CE->getArg(ArgNum), MsgUncontrolledFormatString, C); } -bool GenericTaintChecker::checkSystemCall(const CallExpr *CE, - StringRef Name, +bool GenericTaintChecker::checkSystemCall(const CallExpr *CE, StringRef Name, CheckerContext &C) const { // TODO: It might make sense to run this check on demand. In some cases, // we should check if the environment has been cleansed here. We also might // need to know if the user was reset before these calls(seteuid). unsigned ArgNum = llvm::StringSwitch(Name) - .Case("system", 0) - .Case("popen", 0) - .Case("execl", 0) - .Case("execle", 0) - .Case("execlp", 0) - .Case("execv", 0) - .Case("execvp", 0) - .Case("execvP", 0) - .Case("execve", 0) - .Case("dlopen", 0) - .Default(UINT_MAX); + .Case("system", 0) + .Case("popen", 0) + .Case("execl", 0) + .Case("execle", 0) + .Case("execlp", 0) + .Case("execv", 0) + .Case("execvp", 0) + .Case("execvP", 0) + .Case("execve", 0) + .Case("dlopen", 0) + .Default(UINT_MAX); if (ArgNum == UINT_MAX || CE->getNumArgs() < (ArgNum + 1)) return false; @@ -712,8 +712,8 @@ bool GenericTaintChecker::checkTaintedBufferSize(const CallExpr *CE, // If the function has a buffer size argument, set ArgNum. unsigned ArgNum = InvalidArgIndex; unsigned BId = 0; - if ( (BId = FDecl->getMemoryFunctionKind()) ) - switch(BId) { + if ((BId = FDecl->getMemoryFunctionKind())) + switch (BId) { case Builtin::BImemcpy: case Builtin::BImemmove: case Builtin::BIstrncpy: -- cgit v1.2.3 From b7d3d0f44d9f7c8602cd7f521a9ad586ceaf6f11 Mon Sep 17 00:00:00 2001 From: Artem Dergachev Date: Wed, 19 Dec 2018 23:48:44 +0000 Subject: [analyzer] pr38668: Do not attempt to cast loaded values of non-scalar types. It is expected to have the same object (memory region) treated as if it has different types in different program points. The correct behavior for RegionStore when an object is stored as an object of type T1 but loaded as an object of type T2 is to store the object as if it has type T1 but cast it to T2 during load. Note that the cast here is some sort of a "reinterpret_cast" (even in C). For instance, if you store a float and load an integer, you won't have your float rounded to an integer; instead, you will have garbage. Admit that we cannot perform the cast as long as types we're dealing with are non-trivial (neither integers, nor pointers). Of course, if the cast is not necessary (eg, T1 == T2), we can still load the value just fine. Differential Revision: https://reviews.llvm.org/D55875 rdar://problem/45062567 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349701 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/StaticAnalyzer/Core/Store.cpp | 26 ++++++++++++++++++++------ test/Analysis/casts.c | 11 +++++++++++ test/Analysis/pointer-to-member.cpp | 7 +++---- 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/lib/StaticAnalyzer/Core/Store.cpp b/lib/StaticAnalyzer/Core/Store.cpp index 794fd84364..ac9cb4bc42 100644 --- a/lib/StaticAnalyzer/Core/Store.cpp +++ b/lib/StaticAnalyzer/Core/Store.cpp @@ -394,14 +394,28 @@ SVal StoreManager::attemptDownCast(SVal Base, QualType TargetType, return UnknownVal(); } +static bool isScalarEnoughToAttemptACast(QualType T) { + return T->isIntegralOrEnumerationType() || T->isAnyPointerType() || + T->isReferenceType(); +} + /// CastRetrievedVal - Used by subclasses of StoreManager to implement /// implicit casts that arise from loads from regions that are reinterpreted /// as another region. SVal StoreManager::CastRetrievedVal(SVal V, const TypedValueRegion *R, - QualType castTy) { - if (castTy.isNull() || V.isUnknownOrUndef()) + QualType CastTy) { + if (CastTy.isNull() || V.isUnknownOrUndef()) return V; + QualType OrigTy = R->getValueType(); + + if (!isScalarEnoughToAttemptACast(OrigTy) || + !isScalarEnoughToAttemptACast(CastTy)) { + if (OrigTy.getUnqualifiedType() == CastTy.getUnqualifiedType()) + return V; + return UnknownVal(); + } + // When retrieving symbolic pointer and expecting a non-void pointer, // wrap them into element regions of the expected type if necessary. // SValBuilder::dispatchCast() doesn't do that, but it is necessary to @@ -410,13 +424,13 @@ SVal StoreManager::CastRetrievedVal(SVal V, const TypedValueRegion *R, // We might need to do that for non-void pointers as well. // FIXME: We really need a single good function to perform casts for us // correctly every time we need it. - if (castTy->isPointerType() && !castTy->isVoidPointerType()) + if (CastTy->isPointerType() && !CastTy->isVoidPointerType()) if (const auto *SR = dyn_cast_or_null(V.getAsRegion())) if (SR->getSymbol()->getType().getCanonicalType() != - castTy.getCanonicalType()) - return loc::MemRegionVal(castRegion(SR, castTy)); + CastTy.getCanonicalType()) + return loc::MemRegionVal(castRegion(SR, CastTy)); - return svalBuilder.dispatchCast(V, castTy); + return svalBuilder.dispatchCast(V, CastTy); } SVal StoreManager::getLValueFieldOrIvar(const Decl *D, SVal Base) { diff --git a/test/Analysis/casts.c b/test/Analysis/casts.c index 45ce1940df..dd14b8a6e3 100644 --- a/test/Analysis/casts.c +++ b/test/Analysis/casts.c @@ -213,3 +213,14 @@ void no_crash_on_symsym_cast_to_long() { } #endif + +char no_crash_SymbolCast_of_float_type_aux(int *p) { + *p += 1; + return *p; +} + +void no_crash_SymbolCast_of_float_type() { + extern float x; + char (*f)() = no_crash_SymbolCast_of_float_type_aux; + f(&x); +} diff --git a/test/Analysis/pointer-to-member.cpp b/test/Analysis/pointer-to-member.cpp index 65882527d2..7f19655840 100644 --- a/test/Analysis/pointer-to-member.cpp +++ b/test/Analysis/pointer-to-member.cpp @@ -253,11 +253,10 @@ void test() { clang_analyzer_eval(&A::y); // expected-warning{{TRUE}} clang_analyzer_eval(&A::z); // expected-warning{{TRUE}} - // FIXME: These should be true. int A::*l = &A::x, A::*m = &A::y, A::*n = &A::z; - clang_analyzer_eval(l); // expected-warning{{UNKNOWN}} - clang_analyzer_eval(m); // expected-warning{{UNKNOWN}} - clang_analyzer_eval(n); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(l); // expected-warning{{TRUE}} + clang_analyzer_eval(m); // expected-warning{{TRUE}} + clang_analyzer_eval(n); // expected-warning{{TRUE}} // FIXME: These should be true as well. A a; -- cgit v1.2.3 From 72a4de819f791bd65b29e884f207bef37072d7cb Mon Sep 17 00:00:00 2001 From: Clement Courbet Date: Thu, 20 Dec 2018 09:05:15 +0000 Subject: [Sema] Better static assert diagnostics for expressions involving temporaries/casts/.... Summary: Handles expressions such as: - `std::is_const()` - `std::is_const()()`; - `std::is_same(decltype(U()), V>::value`; Reviewers: aaron.ballman, Quuxplusone Subscribers: cfe-commits, llvm-commits Differential Revision: https://reviews.llvm.org/D55552 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349729 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/PrettyPrinter.h | 5 ++++- include/clang/AST/Type.h | 8 ++----- lib/AST/TypePrinter.cpp | 31 ++++++++++++++++++++++----- lib/Sema/SemaTemplate.cpp | 6 ++++-- test/SemaCXX/static-assert-cxx17.cpp | 41 ++++++++++++++++++++++++++++++++++++ test/SemaCXX/static-assert.cpp | 15 +++++++++++++ 6 files changed, 92 insertions(+), 14 deletions(-) diff --git a/include/clang/AST/PrettyPrinter.h b/include/clang/AST/PrettyPrinter.h index 0a4dc42898..3c877f5ea1 100644 --- a/include/clang/AST/PrettyPrinter.h +++ b/include/clang/AST/PrettyPrinter.h @@ -51,7 +51,7 @@ struct PrintingPolicy { MSWChar(LO.MicrosoftExt && !LO.WChar), IncludeNewlines(true), MSVCFormatting(false), ConstantsAsWritten(false), SuppressImplicitBase(false), FullyQualifiedName(false), - RemapFilePaths(false) {} + RemapFilePaths(false), PrintCanonicalTypes(false) {} /// Adjust this printing policy for cases where it's known that we're /// printing C++ code (for instance, if AST dumping reaches a C++-only @@ -228,6 +228,9 @@ struct PrintingPolicy { /// Whether to apply -fdebug-prefix-map to any file paths. unsigned RemapFilePaths : 1; + /// Whether to print types as written or canonically. + unsigned PrintCanonicalTypes : 1; + /// When RemapFilePaths is true, this function performs the action. std::function remapPath; }; diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index 5b69570aab..cff63d0926 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -980,9 +980,7 @@ public: void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder = Twine(), - unsigned Indentation = 0) const { - print(split(), OS, Policy, PlaceHolder, Indentation); - } + unsigned Indentation = 0) const; static void print(SplitQualType split, raw_ostream &OS, const PrintingPolicy &policy, const Twine &PlaceHolder, @@ -996,9 +994,7 @@ public: unsigned Indentation = 0); void getAsStringInternal(std::string &Str, - const PrintingPolicy &Policy) const { - return getAsStringInternal(split(), Str, Policy); - } + const PrintingPolicy &Policy) const; static void getAsStringInternal(SplitQualType split, std::string &out, const PrintingPolicy &policy) { diff --git a/lib/AST/TypePrinter.cpp b/lib/AST/TypePrinter.cpp index 031b44f11e..32c75afb43 100644 --- a/lib/AST/TypePrinter.cpp +++ b/lib/AST/TypePrinter.cpp @@ -117,9 +117,7 @@ namespace { void spaceBeforePlaceHolder(raw_ostream &OS); void printTypeSpec(NamedDecl *D, raw_ostream &OS); - void printBefore(const Type *ty, Qualifiers qs, raw_ostream &OS); void printBefore(QualType T, raw_ostream &OS); - void printAfter(const Type *ty, Qualifiers qs, raw_ostream &OS); void printAfter(QualType T, raw_ostream &OS); void AppendScope(DeclContext *DC, raw_ostream &OS); void printTag(TagDecl *T, raw_ostream &OS); @@ -129,6 +127,10 @@ namespace { void print##CLASS##Before(const CLASS##Type *T, raw_ostream &OS); \ void print##CLASS##After(const CLASS##Type *T, raw_ostream &OS); #include "clang/AST/TypeNodes.def" + + private: + void printBefore(const Type *ty, Qualifiers qs, raw_ostream &OS); + void printAfter(const Type *ty, Qualifiers qs, raw_ostream &OS); }; } // namespace @@ -160,8 +162,15 @@ void TypePrinter::spaceBeforePlaceHolder(raw_ostream &OS) { OS << ' '; } +static SplitQualType splitAccordingToPolicy(QualType QT, + const PrintingPolicy &Policy) { + if (Policy.PrintCanonicalTypes) + QT = QT.getCanonicalType(); + return QT.split(); +} + void TypePrinter::print(QualType t, raw_ostream &OS, StringRef PlaceHolder) { - SplitQualType split = t.split(); + SplitQualType split = splitAccordingToPolicy(t, Policy); print(split.Ty, split.Quals, OS, PlaceHolder); } @@ -260,7 +269,7 @@ bool TypePrinter::canPrefixQualifiers(const Type *T, } void TypePrinter::printBefore(QualType T, raw_ostream &OS) { - SplitQualType Split = T.split(); + SplitQualType Split = splitAccordingToPolicy(T, Policy); // If we have cv1 T, where T is substituted for cv2 U, only print cv1 - cv2 // at this level. @@ -320,7 +329,7 @@ void TypePrinter::printBefore(const Type *T,Qualifiers Quals, raw_ostream &OS) { } void TypePrinter::printAfter(QualType t, raw_ostream &OS) { - SplitQualType split = t.split(); + SplitQualType split = splitAccordingToPolicy(t, Policy); printAfter(split.Ty, split.Quals, OS); } @@ -1815,6 +1824,12 @@ std::string QualType::getAsString(const Type *ty, Qualifiers qs, return buffer; } +void QualType::print(raw_ostream &OS, const PrintingPolicy &Policy, + const Twine &PlaceHolder, unsigned Indentation) const { + print(splitAccordingToPolicy(*this, Policy), OS, Policy, PlaceHolder, + Indentation); +} + void QualType::print(const Type *ty, Qualifiers qs, raw_ostream &OS, const PrintingPolicy &policy, const Twine &PlaceHolder, unsigned Indentation) { @@ -1824,6 +1839,12 @@ void QualType::print(const Type *ty, Qualifiers qs, TypePrinter(policy, Indentation).print(ty, qs, OS, PH); } +void QualType::getAsStringInternal(std::string &Str, + const PrintingPolicy &Policy) const { + return getAsStringInternal(splitAccordingToPolicy(*this, Policy), Str, + Policy); +} + void QualType::getAsStringInternal(const Type *ty, Qualifiers qs, std::string &buffer, const PrintingPolicy &policy) { diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index c1763528df..e0f4d2e495 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -3122,8 +3122,10 @@ Sema::findFailedBooleanCondition(Expr *Cond) { std::string Description; { llvm::raw_string_ostream Out(Description); - FailedBooleanConditionPrinterHelper Helper(getPrintingPolicy()); - FailedCond->printPretty(Out, &Helper, getPrintingPolicy()); + PrintingPolicy Policy = getPrintingPolicy(); + Policy.PrintCanonicalTypes = true; + FailedBooleanConditionPrinterHelper Helper(Policy); + FailedCond->printPretty(Out, &Helper, Policy, 0, "\n", nullptr); } return { FailedCond, Description }; } diff --git a/test/SemaCXX/static-assert-cxx17.cpp b/test/SemaCXX/static-assert-cxx17.cpp index 67b3541bea..7fff59e7f8 100644 --- a/test/SemaCXX/static-assert-cxx17.cpp +++ b/test/SemaCXX/static-assert-cxx17.cpp @@ -54,3 +54,44 @@ void foo5() { } template void foo5(); // expected-note@-1{{in instantiation of function template specialization 'foo5' requested here}} + +struct ExampleTypes { + explicit ExampleTypes(int); + using T = int; + using U = float; +}; + +template +struct X { + int i = 0; + int j = 0; + constexpr operator bool() const { return false; } +}; + +template +void foo6() { + static_assert(X()); + // expected-error@-1{{static_assert failed due to requirement 'X()'}} + static_assert(X{}); + // expected-error@-1{{static_assert failed due to requirement 'X{}'}} + static_assert(X{1, 2}); + // expected-error@-1{{static_assert failed due to requirement 'X{1, 2}'}} + static_assert(X({1, 2})); + // expected-error@-1{{static_assert failed due to requirement 'X({1, 2})'}} + static_assert(typename T::T{0}); + // expected-error@-1{{static_assert failed due to requirement 'int{0}'}} + static_assert(typename T::T(0)); + // expected-error@-1{{static_assert failed due to requirement 'int(0)'}} + static_assert(sizeof(X) == 0); + // expected-error@-1{{static_assert failed due to requirement 'sizeof(X) == 0'}} + static_assert((const X *)nullptr); + // expected-error@-1{{static_assert failed due to requirement '(const X *)nullptr'}} + static_assert(static_cast *>(nullptr)); + // expected-error@-1{{static_assert failed due to requirement 'static_cast *>(nullptr)'}} + static_assert((const X[]){} == nullptr); + // expected-error@-1{{static_assert failed due to requirement '(X const[0]){} == nullptr'}} + static_assert(sizeof(X().X::~X())>) == 0); + // expected-error@-1{{static_assert failed due to requirement 'sizeof(X) == 0'}} +} +template void foo6(); +// expected-note@-1{{in instantiation of function template specialization 'foo6' requested here}} diff --git a/test/SemaCXX/static-assert.cpp b/test/SemaCXX/static-assert.cpp index b43d56a922..a21cc874b5 100644 --- a/test/SemaCXX/static-assert.cpp +++ b/test/SemaCXX/static-assert.cpp @@ -76,6 +76,8 @@ struct integral_constant { static const Tp value = v; typedef Tp value_type; typedef integral_constant type; + constexpr operator value_type() const noexcept { return value; } + constexpr value_type operator()() const noexcept { return value; } }; template @@ -103,6 +105,7 @@ struct is_same { } // namespace std struct ExampleTypes { + explicit ExampleTypes(int); using T = int; using U = float; }; @@ -119,6 +122,18 @@ static_assert(std::is_const::value == false, "message"); // expected-error@-1{{static_assert failed due to requirement 'std::is_const::value == false' "message"}} static_assert(!(std::is_const::value == true), "message"); // expected-error@-1{{static_assert failed due to requirement '!(std::is_const::value == true)' "message"}} +static_assert(std::is_const(), "message"); +// expected-error@-1{{static_assert failed due to requirement 'std::is_const()' "message"}} +static_assert(!(std::is_const()()), "message"); +// expected-error@-1{{static_assert failed due to requirement '!(std::is_const()())' "message"}} +static_assert(std::is_same()), int>::value, "message"); +// expected-error@-1{{static_assert failed due to requirement 'std::is_same, int>::value' "message"}} +static_assert(std::is_const::value, "message"); +// expected-error@-1{{static_assert failed due to requirement 'std::is_const::value' "message"}} +static_assert(std::is_const::value, "message"); +// expected-error@-1{{static_assert failed due to requirement 'std::is_const::value' "message"}} +static_assert(std::is_const::value, "message"); +// expected-error@-1{{static_assert failed due to requirement 'std::is_const::value' "message"}} struct BI_tag {}; struct RAI_tag : BI_tag {}; -- cgit v1.2.3 From 7853d35ba79f9226ef77d5ca81a5bca85551a7ac Mon Sep 17 00:00:00 2001 From: Simon Pilgrim Date: Thu, 20 Dec 2018 11:53:45 +0000 Subject: [X86][SSE] Auto upgrade PADDS/PSUBS intrinsics to SADD_SAT/SSUB_SAT generic intrinsics (clang) This emits SADD_SAT/SSUB_SAT generic intrinsics for the SSE signed saturated math intrinsics. LLVM counterpart: https://reviews.llvm.org/D55894 Differential Revision: https://reviews.llvm.org/D55890 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349743 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGBuiltin.cpp | 27 +++++++++++++++++++++------ test/CodeGen/avx2-builtins.c | 8 ++++---- test/CodeGen/avx512bw-builtins.c | 24 ++++++++++++------------ test/CodeGen/avx512vlbw-builtins.c | 32 ++++++++++++++++---------------- test/CodeGen/sse2-builtins.c | 8 ++++---- 5 files changed, 57 insertions(+), 42 deletions(-) diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp index 486e7d8ec3..d38e6b0262 100644 --- a/lib/CodeGen/CGBuiltin.cpp +++ b/lib/CodeGen/CGBuiltin.cpp @@ -9487,12 +9487,13 @@ static Value *EmitX86SExtMask(CodeGenFunction &CGF, Value *Op, return CGF.Builder.CreateSExt(Mask, DstTy, "vpmovm2"); } -// Emit addition or subtraction with unsigned saturation. -// TODO: Handle signed intrinsics. +// Emit addition or subtraction with signed/unsigned saturation. static Value *EmitX86AddSubSatExpr(CodeGenFunction &CGF, - SmallVectorImpl &Ops, + ArrayRef Ops, bool IsSigned, bool IsAddition) { - Intrinsic::ID IID = IsAddition ? Intrinsic::uadd_sat : Intrinsic::usub_sat; + Intrinsic::ID IID = + IsSigned ? (IsAddition ? Intrinsic::sadd_sat : Intrinsic::ssub_sat) + : (IsAddition ? Intrinsic::uadd_sat : Intrinsic::usub_sat); llvm::Function *F = CGF.CGM.getIntrinsic(IID, Ops[0]->getType()); return CGF.Builder.CreateCall(F, {Ops[0], Ops[1]}); } @@ -11359,20 +11360,34 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID, Load->setVolatile(true); return Load; } + case X86::BI__builtin_ia32_paddsb512: + case X86::BI__builtin_ia32_paddsw512: + case X86::BI__builtin_ia32_paddsb256: + case X86::BI__builtin_ia32_paddsw256: + case X86::BI__builtin_ia32_paddsb128: + case X86::BI__builtin_ia32_paddsw128: + return EmitX86AddSubSatExpr(*this, Ops, true, true); case X86::BI__builtin_ia32_paddusb512: case X86::BI__builtin_ia32_paddusw512: case X86::BI__builtin_ia32_paddusb256: case X86::BI__builtin_ia32_paddusw256: case X86::BI__builtin_ia32_paddusb128: case X86::BI__builtin_ia32_paddusw128: - return EmitX86AddSubSatExpr(*this, Ops, true /* IsAddition */); + return EmitX86AddSubSatExpr(*this, Ops, false, true); + case X86::BI__builtin_ia32_psubsb512: + case X86::BI__builtin_ia32_psubsw512: + case X86::BI__builtin_ia32_psubsb256: + case X86::BI__builtin_ia32_psubsw256: + case X86::BI__builtin_ia32_psubsb128: + case X86::BI__builtin_ia32_psubsw128: + return EmitX86AddSubSatExpr(*this, Ops, true, false); case X86::BI__builtin_ia32_psubusb512: case X86::BI__builtin_ia32_psubusw512: case X86::BI__builtin_ia32_psubusb256: case X86::BI__builtin_ia32_psubusw256: case X86::BI__builtin_ia32_psubusb128: case X86::BI__builtin_ia32_psubusw128: - return EmitX86AddSubSatExpr(*this, Ops, false /* IsAddition */); + return EmitX86AddSubSatExpr(*this, Ops, false, false); } } diff --git a/test/CodeGen/avx2-builtins.c b/test/CodeGen/avx2-builtins.c index c943796c12..89225e69aa 100644 --- a/test/CodeGen/avx2-builtins.c +++ b/test/CodeGen/avx2-builtins.c @@ -56,13 +56,13 @@ __m256i test_mm256_add_epi64(__m256i a, __m256i b) { __m256i test_mm256_adds_epi8(__m256i a, __m256i b) { // CHECK-LABEL: test_mm256_adds_epi8 - // CHECK: call <32 x i8> @llvm.x86.avx2.padds.b(<32 x i8> %{{.*}}, <32 x i8> %{{.*}}) + // CHECK: call <32 x i8> @llvm.sadd.sat.v32i8(<32 x i8> %{{.*}}, <32 x i8> %{{.*}}) return _mm256_adds_epi8(a, b); } __m256i test_mm256_adds_epi16(__m256i a, __m256i b) { // CHECK-LABEL: test_mm256_adds_epi16 - // CHECK: call <16 x i16> @llvm.x86.avx2.padds.w(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}) + // CHECK: call <16 x i16> @llvm.sadd.sat.v16i16(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}) return _mm256_adds_epi16(a, b); } @@ -1171,13 +1171,13 @@ __m256i test_mm256_sub_epi64(__m256i a, __m256i b) { __m256i test_mm256_subs_epi8(__m256i a, __m256i b) { // CHECK-LABEL: test_mm256_subs_epi8 - // CHECK: call <32 x i8> @llvm.x86.avx2.psubs.b(<32 x i8> %{{.*}}, <32 x i8> %{{.*}}) + // CHECK: call <32 x i8> @llvm.ssub.sat.v32i8(<32 x i8> %{{.*}}, <32 x i8> %{{.*}}) return _mm256_subs_epi8(a, b); } __m256i test_mm256_subs_epi16(__m256i a, __m256i b) { // CHECK-LABEL: test_mm256_subs_epi16 - // CHECK: call <16 x i16> @llvm.x86.avx2.psubs.w(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}) + // CHECK: call <16 x i16> @llvm.ssub.sat.v16i16(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}) return _mm256_subs_epi16(a, b); } diff --git a/test/CodeGen/avx512bw-builtins.c b/test/CodeGen/avx512bw-builtins.c index 64204bf2e8..aa6b45325c 100644 --- a/test/CodeGen/avx512bw-builtins.c +++ b/test/CodeGen/avx512bw-builtins.c @@ -992,35 +992,35 @@ __m512i test_mm512_maskz_packus_epi16(__mmask64 __M, __m512i __A, __m512i __B) { } __m512i test_mm512_adds_epi8(__m512i __A, __m512i __B) { // CHECK-LABEL: @test_mm512_adds_epi8 - // CHECK: @llvm.x86.avx512.padds.b.512 + // CHECK: @llvm.sadd.sat.v64i8 return _mm512_adds_epi8(__A,__B); } __m512i test_mm512_mask_adds_epi8(__m512i __W, __mmask64 __U, __m512i __A, __m512i __B) { // CHECK-LABEL: @test_mm512_mask_adds_epi8 - // CHECK: @llvm.x86.avx512.padds.b.512 + // CHECK: @llvm.sadd.sat.v64i8 // CHECK: select <64 x i1> %{{.*}}, <64 x i8> %{{.*}}, <64 x i8> %{{.*}} return _mm512_mask_adds_epi8(__W,__U,__A,__B); } __m512i test_mm512_maskz_adds_epi8(__mmask64 __U, __m512i __A, __m512i __B) { // CHECK-LABEL: @test_mm512_maskz_adds_epi8 - // CHECK: @llvm.x86.avx512.padds.b.512 + // CHECK: @llvm.sadd.sat.v64i8 // CHECK: select <64 x i1> %{{.*}}, <64 x i8> %{{.*}}, <64 x i8> %{{.*}} return _mm512_maskz_adds_epi8(__U,__A,__B); } __m512i test_mm512_adds_epi16(__m512i __A, __m512i __B) { // CHECK-LABEL: @test_mm512_adds_epi16 - // CHECK: @llvm.x86.avx512.padds.w.512 + // CHECK: @llvm.sadd.sat.v32i16 return _mm512_adds_epi16(__A,__B); } __m512i test_mm512_mask_adds_epi16(__m512i __W, __mmask32 __U, __m512i __A, __m512i __B) { // CHECK-LABEL: @test_mm512_mask_adds_epi16 - // CHECK: @llvm.x86.avx512.padds.w.512 + // CHECK: @llvm.sadd.sat.v32i16 // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}} return _mm512_mask_adds_epi16(__W,__U,__A,__B); } __m512i test_mm512_maskz_adds_epi16(__mmask32 __U, __m512i __A, __m512i __B) { // CHECK-LABEL: @test_mm512_maskz_adds_epi16 - // CHECK: @llvm.x86.avx512.padds.w.512 + // CHECK: @llvm.sadd.sat.v32i16 // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}} return _mm512_maskz_adds_epi16(__U,__A,__B); } @@ -1315,35 +1315,35 @@ __m512i test_mm512_maskz_shuffle_epi8(__mmask64 __U, __m512i __A, __m512i __B) { } __m512i test_mm512_subs_epi8(__m512i __A, __m512i __B) { // CHECK-LABEL: @test_mm512_subs_epi8 - // CHECK: @llvm.x86.avx512.psubs.b.512 + // CHECK: @llvm.ssub.sat.v64i8 return _mm512_subs_epi8(__A,__B); } __m512i test_mm512_mask_subs_epi8(__m512i __W, __mmask64 __U, __m512i __A, __m512i __B) { // CHECK-LABEL: @test_mm512_mask_subs_epi8 - // CHECK: @llvm.x86.avx512.psubs.b.512 + // CHECK: @llvm.ssub.sat.v64i8 // CHECK: select <64 x i1> %{{.*}}, <64 x i8> %{{.*}}, <64 x i8> %{{.*}} return _mm512_mask_subs_epi8(__W,__U,__A,__B); } __m512i test_mm512_maskz_subs_epi8(__mmask64 __U, __m512i __A, __m512i __B) { // CHECK-LABEL: @test_mm512_maskz_subs_epi8 - // CHECK: @llvm.x86.avx512.psubs.b.512 + // CHECK: @llvm.ssub.sat.v64i8 // CHECK: select <64 x i1> %{{.*}}, <64 x i8> %{{.*}}, <64 x i8> %{{.*}} return _mm512_maskz_subs_epi8(__U,__A,__B); } __m512i test_mm512_subs_epi16(__m512i __A, __m512i __B) { // CHECK-LABEL: @test_mm512_subs_epi16 - // CHECK: @llvm.x86.avx512.psubs.w.512 + // CHECK: @llvm.ssub.sat.v32i16 return _mm512_subs_epi16(__A,__B); } __m512i test_mm512_mask_subs_epi16(__m512i __W, __mmask32 __U, __m512i __A, __m512i __B) { // CHECK-LABEL: @test_mm512_mask_subs_epi16 - // CHECK: @llvm.x86.avx512.psubs.w.512 + // CHECK: @llvm.ssub.sat.v32i16 // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}} return _mm512_mask_subs_epi16(__W,__U,__A,__B); } __m512i test_mm512_maskz_subs_epi16(__mmask32 __U, __m512i __A, __m512i __B) { // CHECK-LABEL: @test_mm512_maskz_subs_epi16 - // CHECK: @llvm.x86.avx512.psubs.w.512 + // CHECK: @llvm.ssub.sat.v32i16 // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}} return _mm512_maskz_subs_epi16(__U,__A,__B); } diff --git a/test/CodeGen/avx512vlbw-builtins.c b/test/CodeGen/avx512vlbw-builtins.c index fb42ffc392..1037617eab 100644 --- a/test/CodeGen/avx512vlbw-builtins.c +++ b/test/CodeGen/avx512vlbw-builtins.c @@ -1075,49 +1075,49 @@ __m256i test_mm256_mask_packus_epi16(__m256i __W, __mmask32 __M, __m256i __A, __ __m128i test_mm_mask_adds_epi8(__m128i __W, __mmask16 __U, __m128i __A, __m128i __B) { // CHECK-LABEL: @test_mm_mask_adds_epi8 - // CHECK: @llvm.x86.sse2.padds.b + // CHECK: @llvm.sadd.sat.v16i8 // CHECK: select <16 x i1> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}} return _mm_mask_adds_epi8(__W,__U,__A,__B); } __m128i test_mm_maskz_adds_epi8(__mmask16 __U, __m128i __A, __m128i __B) { // CHECK-LABEL: @test_mm_maskz_adds_epi8 - // CHECK: @llvm.x86.sse2.padds.b + // CHECK: @llvm.sadd.sat.v16i8 // CHECK: select <16 x i1> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}} return _mm_maskz_adds_epi8(__U,__A,__B); } __m256i test_mm256_mask_adds_epi8(__m256i __W, __mmask32 __U, __m256i __A, __m256i __B) { // CHECK-LABEL: @test_mm256_mask_adds_epi8 - // CHECK: @llvm.x86.avx2.padds.b + // CHECK: @llvm.sadd.sat.v32i8 // CHECK: select <32 x i1> %{{.*}}, <32 x i8> %{{.*}}, <32 x i8> %{{.*}} return _mm256_mask_adds_epi8(__W,__U,__A,__B); } __m256i test_mm256_maskz_adds_epi8(__mmask32 __U, __m256i __A, __m256i __B) { // CHECK-LABEL: @test_mm256_maskz_adds_epi8 - // CHECK: @llvm.x86.avx2.padds.b + // CHECK: @llvm.sadd.sat.v32i8 // CHECK: select <32 x i1> %{{.*}}, <32 x i8> %{{.*}}, <32 x i8> %{{.*}} return _mm256_maskz_adds_epi8(__U,__A,__B); } __m128i test_mm_mask_adds_epi16(__m128i __W, __mmask8 __U, __m128i __A, __m128i __B) { // CHECK-LABEL: @test_mm_mask_adds_epi16 - // CHECK: @llvm.x86.sse2.padds.w + // CHECK: @llvm.sadd.sat.v8i16 // CHECK: select <8 x i1> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}} return _mm_mask_adds_epi16(__W,__U,__A,__B); } __m128i test_mm_maskz_adds_epi16(__mmask8 __U, __m128i __A, __m128i __B) { // CHECK-LABEL: @test_mm_maskz_adds_epi16 - // CHECK: @llvm.x86.sse2.padds.w + // CHECK: @llvm.sadd.sat.v8i16 // CHECK: select <8 x i1> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}} return _mm_maskz_adds_epi16(__U,__A,__B); } __m256i test_mm256_mask_adds_epi16(__m256i __W, __mmask16 __U, __m256i __A, __m256i __B) { // CHECK-LABEL: @test_mm256_mask_adds_epi16 - // CHECK: @llvm.x86.avx2.padds.w + // CHECK: @llvm.sadd.sat.v16i16 // CHECK: select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}} return _mm256_mask_adds_epi16(__W,__U,__A,__B); } __m256i test_mm256_maskz_adds_epi16(__mmask16 __U, __m256i __A, __m256i __B) { // CHECK-LABEL: @test_mm256_maskz_adds_epi16 - // CHECK: @llvm.x86.avx2.padds.w + // CHECK: @llvm.sadd.sat.v16i16 // CHECK: select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}} return _mm256_maskz_adds_epi16(__U,__A,__B); } @@ -1527,49 +1527,49 @@ __m256i test_mm256_maskz_shuffle_epi8(__mmask32 __U, __m256i __A, __m256i __B) { } __m128i test_mm_mask_subs_epi8(__m128i __W, __mmask16 __U, __m128i __A, __m128i __B) { // CHECK-LABEL: @test_mm_mask_subs_epi8 - // CHECK: @llvm.x86.sse2.psubs.b + // CHECK: @llvm.ssub.sat.v16i8 // CHECK: select <16 x i1> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}} return _mm_mask_subs_epi8(__W,__U,__A,__B); } __m128i test_mm_maskz_subs_epi8(__mmask16 __U, __m128i __A, __m128i __B) { // CHECK-LABEL: @test_mm_maskz_subs_epi8 - // CHECK: @llvm.x86.sse2.psubs.b + // CHECK: @llvm.ssub.sat.v16i8 // CHECK: select <16 x i1> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}} return _mm_maskz_subs_epi8(__U,__A,__B); } __m256i test_mm256_mask_subs_epi8(__m256i __W, __mmask32 __U, __m256i __A, __m256i __B) { // CHECK-LABEL: @test_mm256_mask_subs_epi8 - // CHECK: @llvm.x86.avx2.psubs.b + // CHECK: @llvm.ssub.sat.v32i8 // CHECK: select <32 x i1> %{{.*}}, <32 x i8> %{{.*}}, <32 x i8> %{{.*}} return _mm256_mask_subs_epi8(__W,__U,__A,__B); } __m256i test_mm256_maskz_subs_epi8(__mmask32 __U, __m256i __A, __m256i __B) { // CHECK-LABEL: @test_mm256_maskz_subs_epi8 - // CHECK: @llvm.x86.avx2.psubs.b + // CHECK: @llvm.ssub.sat.v32i8 // CHECK: select <32 x i1> %{{.*}}, <32 x i8> %{{.*}}, <32 x i8> %{{.*}} return _mm256_maskz_subs_epi8(__U,__A,__B); } __m128i test_mm_mask_subs_epi16(__m128i __W, __mmask8 __U, __m128i __A, __m128i __B) { // CHECK-LABEL: @test_mm_mask_subs_epi16 - // CHECK: @llvm.x86.sse2.psubs.w + // CHECK: @llvm.ssub.sat.v8i16 // CHECK: select <8 x i1> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}} return _mm_mask_subs_epi16(__W,__U,__A,__B); } __m128i test_mm_maskz_subs_epi16(__mmask8 __U, __m128i __A, __m128i __B) { // CHECK-LABEL: @test_mm_maskz_subs_epi16 - // CHECK: @llvm.x86.sse2.psubs.w + // CHECK: @llvm.ssub.sat.v8i16 // CHECK: select <8 x i1> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}} return _mm_maskz_subs_epi16(__U,__A,__B); } __m256i test_mm256_mask_subs_epi16(__m256i __W, __mmask16 __U, __m256i __A, __m256i __B) { // CHECK-LABEL: @test_mm256_mask_subs_epi16 - // CHECK: @llvm.x86.avx2.psubs.w + // CHECK: @llvm.ssub.sat.v16i16 // CHECK: select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}} return _mm256_mask_subs_epi16(__W,__U,__A,__B); } __m256i test_mm256_maskz_subs_epi16(__mmask16 __U, __m256i __A, __m256i __B) { // CHECK-LABEL: @test_mm256_maskz_subs_epi16 - // CHECK: @llvm.x86.avx2.psubs.w + // CHECK: @llvm.ssub.sat.v16i16 // CHECK: select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}} return _mm256_maskz_subs_epi16(__U,__A,__B); } diff --git a/test/CodeGen/sse2-builtins.c b/test/CodeGen/sse2-builtins.c index 942e86b28f..029340abd9 100644 --- a/test/CodeGen/sse2-builtins.c +++ b/test/CodeGen/sse2-builtins.c @@ -47,13 +47,13 @@ __m128d test_mm_add_sd(__m128d A, __m128d B) { __m128i test_mm_adds_epi8(__m128i A, __m128i B) { // CHECK-LABEL: test_mm_adds_epi8 - // CHECK: call <16 x i8> @llvm.x86.sse2.padds.b(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK: call <16 x i8> @llvm.sadd.sat.v16i8(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) return _mm_adds_epi8(A, B); } __m128i test_mm_adds_epi16(__m128i A, __m128i B) { // CHECK-LABEL: test_mm_adds_epi16 - // CHECK: call <8 x i16> @llvm.x86.sse2.padds.w(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK: call <8 x i16> @llvm.sadd.sat.v8i16(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) return _mm_adds_epi16(A, B); } @@ -1460,13 +1460,13 @@ __m128d test_mm_sub_sd(__m128d A, __m128d B) { __m128i test_mm_subs_epi8(__m128i A, __m128i B) { // CHECK-LABEL: test_mm_subs_epi8 - // CHECK: call <16 x i8> @llvm.x86.sse2.psubs.b(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK: call <16 x i8> @llvm.ssub.sat.v16i8(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) return _mm_subs_epi8(A, B); } __m128i test_mm_subs_epi16(__m128i A, __m128i B) { // CHECK-LABEL: test_mm_subs_epi16 - // CHECK: call <8 x i16> @llvm.x86.sse2.psubs.w(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK: call <8 x i16> @llvm.ssub.sat.v8i16(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) return _mm_subs_epi16(A, B); } -- cgit v1.2.3 From 2bf3cc07f09341d5cb995efe8d84010ca3228253 Mon Sep 17 00:00:00 2001 From: Ulrich Weigand Date: Thu, 20 Dec 2018 13:09:09 +0000 Subject: [SystemZ] Fix wrong codegen caused by typos in vecintrin.h The following two bugs in SystemZ high-level vector intrinsics are fixes by this patch: - The float case of vec_insert_and_zero should generate a VLLEZF pattern, but currently erroneously generates VLLEZLF. - The float and double versions of vec_orc erroneously generate and-with-complement instead of or-with-complement. The patch also fixes a couple of typos in the associated test. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349751 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Headers/vecintrin.h | 6 +++--- test/CodeGen/builtins-systemz-zvector2.c | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/Headers/vecintrin.h b/lib/Headers/vecintrin.h index f7061e8894..e627389838 100644 --- a/lib/Headers/vecintrin.h +++ b/lib/Headers/vecintrin.h @@ -381,7 +381,7 @@ vec_insert_and_zero(const unsigned long long *__ptr) { static inline __ATTRS_o_ai vector float vec_insert_and_zero(const float *__ptr) { vector float __vec = (vector float)0; - __vec[0] = *__ptr; + __vec[1] = *__ptr; return __vec; } #endif @@ -5942,13 +5942,13 @@ vec_orc(vector unsigned long long __a, vector unsigned long long __b) { static inline __ATTRS_o_ai vector float vec_orc(vector float __a, vector float __b) { - return (vector float)((vector unsigned int)__a & + return (vector float)((vector unsigned int)__a | ~(vector unsigned int)__b); } static inline __ATTRS_o_ai vector double vec_orc(vector double __a, vector double __b) { - return (vector double)((vector unsigned long long)__a & + return (vector double)((vector unsigned long long)__a | ~(vector unsigned long long)__b); } #endif diff --git a/test/CodeGen/builtins-systemz-zvector2.c b/test/CodeGen/builtins-systemz-zvector2.c index d9607b3a87..acdaebd7a5 100644 --- a/test/CodeGen/builtins-systemz-zvector2.c +++ b/test/CodeGen/builtins-systemz-zvector2.c @@ -65,9 +65,9 @@ void test_core(void) { d = vec_extract(vd, idx); // CHECK: extractelement <2 x double> %{{.*}}, i32 %{{.*}} - vf = vec_insert(d, vf, idx); + vf = vec_insert(f, vf, idx); // CHECK: insertelement <4 x float> %{{.*}}, float %{{.*}}, i32 %{{.*}} - vd = vec_insert(f, vd, idx); + vd = vec_insert(d, vd, idx); // CHECK: insertelement <2 x double> %{{.*}}, double %{{.*}}, i32 %{{.*}} vf = vec_promote(f, idx); @@ -76,7 +76,7 @@ void test_core(void) { // CHECK: insertelement <2 x double> undef, double %{{.*}}, i32 %{{.*}} vf = vec_insert_and_zero(cptrf); - // CHECK: insertelement <4 x float> , float %{{.*}}, i32 0 + // CHECK: insertelement <4 x float> , float %{{.*}}, i32 1 vd = vec_insert_and_zero(cptrd); // CHECK: insertelement <2 x double> , double %{{.*}}, i32 0 @@ -227,8 +227,8 @@ void test_compare(void) { idx = vec_all_lt(vd, vd); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchdbs(<2 x double> %{{.*}}, <2 x double> %{{.*}}) - idx = vec_all_nge(vd, vd); - // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchedbs(<2 x double> %{{.*}}, <2 x double> %{{.*}}) + idx = vec_all_nge(vf, vf); + // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfchesbs(<4 x float> %{{.*}}, <4 x float> %{{.*}}) idx = vec_all_nge(vd, vd); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchedbs(<2 x double> %{{.*}}, <2 x double> %{{.*}}) -- cgit v1.2.3 From 2c99c22ca96b05c9590d1917675e11258927e692 Mon Sep 17 00:00:00 2001 From: Michal Gorny Date: Thu, 20 Dec 2018 13:09:30 +0000 Subject: Replace getOS() == llvm::Triple::*BSD with isOS*BSD() [NFCI] Replace multiple comparisons of getOS() value with FreeBSD, NetBSD, OpenBSD and DragonFly with matching isOS*BSD() methods. This should improve the consistency of coding style without changing the behavior. Direct getOS() comparisons were left whenever used in switch or switch- like context. Differential Revision: https://reviews.llvm.org/D55916 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349752 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Basic/Targets/AArch64.cpp | 4 ++-- lib/Basic/Targets/ARM.cpp | 12 +++++------ lib/Basic/Targets/Mips.h | 8 ++++---- lib/Basic/Targets/PPC.cpp | 4 ++-- lib/Basic/Targets/PPC.h | 2 +- lib/Basic/Targets/Sparc.h | 2 +- lib/Driver/ToolChains/Arch/Mips.cpp | 4 ++-- lib/Driver/ToolChains/Clang.cpp | 10 ++++----- lib/Driver/ToolChains/CommonArgs.cpp | 24 +++++++++++----------- lib/Driver/ToolChains/Gnu.cpp | 2 +- lib/Driver/XRayArgs.cpp | 6 +++--- .../Checkers/CheckSecuritySyntaxOnly.cpp | 8 ++++---- 12 files changed, 43 insertions(+), 43 deletions(-) diff --git a/lib/Basic/Targets/AArch64.cpp b/lib/Basic/Targets/AArch64.cpp index 376cba6e45..62919a02dc 100644 --- a/lib/Basic/Targets/AArch64.cpp +++ b/lib/Basic/Targets/AArch64.cpp @@ -37,11 +37,11 @@ const Builtin::Info AArch64TargetInfo::BuiltinInfo[] = { AArch64TargetInfo::AArch64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) : TargetInfo(Triple), ABI("aapcs") { - if (getTriple().getOS() == llvm::Triple::OpenBSD) { + if (getTriple().isOSOpenBSD()) { Int64Type = SignedLongLong; IntMaxType = SignedLongLong; } else { - if (!getTriple().isOSDarwin() && getTriple().getOS() != llvm::Triple::NetBSD) + if (!getTriple().isOSDarwin() && !getTriple().isOSNetBSD()) WCharType = UnsignedInt; Int64Type = SignedLong; diff --git a/lib/Basic/Targets/ARM.cpp b/lib/Basic/Targets/ARM.cpp index cb202eac98..16644ace10 100644 --- a/lib/Basic/Targets/ARM.cpp +++ b/lib/Basic/Targets/ARM.cpp @@ -28,8 +28,8 @@ void ARMTargetInfo::setABIAAPCS() { DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 64; const llvm::Triple &T = getTriple(); - bool IsNetBSD = T.getOS() == llvm::Triple::NetBSD; - bool IsOpenBSD = T.getOS() == llvm::Triple::OpenBSD; + bool IsNetBSD = T.isOSNetBSD(); + bool IsOpenBSD = T.isOSOpenBSD(); if (!T.isOSWindows() && !IsNetBSD && !IsOpenBSD) WCharType = UnsignedInt; @@ -217,8 +217,8 @@ ARMTargetInfo::ARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) : TargetInfo(Triple), FPMath(FP_Default), IsAAPCS(true), LDREX(0), HW_FP(0) { - bool IsOpenBSD = Triple.getOS() == llvm::Triple::OpenBSD; - bool IsNetBSD = Triple.getOS() == llvm::Triple::NetBSD; + bool IsOpenBSD = Triple.isOSOpenBSD(); + bool IsNetBSD = Triple.isOSNetBSD(); // FIXME: the isOSBinFormatMachO is a workaround for identifying a Darwin-like // environment where size_t is `unsigned long` rather than `unsigned int` @@ -282,9 +282,9 @@ ARMTargetInfo::ARMTargetInfo(const llvm::Triple &Triple, setABI("apcs-gnu"); break; default: - if (Triple.getOS() == llvm::Triple::NetBSD) + if (IsNetBSD) setABI("apcs-gnu"); - else if (Triple.getOS() == llvm::Triple::OpenBSD) + else if (IsOpenBSD) setABI("aapcs-linux"); else setABI("aapcs"); diff --git a/lib/Basic/Targets/Mips.h b/lib/Basic/Targets/Mips.h index f20780915d..d49f49888b 100644 --- a/lib/Basic/Targets/Mips.h +++ b/lib/Basic/Targets/Mips.h @@ -78,8 +78,8 @@ public: CPU = ABI == "o32" ? "mips32r2" : "mips64r2"; - CanUseBSDABICalls = Triple.getOS() == llvm::Triple::FreeBSD || - Triple.getOS() == llvm::Triple::OpenBSD; + CanUseBSDABICalls = Triple.isOSFreeBSD() || + Triple.isOSOpenBSD(); } bool isIEEE754_2008Default() const { @@ -132,7 +132,7 @@ public: void setN32N64ABITypes() { LongDoubleWidth = LongDoubleAlign = 128; LongDoubleFormat = &llvm::APFloat::IEEEquad(); - if (getTriple().getOS() == llvm::Triple::FreeBSD) { + if (getTriple().isOSFreeBSD()) { LongDoubleWidth = LongDoubleAlign = 64; LongDoubleFormat = &llvm::APFloat::IEEEdouble(); } @@ -142,7 +142,7 @@ public: void setN64ABITypes() { setN32N64ABITypes(); - if (getTriple().getOS() == llvm::Triple::OpenBSD) { + if (getTriple().isOSOpenBSD()) { Int64Type = SignedLongLong; } else { Int64Type = SignedLong; diff --git a/lib/Basic/Targets/PPC.cpp b/lib/Basic/Targets/PPC.cpp index db54fcff0d..6cfbed1713 100644 --- a/lib/Basic/Targets/PPC.cpp +++ b/lib/Basic/Targets/PPC.cpp @@ -83,8 +83,8 @@ void PPCTargetInfo::getTargetDefines(const LangOptions &Opts, if (getTriple().getArch() == llvm::Triple::ppc64le) { Builder.defineMacro("_LITTLE_ENDIAN"); } else { - if (getTriple().getOS() != llvm::Triple::NetBSD && - getTriple().getOS() != llvm::Triple::OpenBSD) + if (!getTriple().isOSNetBSD() && + !getTriple().isOSOpenBSD()) Builder.defineMacro("_BIG_ENDIAN"); } diff --git a/lib/Basic/Targets/PPC.h b/lib/Basic/Targets/PPC.h index 30f13c919c..058970a0e0 100644 --- a/lib/Basic/Targets/PPC.h +++ b/lib/Basic/Targets/PPC.h @@ -331,7 +331,7 @@ public: break; } - if (getTriple().getOS() == llvm::Triple::FreeBSD) { + if (getTriple().isOSFreeBSD()) { LongDoubleWidth = LongDoubleAlign = 64; LongDoubleFormat = &llvm::APFloat::IEEEdouble(); } diff --git a/lib/Basic/Targets/Sparc.h b/lib/Basic/Targets/Sparc.h index af2189f214..5ae305bffb 100644 --- a/lib/Basic/Targets/Sparc.h +++ b/lib/Basic/Targets/Sparc.h @@ -199,7 +199,7 @@ public: LongWidth = LongAlign = PointerWidth = PointerAlign = 64; // OpenBSD uses long long for int64_t and intmax_t. - if (getTriple().getOS() == llvm::Triple::OpenBSD) + if (getTriple().isOSOpenBSD()) IntMaxType = SignedLongLong; else IntMaxType = SignedLong; diff --git a/lib/Driver/ToolChains/Arch/Mips.cpp b/lib/Driver/ToolChains/Arch/Mips.cpp index a1591039db..e10a5e1c77 100644 --- a/lib/Driver/ToolChains/Arch/Mips.cpp +++ b/lib/Driver/ToolChains/Arch/Mips.cpp @@ -47,12 +47,12 @@ void mips::getMipsCPUAndABI(const ArgList &Args, const llvm::Triple &Triple, } // MIPS3 is the default for mips64*-unknown-openbsd. - if (Triple.getOS() == llvm::Triple::OpenBSD) + if (Triple.isOSOpenBSD()) DefMips64CPU = "mips3"; // MIPS2 is the default for mips(el)?-unknown-freebsd. // MIPS3 is the default for mips64(el)?-unknown-freebsd. - if (Triple.getOS() == llvm::Triple::FreeBSD) { + if (Triple.isOSFreeBSD()) { DefMips32CPU = "mips2"; DefMips64CPU = "mips3"; } diff --git a/lib/Driver/ToolChains/Clang.cpp b/lib/Driver/ToolChains/Clang.cpp index 1efaf0b584..d377b3c032 100644 --- a/lib/Driver/ToolChains/Clang.cpp +++ b/lib/Driver/ToolChains/Clang.cpp @@ -526,7 +526,7 @@ static bool useFramePointerForTargetByDefault(const ArgList &Args, break; } - if (Triple.getOS() == llvm::Triple::NetBSD) { + if (Triple.isOSNetBSD()) { return !areOptimizationsEnabled(Args); } @@ -2848,8 +2848,8 @@ static void RenderCharacterOptions(const ArgList &Args, const llvm::Triple &T, } else { bool IsARM = T.isARM() || T.isThumb() || T.isAArch64(); CmdArgs.push_back("-fwchar-type=int"); - if (IsARM && !(T.isOSWindows() || T.getOS() == llvm::Triple::NetBSD || - T.getOS() == llvm::Triple::OpenBSD)) + if (IsARM && !(T.isOSWindows() || T.isOSNetBSD() || + T.isOSOpenBSD())) CmdArgs.push_back("-fno-signed-wchar"); else CmdArgs.push_back("-fsigned-wchar"); @@ -5274,8 +5274,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, (TC.getTriple().isOSBinFormatELF() || TC.getTriple().isOSBinFormatCOFF()) && !TC.getTriple().isPS4() && - TC.useIntegratedAs() && - RawTriple.getOS() != llvm::Triple::NetBSD)) + !TC.getTriple().isOSNetBSD() && + TC.useIntegratedAs())) CmdArgs.push_back("-faddrsig"); // Finally add the compile command to the compilation. diff --git a/lib/Driver/ToolChains/CommonArgs.cpp b/lib/Driver/ToolChains/CommonArgs.cpp index a0762a7cca..be7dc47f58 100644 --- a/lib/Driver/ToolChains/CommonArgs.cpp +++ b/lib/Driver/ToolChains/CommonArgs.cpp @@ -603,19 +603,19 @@ void tools::linkSanitizerRuntimeDeps(const ToolChain &TC, if (TC.getTriple().getOS() != llvm::Triple::RTEMS && !TC.getTriple().isAndroid()) { CmdArgs.push_back("-lpthread"); - if (TC.getTriple().getOS() != llvm::Triple::OpenBSD) + if (TC.getTriple().isOSOpenBSD()) CmdArgs.push_back("-lrt"); } CmdArgs.push_back("-lm"); // There's no libdl on all OSes. - if (TC.getTriple().getOS() != llvm::Triple::FreeBSD && - TC.getTriple().getOS() != llvm::Triple::NetBSD && - TC.getTriple().getOS() != llvm::Triple::OpenBSD && - TC.getTriple().getOS() != llvm::Triple::RTEMS) + if (!TC.getTriple().isOSFreeBSD() && + !TC.getTriple().isOSNetBSD() && + !TC.getTriple().isOSOpenBSD() && + TC.getTriple().getOS() != llvm::Triple::RTEMS) CmdArgs.push_back("-ldl"); // Required for backtrace on some OSes - if (TC.getTriple().getOS() == llvm::Triple::NetBSD || - TC.getTriple().getOS() == llvm::Triple::FreeBSD) + if (TC.getTriple().isOSFreeBSD() || + TC.getTriple().isOSNetBSD()) CmdArgs.push_back("-lexecinfo"); } @@ -790,13 +790,13 @@ bool tools::addXRayRuntime(const ToolChain&TC, const ArgList &Args, ArgStringLis void tools::linkXRayRuntimeDeps(const ToolChain &TC, ArgStringList &CmdArgs) { CmdArgs.push_back("--no-as-needed"); CmdArgs.push_back("-lpthread"); - if (TC.getTriple().getOS() != llvm::Triple::OpenBSD) + if (!TC.getTriple().isOSOpenBSD()) CmdArgs.push_back("-lrt"); CmdArgs.push_back("-lm"); - if (TC.getTriple().getOS() != llvm::Triple::FreeBSD && - TC.getTriple().getOS() != llvm::Triple::NetBSD && - TC.getTriple().getOS() != llvm::Triple::OpenBSD) + if (!TC.getTriple().isOSFreeBSD() && + !TC.getTriple().isOSNetBSD() && + !TC.getTriple().isOSOpenBSD()) CmdArgs.push_back("-ldl"); } @@ -933,7 +933,7 @@ tools::ParsePICArgs(const ToolChain &ToolChain, const ArgList &Args) { } // OpenBSD-specific defaults for PIE - if (Triple.getOS() == llvm::Triple::OpenBSD) { + if (Triple.isOSOpenBSD()) { switch (ToolChain.getArch()) { case llvm::Triple::arm: case llvm::Triple::aarch64: diff --git a/lib/Driver/ToolChains/Gnu.cpp b/lib/Driver/ToolChains/Gnu.cpp index fbd4dc72e5..935071f891 100644 --- a/lib/Driver/ToolChains/Gnu.cpp +++ b/lib/Driver/ToolChains/Gnu.cpp @@ -2597,7 +2597,7 @@ void Generic_ELF::addClangTargetOptions(const ArgList &DriverArgs, bool UseInitArrayDefault = getTriple().getArch() == llvm::Triple::aarch64 || getTriple().getArch() == llvm::Triple::aarch64_be || - (getTriple().getOS() == llvm::Triple::FreeBSD && + (getTriple().isOSFreeBSD() && getTriple().getOSMajorVersion() >= 12) || (getTriple().getOS() == llvm::Triple::Linux && ((!GCCInstallation.isValid() || !V.isOlderThan(4, 7, 0)) || diff --git a/lib/Driver/XRayArgs.cpp b/lib/Driver/XRayArgs.cpp index 3d294998cd..1a48493d7d 100644 --- a/lib/Driver/XRayArgs.cpp +++ b/lib/Driver/XRayArgs.cpp @@ -50,9 +50,9 @@ XRayArgs::XRayArgs(const ToolChain &TC, const ArgList &Args) { D.Diag(diag::err_drv_clang_unsupported) << (std::string(XRayInstrumentOption) + " on " + Triple.str()); } - } else if (Triple.getOS() == llvm::Triple::FreeBSD || - Triple.getOS() == llvm::Triple::OpenBSD || - Triple.getOS() == llvm::Triple::NetBSD || + } else if (Triple.isOSFreeBSD() || + Triple.isOSOpenBSD() || + Triple.isOSNetBSD() || Triple.getOS() == llvm::Triple::Darwin) { if (Triple.getArch() != llvm::Triple::x86_64) { D.Diag(diag::err_drv_clang_unsupported) diff --git a/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp b/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp index a4f782c68f..4a73810a6f 100644 --- a/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp +++ b/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp @@ -29,10 +29,10 @@ static bool isArc4RandomAvailable(const ASTContext &Ctx) { const llvm::Triple &T = Ctx.getTargetInfo().getTriple(); return T.getVendor() == llvm::Triple::Apple || T.getOS() == llvm::Triple::CloudABI || - T.getOS() == llvm::Triple::FreeBSD || - T.getOS() == llvm::Triple::NetBSD || - T.getOS() == llvm::Triple::OpenBSD || - T.getOS() == llvm::Triple::DragonFly; + T.isOSFreeBSD() || + T.isOSNetBSD() || + T.isOSOpenBSD() || + T.isOSDragonFly(); } namespace { -- cgit v1.2.3 From 0181ac9c923ea93719dded37fa9ebfe9f89f7796 Mon Sep 17 00:00:00 2001 From: Ulrich Weigand Date: Thu, 20 Dec 2018 13:10:47 +0000 Subject: [SystemZ] Improve testing of vecintrin.h intrinsics This adds assembly-level tests to verify that the high-level intrinsics generate the instructions they're supposed to. These tests would have caught the codegen bugs I just fixed. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349753 91177308-0d34-0410-b5e6-96231b3b80d8 --- test/CodeGen/builtins-systemz-zvector.c | 1529 +++++++++++++++++++++++++++++- test/CodeGen/builtins-systemz-zvector2.c | 293 +++++- 2 files changed, 1819 insertions(+), 3 deletions(-) diff --git a/test/CodeGen/builtins-systemz-zvector.c b/test/CodeGen/builtins-systemz-zvector.c index a8adbd717e..f8e5aa3f40 100644 --- a/test/CodeGen/builtins-systemz-zvector.c +++ b/test/CodeGen/builtins-systemz-zvector.c @@ -2,6 +2,9 @@ // RUN: %clang_cc1 -target-cpu z13 -triple s390x-linux-gnu \ // RUN: -O -fzvector -fno-lax-vector-conversions \ // RUN: -Wall -Wno-unused -Werror -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -target-cpu z13 -triple s390x-linux-gnu \ +// RUN: -O -fzvector -fno-lax-vector-conversions \ +// RUN: -Wall -Wno-unused -Werror -S %s -o - | FileCheck %s --check-prefix=CHECK-ASM #include @@ -58,367 +61,598 @@ volatile int idx; int cc; void test_core(void) { + // CHECK-ASM-LABEL: test_core + len = __lcbb(cptr, 64); // CHECK: call i32 @llvm.s390.lcbb(i8* %{{.*}}, i32 0) + // CHECK-ASM: lcbb len = __lcbb(cptr, 128); // CHECK: call i32 @llvm.s390.lcbb(i8* %{{.*}}, i32 1) + // CHECK-ASM: lcbb len = __lcbb(cptr, 256); // CHECK: call i32 @llvm.s390.lcbb(i8* %{{.*}}, i32 2) + // CHECK-ASM: lcbb len = __lcbb(cptr, 512); // CHECK: call i32 @llvm.s390.lcbb(i8* %{{.*}}, i32 3) + // CHECK-ASM: lcbb len = __lcbb(cptr, 1024); // CHECK: call i32 @llvm.s390.lcbb(i8* %{{.*}}, i32 4) + // CHECK-ASM: lcbb len = __lcbb(cptr, 2048); // CHECK: call i32 @llvm.s390.lcbb(i8* %{{.*}}, i32 5) + // CHECK-ASM: lcbb len = __lcbb(cptr, 4096); // CHECK: call i32 @llvm.s390.lcbb(i8* %{{.*}}, i32 6) + // CHECK-ASM: lcbb sc = vec_extract(vsc, idx); // CHECK: extractelement <16 x i8> %{{.*}}, i32 %{{.*}} + // CHECK-ASM: vlgvb uc = vec_extract(vuc, idx); // CHECK: extractelement <16 x i8> %{{.*}}, i32 %{{.*}} + // CHECK-ASM: vlgvb uc = vec_extract(vbc, idx); // CHECK: extractelement <16 x i8> %{{.*}}, i32 %{{.*}} + // CHECK-ASM: vlgvb ss = vec_extract(vss, idx); // CHECK: extractelement <8 x i16> %{{.*}}, i32 %{{.*}} + // CHECK-ASM: vlgvh us = vec_extract(vus, idx); // CHECK: extractelement <8 x i16> %{{.*}}, i32 %{{.*}} + // CHECK-ASM: vlgvh us = vec_extract(vbs, idx); // CHECK: extractelement <8 x i16> %{{.*}}, i32 %{{.*}} + // CHECK-ASM: vlgvh si = vec_extract(vsi, idx); // CHECK: extractelement <4 x i32> %{{.*}}, i32 %{{.*}} + // CHECK-ASM: vlgvf ui = vec_extract(vui, idx); // CHECK: extractelement <4 x i32> %{{.*}}, i32 %{{.*}} + // CHECK-ASM: vlgvf ui = vec_extract(vbi, idx); // CHECK: extractelement <4 x i32> %{{.*}}, i32 %{{.*}} + // CHECK-ASM: vlgvf sl = vec_extract(vsl, idx); // CHECK: extractelement <2 x i64> %{{.*}}, i32 %{{.*}} + // CHECK-ASM: vlgvg ul = vec_extract(vul, idx); // CHECK: extractelement <2 x i64> %{{.*}}, i32 %{{.*}} + // CHECK-ASM: vlgvg ul = vec_extract(vbl, idx); // CHECK: extractelement <2 x i64> %{{.*}}, i32 %{{.*}} + // CHECK-ASM: vlgvg d = vec_extract(vd, idx); // CHECK: extractelement <2 x double> %{{.*}}, i32 %{{.*}} + // CHECK-ASM: vlgvg vsc = vec_insert(sc, vsc, idx); // CHECK: insertelement <16 x i8> %{{.*}}, i8 %{{.*}}, i32 %{{.*}} + // CHECK-ASM: vlvgb vuc = vec_insert(uc, vuc, idx); // CHECK: insertelement <16 x i8> %{{.*}}, i8 %{{.*}}, i32 %{{.*}} + // CHECK-ASM: vlvgb vuc = vec_insert(uc, vbc, idx); // CHECK: insertelement <16 x i8> %{{.*}}, i8 %{{.*}}, i32 %{{.*}} + // CHECK-ASM: vlvgb vss = vec_insert(ss, vss, idx); // CHECK: insertelement <8 x i16> %{{.*}}, i16 %{{.*}}, i32 %{{.*}} + // CHECK-ASM: vlvgh vus = vec_insert(us, vus, idx); // CHECK: insertelement <8 x i16> %{{.*}}, i16 %{{.*}}, i32 %{{.*}} + // CHECK-ASM: vlvgh vus = vec_insert(us, vbs, idx); // CHECK: insertelement <8 x i16> %{{.*}}, i16 %{{.*}}, i32 %{{.*}} + // CHECK-ASM: vlvgh vsi = vec_insert(si, vsi, idx); // CHECK: insertelement <4 x i32> %{{.*}}, i32 %{{.*}}, i32 %{{.*}} + // CHECK-ASM: vlvgf vui = vec_insert(ui, vui, idx); // CHECK: insertelement <4 x i32> %{{.*}}, i32 %{{.*}}, i32 %{{.*}} + // CHECK-ASM: vlvgf vui = vec_insert(ui, vbi, idx); // CHECK: insertelement <4 x i32> %{{.*}}, i32 %{{.*}}, i32 %{{.*}} + // CHECK-ASM: vlvgf vsl = vec_insert(sl, vsl, idx); // CHECK: insertelement <2 x i64> %{{.*}}, i64 %{{.*}}, i32 %{{.*}} + // CHECK-ASM: vlvgg vul = vec_insert(ul, vul, idx); // CHECK: insertelement <2 x i64> %{{.*}}, i64 %{{.*}}, i32 %{{.*}} + // CHECK-ASM: vlvgg vul = vec_insert(ul, vbl, idx); // CHECK: insertelement <2 x i64> %{{.*}}, i64 %{{.*}}, i32 %{{.*}} + // CHECK-ASM: vlvgg vd = vec_insert(d, vd, idx); // CHECK: insertelement <2 x double> %{{.*}}, double %{{.*}}, i32 %{{.*}} + // CHECK-ASM: vlvgg vsc = vec_promote(sc, idx); // CHECK: insertelement <16 x i8> undef, i8 %{{.*}}, i32 %{{.*}} + // CHECK-ASM: vlvgb vuc = vec_promote(uc, idx); // CHECK: insertelement <16 x i8> undef, i8 %{{.*}}, i32 %{{.*}} + // CHECK-ASM: vlvgb vss = vec_promote(ss, idx); // CHECK: insertelement <8 x i16> undef, i16 %{{.*}}, i32 %{{.*}} + // CHECK-ASM: vlvgh vus = vec_promote(us, idx); // CHECK: insertelement <8 x i16> undef, i16 %{{.*}}, i32 %{{.*}} + // CHECK-ASM: vlvgh vsi = vec_promote(si, idx); // CHECK: insertelement <4 x i32> undef, i32 %{{.*}}, i32 %{{.*}} + // CHECK-ASM: vlvgf vui = vec_promote(ui, idx); // CHECK: insertelement <4 x i32> undef, i32 %{{.*}}, i32 %{{.*}} + // CHECK-ASM: vlvgf vsl = vec_promote(sl, idx); // CHECK: insertelement <2 x i64> undef, i64 %{{.*}}, i32 %{{.*}} + // CHECK-ASM: vlvgg vul = vec_promote(ul, idx); // CHECK: insertelement <2 x i64> undef, i64 %{{.*}}, i32 %{{.*}} + // CHECK-ASM: vlvgg vd = vec_promote(d, idx); // CHECK: insertelement <2 x double> undef, double %{{.*}}, i32 %{{.*}} + // CHECK-ASM: vlvgg vsc = vec_insert_and_zero(cptrsc); // CHECK: insertelement <16 x i8> , i8 %{{.*}}, i32 7 + // CHECK-ASM: vllezb vuc = vec_insert_and_zero(cptruc); // CHECK: insertelement <16 x i8> , i8 %{{.*}}, i32 7 + // CHECK-ASM: vllezb vss = vec_insert_and_zero(cptrss); // CHECK: insertelement <8 x i16> , i16 %{{.*}}, i32 3 + // CHECK-ASM: vllezh vus = vec_insert_and_zero(cptrus); // CHECK: insertelement <8 x i16> , i16 %{{.*}}, i32 3 + // CHECK-ASM: vllezh vsi = vec_insert_and_zero(cptrsi); // CHECK: insertelement <4 x i32> , i32 %{{.*}}, i32 1 + // CHECK-ASM: vllezf vui = vec_insert_and_zero(cptrui); // CHECK: insertelement <4 x i32> , i32 %{{.*}}, i32 1 + // CHECK-ASM: vllezf vsl = vec_insert_and_zero(cptrsl); // CHECK: insertelement <2 x i64> , i64 %{{.*}}, i32 0 + // CHECK-ASM: vllezg vul = vec_insert_and_zero(cptrul); // CHECK: insertelement <2 x i64> , i64 %{{.*}}, i32 0 + // CHECK-ASM: vllezg vd = vec_insert_and_zero(cptrd); // CHECK: insertelement <2 x double> , double %{{.*}}, i32 0 + // CHECK-ASM: vllezg vsc = vec_perm(vsc, vsc, vuc); // CHECK: call <16 x i8> @llvm.s390.vperm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vperm vuc = vec_perm(vuc, vuc, vuc); // CHECK: call <16 x i8> @llvm.s390.vperm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vperm vbc = vec_perm(vbc, vbc, vuc); // CHECK: call <16 x i8> @llvm.s390.vperm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vperm vss = vec_perm(vss, vss, vuc); // CHECK: call <16 x i8> @llvm.s390.vperm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vperm vus = vec_perm(vus, vus, vuc); // CHECK: call <16 x i8> @llvm.s390.vperm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vperm vbs = vec_perm(vbs, vbs, vuc); // CHECK: call <16 x i8> @llvm.s390.vperm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vperm vsi = vec_perm(vsi, vsi, vuc); // CHECK: call <16 x i8> @llvm.s390.vperm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vperm vui = vec_perm(vui, vui, vuc); // CHECK: call <16 x i8> @llvm.s390.vperm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vperm vbi = vec_perm(vbi, vbi, vuc); // CHECK: call <16 x i8> @llvm.s390.vperm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vperm vsl = vec_perm(vsl, vsl, vuc); // CHECK: call <16 x i8> @llvm.s390.vperm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vperm vul = vec_perm(vul, vul, vuc); // CHECK: call <16 x i8> @llvm.s390.vperm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vperm vbl = vec_perm(vbl, vbl, vuc); // CHECK: call <16 x i8> @llvm.s390.vperm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vperm vd = vec_perm(vd, vd, vuc); // CHECK: call <16 x i8> @llvm.s390.vperm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vperm vsl = vec_permi(vsl, vsl, 0); // CHECK: call <2 x i64> @llvm.s390.vpdi(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, i32 0) + // CHECK-ASM: vpdi vsl = vec_permi(vsl, vsl, 1); // CHECK: call <2 x i64> @llvm.s390.vpdi(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, i32 1) + // CHECK-ASM: vpdi vsl = vec_permi(vsl, vsl, 2); // CHECK: call <2 x i64> @llvm.s390.vpdi(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, i32 4) + // CHECK-ASM: vpdi vsl = vec_permi(vsl, vsl, 3); // CHECK: call <2 x i64> @llvm.s390.vpdi(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, i32 5) + // CHECK-ASM: vpdi vul = vec_permi(vul, vul, 0); // CHECK: call <2 x i64> @llvm.s390.vpdi(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, i32 0) + // CHECK-ASM: vpdi vul = vec_permi(vul, vul, 1); // CHECK: call <2 x i64> @llvm.s390.vpdi(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, i32 1) + // CHECK-ASM: vpdi vul = vec_permi(vul, vul, 2); // CHECK: call <2 x i64> @llvm.s390.vpdi(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, i32 4) + // CHECK-ASM: vpdi vul = vec_permi(vul, vul, 3); // CHECK: call <2 x i64> @llvm.s390.vpdi(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, i32 5) + // CHECK-ASM: vpdi vbl = vec_permi(vbl, vbl, 0); // CHECK: call <2 x i64> @llvm.s390.vpdi(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, i32 0) + // CHECK-ASM: vpdi vbl = vec_permi(vbl, vbl, 1); // CHECK: call <2 x i64> @llvm.s390.vpdi(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, i32 1) + // CHECK-ASM: vpdi vbl = vec_permi(vbl, vbl, 2); // CHECK: call <2 x i64> @llvm.s390.vpdi(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, i32 4) + // CHECK-ASM: vpdi vbl = vec_permi(vbl, vbl, 3); // CHECK: call <2 x i64> @llvm.s390.vpdi(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, i32 5) + // CHECK-ASM: vpdi vd = vec_permi(vd, vd, 0); // CHECK: call <2 x i64> @llvm.s390.vpdi(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, i32 0) + // CHECK-ASM: vpdi vd = vec_permi(vd, vd, 1); // CHECK: call <2 x i64> @llvm.s390.vpdi(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, i32 1) + // CHECK-ASM: vpdi vd = vec_permi(vd, vd, 2); // CHECK: call <2 x i64> @llvm.s390.vpdi(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, i32 4) + // CHECK-ASM: vpdi vd = vec_permi(vd, vd, 3); // CHECK: call <2 x i64> @llvm.s390.vpdi(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, i32 5) + // CHECK-ASM: vpdi vsc = vec_sel(vsc, vsc, vuc); + // CHECK-ASM: vsel vsc = vec_sel(vsc, vsc, vbc); + // CHECK-ASM: vsel vuc = vec_sel(vuc, vuc, vuc); + // CHECK-ASM: vsel vuc = vec_sel(vuc, vuc, vbc); + // CHECK-ASM: vsel vbc = vec_sel(vbc, vbc, vuc); + // CHECK-ASM: vsel vbc = vec_sel(vbc, vbc, vbc); + // CHECK-ASM: vsel vss = vec_sel(vss, vss, vus); + // CHECK-ASM: vsel vss = vec_sel(vss, vss, vbs); + // CHECK-ASM: vsel vus = vec_sel(vus, vus, vus); + // CHECK-ASM: vsel vus = vec_sel(vus, vus, vbs); + // CHECK-ASM: vsel vbs = vec_sel(vbs, vbs, vus); + // CHECK-ASM: vsel vbs = vec_sel(vbs, vbs, vbs); + // CHECK-ASM: vsel vsi = vec_sel(vsi, vsi, vui); + // CHECK-ASM: vsel vsi = vec_sel(vsi, vsi, vbi); + // CHECK-ASM: vsel vui = vec_sel(vui, vui, vui); + // CHECK-ASM: vsel vui = vec_sel(vui, vui, vbi); + // CHECK-ASM: vsel vbi = vec_sel(vbi, vbi, vui); + // CHECK-ASM: vsel vbi = vec_sel(vbi, vbi, vbi); + // CHECK-ASM: vsel vsl = vec_sel(vsl, vsl, vul); + // CHECK-ASM: vsel vsl = vec_sel(vsl, vsl, vbl); + // CHECK-ASM: vsel vul = vec_sel(vul, vul, vul); + // CHECK-ASM: vsel vul = vec_sel(vul, vul, vbl); + // CHECK-ASM: vsel vbl = vec_sel(vbl, vbl, vul); + // CHECK-ASM: vsel vbl = vec_sel(vbl, vbl, vbl); + // CHECK-ASM: vsel vd = vec_sel(vd, vd, vul); + // CHECK-ASM: vsel vd = vec_sel(vd, vd, vbl); + // CHECK-ASM: vsel vsi = vec_gather_element(vsi, vui, cptrsi, 0); + // CHECK-ASM: vgef %{{.*}}, 0(%{{.*}},%{{.*}}), 0 vsi = vec_gather_element(vsi, vui, cptrsi, 1); + // CHECK-ASM: vgef %{{.*}}, 0(%{{.*}},%{{.*}}), 1 vsi = vec_gather_element(vsi, vui, cptrsi, 2); + // CHECK-ASM: vgef %{{.*}}, 0(%{{.*}},%{{.*}}), 2 vsi = vec_gather_element(vsi, vui, cptrsi, 3); + // CHECK-ASM: vgef %{{.*}}, 0(%{{.*}},%{{.*}}), 3 vui = vec_gather_element(vui, vui, cptrui, 0); + // CHECK-ASM: vgef %{{.*}}, 0(%{{.*}},%{{.*}}), 0 vui = vec_gather_element(vui, vui, cptrui, 1); + // CHECK-ASM: vgef %{{.*}}, 0(%{{.*}},%{{.*}}), 1 vui = vec_gather_element(vui, vui, cptrui, 2); + // CHECK-ASM: vgef %{{.*}}, 0(%{{.*}},%{{.*}}), 2 vui = vec_gather_element(vui, vui, cptrui, 3); + // CHECK-ASM: vgef %{{.*}}, 0(%{{.*}},%{{.*}}), 3 vbi = vec_gather_element(vbi, vui, cptrui, 0); + // CHECK-ASM: vgef %{{.*}}, 0(%{{.*}},%{{.*}}), 0 vbi = vec_gather_element(vbi, vui, cptrui, 1); + // CHECK-ASM: vgef %{{.*}}, 0(%{{.*}},%{{.*}}), 1 vbi = vec_gather_element(vbi, vui, cptrui, 2); + // CHECK-ASM: vgef %{{.*}}, 0(%{{.*}},%{{.*}}), 2 vbi = vec_gather_element(vbi, vui, cptrui, 3); + // CHECK-ASM: vgef %{{.*}}, 0(%{{.*}},%{{.*}}), 3 vsl = vec_gather_element(vsl, vul, cptrsl, 0); + // CHECK-ASM: vgeg %{{.*}}, 0(%{{.*}},%{{.*}}), 0 vsl = vec_gather_element(vsl, vul, cptrsl, 1); + // CHECK-ASM: vgeg %{{.*}}, 0(%{{.*}},%{{.*}}), 1 vul = vec_gather_element(vul, vul, cptrul, 0); + // CHECK-ASM: vgeg %{{.*}}, 0(%{{.*}},%{{.*}}), 0 vul = vec_gather_element(vul, vul, cptrul, 1); + // CHECK-ASM: vgeg %{{.*}}, 0(%{{.*}},%{{.*}}), 1 vbl = vec_gather_element(vbl, vul, cptrul, 0); + // CHECK-ASM: vgeg %{{.*}}, 0(%{{.*}},%{{.*}}), 0 vbl = vec_gather_element(vbl, vul, cptrul, 1); + // CHECK-ASM: vgeg %{{.*}}, 0(%{{.*}},%{{.*}}), 1 vd = vec_gather_element(vd, vul, cptrd, 0); + // CHECK-ASM: vgeg %{{.*}}, 0(%{{.*}},%{{.*}}), 0 vd = vec_gather_element(vd, vul, cptrd, 1); + // CHECK-ASM: vgeg %{{.*}}, 0(%{{.*}},%{{.*}}), 1 vec_scatter_element(vsi, vui, ptrsi, 0); + // CHECK-ASM: vscef %{{.*}}, 0(%{{.*}},%{{.*}}), 0 vec_scatter_element(vsi, vui, ptrsi, 1); + // CHECK-ASM: vscef %{{.*}}, 0(%{{.*}},%{{.*}}), 1 vec_scatter_element(vsi, vui, ptrsi, 2); + // CHECK-ASM: vscef %{{.*}}, 0(%{{.*}},%{{.*}}), 2 vec_scatter_element(vsi, vui, ptrsi, 3); + // CHECK-ASM: vscef %{{.*}}, 0(%{{.*}},%{{.*}}), 3 vec_scatter_element(vui, vui, ptrui, 0); + // CHECK-ASM: vscef %{{.*}}, 0(%{{.*}},%{{.*}}), 0 vec_scatter_element(vui, vui, ptrui, 1); + // CHECK-ASM: vscef %{{.*}}, 0(%{{.*}},%{{.*}}), 1 vec_scatter_element(vui, vui, ptrui, 2); + // CHECK-ASM: vscef %{{.*}}, 0(%{{.*}},%{{.*}}), 2 vec_scatter_element(vui, vui, ptrui, 3); + // CHECK-ASM: vscef %{{.*}}, 0(%{{.*}},%{{.*}}), 3 vec_scatter_element(vbi, vui, ptrui, 0); + // CHECK-ASM: vscef %{{.*}}, 0(%{{.*}},%{{.*}}), 0 vec_scatter_element(vbi, vui, ptrui, 1); + // CHECK-ASM: vscef %{{.*}}, 0(%{{.*}},%{{.*}}), 1 vec_scatter_element(vbi, vui, ptrui, 2); + // CHECK-ASM: vscef %{{.*}}, 0(%{{.*}},%{{.*}}), 2 vec_scatter_element(vbi, vui, ptrui, 3); + // CHECK-ASM: vscef %{{.*}}, 0(%{{.*}},%{{.*}}), 3 vec_scatter_element(vsl, vul, ptrsl, 0); + // CHECK-ASM: vsceg %{{.*}}, 0(%{{.*}},%{{.*}}), 0 vec_scatter_element(vsl, vul, ptrsl, 1); + // CHECK-ASM: vsceg %{{.*}}, 0(%{{.*}},%{{.*}}), 1 vec_scatter_element(vul, vul, ptrul, 0); + // CHECK-ASM: vsceg %{{.*}}, 0(%{{.*}},%{{.*}}), 0 vec_scatter_element(vul, vul, ptrul, 1); + // CHECK-ASM: vsceg %{{.*}}, 0(%{{.*}},%{{.*}}), 1 vec_scatter_element(vbl, vul, ptrul, 0); + // CHECK-ASM: vsceg %{{.*}}, 0(%{{.*}},%{{.*}}), 0 vec_scatter_element(vbl, vul, ptrul, 1); + // CHECK-ASM: vsceg %{{.*}}, 0(%{{.*}},%{{.*}}), 1 vec_scatter_element(vd, vul, ptrd, 0); + // CHECK-ASM: vsceg %{{.*}}, 0(%{{.*}},%{{.*}}), 0 vec_scatter_element(vd, vul, ptrd, 1); + // CHECK-ASM: vsceg %{{.*}}, 0(%{{.*}},%{{.*}}), 1 vsc = vec_xl(idx, cptrsc); + // CHECK-ASM: vl vuc = vec_xl(idx, cptruc); + // CHECK-ASM: vl vss = vec_xl(idx, cptrss); + // CHECK-ASM: vl vus = vec_xl(idx, cptrus); + // CHECK-ASM: vl vsi = vec_xl(idx, cptrsi); + // CHECK-ASM: vl vui = vec_xl(idx, cptrui); + // CHECK-ASM: vl vsl = vec_xl(idx, cptrsl); + // CHECK-ASM: vl vul = vec_xl(idx, cptrul); + // CHECK-ASM: vl vd = vec_xl(idx, cptrd); + // CHECK-ASM: vl vsc = vec_xld2(idx, cptrsc); + // CHECK-ASM: vl vuc = vec_xld2(idx, cptruc); + // CHECK-ASM: vl vss = vec_xld2(idx, cptrss); + // CHECK-ASM: vl vus = vec_xld2(idx, cptrus); + // CHECK-ASM: vl vsi = vec_xld2(idx, cptrsi); + // CHECK-ASM: vl vui = vec_xld2(idx, cptrui); + // CHECK-ASM: vl vsl = vec_xld2(idx, cptrsl); + // CHECK-ASM: vl vul = vec_xld2(idx, cptrul); + // CHECK-ASM: vl vd = vec_xld2(idx, cptrd); + // CHECK-ASM: vl vsc = vec_xlw4(idx, cptrsc); + // CHECK-ASM: vl vuc = vec_xlw4(idx, cptruc); + // CHECK-ASM: vl vss = vec_xlw4(idx, cptrss); + // CHECK-ASM: vl vus = vec_xlw4(idx, cptrus); + // CHECK-ASM: vl vsi = vec_xlw4(idx, cptrsi); + // CHECK-ASM: vl vui = vec_xlw4(idx, cptrui); + // CHECK-ASM: vl vec_xst(vsc, idx, ptrsc); + // CHECK-ASM: vst vec_xst(vuc, idx, ptruc); + // CHECK-ASM: vst vec_xst(vss, idx, ptrss); + // CHECK-ASM: vst vec_xst(vus, idx, ptrus); + // CHECK-ASM: vst vec_xst(vsi, idx, ptrsi); + // CHECK-ASM: vst vec_xst(vui, idx, ptrui); + // CHECK-ASM: vst vec_xst(vsl, idx, ptrsl); + // CHECK-ASM: vst vec_xst(vul, idx, ptrul); + // CHECK-ASM: vst vec_xst(vd, idx, ptrd); + // CHECK-ASM: vst vec_xstd2(vsc, idx, ptrsc); + // CHECK-ASM: vst vec_xstd2(vuc, idx, ptruc); + // CHECK-ASM: vst vec_xstd2(vss, idx, ptrss); + // CHECK-ASM: vst vec_xstd2(vus, idx, ptrus); + // CHECK-ASM: vst vec_xstd2(vsi, idx, ptrsi); + // CHECK-ASM: vst vec_xstd2(vui, idx, ptrui); + // CHECK-ASM: vst vec_xstd2(vsl, idx, ptrsl); + // CHECK-ASM: vst vec_xstd2(vul, idx, ptrul); + // CHECK-ASM: vst vec_xstd2(vd, idx, ptrd); + // CHECK-ASM: vst vec_xstw4(vsc, idx, ptrsc); + // CHECK-ASM: vst vec_xstw4(vuc, idx, ptruc); + // CHECK-ASM: vst vec_xstw4(vss, idx, ptrss); + // CHECK-ASM: vst vec_xstw4(vus, idx, ptrus); + // CHECK-ASM: vst vec_xstw4(vsi, idx, ptrsi); + // CHECK-ASM: vst vec_xstw4(vui, idx, ptrui); + // CHECK-ASM: vst vsc = vec_load_bndry(cptrsc, 64); // CHECK: call <16 x i8> @llvm.s390.vlbb(i8* %{{.*}}, i32 0) + // CHECK-ASM: vlbb vuc = vec_load_bndry(cptruc, 64); // CHECK: call <16 x i8> @llvm.s390.vlbb(i8* %{{.*}}, i32 0) + // CHECK-ASM: vlbb vss = vec_load_bndry(cptrss, 64); // CHECK: call <16 x i8> @llvm.s390.vlbb(i8* %{{.*}}, i32 0) + // CHECK-ASM: vlbb vus = vec_load_bndry(cptrus, 64); // CHECK: call <16 x i8> @llvm.s390.vlbb(i8* %{{.*}}, i32 0) + // CHECK-ASM: vlbb vsi = vec_load_bndry(cptrsi, 64); // CHECK: call <16 x i8> @llvm.s390.vlbb(i8* %{{.*}}, i32 0) + // CHECK-ASM: vlbb vui = vec_load_bndry(cptrui, 64); // CHECK: call <16 x i8> @llvm.s390.vlbb(i8* %{{.*}}, i32 0) + // CHECK-ASM: vlbb vsl = vec_load_bndry(cptrsl, 64); // CHECK: call <16 x i8> @llvm.s390.vlbb(i8* %{{.*}}, i32 0) + // CHECK-ASM: vlbb vul = vec_load_bndry(cptrul, 64); // CHECK: call <16 x i8> @llvm.s390.vlbb(i8* %{{.*}}, i32 0) + // CHECK-ASM: vlbb vd = vec_load_bndry(cptrd, 64); // CHECK: call <16 x i8> @llvm.s390.vlbb(i8* %{{.*}}, i32 0) + // CHECK-ASM: vlbb vsc = vec_load_bndry(cptrsc, 128); // CHECK: call <16 x i8> @llvm.s390.vlbb(i8* %{{.*}}, i32 1) + // CHECK-ASM: vlbb vsc = vec_load_bndry(cptrsc, 256); // CHECK: call <16 x i8> @llvm.s390.vlbb(i8* %{{.*}}, i32 2) + // CHECK-ASM: vlbb vsc = vec_load_bndry(cptrsc, 512); // CHECK: call <16 x i8> @llvm.s390.vlbb(i8* %{{.*}}, i32 3) + // CHECK-ASM: vlbb vsc = vec_load_bndry(cptrsc, 1024); // CHECK: call <16 x i8> @llvm.s390.vlbb(i8* %{{.*}}, i32 4) + // CHECK-ASM: vlbb vsc = vec_load_bndry(cptrsc, 2048); // CHECK: call <16 x i8> @llvm.s390.vlbb(i8* %{{.*}}, i32 5) + // CHECK-ASM: vlbb vsc = vec_load_bndry(cptrsc, 4096); // CHECK: call <16 x i8> @llvm.s390.vlbb(i8* %{{.*}}, i32 6) + // CHECK-ASM: vlbb vsc = vec_load_len(cptrsc, idx); // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, i8* %{{.*}}) + // CHECK-ASM: vll vuc = vec_load_len(cptruc, idx); // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, i8* %{{.*}}) + // CHECK-ASM: vll vss = vec_load_len(cptrss, idx); // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, i8* %{{.*}}) + // CHECK-ASM: vll vus = vec_load_len(cptrus, idx); // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, i8* %{{.*}}) + // CHECK-ASM: vll vsi = vec_load_len(cptrsi, idx); // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, i8* %{{.*}}) + // CHECK-ASM: vll vui = vec_load_len(cptrui, idx); // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, i8* %{{.*}}) + // CHECK-ASM: vll vsl = vec_load_len(cptrsl, idx); // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, i8* %{{.*}}) + // CHECK-ASM: vll vul = vec_load_len(cptrul, idx); // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, i8* %{{.*}}) + // CHECK-ASM: vll vd = vec_load_len(cptrd, idx); // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, i8* %{{.*}}) + // CHECK-ASM: vll vec_store_len(vsc, ptrsc, idx); // CHECK: call void @llvm.s390.vstl(<16 x i8> %{{.*}}, i32 %{{.*}}, i8* %{{.*}}) + // CHECK-ASM: vstl vec_store_len(vuc, ptruc, idx); // CHECK: call void @llvm.s390.vstl(<16 x i8> %{{.*}}, i32 %{{.*}}, i8* %{{.*}}) + // CHECK-ASM: vstl vec_store_len(vss, ptrss, idx); // CHECK: call void @llvm.s390.vstl(<16 x i8> %{{.*}}, i32 %{{.*}}, i8* %{{.*}}) + // CHECK-ASM: vstl vec_store_len(vus, ptrus, idx); // CHECK: call void @llvm.s390.vstl(<16 x i8> %{{.*}}, i32 %{{.*}}, i8* %{{.*}}) + // CHECK-ASM: vstl vec_store_len(vsi, ptrsi, idx); // CHECK: call void @llvm.s390.vstl(<16 x i8> %{{.*}}, i32 %{{.*}}, i8* %{{.*}}) + // CHECK-ASM: vstl vec_store_len(vui, ptrui, idx); // CHECK: call void @llvm.s390.vstl(<16 x i8> %{{.*}}, i32 %{{.*}}, i8* %{{.*}}) + // CHECK-ASM: vstl vec_store_len(vsl, ptrsl, idx); // CHECK: call void @llvm.s390.vstl(<16 x i8> %{{.*}}, i32 %{{.*}}, i8* %{{.*}}) + // CHECK-ASM: vstl vec_store_len(vul, ptrul, idx); // CHECK: call void @llvm.s390.vstl(<16 x i8> %{{.*}}, i32 %{{.*}}, i8* %{{.*}}) + // CHECK-ASM: vstl vec_store_len(vd, ptrd, idx); // CHECK: call void @llvm.s390.vstl(<16 x i8> %{{.*}}, i32 %{{.*}}, i8* %{{.*}}) + // CHECK-ASM: vstl - vsl = vec_load_pair(sl, sl); - vul = vec_load_pair(ul, ul); + vsl = vec_load_pair(sl + 1, sl - 1); + // CHECK-ASM: vlvgp + vul = vec_load_pair(ul + 1, ul - 1); + // CHECK-ASM: vlvgp vuc = vec_genmask(0); // CHECK: <16 x i8> zeroinitializer @@ -454,56 +688,82 @@ void test_core(void) { vsc = vec_splat(vsc, 0); // CHECK: shufflevector <16 x i8> %{{.*}}, <16 x i8> undef, <16 x i32> zeroinitializer + // CHECK-ASM: vrepb vsc = vec_splat(vsc, 15); // CHECK: shufflevector <16 x i8> %{{.*}}, <16 x i8> undef, <16 x i32> + // CHECK-ASM: vrepb vuc = vec_splat(vuc, 0); // CHECK: shufflevector <16 x i8> %{{.*}}, <16 x i8> undef, <16 x i32> zeroinitializer + // CHECK-ASM: vrepb vuc = vec_splat(vuc, 15); // CHECK: shufflevector <16 x i8> %{{.*}}, <16 x i8> undef, <16 x i32> + // CHECK-ASM: vrepb vbc = vec_splat(vbc, 0); // CHECK: shufflevector <16 x i8> %{{.*}}, <16 x i8> undef, <16 x i32> zeroinitializer + // CHECK-ASM: vrepb vbc = vec_splat(vbc, 15); // CHECK: shufflevector <16 x i8> %{{.*}}, <16 x i8> undef, <16 x i32> + // CHECK-ASM: vrepb vss = vec_splat(vss, 0); // CHECK: shufflevector <8 x i16> %{{.*}}, <8 x i16> undef, <8 x i32> zeroinitializer + // CHECK-ASM: vreph vss = vec_splat(vss, 7); // CHECK: shufflevector <8 x i16> %{{.*}}, <8 x i16> undef, <8 x i32> + // CHECK-ASM: vreph vus = vec_splat(vus, 0); // CHECK: shufflevector <8 x i16> %{{.*}}, <8 x i16> undef, <8 x i32> zeroinitializer + // CHECK-ASM: vreph vus = vec_splat(vus, 7); // CHECK: shufflevector <8 x i16> %{{.*}}, <8 x i16> undef, <8 x i32> + // CHECK-ASM: vreph vbs = vec_splat(vbs, 0); // CHECK: shufflevector <8 x i16> %{{.*}}, <8 x i16> undef, <8 x i32> zeroinitializer + // CHECK-ASM: vreph vbs = vec_splat(vbs, 7); // CHECK: shufflevector <8 x i16> %{{.*}}, <8 x i16> undef, <8 x i32> + // CHECK-ASM: vreph vsi = vec_splat(vsi, 0); // CHECK: shufflevector <4 x i32> %{{.*}}, <4 x i32> undef, <4 x i32> zeroinitializer + // CHECK-ASM: vrepf vsi = vec_splat(vsi, 3); // CHECK: shufflevector <4 x i32> %{{.*}}, <4 x i32> undef, <4 x i32> + // CHECK-ASM: vrepf vui = vec_splat(vui, 0); // CHECK: shufflevector <4 x i32> %{{.*}}, <4 x i32> undef, <4 x i32> zeroinitializer + // CHECK-ASM: vrepf vui = vec_splat(vui, 3); // CHECK: shufflevector <4 x i32> %{{.*}}, <4 x i32> undef, <4 x i32> + // CHECK-ASM: vrepf vbi = vec_splat(vbi, 0); // CHECK: shufflevector <4 x i32> %{{.*}}, <4 x i32> undef, <4 x i32> zeroinitializer + // CHECK-ASM: vrepf vbi = vec_splat(vbi, 3); // CHECK: shufflevector <4 x i32> %{{.*}}, <4 x i32> undef, <4 x i32> + // CHECK-ASM: vrepf vsl = vec_splat(vsl, 0); // CHECK: shufflevector <2 x i64> %{{.*}}, <2 x i64> undef, <2 x i32> zeroinitializer + // CHECK-ASM: vrepg vsl = vec_splat(vsl, 1); // CHECK: shufflevector <2 x i64> %{{.*}}, <2 x i64> undef, <2 x i32> + // CHECK-ASM: vrepg vul = vec_splat(vul, 0); // CHECK: shufflevector <2 x i64> %{{.*}}, <2 x i64> undef, <2 x i32> zeroinitializer + // CHECK-ASM: vrepg vul = vec_splat(vul, 1); // CHECK: shufflevector <2 x i64> %{{.*}}, <2 x i64> undef, <2 x i32> + // CHECK-ASM: vrepg vbl = vec_splat(vbl, 0); // CHECK: shufflevector <2 x i64> %{{.*}}, <2 x i64> undef, <2 x i32> zeroinitializer + // CHECK-ASM: vrepg vbl = vec_splat(vbl, 1); // CHECK: shufflevector <2 x i64> %{{.*}}, <2 x i64> undef, <2 x i32> + // CHECK-ASM: vrepg vd = vec_splat(vd, 0); // CHECK: shufflevector <2 x double> %{{.*}}, <2 x double> undef, <2 x i32> zeroinitializer + // CHECK-ASM: vrepg vd = vec_splat(vd, 1); // CHECK: shufflevector <2 x double> %{{.*}}, <2 x double> undef, <2 x i32> + // CHECK-ASM: vrepg vsc = vec_splat_s8(-128); // CHECK: <16 x i8> @@ -540,2516 +800,3781 @@ void test_core(void) { vsc = vec_splats(sc); // CHECK: shufflevector <16 x i8> %{{.*}}, <16 x i8> undef, <16 x i32> zeroinitializer + // CHECK-ASM: vlrepb vuc = vec_splats(uc); // CHECK: shufflevector <16 x i8> %{{.*}}, <16 x i8> undef, <16 x i32> zeroinitializer + // CHECK-ASM: vlrepb vss = vec_splats(ss); // CHECK: shufflevector <8 x i16> %{{.*}}, <8 x i16> undef, <8 x i32> zeroinitializer + // CHECK-ASM: vlreph vus = vec_splats(us); // CHECK: shufflevector <8 x i16> %{{.*}}, <8 x i16> undef, <8 x i32> zeroinitializer + // CHECK-ASM: vlreph vsi = vec_splats(si); // CHECK: shufflevector <4 x i32> %{{.*}}, <4 x i32> undef, <4 x i32> zeroinitializer + // CHECK-ASM: vlrepf vui = vec_splats(ui); // CHECK: shufflevector <4 x i32> %{{.*}}, <4 x i32> undef, <4 x i32> zeroinitializer + // CHECK-ASM: vlrepf vsl = vec_splats(sl); // CHECK: shufflevector <2 x i64> %{{.*}}, <2 x i64> undef, <2 x i32> zeroinitializer + // CHECK-ASM: vlrepg vul = vec_splats(ul); // CHECK: shufflevector <2 x i64> %{{.*}}, <2 x i64> undef, <2 x i32> zeroinitializer + // CHECK-ASM: vlrepg vd = vec_splats(d); // CHECK: shufflevector <2 x double> %{{.*}}, <2 x double> undef, <2 x i32> zeroinitializer + // CHECK-ASM: vlrepg vsl = vec_extend_s64(vsc); + // CHECK-ASM: vsegb vsl = vec_extend_s64(vss); + // CHECK-ASM: vsegh vsl = vec_extend_s64(vsi); + // CHECK-ASM: vsegf vsc = vec_mergeh(vsc, vsc); // shufflevector <16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i32> + // CHECK-ASM: vmrhb vuc = vec_mergeh(vuc, vuc); // shufflevector <16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i32> + // CHECK-ASM: vmrhb vbc = vec_mergeh(vbc, vbc); // shufflevector <16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i32> + // CHECK-ASM: vmrhb vss = vec_mergeh(vss, vss); // shufflevector <8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i32> + // CHECK-ASM: vmrhh vus = vec_mergeh(vus, vus); // shufflevector <8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i32> + // CHECK-ASM: vmrhh vbs = vec_mergeh(vbs, vbs); // shufflevector <8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i32> + // CHECK-ASM: vmrhh vsi = vec_mergeh(vsi, vsi); // shufflevector <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> + // CHECK-ASM: vmrhf vui = vec_mergeh(vui, vui); // shufflevector <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> + // CHECK-ASM: vmrhf vbi = vec_mergeh(vbi, vbi); // shufflevector <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> + // CHECK-ASM: vmrhf vsl = vec_mergeh(vsl, vsl); // shufflevector <2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <2 x i32> + // CHECK-ASM: vmrhg vul = vec_mergeh(vul, vul); // shufflevector <2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <2 x i32> + // CHECK-ASM: vmrhg vbl = vec_mergeh(vbl, vbl); // shufflevector <2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <2 x i32> + // CHECK-ASM: vmrhg vd = vec_mergeh(vd, vd); // shufflevector <2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x i32> + // CHECK-ASM: vmrhg vsc = vec_mergel(vsc, vsc); // shufflevector <16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %a, <16 x i8> %b, <16 x i32> + // CHECK-ASM: vmrlb vuc = vec_mergel(vuc, vuc); // shufflevector <16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %a, <16 x i8> %b, <16 x i32> + // CHECK-ASM: vmrlb vbc = vec_mergel(vbc, vbc); // shufflevector <16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %a, <16 x i8> %b, <16 x i32> + // CHECK-ASM: vmrlb vss = vec_mergel(vss, vss); // shufflevector <8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i32> + // CHECK-ASM: vmrlh vus = vec_mergel(vus, vus); // shufflevector <8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i32> + // CHECK-ASM: vmrlh vbs = vec_mergel(vbs, vbs); // shufflevector <8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i32> + // CHECK-ASM: vmrlh vsi = vec_mergel(vsi, vsi); // shufflevector <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, + // CHECK-ASM: vmrlf vui = vec_mergel(vui, vui); // shufflevector <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, + // CHECK-ASM: vmrlf vbi = vec_mergel(vbi, vbi); // shufflevector <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, + // CHECK-ASM: vmrlf vsl = vec_mergel(vsl, vsl); // shufflevector <2 x i64> %{{.*}}, <2 x i64> %{{.*}}, + // CHECK-ASM: vmrlg vul = vec_mergel(vul, vul); // shufflevector <2 x i64> %{{.*}}, <2 x i64> %{{.*}}, + // CHECK-ASM: vmrlg vbl = vec_mergel(vbl, vbl); // shufflevector <2 x i64> %{{.*}}, <2 x i64> %{{.*}}, + // CHECK-ASM: vmrlg vd = vec_mergel(vd, vd); // shufflevector <2 x double> %{{.*}}, <2 x double> %{{.*}}, + // CHECK-ASM: vmrlg vsc = vec_pack(vss, vss); // CHECK: shufflevector <16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i32> + // CHECK-ASM: vpkh vuc = vec_pack(vus, vus); // CHECK: shufflevector <16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i32> + // CHECK-ASM: vpkh vbc = vec_pack(vbs, vbs); // CHECK: shufflevector <16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i32> + // CHECK-ASM: vpkh vss = vec_pack(vsi, vsi); // CHECK: shufflevector <8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i32> + // CHECK-ASM: vpkf vus = vec_pack(vui, vui); // CHECK: shufflevector <8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i32> + // CHECK-ASM: vpkf vbs = vec_pack(vbi, vbi); // CHECK: shufflevector <8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i32> + // CHECK-ASM: vpkf vsi = vec_pack(vsl, vsl); // CHECK: shufflevector <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> + // CHECK-ASM: vpkg vui = vec_pack(vul, vul); // CHECK: shufflevector <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> + // CHECK-ASM: vpkg vbi = vec_pack(vbl, vbl); // CHECK: shufflevector <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> + // CHECK-ASM: vpkg vsc = vec_packs(vss, vss); // CHECK: call <16 x i8> @llvm.s390.vpksh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vpksh vuc = vec_packs(vus, vus); // CHECK: call <16 x i8> @llvm.s390.vpklsh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vpklsh vss = vec_packs(vsi, vsi); // CHECK: call <8 x i16> @llvm.s390.vpksf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vpksf vus = vec_packs(vui, vui); // CHECK: call <8 x i16> @llvm.s390.vpklsf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vpklsf vsi = vec_packs(vsl, vsl); // CHECK: call <4 x i32> @llvm.s390.vpksg(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vpksg vui = vec_packs(vul, vul); // CHECK: call <4 x i32> @llvm.s390.vpklsg(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vpklsg vsc = vec_packs_cc(vss, vss, &cc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vpkshs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vpkshs vuc = vec_packs_cc(vus, vus, &cc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vpklshs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vpklshs vss = vec_packs_cc(vsi, vsi, &cc); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vpksfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vpksfs vus = vec_packs_cc(vui, vui, &cc); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vpklsfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vpklsfs vsi = vec_packs_cc(vsl, vsl, &cc); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vpksgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vpksgs vui = vec_packs_cc(vul, vul, &cc); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vpklsgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vpklsgs vuc = vec_packsu(vss, vss); // CHECK: call <16 x i8> @llvm.s390.vpklsh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vpklsh vuc = vec_packsu(vus, vus); // CHECK: call <16 x i8> @llvm.s390.vpklsh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vpklsh vus = vec_packsu(vsi, vsi); // CHECK: call <8 x i16> @llvm.s390.vpklsf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vpklsf vus = vec_packsu(vui, vui); // CHECK: call <8 x i16> @llvm.s390.vpklsf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vpklsf vui = vec_packsu(vsl, vsl); // CHECK: call <4 x i32> @llvm.s390.vpklsg(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vpklsg vui = vec_packsu(vul, vul); // CHECK: call <4 x i32> @llvm.s390.vpklsg(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vpklsg vuc = vec_packsu_cc(vus, vus, &cc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vpklshs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vpklshs vus = vec_packsu_cc(vui, vui, &cc); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vpklsfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vpklsfs vui = vec_packsu_cc(vul, vul, &cc); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vpklsgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vpklsgs vss = vec_unpackh(vsc); // CHECK: call <8 x i16> @llvm.s390.vuphb(<16 x i8> %{{.*}}) + // CHECK-ASM: vuphb vus = vec_unpackh(vuc); // CHECK: call <8 x i16> @llvm.s390.vuplhb(<16 x i8> %{{.*}}) + // CHECK-ASM: vuplhb vbs = vec_unpackh(vbc); // CHECK: call <8 x i16> @llvm.s390.vuphb(<16 x i8> %{{.*}}) + // CHECK-ASM: vuphb vsi = vec_unpackh(vss); // CHECK: call <4 x i32> @llvm.s390.vuphh(<8 x i16> %{{.*}}) + // CHECK-ASM: vuphh vui = vec_unpackh(vus); // CHECK: call <4 x i32> @llvm.s390.vuplhh(<8 x i16> %{{.*}}) + // CHECK-ASM: vuplhh vbi = vec_unpackh(vbs); // CHECK: call <4 x i32> @llvm.s390.vuphh(<8 x i16> %{{.*}}) + // CHECK-ASM: vuphh vsl = vec_unpackh(vsi); // CHECK: call <2 x i64> @llvm.s390.vuphf(<4 x i32> %{{.*}}) + // CHECK-ASM: vuphf vul = vec_unpackh(vui); // CHECK: call <2 x i64> @llvm.s390.vuplhf(<4 x i32> %{{.*}}) + // CHECK-ASM: vuplhf vbl = vec_unpackh(vbi); // CHECK: call <2 x i64> @llvm.s390.vuphf(<4 x i32> %{{.*}}) + // CHECK-ASM: vuphf vss = vec_unpackl(vsc); // CHECK: call <8 x i16> @llvm.s390.vuplb(<16 x i8> %{{.*}}) + // CHECK-ASM: vuplb vus = vec_unpackl(vuc); // CHECK: call <8 x i16> @llvm.s390.vupllb(<16 x i8> %{{.*}}) + // CHECK-ASM: vupllb vbs = vec_unpackl(vbc); // CHECK: call <8 x i16> @llvm.s390.vuplb(<16 x i8> %{{.*}}) + // CHECK-ASM: vuplb vsi = vec_unpackl(vss); // CHECK: call <4 x i32> @llvm.s390.vuplhw(<8 x i16> %{{.*}}) + // CHECK-ASM: vuplhw vui = vec_unpackl(vus); // CHECK: call <4 x i32> @llvm.s390.vupllh(<8 x i16> %{{.*}}) + // CHECK-ASM: vupllh vbi = vec_unpackl(vbs); // CHECK: call <4 x i32> @llvm.s390.vuplhw(<8 x i16> %{{.*}}) + // CHECK-ASM: vuplhw vsl = vec_unpackl(vsi); // CHECK: call <2 x i64> @llvm.s390.vuplf(<4 x i32> %{{.*}}) + // CHECK-ASM: vuplf vul = vec_unpackl(vui); // CHECK: call <2 x i64> @llvm.s390.vupllf(<4 x i32> %{{.*}}) + // CHECK-ASM: vupllf vbl = vec_unpackl(vbi); // CHECK: call <2 x i64> @llvm.s390.vuplf(<4 x i32> %{{.*}}) + // CHECK-ASM: vuplf } void test_compare(void) { + // CHECK-ASM-LABEL: test_compare + vbc = vec_cmpeq(vsc, vsc); // CHECK: icmp eq <16 x i8> %{{.*}}, %{{.*}} + // CHECK-ASM: vceqb vbc = vec_cmpeq(vuc, vuc); // CHECK: icmp eq <16 x i8> %{{.*}}, %{{.*}} + // CHECK-ASM: vceqb vbc = vec_cmpeq(vbc, vbc); // CHECK: icmp eq <16 x i8> %{{.*}}, %{{.*}} + // CHECK-ASM: vceqb vbs = vec_cmpeq(vss, vss); // CHECK: icmp eq <8 x i16> %{{.*}}, %{{.*}} + // CHECK-ASM: vceqh vbs = vec_cmpeq(vus, vus); // CHECK: icmp eq <8 x i16> %{{.*}}, %{{.*}} + // CHECK-ASM: vceqh vbs = vec_cmpeq(vbs, vbs); // CHECK: icmp eq <8 x i16> %{{.*}}, %{{.*}} + // CHECK-ASM: vceqh vbi = vec_cmpeq(vsi, vsi); // CHECK: icmp eq <4 x i32> %{{.*}}, %{{.*}} + // CHECK-ASM: vceqf vbi = vec_cmpeq(vui, vui); // CHECK: icmp eq <4 x i32> %{{.*}}, %{{.*}} + // CHECK-ASM: vceqf vbi = vec_cmpeq(vbi, vbi); // CHECK: icmp eq <4 x i32> %{{.*}}, %{{.*}} + // CHECK-ASM: vceqf vbl = vec_cmpeq(vsl, vsl); // CHECK: icmp eq <2 x i64> %{{.*}}, %{{.*}} + // CHECK-ASM: vceqg vbl = vec_cmpeq(vul, vul); // CHECK: icmp eq <2 x i64> %{{.*}}, %{{.*}} + // CHECK-ASM: vceqg vbl = vec_cmpeq(vbl, vbl); // CHECK: icmp eq <2 x i64> %{{.*}}, %{{.*}} + // CHECK-ASM: vceqg vbl = vec_cmpeq(vd, vd); // CHECK: fcmp oeq <2 x double> %{{.*}}, %{{.*}} + // CHECK-ASM: vfcedb vbc = vec_cmpge(vsc, vsc); // CHECK: icmp sge <16 x i8> %{{.*}}, %{{.*}} + // CHECK-ASM: vchb vbc = vec_cmpge(vuc, vuc); // CHECK: icmp uge <16 x i8> %{{.*}}, %{{.*}} + // CHECK-ASM: vchlb vbs = vec_cmpge(vss, vss); // CHECK: icmp sge <8 x i16> %{{.*}}, %{{.*}} + // CHECK-ASM: vchh vbs = vec_cmpge(vus, vus); // CHECK: icmp uge <8 x i16> %{{.*}}, %{{.*}} + // CHECK-ASM: vchlh vbi = vec_cmpge(vsi, vsi); // CHECK: icmp sge <4 x i32> %{{.*}}, %{{.*}} + // CHECK-ASM: vchf vbi = vec_cmpge(vui, vui); // CHECK: icmp uge <4 x i32> %{{.*}}, %{{.*}} + // CHECK-ASM: vchlf vbl = vec_cmpge(vsl, vsl); // CHECK: icmp sge <2 x i64> %{{.*}}, %{{.*}} + // CHECK-ASM: vchg vbl = vec_cmpge(vul, vul); // CHECK: icmp uge <2 x i64> %{{.*}}, %{{.*}} + // CHECK-ASM: vchlg vbl = vec_cmpge(vd, vd); // CHECK: fcmp oge <2 x double> %{{.*}}, %{{.*}} + // CHECK-ASM: vfchedb vbc = vec_cmpgt(vsc, vsc); // CHECK: icmp sgt <16 x i8> %{{.*}}, %{{.*}} + // CHECK-ASM: vchb vbc = vec_cmpgt(vuc, vuc); // CHECK: icmp ugt <16 x i8> %{{.*}}, %{{.*}} + // CHECK-ASM: vchlb vbs = vec_cmpgt(vss, vss); // CHECK: icmp sgt <8 x i16> %{{.*}}, %{{.*}} + // CHECK-ASM: vchh vbs = vec_cmpgt(vus, vus); // CHECK: icmp ugt <8 x i16> %{{.*}}, %{{.*}} + // CHECK-ASM: vchlh vbi = vec_cmpgt(vsi, vsi); // CHECK: icmp sgt <4 x i32> %{{.*}}, %{{.*}} + // CHECK-ASM: vchf vbi = vec_cmpgt(vui, vui); // CHECK: icmp ugt <4 x i32> %{{.*}}, %{{.*}} + // CHECK-ASM: vchlf vbl = vec_cmpgt(vsl, vsl); // CHECK: icmp sgt <2 x i64> %{{.*}}, %{{.*}} + // CHECK-ASM: vchg vbl = vec_cmpgt(vul, vul); // CHECK: icmp ugt <2 x i64> %{{.*}}, %{{.*}} + // CHECK-ASM: vchlg vbl = vec_cmpgt(vd, vd); // CHECK: fcmp ogt <2 x double> %{{.*}}, %{{.*}} + // CHECK-ASM: vfchdb vbc = vec_cmple(vsc, vsc); // CHECK: icmp sle <16 x i8> %{{.*}}, %{{.*}} + // CHECK-ASM: vchb vbc = vec_cmple(vuc, vuc); // CHECK: icmp ule <16 x i8> %{{.*}}, %{{.*}} + // CHECK-ASM: vchlb vbs = vec_cmple(vss, vss); // CHECK: icmp sle <8 x i16> %{{.*}}, %{{.*}} + // CHECK-ASM: vchh vbs = vec_cmple(vus, vus); // CHECK: icmp ule <8 x i16> %{{.*}}, %{{.*}} + // CHECK-ASM: vchlh vbi = vec_cmple(vsi, vsi); // CHECK: icmp sle <4 x i32> %{{.*}}, %{{.*}} + // CHECK-ASM: vchf vbi = vec_cmple(vui, vui); // CHECK: icmp ule <4 x i32> %{{.*}}, %{{.*}} + // CHECK-ASM: vchlf vbl = vec_cmple(vsl, vsl); // CHECK: icmp sle <2 x i64> %{{.*}}, %{{.*}} + // CHECK-ASM: vchg vbl = vec_cmple(vul, vul); // CHECK: icmp ule <2 x i64> %{{.*}}, %{{.*}} + // CHECK-ASM: vchlg vbl = vec_cmple(vd, vd); // CHECK: fcmp ole <2 x double> %{{.*}}, %{{.*}} + // CHECK-ASM: vfchedb vbc = vec_cmplt(vsc, vsc); // CHECK: icmp slt <16 x i8> %{{.*}}, %{{.*}} + // CHECK-ASM: vchb vbc = vec_cmplt(vuc, vuc); // CHECK: icmp ult <16 x i8> %{{.*}}, %{{.*}} + // CHECK-ASM: vchlb vbs = vec_cmplt(vss, vss); // CHECK: icmp slt <8 x i16> %{{.*}}, %{{.*}} + // CHECK-ASM: vchh vbs = vec_cmplt(vus, vus); // CHECK: icmp ult <8 x i16> %{{.*}}, %{{.*}} + // CHECK-ASM: vchlh vbi = vec_cmplt(vsi, vsi); // CHECK: icmp slt <4 x i32> %{{.*}}, %{{.*}} + // CHECK-ASM: vchf vbi = vec_cmplt(vui, vui); // CHECK: icmp ult <4 x i32> %{{.*}}, %{{.*}} + // CHECK-ASM: vchlf vbl = vec_cmplt(vsl, vsl); // CHECK: icmp slt <2 x i64> %{{.*}}, %{{.*}} + // CHECK-ASM: vchg vbl = vec_cmplt(vul, vul); // CHECK: icmp ult <2 x i64> %{{.*}}, %{{.*}} + // CHECK-ASM: vchlg vbl = vec_cmplt(vd, vd); // CHECK: fcmp olt <2 x double> %{{.*}}, %{{.*}} + // CHECK-ASM: vfchdb idx = vec_all_eq(vsc, vsc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vceqbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vceqbs idx = vec_all_eq(vsc, vbc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vceqbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vceqbs idx = vec_all_eq(vbc, vsc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vceqbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vceqbs idx = vec_all_eq(vuc, vuc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vceqbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vceqbs idx = vec_all_eq(vuc, vbc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vceqbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vceqbs idx = vec_all_eq(vbc, vuc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vceqbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vceqbs idx = vec_all_eq(vbc, vbc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vceqbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vceqbs idx = vec_all_eq(vss, vss); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vceqhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vceqhs idx = vec_all_eq(vss, vbs); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vceqhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vceqhs idx = vec_all_eq(vbs, vss); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vceqhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vceqhs idx = vec_all_eq(vus, vus); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vceqhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vceqhs idx = vec_all_eq(vus, vbs); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vceqhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vceqhs idx = vec_all_eq(vbs, vus); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vceqhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vceqhs idx = vec_all_eq(vbs, vbs); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vceqhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vceqhs idx = vec_all_eq(vsi, vsi); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vceqfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vceqfs idx = vec_all_eq(vsi, vbi); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vceqfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vceqfs idx = vec_all_eq(vbi, vsi); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vceqfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vceqfs idx = vec_all_eq(vui, vui); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vceqfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vceqfs idx = vec_all_eq(vui, vbi); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vceqfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vceqfs idx = vec_all_eq(vbi, vui); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vceqfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vceqfs idx = vec_all_eq(vbi, vbi); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vceqfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vceqfs idx = vec_all_eq(vsl, vsl); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vceqgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vceqgs idx = vec_all_eq(vsl, vbl); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vceqgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vceqgs idx = vec_all_eq(vbl, vsl); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vceqgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vceqgs idx = vec_all_eq(vul, vul); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vceqgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vceqgs idx = vec_all_eq(vul, vbl); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vceqgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vceqgs idx = vec_all_eq(vbl, vul); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vceqgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vceqgs idx = vec_all_eq(vbl, vbl); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vceqgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vceqgs idx = vec_all_eq(vd, vd); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfcedbs(<2 x double> %{{.*}}, <2 x double> %{{.*}}) + // CHECK-ASM: vfcedbs idx = vec_all_ne(vsc, vsc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vceqbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vceqbs idx = vec_all_ne(vsc, vbc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vceqbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vceqbs idx = vec_all_ne(vbc, vsc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vceqbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vceqbs idx = vec_all_ne(vuc, vuc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vceqbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vceqbs idx = vec_all_ne(vuc, vbc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vceqbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vceqbs idx = vec_all_ne(vbc, vuc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vceqbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vceqbs idx = vec_all_ne(vbc, vbc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vceqbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vceqbs idx = vec_all_ne(vss, vss); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vceqhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vceqhs idx = vec_all_ne(vss, vbs); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vceqhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vceqhs idx = vec_all_ne(vbs, vss); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vceqhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vceqhs idx = vec_all_ne(vus, vus); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vceqhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vceqhs idx = vec_all_ne(vus, vbs); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vceqhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vceqhs idx = vec_all_ne(vbs, vus); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vceqhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vceqhs idx = vec_all_ne(vbs, vbs); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vceqhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vceqhs idx = vec_all_ne(vsi, vsi); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vceqfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vceqfs idx = vec_all_ne(vsi, vbi); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vceqfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vceqfs idx = vec_all_ne(vbi, vsi); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vceqfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vceqfs idx = vec_all_ne(vui, vui); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vceqfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vceqfs idx = vec_all_ne(vui, vbi); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vceqfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vceqfs idx = vec_all_ne(vbi, vui); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vceqfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vceqfs idx = vec_all_ne(vbi, vbi); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vceqfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vceqfs idx = vec_all_ne(vsl, vsl); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vceqgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vceqgs idx = vec_all_ne(vsl, vbl); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vceqgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vceqgs idx = vec_all_ne(vbl, vsl); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vceqgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vceqgs idx = vec_all_ne(vul, vul); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vceqgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vceqgs idx = vec_all_ne(vul, vbl); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vceqgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vceqgs idx = vec_all_ne(vbl, vul); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vceqgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vceqgs idx = vec_all_ne(vbl, vbl); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vceqgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vceqgs idx = vec_all_ne(vd, vd); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfcedbs(<2 x double> %{{.*}}, <2 x double> %{{.*}}) + // CHECK-ASM: vfcedbs idx = vec_all_ge(vsc, vsc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vchbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vchbs idx = vec_all_ge(vsc, vbc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vchbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vchbs idx = vec_all_ge(vbc, vsc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vchbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vchbs idx = vec_all_ge(vuc, vuc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vchlbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vchlbs idx = vec_all_ge(vuc, vbc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vchlbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vchlbs idx = vec_all_ge(vbc, vuc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vchlbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vchlbs idx = vec_all_ge(vbc, vbc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vchlbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vchlbs idx = vec_all_ge(vss, vss); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vchhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vchhs idx = vec_all_ge(vss, vbs); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vchhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vchhs idx = vec_all_ge(vbs, vss); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vchhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vchhs idx = vec_all_ge(vus, vus); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vchlhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vchlhs idx = vec_all_ge(vus, vbs); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vchlhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vchlhs idx = vec_all_ge(vbs, vus); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vchlhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vchlhs idx = vec_all_ge(vbs, vbs); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vchlhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vchlhs idx = vec_all_ge(vsi, vsi); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vchfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vchfs idx = vec_all_ge(vsi, vbi); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vchfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vchfs idx = vec_all_ge(vbi, vsi); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vchfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vchfs idx = vec_all_ge(vui, vui); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vchlfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vchlfs idx = vec_all_ge(vui, vbi); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vchlfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vchlfs idx = vec_all_ge(vbi, vui); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vchlfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vchlfs idx = vec_all_ge(vbi, vbi); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vchlfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vchlfs idx = vec_all_ge(vsl, vsl); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vchgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vchgs idx = vec_all_ge(vsl, vbl); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vchgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vchgs idx = vec_all_ge(vbl, vsl); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vchgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vchgs idx = vec_all_ge(vul, vul); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vchlgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vchlgs idx = vec_all_ge(vul, vbl); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vchlgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vchlgs idx = vec_all_ge(vbl, vul); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vchlgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vchlgs idx = vec_all_ge(vbl, vbl); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vchlgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vchlgs idx = vec_all_ge(vd, vd); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchedbs(<2 x double> %{{.*}}, <2 x double> %{{.*}}) + // CHECK-ASM: vfchedbs idx = vec_all_gt(vsc, vsc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vchbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vchbs idx = vec_all_gt(vsc, vbc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vchbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vchbs idx = vec_all_gt(vbc, vsc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vchbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vchbs idx = vec_all_gt(vuc, vuc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vchlbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vchlbs idx = vec_all_gt(vuc, vbc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vchlbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vchlbs idx = vec_all_gt(vbc, vuc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vchlbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vchlbs idx = vec_all_gt(vbc, vbc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vchlbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vchlbs idx = vec_all_gt(vss, vss); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vchhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vchhs idx = vec_all_gt(vss, vbs); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vchhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vchhs idx = vec_all_gt(vbs, vss); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vchhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vchhs idx = vec_all_gt(vus, vus); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vchlhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vchlhs idx = vec_all_gt(vus, vbs); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vchlhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vchlhs idx = vec_all_gt(vbs, vus); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vchlhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vchlhs idx = vec_all_gt(vbs, vbs); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vchlhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vchlhs idx = vec_all_gt(vsi, vsi); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vchfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vchfs idx = vec_all_gt(vsi, vbi); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vchfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vchfs idx = vec_all_gt(vbi, vsi); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vchfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vchfs idx = vec_all_gt(vui, vui); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vchlfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vchlfs idx = vec_all_gt(vui, vbi); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vchlfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vchlfs idx = vec_all_gt(vbi, vui); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vchlfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vchlfs idx = vec_all_gt(vbi, vbi); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vchlfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vchlfs idx = vec_all_gt(vsl, vsl); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vchgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vchgs idx = vec_all_gt(vsl, vbl); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vchgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vchgs idx = vec_all_gt(vbl, vsl); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vchgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vchgs idx = vec_all_gt(vul, vul); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vchlgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vchlgs idx = vec_all_gt(vul, vbl); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vchlgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vchlgs idx = vec_all_gt(vbl, vul); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vchlgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vchlgs idx = vec_all_gt(vbl, vbl); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vchlgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vchlgs idx = vec_all_gt(vd, vd); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchdbs(<2 x double> %{{.*}}, <2 x double> %{{.*}}) + // CHECK-ASM: vfchdbs idx = vec_all_le(vsc, vsc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vchbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vchbs idx = vec_all_le(vsc, vbc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vchbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vchbs idx = vec_all_le(vbc, vsc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vchbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vchbs idx = vec_all_le(vuc, vuc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vchlbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vchlbs idx = vec_all_le(vuc, vbc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vchlbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vchlbs idx = vec_all_le(vbc, vuc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vchlbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vchlbs idx = vec_all_le(vbc, vbc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vchlbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vchlbs idx = vec_all_le(vss, vss); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vchhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vchhs idx = vec_all_le(vss, vbs); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vchhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vchhs idx = vec_all_le(vbs, vss); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vchhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vchhs idx = vec_all_le(vus, vus); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vchlhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vchlhs idx = vec_all_le(vus, vbs); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vchlhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vchlhs idx = vec_all_le(vbs, vus); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vchlhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vchlhs idx = vec_all_le(vbs, vbs); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vchlhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vchlhs idx = vec_all_le(vsi, vsi); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vchfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vchfs idx = vec_all_le(vsi, vbi); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vchfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vchfs idx = vec_all_le(vbi, vsi); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vchfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vchfs idx = vec_all_le(vui, vui); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vchlfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vchlfs idx = vec_all_le(vui, vbi); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vchlfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vchlfs idx = vec_all_le(vbi, vui); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vchlfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vchlfs idx = vec_all_le(vbi, vbi); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vchlfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vchlfs idx = vec_all_le(vsl, vsl); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vchgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vchgs idx = vec_all_le(vsl, vbl); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vchgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vchgs idx = vec_all_le(vbl, vsl); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vchgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vchgs idx = vec_all_le(vul, vul); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vchlgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vchlgs idx = vec_all_le(vul, vbl); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vchlgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vchlgs idx = vec_all_le(vbl, vul); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vchlgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vchlgs idx = vec_all_le(vbl, vbl); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vchlgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vchlgs idx = vec_all_le(vd, vd); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchedbs(<2 x double> %{{.*}}, <2 x double> %{{.*}}) + // CHECK-ASM: vfchedbs idx = vec_all_lt(vsc, vsc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vchbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vchbs idx = vec_all_lt(vsc, vbc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vchbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vchbs idx = vec_all_lt(vbc, vsc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vchbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vchbs idx = vec_all_lt(vuc, vuc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vchlbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vchlbs idx = vec_all_lt(vuc, vbc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vchlbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vchlbs idx = vec_all_lt(vbc, vuc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vchlbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vchlbs idx = vec_all_lt(vbc, vbc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vchlbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vchlbs idx = vec_all_lt(vss, vss); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vchhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vchhs idx = vec_all_lt(vss, vbs); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vchhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vchhs idx = vec_all_lt(vbs, vss); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vchhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vchhs idx = vec_all_lt(vus, vus); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vchlhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vchlhs idx = vec_all_lt(vus, vbs); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vchlhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vchlhs idx = vec_all_lt(vbs, vus); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vchlhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vchlhs idx = vec_all_lt(vbs, vbs); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vchlhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vchlhs idx = vec_all_lt(vsi, vsi); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vchfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vchfs idx = vec_all_lt(vsi, vbi); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vchfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vchfs idx = vec_all_lt(vbi, vsi); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vchfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vchfs idx = vec_all_lt(vui, vui); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vchlfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vchlfs idx = vec_all_lt(vui, vbi); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vchlfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vchlfs idx = vec_all_lt(vbi, vui); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vchlfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vchlfs idx = vec_all_lt(vbi, vbi); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vchlfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vchlfs idx = vec_all_lt(vsl, vsl); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vchgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vchgs idx = vec_all_lt(vsl, vbl); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vchgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vchgs idx = vec_all_lt(vbl, vsl); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vchgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vchgs idx = vec_all_lt(vul, vul); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vchlgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vchlgs idx = vec_all_lt(vul, vbl); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vchlgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vchlgs idx = vec_all_lt(vbl, vul); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vchlgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vchlgs idx = vec_all_lt(vbl, vbl); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vchlgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vchlgs idx = vec_all_lt(vd, vd); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchdbs(<2 x double> %{{.*}}, <2 x double> %{{.*}}) + // CHECK-ASM: vfchdbs idx = vec_all_nge(vd, vd); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchedbs(<2 x double> %{{.*}}, <2 x double> %{{.*}}) + // CHECK-ASM: vfchedbs idx = vec_all_ngt(vd, vd); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchdbs(<2 x double> %{{.*}}, <2 x double> %{{.*}}) + // CHECK-ASM: vfchdbs idx = vec_all_nle(vd, vd); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchedbs(<2 x double> %{{.*}}, <2 x double> %{{.*}}) + // CHECK-ASM: vfchedbs idx = vec_all_nlt(vd, vd); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchdbs(<2 x double> %{{.*}}, <2 x double> %{{.*}}) + // CHECK-ASM: vfchdbs idx = vec_all_nan(vd); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 15) + // CHECK-ASM: vftcidb idx = vec_all_numeric(vd); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 15) + // CHECK-ASM: vftcidb idx = vec_any_eq(vsc, vsc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vceqbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vceqbs idx = vec_any_eq(vsc, vbc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vceqbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vceqbs idx = vec_any_eq(vbc, vsc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vceqbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vceqbs idx = vec_any_eq(vuc, vuc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vceqbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vceqbs idx = vec_any_eq(vuc, vbc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vceqbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vceqbs idx = vec_any_eq(vbc, vuc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vceqbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vceqbs idx = vec_any_eq(vbc, vbc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vceqbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vceqbs idx = vec_any_eq(vss, vss); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vceqhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vceqhs idx = vec_any_eq(vss, vbs); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vceqhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vceqhs idx = vec_any_eq(vbs, vss); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vceqhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vceqhs idx = vec_any_eq(vus, vus); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vceqhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vceqhs idx = vec_any_eq(vus, vbs); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vceqhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vceqhs idx = vec_any_eq(vbs, vus); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vceqhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vceqhs idx = vec_any_eq(vbs, vbs); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vceqhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vceqhs idx = vec_any_eq(vsi, vsi); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vceqfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vceqfs idx = vec_any_eq(vsi, vbi); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vceqfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vceqfs idx = vec_any_eq(vbi, vsi); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vceqfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vceqfs idx = vec_any_eq(vui, vui); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vceqfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vceqfs idx = vec_any_eq(vui, vbi); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vceqfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vceqfs idx = vec_any_eq(vbi, vui); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vceqfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vceqfs idx = vec_any_eq(vbi, vbi); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vceqfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vceqfs idx = vec_any_eq(vsl, vsl); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vceqgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vceqgs idx = vec_any_eq(vsl, vbl); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vceqgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vceqgs idx = vec_any_eq(vbl, vsl); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vceqgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vceqgs idx = vec_any_eq(vul, vul); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vceqgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vceqgs idx = vec_any_eq(vul, vbl); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vceqgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vceqgs idx = vec_any_eq(vbl, vul); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vceqgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vceqgs idx = vec_any_eq(vbl, vbl); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vceqgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vceqgs idx = vec_any_eq(vd, vd); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfcedbs(<2 x double> %{{.*}}, <2 x double> %{{.*}}) + // CHECK-ASM: vfcedbs idx = vec_any_ne(vsc, vsc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vceqbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vceqbs idx = vec_any_ne(vsc, vbc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vceqbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vceqbs idx = vec_any_ne(vbc, vsc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vceqbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vceqbs idx = vec_any_ne(vuc, vuc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vceqbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vceqbs idx = vec_any_ne(vuc, vbc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vceqbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vceqbs idx = vec_any_ne(vbc, vuc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vceqbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vceqbs idx = vec_any_ne(vbc, vbc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vceqbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vceqbs idx = vec_any_ne(vss, vss); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vceqhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vceqhs idx = vec_any_ne(vss, vbs); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vceqhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vceqhs idx = vec_any_ne(vbs, vss); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vceqhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vceqhs idx = vec_any_ne(vus, vus); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vceqhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vceqhs idx = vec_any_ne(vus, vbs); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vceqhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vceqhs idx = vec_any_ne(vbs, vus); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vceqhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vceqhs idx = vec_any_ne(vbs, vbs); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vceqhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vceqhs idx = vec_any_ne(vsi, vsi); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vceqfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vceqfs idx = vec_any_ne(vsi, vbi); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vceqfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vceqfs idx = vec_any_ne(vbi, vsi); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vceqfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vceqfs idx = vec_any_ne(vui, vui); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vceqfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vceqfs idx = vec_any_ne(vui, vbi); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vceqfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vceqfs idx = vec_any_ne(vbi, vui); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vceqfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vceqfs idx = vec_any_ne(vbi, vbi); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vceqfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vceqfs idx = vec_any_ne(vsl, vsl); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vceqgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vceqgs idx = vec_any_ne(vsl, vbl); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vceqgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vceqgs idx = vec_any_ne(vbl, vsl); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vceqgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vceqgs idx = vec_any_ne(vul, vul); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vceqgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vceqgs idx = vec_any_ne(vul, vbl); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vceqgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vceqgs idx = vec_any_ne(vbl, vul); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vceqgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vceqgs idx = vec_any_ne(vbl, vbl); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vceqgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vceqgs idx = vec_any_ne(vd, vd); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfcedbs(<2 x double> %{{.*}}, <2 x double> %{{.*}}) + // CHECK-ASM: vfcedbs idx = vec_any_ge(vsc, vsc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vchbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vchbs idx = vec_any_ge(vsc, vbc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vchbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vchbs idx = vec_any_ge(vbc, vsc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vchbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vchbs idx = vec_any_ge(vuc, vuc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vchlbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vchlbs idx = vec_any_ge(vuc, vbc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vchlbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vchlbs idx = vec_any_ge(vbc, vuc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vchlbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vchlbs idx = vec_any_ge(vbc, vbc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vchlbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vchlbs idx = vec_any_ge(vss, vss); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vchhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vchhs idx = vec_any_ge(vss, vbs); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vchhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vchhs idx = vec_any_ge(vbs, vss); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vchhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vchhs idx = vec_any_ge(vus, vus); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vchlhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vchlhs idx = vec_any_ge(vus, vbs); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vchlhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vchlhs idx = vec_any_ge(vbs, vus); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vchlhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vchlhs idx = vec_any_ge(vbs, vbs); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vchlhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vchlhs idx = vec_any_ge(vsi, vsi); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vchfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vchfs idx = vec_any_ge(vsi, vbi); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vchfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vchfs idx = vec_any_ge(vbi, vsi); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vchfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vchfs idx = vec_any_ge(vui, vui); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vchlfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vchlfs idx = vec_any_ge(vui, vbi); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vchlfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vchlfs idx = vec_any_ge(vbi, vui); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vchlfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vchlfs idx = vec_any_ge(vbi, vbi); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vchlfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vchlfs idx = vec_any_ge(vsl, vsl); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vchgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vchgs idx = vec_any_ge(vsl, vbl); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vchgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vchgs idx = vec_any_ge(vbl, vsl); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vchgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vchgs idx = vec_any_ge(vul, vul); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vchlgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vchlgs idx = vec_any_ge(vul, vbl); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vchlgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vchlgs idx = vec_any_ge(vbl, vul); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vchlgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vchlgs idx = vec_any_ge(vbl, vbl); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vchlgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vchlgs idx = vec_any_ge(vd, vd); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchedbs(<2 x double> %{{.*}}, <2 x double> %{{.*}}) + // CHECK-ASM: vfchedbs idx = vec_any_gt(vsc, vsc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vchbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vchbs idx = vec_any_gt(vsc, vbc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vchbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vchbs idx = vec_any_gt(vbc, vsc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vchbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vchbs idx = vec_any_gt(vuc, vuc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vchlbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vchlbs idx = vec_any_gt(vuc, vbc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vchlbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vchlbs idx = vec_any_gt(vbc, vuc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vchlbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vchlbs idx = vec_any_gt(vbc, vbc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vchlbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vchlbs idx = vec_any_gt(vss, vss); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vchhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vchhs idx = vec_any_gt(vss, vbs); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vchhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vchhs idx = vec_any_gt(vbs, vss); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vchhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vchhs idx = vec_any_gt(vus, vus); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vchlhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vchlhs idx = vec_any_gt(vus, vbs); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vchlhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vchlhs idx = vec_any_gt(vbs, vus); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vchlhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vchlhs idx = vec_any_gt(vbs, vbs); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vchlhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vchlhs idx = vec_any_gt(vsi, vsi); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vchfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vchfs idx = vec_any_gt(vsi, vbi); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vchfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vchfs idx = vec_any_gt(vbi, vsi); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vchfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vchfs idx = vec_any_gt(vui, vui); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vchlfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vchlfs idx = vec_any_gt(vui, vbi); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vchlfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vchlfs idx = vec_any_gt(vbi, vui); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vchlfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vchlfs idx = vec_any_gt(vbi, vbi); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vchlfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vchlfs idx = vec_any_gt(vsl, vsl); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vchgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vchgs idx = vec_any_gt(vsl, vbl); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vchgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vchgs idx = vec_any_gt(vbl, vsl); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vchgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vchgs idx = vec_any_gt(vul, vul); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vchlgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vchlgs idx = vec_any_gt(vul, vbl); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vchlgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vchlgs idx = vec_any_gt(vbl, vul); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vchlgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vchlgs idx = vec_any_gt(vbl, vbl); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vchlgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vchlgs idx = vec_any_gt(vd, vd); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchdbs(<2 x double> %{{.*}}, <2 x double> %{{.*}}) + // CHECK-ASM: vfchdbs idx = vec_any_le(vsc, vsc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vchbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vchbs idx = vec_any_le(vsc, vbc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vchbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vchbs idx = vec_any_le(vbc, vsc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vchbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vchbs idx = vec_any_le(vuc, vuc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vchlbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vchlbs idx = vec_any_le(vuc, vbc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vchlbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vchlbs idx = vec_any_le(vbc, vuc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vchlbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vchlbs idx = vec_any_le(vbc, vbc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vchlbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vchlbs idx = vec_any_le(vss, vss); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vchhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vchhs idx = vec_any_le(vss, vbs); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vchhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vchhs idx = vec_any_le(vbs, vss); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vchhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vchhs idx = vec_any_le(vus, vus); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vchlhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vchlhs idx = vec_any_le(vus, vbs); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vchlhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vchlhs idx = vec_any_le(vbs, vus); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vchlhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vchlhs idx = vec_any_le(vbs, vbs); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vchlhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vchlhs idx = vec_any_le(vsi, vsi); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vchfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vchfs idx = vec_any_le(vsi, vbi); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vchfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vchfs idx = vec_any_le(vbi, vsi); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vchfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vchfs idx = vec_any_le(vui, vui); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vchlfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vchlfs idx = vec_any_le(vui, vbi); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vchlfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vchlfs idx = vec_any_le(vbi, vui); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vchlfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vchlfs idx = vec_any_le(vbi, vbi); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vchlfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vchlfs idx = vec_any_le(vsl, vsl); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vchgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vchgs idx = vec_any_le(vsl, vbl); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vchgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vchgs idx = vec_any_le(vbl, vsl); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vchgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vchgs idx = vec_any_le(vul, vul); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vchlgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vchlgs idx = vec_any_le(vul, vbl); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vchlgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vchlgs idx = vec_any_le(vbl, vul); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vchlgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vchlgs idx = vec_any_le(vbl, vbl); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vchlgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vchlgs idx = vec_any_le(vd, vd); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchedbs(<2 x double> %{{.*}}, <2 x double> %{{.*}}) + // CHECK-ASM: vfchedbs idx = vec_any_lt(vsc, vsc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vchbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vchbs idx = vec_any_lt(vsc, vbc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vchbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vchbs idx = vec_any_lt(vbc, vsc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vchbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vchbs idx = vec_any_lt(vuc, vuc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vchlbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vchlbs idx = vec_any_lt(vuc, vbc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vchlbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vchlbs idx = vec_any_lt(vbc, vuc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vchlbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vchlbs idx = vec_any_lt(vbc, vbc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vchlbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vchlbs idx = vec_any_lt(vss, vss); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vchhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vchhs idx = vec_any_lt(vss, vbs); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vchhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vchhs idx = vec_any_lt(vbs, vss); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vchhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vchhs idx = vec_any_lt(vus, vus); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vchlhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vchlhs idx = vec_any_lt(vus, vbs); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vchlhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vchlhs idx = vec_any_lt(vbs, vus); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vchlhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vchlhs idx = vec_any_lt(vbs, vbs); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vchlhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vchlhs idx = vec_any_lt(vsi, vsi); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vchfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vchfs idx = vec_any_lt(vsi, vbi); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vchfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vchfs idx = vec_any_lt(vbi, vsi); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vchfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vchfs idx = vec_any_lt(vui, vui); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vchlfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vchlfs idx = vec_any_lt(vui, vbi); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vchlfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vchlfs idx = vec_any_lt(vbi, vui); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vchlfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vchlfs idx = vec_any_lt(vbi, vbi); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vchlfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vchlfs idx = vec_any_lt(vsl, vsl); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vchgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vchgs idx = vec_any_lt(vsl, vbl); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vchgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vchgs idx = vec_any_lt(vbl, vsl); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vchgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vchgs idx = vec_any_lt(vul, vul); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vchlgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vchlgs idx = vec_any_lt(vul, vbl); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vchlgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vchlgs idx = vec_any_lt(vbl, vul); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vchlgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vchlgs idx = vec_any_lt(vbl, vbl); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vchlgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vchlgs idx = vec_any_lt(vd, vd); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchdbs(<2 x double> %{{.*}}, <2 x double> %{{.*}}) + // CHECK-ASM: vfchdbs idx = vec_any_nge(vd, vd); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchedbs(<2 x double> %{{.*}}, <2 x double> %{{.*}}) + // CHECK-ASM: vfchedbs idx = vec_any_ngt(vd, vd); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchdbs(<2 x double> %{{.*}}, <2 x double> %{{.*}}) + // CHECK-ASM: vfchdbs idx = vec_any_nle(vd, vd); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchedbs(<2 x double> %{{.*}}, <2 x double> %{{.*}}) + // CHECK-ASM: vfchedbs idx = vec_any_nlt(vd, vd); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchdbs(<2 x double> %{{.*}}, <2 x double> %{{.*}}) + // CHECK-ASM: vfchdbs idx = vec_any_nan(vd); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 15) + // CHECK-ASM: vftcidb idx = vec_any_numeric(vd); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 15) + // CHECK-ASM: vftcidb } void test_integer(void) { + // CHECK-ASM-LABEL: test_integer + vsc = vec_andc(vsc, vsc); + // CHECK-ASM: vnc vsc = vec_andc(vsc, vbc); + // CHECK-ASM: vnc vsc = vec_andc(vbc, vsc); + // CHECK-ASM: vnc vuc = vec_andc(vuc, vuc); + // CHECK-ASM: vnc vuc = vec_andc(vuc, vbc); + // CHECK-ASM: vnc vuc = vec_andc(vbc, vuc); + // CHECK-ASM: vnc vbc = vec_andc(vbc, vbc); + // CHECK-ASM: vnc vss = vec_andc(vss, vss); + // CHECK-ASM: vnc vss = vec_andc(vss, vbs); + // CHECK-ASM: vnc vss = vec_andc(vbs, vss); + // CHECK-ASM: vnc vus = vec_andc(vus, vus); + // CHECK-ASM: vnc vus = vec_andc(vus, vbs); + // CHECK-ASM: vnc vus = vec_andc(vbs, vus); + // CHECK-ASM: vnc vbs = vec_andc(vbs, vbs); + // CHECK-ASM: vnc vsi = vec_andc(vsi, vsi); + // CHECK-ASM: vnc vsi = vec_andc(vsi, vbi); + // CHECK-ASM: vnc vsi = vec_andc(vbi, vsi); + // CHECK-ASM: vnc vui = vec_andc(vui, vui); + // CHECK-ASM: vnc vui = vec_andc(vui, vbi); + // CHECK-ASM: vnc vui = vec_andc(vbi, vui); + // CHECK-ASM: vnc vbi = vec_andc(vbi, vbi); + // CHECK-ASM: vnc vsl = vec_andc(vsl, vsl); + // CHECK-ASM: vnc vsl = vec_andc(vsl, vbl); + // CHECK-ASM: vnc vsl = vec_andc(vbl, vsl); + // CHECK-ASM: vnc vul = vec_andc(vul, vul); + // CHECK-ASM: vnc vul = vec_andc(vul, vbl); + // CHECK-ASM: vnc vul = vec_andc(vbl, vul); + // CHECK-ASM: vnc vbl = vec_andc(vbl, vbl); + // CHECK-ASM: vnc vd = vec_andc(vd, vd); + // CHECK-ASM: vnc vd = vec_andc(vd, vbl); + // CHECK-ASM: vnc vd = vec_andc(vbl, vd); + // CHECK-ASM: vnc vsc = vec_nor(vsc, vsc); + // CHECK-ASM: vno vsc = vec_nor(vsc, vbc); + // CHECK-ASM: vno vsc = vec_nor(vbc, vsc); + // CHECK-ASM: vno vuc = vec_nor(vuc, vuc); + // CHECK-ASM: vno vuc = vec_nor(vuc, vbc); + // CHECK-ASM: vno vuc = vec_nor(vbc, vuc); + // CHECK-ASM: vno vbc = vec_nor(vbc, vbc); + // CHECK-ASM: vno vss = vec_nor(vss, vss); + // CHECK-ASM: vno vss = vec_nor(vss, vbs); + // CHECK-ASM: vno vss = vec_nor(vbs, vss); + // CHECK-ASM: vno vus = vec_nor(vus, vus); + // CHECK-ASM: vno vus = vec_nor(vus, vbs); + // CHECK-ASM: vno vus = vec_nor(vbs, vus); + // CHECK-ASM: vno vbs = vec_nor(vbs, vbs); + // CHECK-ASM: vno vsi = vec_nor(vsi, vsi); + // CHECK-ASM: vno vsi = vec_nor(vsi, vbi); + // CHECK-ASM: vno vsi = vec_nor(vbi, vsi); + // CHECK-ASM: vno vui = vec_nor(vui, vui); + // CHECK-ASM: vno vui = vec_nor(vui, vbi); + // CHECK-ASM: vno vui = vec_nor(vbi, vui); + // CHECK-ASM: vno vbi = vec_nor(vbi, vbi); + // CHECK-ASM: vno vsl = vec_nor(vsl, vsl); + // CHECK-ASM: vno vsl = vec_nor(vsl, vbl); + // CHECK-ASM: vno vsl = vec_nor(vbl, vsl); + // CHECK-ASM: vno vul = vec_nor(vul, vul); + // CHECK-ASM: vno vul = vec_nor(vul, vbl); + // CHECK-ASM: vno vul = vec_nor(vbl, vul); + // CHECK-ASM: vno vbl = vec_nor(vbl, vbl); + // CHECK-ASM: vno vd = vec_nor(vd, vd); + // CHECK-ASM: vno vd = vec_nor(vd, vbl); + // CHECK-ASM: vno vd = vec_nor(vbl, vd); + // CHECK-ASM: vno vuc = vec_cntlz(vsc); // CHECK: call <16 x i8> @llvm.ctlz.v16i8(<16 x i8> %{{.*}}, i1 false) + // CHECK-ASM: vclzb vuc = vec_cntlz(vuc); // CHECK: call <16 x i8> @llvm.ctlz.v16i8(<16 x i8> %{{.*}}, i1 false) + // CHECK-ASM: vclzb vus = vec_cntlz(vss); // CHECK: call <8 x i16> @llvm.ctlz.v8i16(<8 x i16> %{{.*}}, i1 false) + // CHECK-ASM: vclzh vus = vec_cntlz(vus); // CHECK: call <8 x i16> @llvm.ctlz.v8i16(<8 x i16> %{{.*}}, i1 false) + // CHECK-ASM: vclzh vui = vec_cntlz(vsi); // CHECK: call <4 x i32> @llvm.ctlz.v4i32(<4 x i32> %{{.*}}, i1 false) + // CHECK-ASM: vclzf vui = vec_cntlz(vui); // CHECK: call <4 x i32> @llvm.ctlz.v4i32(<4 x i32> %{{.*}}, i1 false) + // CHECK-ASM: vclzf vul = vec_cntlz(vsl); // CHECK: call <2 x i64> @llvm.ctlz.v2i64(<2 x i64> %{{.*}}, i1 false) + // CHECK-ASM: vclzg vul = vec_cntlz(vul); // CHECK: call <2 x i64> @llvm.ctlz.v2i64(<2 x i64> %{{.*}}, i1 false) + // CHECK-ASM: vclzg vuc = vec_cnttz(vsc); // CHECK: call <16 x i8> @llvm.cttz.v16i8(<16 x i8> %{{.*}}, i1 false) + // CHECK-ASM: vctzb vuc = vec_cnttz(vuc); // CHECK: call <16 x i8> @llvm.cttz.v16i8(<16 x i8> %{{.*}}, i1 false) + // CHECK-ASM: vctzb vus = vec_cnttz(vss); // CHECK: call <8 x i16> @llvm.cttz.v8i16(<8 x i16> %{{.*}}, i1 false) + // CHECK-ASM: vctzh vus = vec_cnttz(vus); // CHECK: call <8 x i16> @llvm.cttz.v8i16(<8 x i16> %{{.*}}, i1 false) + // CHECK-ASM: vctzh vui = vec_cnttz(vsi); // CHECK: call <4 x i32> @llvm.cttz.v4i32(<4 x i32> %{{.*}}, i1 false) + // CHECK-ASM: vctzf vui = vec_cnttz(vui); // CHECK: call <4 x i32> @llvm.cttz.v4i32(<4 x i32> %{{.*}}, i1 false) + // CHECK-ASM: vctzf vul = vec_cnttz(vsl); // CHECK: call <2 x i64> @llvm.cttz.v2i64(<2 x i64> %{{.*}}, i1 false) + // CHECK-ASM: vctzg vul = vec_cnttz(vul); // CHECK: call <2 x i64> @llvm.cttz.v2i64(<2 x i64> %{{.*}}, i1 false) + // CHECK-ASM: vctzg vuc = vec_popcnt(vsc); // CHECK: call <16 x i8> @llvm.ctpop.v16i8(<16 x i8> %{{.*}}) + // CHECK-ASM: vpopct vuc = vec_popcnt(vuc); // CHECK: call <16 x i8> @llvm.ctpop.v16i8(<16 x i8> %{{.*}}) + // CHECK-ASM: vpopct vus = vec_popcnt(vss); // CHECK: call <8 x i16> @llvm.ctpop.v8i16(<8 x i16> %{{.*}}) + // (emulated) vus = vec_popcnt(vus); // CHECK: call <8 x i16> @llvm.ctpop.v8i16(<8 x i16> %{{.*}}) + // (emulated) vui = vec_popcnt(vsi); // CHECK: call <4 x i32> @llvm.ctpop.v4i32(<4 x i32> %{{.*}}) + // (emulated) vui = vec_popcnt(vui); // CHECK: call <4 x i32> @llvm.ctpop.v4i32(<4 x i32> %{{.*}}) + // (emulated) vul = vec_popcnt(vsl); // CHECK: call <2 x i64> @llvm.ctpop.v2i64(<2 x i64> %{{.*}}) + // (emulated) vul = vec_popcnt(vul); // CHECK: call <2 x i64> @llvm.ctpop.v2i64(<2 x i64> %{{.*}}) + // (emulated) vsc = vec_rl(vsc, vuc); // CHECK: call <16 x i8> @llvm.s390.verllvb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: verllvb vuc = vec_rl(vuc, vuc); // CHECK: call <16 x i8> @llvm.s390.verllvb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: verllvb vss = vec_rl(vss, vus); // CHECK: call <8 x i16> @llvm.s390.verllvh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: verllvh vus = vec_rl(vus, vus); // CHECK: call <8 x i16> @llvm.s390.verllvh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: verllvh vsi = vec_rl(vsi, vui); // CHECK: call <4 x i32> @llvm.s390.verllvf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: verllvf vui = vec_rl(vui, vui); // CHECK: call <4 x i32> @llvm.s390.verllvf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: verllvf vsl = vec_rl(vsl, vul); // CHECK: call <2 x i64> @llvm.s390.verllvg(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: verllvg vul = vec_rl(vul, vul); // CHECK: call <2 x i64> @llvm.s390.verllvg(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: verllvg vsc = vec_rli(vsc, ul); // CHECK: call <16 x i8> @llvm.s390.verllb(<16 x i8> %{{.*}}, i32 %{{.*}}) + // CHECK-ASM: verllb vuc = vec_rli(vuc, ul); // CHECK: call <16 x i8> @llvm.s390.verllb(<16 x i8> %{{.*}}, i32 %{{.*}}) + // CHECK-ASM: verllb vss = vec_rli(vss, ul); // CHECK: call <8 x i16> @llvm.s390.verllh(<8 x i16> %{{.*}}, i32 %{{.*}}) + // CHECK-ASM: verllh vus = vec_rli(vus, ul); // CHECK: call <8 x i16> @llvm.s390.verllh(<8 x i16> %{{.*}}, i32 %{{.*}}) + // CHECK-ASM: verllh vsi = vec_rli(vsi, ul); // CHECK: call <4 x i32> @llvm.s390.verllf(<4 x i32> %{{.*}}, i32 %{{.*}}) + // CHECK-ASM: verllf vui = vec_rli(vui, ul); // CHECK: call <4 x i32> @llvm.s390.verllf(<4 x i32> %{{.*}}, i32 %{{.*}}) + // CHECK-ASM: verllf vsl = vec_rli(vsl, ul); // CHECK: call <2 x i64> @llvm.s390.verllg(<2 x i64> %{{.*}}, i32 %{{.*}}) + // CHECK-ASM: verllg vul = vec_rli(vul, ul); // CHECK: call <2 x i64> @llvm.s390.verllg(<2 x i64> %{{.*}}, i32 %{{.*}}) + // CHECK-ASM: verllg vsc = vec_rl_mask(vsc, vuc, 0); // CHECK: call <16 x i8> @llvm.s390.verimb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0) + // CHECK-ASM: verimb vsc = vec_rl_mask(vsc, vuc, 255); // CHECK: call <16 x i8> @llvm.s390.verimb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 255) + // CHECK-ASM: verimb vuc = vec_rl_mask(vuc, vuc, 0); // CHECK: call <16 x i8> @llvm.s390.verimb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0) + // CHECK-ASM: verimb vuc = vec_rl_mask(vuc, vuc, 255); // CHECK: call <16 x i8> @llvm.s390.verimb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 255) + // CHECK-ASM: verimb vss = vec_rl_mask(vss, vus, 0); // CHECK: call <8 x i16> @llvm.s390.verimh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 0) + // CHECK-ASM: verimh vss = vec_rl_mask(vss, vus, 255); // CHECK: call <8 x i16> @llvm.s390.verimh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 255) + // CHECK-ASM: verimh vus = vec_rl_mask(vus, vus, 0); // CHECK: call <8 x i16> @llvm.s390.verimh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 0) + // CHECK-ASM: verimh vus = vec_rl_mask(vus, vus, 255); // CHECK: call <8 x i16> @llvm.s390.verimh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 255) + // CHECK-ASM: verimh vsi = vec_rl_mask(vsi, vui, 0); // CHECK: call <4 x i32> @llvm.s390.verimf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 0) + // CHECK-ASM: verimf vsi = vec_rl_mask(vsi, vui, 255); // CHECK: call <4 x i32> @llvm.s390.verimf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 255) + // CHECK-ASM: verimf vui = vec_rl_mask(vui, vui, 0); // CHECK: call <4 x i32> @llvm.s390.verimf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 0) + // CHECK-ASM: verimf vui = vec_rl_mask(vui, vui, 255); // CHECK: call <4 x i32> @llvm.s390.verimf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 255) + // CHECK-ASM: verimf vsl = vec_rl_mask(vsl, vul, 0); // CHECK: call <2 x i64> @llvm.s390.verimg(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}}, i32 0) + // CHECK-ASM: verimg vsl = vec_rl_mask(vsl, vul, 255); // CHECK: call <2 x i64> @llvm.s390.verimg(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}}, i32 255) + // CHECK-ASM: verimg vul = vec_rl_mask(vul, vul, 0); // CHECK: call <2 x i64> @llvm.s390.verimg(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}}, i32 0) + // CHECK-ASM: verimg vul = vec_rl_mask(vul, vul, 255); // CHECK: call <2 x i64> @llvm.s390.verimg(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}}, i32 255) + // CHECK-ASM: verimg vsc = vec_sll(vsc, vuc); // CHECK: call <16 x i8> @llvm.s390.vsl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsl vsc = vec_sll(vsc, vus); // CHECK: call <16 x i8> @llvm.s390.vsl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsl vsc = vec_sll(vsc, vui); // CHECK: call <16 x i8> @llvm.s390.vsl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsl vuc = vec_sll(vuc, vuc); // CHECK: call <16 x i8> @llvm.s390.vsl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsl vuc = vec_sll(vuc, vus); // CHECK: call <16 x i8> @llvm.s390.vsl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsl vuc = vec_sll(vuc, vui); // CHECK: call <16 x i8> @llvm.s390.vsl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsl vbc = vec_sll(vbc, vuc); // CHECK: call <16 x i8> @llvm.s390.vsl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsl vbc = vec_sll(vbc, vus); // CHECK: call <16 x i8> @llvm.s390.vsl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsl vbc = vec_sll(vbc, vui); // CHECK: call <16 x i8> @llvm.s390.vsl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsl vss = vec_sll(vss, vuc); // CHECK: call <16 x i8> @llvm.s390.vsl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsl vss = vec_sll(vss, vus); // CHECK: call <16 x i8> @llvm.s390.vsl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsl vss = vec_sll(vss, vui); // CHECK: call <16 x i8> @llvm.s390.vsl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsl vus = vec_sll(vus, vuc); // CHECK: call <16 x i8> @llvm.s390.vsl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsl vus = vec_sll(vus, vus); // CHECK: call <16 x i8> @llvm.s390.vsl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsl vus = vec_sll(vus, vui); // CHECK: call <16 x i8> @llvm.s390.vsl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsl vbs = vec_sll(vbs, vuc); // CHECK: call <16 x i8> @llvm.s390.vsl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsl vbs = vec_sll(vbs, vus); // CHECK: call <16 x i8> @llvm.s390.vsl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsl vbs = vec_sll(vbs, vui); // CHECK: call <16 x i8> @llvm.s390.vsl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsl vsi = vec_sll(vsi, vuc); // CHECK: call <16 x i8> @llvm.s390.vsl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsl vsi = vec_sll(vsi, vus); // CHECK: call <16 x i8> @llvm.s390.vsl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsl vsi = vec_sll(vsi, vui); // CHECK: call <16 x i8> @llvm.s390.vsl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsl vui = vec_sll(vui, vuc); // CHECK: call <16 x i8> @llvm.s390.vsl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsl vui = vec_sll(vui, vus); // CHECK: call <16 x i8> @llvm.s390.vsl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsl vui = vec_sll(vui, vui); // CHECK: call <16 x i8> @llvm.s390.vsl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsl vbi = vec_sll(vbi, vuc); // CHECK: call <16 x i8> @llvm.s390.vsl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsl vbi = vec_sll(vbi, vus); // CHECK: call <16 x i8> @llvm.s390.vsl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsl vbi = vec_sll(vbi, vui); // CHECK: call <16 x i8> @llvm.s390.vsl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsl vsl = vec_sll(vsl, vuc); // CHECK: call <16 x i8> @llvm.s390.vsl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsl vsl = vec_sll(vsl, vus); // CHECK: call <16 x i8> @llvm.s390.vsl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsl vsl = vec_sll(vsl, vui); // CHECK: call <16 x i8> @llvm.s390.vsl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsl vul = vec_sll(vul, vuc); // CHECK: call <16 x i8> @llvm.s390.vsl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsl vul = vec_sll(vul, vus); // CHECK: call <16 x i8> @llvm.s390.vsl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsl vul = vec_sll(vul, vui); // CHECK: call <16 x i8> @llvm.s390.vsl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsl vbl = vec_sll(vbl, vuc); // CHECK: call <16 x i8> @llvm.s390.vsl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsl vbl = vec_sll(vbl, vus); // CHECK: call <16 x i8> @llvm.s390.vsl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsl vbl = vec_sll(vbl, vui); // CHECK: call <16 x i8> @llvm.s390.vsl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsl vsc = vec_slb(vsc, vsc); // CHECK: call <16 x i8> @llvm.s390.vslb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vslb vsc = vec_slb(vsc, vuc); // CHECK: call <16 x i8> @llvm.s390.vslb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vslb vuc = vec_slb(vuc, vsc); // CHECK: call <16 x i8> @llvm.s390.vslb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vslb vuc = vec_slb(vuc, vuc); // CHECK: call <16 x i8> @llvm.s390.vslb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vslb vss = vec_slb(vss, vss); // CHECK: call <16 x i8> @llvm.s390.vslb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vslb vss = vec_slb(vss, vus); // CHECK: call <16 x i8> @llvm.s390.vslb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vslb vus = vec_slb(vus, vss); // CHECK: call <16 x i8> @llvm.s390.vslb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vslb vus = vec_slb(vus, vus); // CHECK: call <16 x i8> @llvm.s390.vslb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vslb vsi = vec_slb(vsi, vsi); // CHECK: call <16 x i8> @llvm.s390.vslb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vslb vsi = vec_slb(vsi, vui); // CHECK: call <16 x i8> @llvm.s390.vslb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vslb vui = vec_slb(vui, vsi); // CHECK: call <16 x i8> @llvm.s390.vslb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vslb vui = vec_slb(vui, vui); // CHECK: call <16 x i8> @llvm.s390.vslb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vslb vsl = vec_slb(vsl, vsl); // CHECK: call <16 x i8> @llvm.s390.vslb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vslb vsl = vec_slb(vsl, vul); // CHECK: call <16 x i8> @llvm.s390.vslb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vslb vul = vec_slb(vul, vsl); // CHECK: call <16 x i8> @llvm.s390.vslb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vslb vul = vec_slb(vul, vul); // CHECK: call <16 x i8> @llvm.s390.vslb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vslb vd = vec_slb(vd, vsl); // CHECK: call <16 x i8> @llvm.s390.vslb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vslb vd = vec_slb(vd, vul); // CHECK: call <16 x i8> @llvm.s390.vslb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vslb vsc = vec_sld(vsc, vsc, 0); // CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0) + // CHECK-ASM: vsldb vsc = vec_sld(vsc, vsc, 15); // CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 15) + // CHECK-ASM: vsldb vuc = vec_sld(vuc, vuc, 0); // CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0) + // CHECK-ASM: vsldb vuc = vec_sld(vuc, vuc, 15); // CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 15) + // CHECK-ASM: vsldb vbc = vec_sld(vbc, vbc, 0); // CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0) + // CHECK-ASM: vsldb vbc = vec_sld(vbc, vbc, 15); // CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 15) + // CHECK-ASM: vsldb vss = vec_sld(vss, vss, 0); // CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0) + // CHECK-ASM: vsldb vss = vec_sld(vss, vss, 15); // CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 15) + // CHECK-ASM: vsldb vus = vec_sld(vus, vus, 0); // CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0) + // CHECK-ASM: vsldb vus = vec_sld(vus, vus, 15); // CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 15) + // CHECK-ASM: vsldb vbs = vec_sld(vbs, vbs, 0); // CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0) + // CHECK-ASM: vsldb vbs = vec_sld(vbs, vbs, 15); // CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 15) + // CHECK-ASM: vsldb vsi = vec_sld(vsi, vsi, 0); // CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0) + // CHECK-ASM: vsldb vsi = vec_sld(vsi, vsi, 15); // CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 15) + // CHECK-ASM: vsldb vui = vec_sld(vui, vui, 0); // CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0) + // CHECK-ASM: vsldb vui = vec_sld(vui, vui, 15); // CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 15) + // CHECK-ASM: vsldb vbi = vec_sld(vbi, vbi, 0); // CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0) + // CHECK-ASM: vsldb vbi = vec_sld(vbi, vbi, 15); // CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 15) + // CHECK-ASM: vsldb vsl = vec_sld(vsl, vsl, 0); // CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0) + // CHECK-ASM: vsldb vsl = vec_sld(vsl, vsl, 15); // CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 15) + // CHECK-ASM: vsldb vul = vec_sld(vul, vul, 0); // CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0) + // CHECK-ASM: vsldb vul = vec_sld(vul, vul, 15); // CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 15) + // CHECK-ASM: vsldb vbl = vec_sld(vbl, vbl, 0); // CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0) + // CHECK-ASM: vsldb vbl = vec_sld(vbl, vbl, 15); // CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 15) + // CHECK-ASM: vsldb vd = vec_sld(vd, vd, 0); // CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0) + // CHECK-ASM: vsldb vd = vec_sld(vd, vd, 15); // CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 15) + // CHECK-ASM: vsldb vsc = vec_sldw(vsc, vsc, 0); // CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0) + // CHECK-ASM: vsldb vsc = vec_sldw(vsc, vsc, 3); // CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 12) + // CHECK-ASM: vsldb vuc = vec_sldw(vuc, vuc, 0); // CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0) + // CHECK-ASM: vsldb vuc = vec_sldw(vuc, vuc, 3); // CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 12) + // CHECK-ASM: vsldb vss = vec_sldw(vss, vss, 0); // CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0) + // CHECK-ASM: vsldb vss = vec_sldw(vss, vss, 3); // CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 12) + // CHECK-ASM: vsldb vus = vec_sldw(vus, vus, 0); // CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0) + // CHECK-ASM: vsldb vus = vec_sldw(vus, vus, 3); // CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 12) + // CHECK-ASM: vsldb vsi = vec_sldw(vsi, vsi, 0); // CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0) + // CHECK-ASM: vsldb vsi = vec_sldw(vsi, vsi, 3); // CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 12) + // CHECK-ASM: vsldb vui = vec_sldw(vui, vui, 0); // CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0) + // CHECK-ASM: vsldb vui = vec_sldw(vui, vui, 3); // CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 12) + // CHECK-ASM: vsldb vsl = vec_sldw(vsl, vsl, 0); // CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0) + // CHECK-ASM: vsldb vsl = vec_sldw(vsl, vsl, 3); // CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 12) + // CHECK-ASM: vsldb vul = vec_sldw(vul, vul, 0); // CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0) + // CHECK-ASM: vsldb vul = vec_sldw(vul, vul, 3); // CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 12) + // CHECK-ASM: vsldb vd = vec_sldw(vd, vd, 0); // CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0) + // CHECK-ASM: vsldb vd = vec_sldw(vd, vd, 3); // CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 12) + // CHECK-ASM: vsldb vsc = vec_sral(vsc, vuc); // CHECK: call <16 x i8> @llvm.s390.vsra(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsra vsc = vec_sral(vsc, vus); // CHECK: call <16 x i8> @llvm.s390.vsra(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsra vsc = vec_sral(vsc, vui); // CHECK: call <16 x i8> @llvm.s390.vsra(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsra vuc = vec_sral(vuc, vuc); // CHECK: call <16 x i8> @llvm.s390.vsra(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsra vuc = vec_sral(vuc, vus); // CHECK: call <16 x i8> @llvm.s390.vsra(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsra vuc = vec_sral(vuc, vui); // CHECK: call <16 x i8> @llvm.s390.vsra(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsra vbc = vec_sral(vbc, vuc); // CHECK: call <16 x i8> @llvm.s390.vsra(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsra vbc = vec_sral(vbc, vus); // CHECK: call <16 x i8> @llvm.s390.vsra(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsra vbc = vec_sral(vbc, vui); // CHECK: call <16 x i8> @llvm.s390.vsra(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsra vss = vec_sral(vss, vuc); // CHECK: call <16 x i8> @llvm.s390.vsra(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsra vss = vec_sral(vss, vus); // CHECK: call <16 x i8> @llvm.s390.vsra(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsra vss = vec_sral(vss, vui); // CHECK: call <16 x i8> @llvm.s390.vsra(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsra vus = vec_sral(vus, vuc); // CHECK: call <16 x i8> @llvm.s390.vsra(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsra vus = vec_sral(vus, vus); // CHECK: call <16 x i8> @llvm.s390.vsra(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsra vus = vec_sral(vus, vui); // CHECK: call <16 x i8> @llvm.s390.vsra(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsra vbs = vec_sral(vbs, vuc); // CHECK: call <16 x i8> @llvm.s390.vsra(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsra vbs = vec_sral(vbs, vus); // CHECK: call <16 x i8> @llvm.s390.vsra(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsra vbs = vec_sral(vbs, vui); // CHECK: call <16 x i8> @llvm.s390.vsra(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsra vsi = vec_sral(vsi, vuc); // CHECK: call <16 x i8> @llvm.s390.vsra(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsra vsi = vec_sral(vsi, vus); // CHECK: call <16 x i8> @llvm.s390.vsra(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsra vsi = vec_sral(vsi, vui); // CHECK: call <16 x i8> @llvm.s390.vsra(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsra vui = vec_sral(vui, vuc); // CHECK: call <16 x i8> @llvm.s390.vsra(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsra vui = vec_sral(vui, vus); // CHECK: call <16 x i8> @llvm.s390.vsra(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsra vui = vec_sral(vui, vui); // CHECK: call <16 x i8> @llvm.s390.vsra(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsra vbi = vec_sral(vbi, vuc); // CHECK: call <16 x i8> @llvm.s390.vsra(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsra vbi = vec_sral(vbi, vus); // CHECK: call <16 x i8> @llvm.s390.vsra(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsra vbi = vec_sral(vbi, vui); // CHECK: call <16 x i8> @llvm.s390.vsra(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsra vsl = vec_sral(vsl, vuc); // CHECK: call <16 x i8> @llvm.s390.vsra(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsra vsl = vec_sral(vsl, vus); // CHECK: call <16 x i8> @llvm.s390.vsra(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsra vsl = vec_sral(vsl, vui); // CHECK: call <16 x i8> @llvm.s390.vsra(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsra vul = vec_sral(vul, vuc); // CHECK: call <16 x i8> @llvm.s390.vsra(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsra vul = vec_sral(vul, vus); // CHECK: call <16 x i8> @llvm.s390.vsra(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsra vul = vec_sral(vul, vui); // CHECK: call <16 x i8> @llvm.s390.vsra(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsra vbl = vec_sral(vbl, vuc); // CHECK: call <16 x i8> @llvm.s390.vsra(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsra vbl = vec_sral(vbl, vus); // CHECK: call <16 x i8> @llvm.s390.vsra(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsra vbl = vec_sral(vbl, vui); // CHECK: call <16 x i8> @llvm.s390.vsra(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsra vsc = vec_srab(vsc, vsc); // CHECK: call <16 x i8> @llvm.s390.vsrab(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrab vsc = vec_srab(vsc, vuc); // CHECK: call <16 x i8> @llvm.s390.vsrab(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrab vuc = vec_srab(vuc, vsc); // CHECK: call <16 x i8> @llvm.s390.vsrab(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrab vuc = vec_srab(vuc, vuc); // CHECK: call <16 x i8> @llvm.s390.vsrab(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrab vss = vec_srab(vss, vss); // CHECK: call <16 x i8> @llvm.s390.vsrab(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrab vss = vec_srab(vss, vus); // CHECK: call <16 x i8> @llvm.s390.vsrab(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrab vus = vec_srab(vus, vss); // CHECK: call <16 x i8> @llvm.s390.vsrab(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrab vus = vec_srab(vus, vus); // CHECK: call <16 x i8> @llvm.s390.vsrab(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrab vsi = vec_srab(vsi, vsi); // CHECK: call <16 x i8> @llvm.s390.vsrab(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrab vsi = vec_srab(vsi, vui); // CHECK: call <16 x i8> @llvm.s390.vsrab(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrab vui = vec_srab(vui, vsi); // CHECK: call <16 x i8> @llvm.s390.vsrab(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrab vui = vec_srab(vui, vui); // CHECK: call <16 x i8> @llvm.s390.vsrab(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrab vsl = vec_srab(vsl, vsl); // CHECK: call <16 x i8> @llvm.s390.vsrab(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrab vsl = vec_srab(vsl, vul); // CHECK: call <16 x i8> @llvm.s390.vsrab(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrab vul = vec_srab(vul, vsl); // CHECK: call <16 x i8> @llvm.s390.vsrab(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrab vul = vec_srab(vul, vul); // CHECK: call <16 x i8> @llvm.s390.vsrab(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrab vd = vec_srab(vd, vsl); // CHECK: call <16 x i8> @llvm.s390.vsrab(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrab vd = vec_srab(vd, vul); // CHECK: call <16 x i8> @llvm.s390.vsrab(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrab vsc = vec_srl(vsc, vuc); // CHECK: call <16 x i8> @llvm.s390.vsrl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrl vsc = vec_srl(vsc, vus); // CHECK: call <16 x i8> @llvm.s390.vsrl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrl vsc = vec_srl(vsc, vui); // CHECK: call <16 x i8> @llvm.s390.vsrl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrl vuc = vec_srl(vuc, vuc); // CHECK: call <16 x i8> @llvm.s390.vsrl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrl vuc = vec_srl(vuc, vus); // CHECK: call <16 x i8> @llvm.s390.vsrl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrl vuc = vec_srl(vuc, vui); // CHECK: call <16 x i8> @llvm.s390.vsrl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrl vbc = vec_srl(vbc, vuc); // CHECK: call <16 x i8> @llvm.s390.vsrl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrl vbc = vec_srl(vbc, vus); // CHECK: call <16 x i8> @llvm.s390.vsrl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrl vbc = vec_srl(vbc, vui); // CHECK: call <16 x i8> @llvm.s390.vsrl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrl vss = vec_srl(vss, vuc); // CHECK: call <16 x i8> @llvm.s390.vsrl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrl vss = vec_srl(vss, vus); // CHECK: call <16 x i8> @llvm.s390.vsrl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrl vss = vec_srl(vss, vui); // CHECK: call <16 x i8> @llvm.s390.vsrl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrl vus = vec_srl(vus, vuc); // CHECK: call <16 x i8> @llvm.s390.vsrl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrl vus = vec_srl(vus, vus); // CHECK: call <16 x i8> @llvm.s390.vsrl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrl vus = vec_srl(vus, vui); // CHECK: call <16 x i8> @llvm.s390.vsrl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrl vbs = vec_srl(vbs, vuc); // CHECK: call <16 x i8> @llvm.s390.vsrl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrl vbs = vec_srl(vbs, vus); // CHECK: call <16 x i8> @llvm.s390.vsrl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrl vbs = vec_srl(vbs, vui); // CHECK: call <16 x i8> @llvm.s390.vsrl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrl vsi = vec_srl(vsi, vuc); // CHECK: call <16 x i8> @llvm.s390.vsrl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrl vsi = vec_srl(vsi, vus); // CHECK: call <16 x i8> @llvm.s390.vsrl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrl vsi = vec_srl(vsi, vui); // CHECK: call <16 x i8> @llvm.s390.vsrl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrl vui = vec_srl(vui, vuc); // CHECK: call <16 x i8> @llvm.s390.vsrl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrl vui = vec_srl(vui, vus); // CHECK: call <16 x i8> @llvm.s390.vsrl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrl vui = vec_srl(vui, vui); // CHECK: call <16 x i8> @llvm.s390.vsrl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrl vbi = vec_srl(vbi, vuc); // CHECK: call <16 x i8> @llvm.s390.vsrl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrl vbi = vec_srl(vbi, vus); // CHECK: call <16 x i8> @llvm.s390.vsrl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrl vbi = vec_srl(vbi, vui); // CHECK: call <16 x i8> @llvm.s390.vsrl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrl vsl = vec_srl(vsl, vuc); // CHECK: call <16 x i8> @llvm.s390.vsrl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrl vsl = vec_srl(vsl, vus); // CHECK: call <16 x i8> @llvm.s390.vsrl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrl vsl = vec_srl(vsl, vui); // CHECK: call <16 x i8> @llvm.s390.vsrl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrl vul = vec_srl(vul, vuc); // CHECK: call <16 x i8> @llvm.s390.vsrl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrl vul = vec_srl(vul, vus); // CHECK: call <16 x i8> @llvm.s390.vsrl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrl vul = vec_srl(vul, vui); // CHECK: call <16 x i8> @llvm.s390.vsrl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrl vbl = vec_srl(vbl, vuc); // CHECK: call <16 x i8> @llvm.s390.vsrl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrl vbl = vec_srl(vbl, vus); // CHECK: call <16 x i8> @llvm.s390.vsrl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrl vbl = vec_srl(vbl, vui); // CHECK: call <16 x i8> @llvm.s390.vsrl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrl vsc = vec_srb(vsc, vsc); // CHECK: call <16 x i8> @llvm.s390.vsrlb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrlb vsc = vec_srb(vsc, vuc); // CHECK: call <16 x i8> @llvm.s390.vsrlb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrlb vuc = vec_srb(vuc, vsc); // CHECK: call <16 x i8> @llvm.s390.vsrlb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrlb vuc = vec_srb(vuc, vuc); // CHECK: call <16 x i8> @llvm.s390.vsrlb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrlb vss = vec_srb(vss, vss); // CHECK: call <16 x i8> @llvm.s390.vsrlb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrlb vss = vec_srb(vss, vus); // CHECK: call <16 x i8> @llvm.s390.vsrlb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrlb vus = vec_srb(vus, vss); // CHECK: call <16 x i8> @llvm.s390.vsrlb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrlb vus = vec_srb(vus, vus); // CHECK: call <16 x i8> @llvm.s390.vsrlb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrlb vsi = vec_srb(vsi, vsi); // CHECK: call <16 x i8> @llvm.s390.vsrlb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrlb vsi = vec_srb(vsi, vui); // CHECK: call <16 x i8> @llvm.s390.vsrlb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrlb vui = vec_srb(vui, vsi); // CHECK: call <16 x i8> @llvm.s390.vsrlb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrlb vui = vec_srb(vui, vui); // CHECK: call <16 x i8> @llvm.s390.vsrlb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrlb vsl = vec_srb(vsl, vsl); // CHECK: call <16 x i8> @llvm.s390.vsrlb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrlb vsl = vec_srb(vsl, vul); // CHECK: call <16 x i8> @llvm.s390.vsrlb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrlb vul = vec_srb(vul, vsl); // CHECK: call <16 x i8> @llvm.s390.vsrlb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrlb vul = vec_srb(vul, vul); // CHECK: call <16 x i8> @llvm.s390.vsrlb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrlb vd = vec_srb(vd, vsl); // CHECK: call <16 x i8> @llvm.s390.vsrlb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrlb vd = vec_srb(vd, vul); // CHECK: call <16 x i8> @llvm.s390.vsrlb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrlb vsc = vec_abs(vsc); + // CHECK-ASM: vlpb vss = vec_abs(vss); + // CHECK-ASM: vlph vsi = vec_abs(vsi); + // CHECK-ASM: vlpf vsl = vec_abs(vsl); + // CHECK-ASM: vlpg vsc = vec_max(vsc, vsc); + // CHECK-ASM: vmxb vsc = vec_max(vsc, vbc); + // CHECK-ASM: vmxb vsc = vec_max(vbc, vsc); + // CHECK-ASM: vmxb vuc = vec_max(vuc, vuc); + // CHECK-ASM: vmxlb vuc = vec_max(vuc, vbc); + // CHECK-ASM: vmxlb vuc = vec_max(vbc, vuc); + // CHECK-ASM: vmxlb vss = vec_max(vss, vss); + // CHECK-ASM: vmxh vss = vec_max(vss, vbs); + // CHECK-ASM: vmxh vss = vec_max(vbs, vss); + // CHECK-ASM: vmxh vus = vec_max(vus, vus); + // CHECK-ASM: vmxlh vus = vec_max(vus, vbs); + // CHECK-ASM: vmxlh vus = vec_max(vbs, vus); + // CHECK-ASM: vmxlh vsi = vec_max(vsi, vsi); + // CHECK-ASM: vmxf vsi = vec_max(vsi, vbi); + // CHECK-ASM: vmxf vsi = vec_max(vbi, vsi); + // CHECK-ASM: vmxf vui = vec_max(vui, vui); + // CHECK-ASM: vmxlf vui = vec_max(vui, vbi); + // CHECK-ASM: vmxlf vui = vec_max(vbi, vui); + // CHECK-ASM: vmxlf vsl = vec_max(vsl, vsl); + // CHECK-ASM: vmxg vsl = vec_max(vsl, vbl); + // CHECK-ASM: vmxg vsl = vec_max(vbl, vsl); + // CHECK-ASM: vmxg vul = vec_max(vul, vul); + // CHECK-ASM: vmxlg vul = vec_max(vul, vbl); + // CHECK-ASM: vmxlg vul = vec_max(vbl, vul); + // CHECK-ASM: vmxlg vd = vec_max(vd, vd); + // (emulated) vsc = vec_min(vsc, vsc); + // CHECK-ASM: vmnb vsc = vec_min(vsc, vbc); + // CHECK-ASM: vmnb vsc = vec_min(vbc, vsc); + // CHECK-ASM: vmnb vuc = vec_min(vuc, vuc); + // CHECK-ASM: vmnlb vuc = vec_min(vuc, vbc); + // CHECK-ASM: vmnlb vuc = vec_min(vbc, vuc); + // CHECK-ASM: vmnlb vss = vec_min(vss, vss); + // CHECK-ASM: vmnh vss = vec_min(vss, vbs); + // CHECK-ASM: vmnh vss = vec_min(vbs, vss); + // CHECK-ASM: vmnh vus = vec_min(vus, vus); + // CHECK-ASM: vmnlh vus = vec_min(vus, vbs); + // CHECK-ASM: vmnlh vus = vec_min(vbs, vus); + // CHECK-ASM: vmnlh vsi = vec_min(vsi, vsi); + // CHECK-ASM: vmnf vsi = vec_min(vsi, vbi); + // CHECK-ASM: vmnf vsi = vec_min(vbi, vsi); + // CHECK-ASM: vmnf vui = vec_min(vui, vui); + // CHECK-ASM: vmnlf vui = vec_min(vui, vbi); + // CHECK-ASM: vmnlf vui = vec_min(vbi, vui); + // CHECK-ASM: vmnlf vsl = vec_min(vsl, vsl); + // CHECK-ASM: vmng vsl = vec_min(vsl, vbl); + // CHECK-ASM: vmng vsl = vec_min(vbl, vsl); + // CHECK-ASM: vmng vul = vec_min(vul, vul); + // CHECK-ASM: vmnlg vul = vec_min(vul, vbl); + // CHECK-ASM: vmnlg vul = vec_min(vbl, vul); + // CHECK-ASM: vmnlg vd = vec_min(vd, vd); + // (emulated) vuc = vec_addc(vuc, vuc); // CHECK: call <16 x i8> @llvm.s390.vaccb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vaccb vus = vec_addc(vus, vus); // CHECK: call <8 x i16> @llvm.s390.vacch(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vacch vui = vec_addc(vui, vui); // CHECK: call <4 x i32> @llvm.s390.vaccf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vaccf vul = vec_addc(vul, vul); // CHECK: call <2 x i64> @llvm.s390.vaccg(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vaccg vuc = vec_add_u128(vuc, vuc); // CHECK: call <16 x i8> @llvm.s390.vaq(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vaq vuc = vec_addc_u128(vuc, vuc); // CHECK: call <16 x i8> @llvm.s390.vaccq(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vaccq vuc = vec_adde_u128(vuc, vuc, vuc); // CHECK: call <16 x i8> @llvm.s390.vacq(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vacq vuc = vec_addec_u128(vuc, vuc, vuc); // CHECK: call <16 x i8> @llvm.s390.vacccq(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vacccq vsc = vec_avg(vsc, vsc); // CHECK: call <16 x i8> @llvm.s390.vavgb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vavgb vuc = vec_avg(vuc, vuc); // CHECK: call <16 x i8> @llvm.s390.vavglb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vavglb vss = vec_avg(vss, vss); // CHECK: call <8 x i16> @llvm.s390.vavgh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vavgh vus = vec_avg(vus, vus); // CHECK: call <8 x i16> @llvm.s390.vavglh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vavglh vsi = vec_avg(vsi, vsi); // CHECK: call <4 x i32> @llvm.s390.vavgf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vavgf vui = vec_avg(vui, vui); // CHECK: call <4 x i32> @llvm.s390.vavglf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vavglf vsl = vec_avg(vsl, vsl); // CHECK: call <2 x i64> @llvm.s390.vavgg(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vavgg vul = vec_avg(vul, vul); // CHECK: call <2 x i64> @llvm.s390.vavglg(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vavglg vui = vec_checksum(vui, vui); // CHECK: call <4 x i32> @llvm.s390.vcksm(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vcksm vus = vec_gfmsum(vuc, vuc); // CHECK: call <8 x i16> @llvm.s390.vgfmb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vgfmb vui = vec_gfmsum(vus, vus); // CHECK: call <4 x i32> @llvm.s390.vgfmh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vgfmh vul = vec_gfmsum(vui, vui); // CHECK: call <2 x i64> @llvm.s390.vgfmf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vgfmf vuc = vec_gfmsum_128(vul, vul); // CHECK: call <16 x i8> @llvm.s390.vgfmg(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vgfmg vus = vec_gfmsum_accum(vuc, vuc, vus); // CHECK: call <8 x i16> @llvm.s390.vgfmab(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vgfmab vui = vec_gfmsum_accum(vus, vus, vui); // CHECK: call <4 x i32> @llvm.s390.vgfmah(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vgfmah vul = vec_gfmsum_accum(vui, vui, vul); // CHECK: call <2 x i64> @llvm.s390.vgfmaf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vgfmaf vuc = vec_gfmsum_accum_128(vul, vul, vuc); // CHECK: call <16 x i8> @llvm.s390.vgfmag(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vgfmag vsc = vec_mladd(vsc, vsc, vsc); + // CHECK-ASM: vmalb vsc = vec_mladd(vuc, vsc, vsc); + // CHECK-ASM: vmalb vsc = vec_mladd(vsc, vuc, vuc); + // CHECK-ASM: vmalb vuc = vec_mladd(vuc, vuc, vuc); + // CHECK-ASM: vmalb vss = vec_mladd(vss, vss, vss); + // CHECK-ASM: vmalhw vss = vec_mladd(vus, vss, vss); + // CHECK-ASM: vmalhw vss = vec_mladd(vss, vus, vus); + // CHECK-ASM: vmalhw vus = vec_mladd(vus, vus, vus); + // CHECK-ASM: vmalhw vsi = vec_mladd(vsi, vsi, vsi); + // CHECK-ASM: vmalf vsi = vec_mladd(vui, vsi, vsi); + // CHECK-ASM: vmalf vsi = vec_mladd(vsi, vui, vui); + // CHECK-ASM: vmalf vui = vec_mladd(vui, vui, vui); + // CHECK-ASM: vmalf vsc = vec_mhadd(vsc, vsc, vsc); // CHECK: call <16 x i8> @llvm.s390.vmahb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vmahb vuc = vec_mhadd(vuc, vuc, vuc); // CHECK: call <16 x i8> @llvm.s390.vmalhb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vmalhb vss = vec_mhadd(vss, vss, vss); // CHECK: call <8 x i16> @llvm.s390.vmahh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vmahh vus = vec_mhadd(vus, vus, vus); // CHECK: call <8 x i16> @llvm.s390.vmalhh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vmalhh vsi = vec_mhadd(vsi, vsi, vsi); // CHECK: call <4 x i32> @llvm.s390.vmahf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vmahf vui = vec_mhadd(vui, vui, vui); // CHECK: call <4 x i32> @llvm.s390.vmalhf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vmalhf vss = vec_meadd(vsc, vsc, vss); // CHECK: call <8 x i16> @llvm.s390.vmaeb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vmaeb vus = vec_meadd(vuc, vuc, vus); // CHECK: call <8 x i16> @llvm.s390.vmaleb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vmaleb vsi = vec_meadd(vss, vss, vsi); // CHECK: call <4 x i32> @llvm.s390.vmaeh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vmaeh vui = vec_meadd(vus, vus, vui); // CHECK: call <4 x i32> @llvm.s390.vmaleh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vmaleh vsl = vec_meadd(vsi, vsi, vsl); // CHECK: call <2 x i64> @llvm.s390.vmaef(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vmaef vul = vec_meadd(vui, vui, vul); // CHECK: call <2 x i64> @llvm.s390.vmalef(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vmalef vss = vec_moadd(vsc, vsc, vss); // CHECK: call <8 x i16> @llvm.s390.vmaob(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vmaob vus = vec_moadd(vuc, vuc, vus); // CHECK: call <8 x i16> @llvm.s390.vmalob(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vmalob vsi = vec_moadd(vss, vss, vsi); // CHECK: call <4 x i32> @llvm.s390.vmaoh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vmaoh vui = vec_moadd(vus, vus, vui); // CHECK: call <4 x i32> @llvm.s390.vmaloh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vmaloh vsl = vec_moadd(vsi, vsi, vsl); // CHECK: call <2 x i64> @llvm.s390.vmaof(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vmaof vul = vec_moadd(vui, vui, vul); // CHECK: call <2 x i64> @llvm.s390.vmalof(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vmalof vsc = vec_mulh(vsc, vsc); // CHECK: call <16 x i8> @llvm.s390.vmhb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vmhb vuc = vec_mulh(vuc, vuc); // CHECK: call <16 x i8> @llvm.s390.vmlhb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vmlhb vss = vec_mulh(vss, vss); // CHECK: call <8 x i16> @llvm.s390.vmhh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vmhh vus = vec_mulh(vus, vus); // CHECK: call <8 x i16> @llvm.s390.vmlhh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vmlhh vsi = vec_mulh(vsi, vsi); // CHECK: call <4 x i32> @llvm.s390.vmhf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vmhf vui = vec_mulh(vui, vui); // CHECK: call <4 x i32> @llvm.s390.vmlhf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vmlhf vss = vec_mule(vsc, vsc); // CHECK: call <8 x i16> @llvm.s390.vmeb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vmeb vus = vec_mule(vuc, vuc); // CHECK: call <8 x i16> @llvm.s390.vmleb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vmleb vsi = vec_mule(vss, vss); // CHECK: call <4 x i32> @llvm.s390.vmeh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vmeh vui = vec_mule(vus, vus); // CHECK: call <4 x i32> @llvm.s390.vmleh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vmleh vsl = vec_mule(vsi, vsi); // CHECK: call <2 x i64> @llvm.s390.vmef(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vmef vul = vec_mule(vui, vui); // CHECK: call <2 x i64> @llvm.s390.vmlef(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vmlef vss = vec_mulo(vsc, vsc); // CHECK: call <8 x i16> @llvm.s390.vmob(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vmob vus = vec_mulo(vuc, vuc); // CHECK: call <8 x i16> @llvm.s390.vmlob(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vmlob vsi = vec_mulo(vss, vss); // CHECK: call <4 x i32> @llvm.s390.vmoh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vmoh vui = vec_mulo(vus, vus); // CHECK: call <4 x i32> @llvm.s390.vmloh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vmloh vsl = vec_mulo(vsi, vsi); // CHECK: call <2 x i64> @llvm.s390.vmof(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vmof vul = vec_mulo(vui, vui); // CHECK: call <2 x i64> @llvm.s390.vmlof(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vmlof vuc = vec_subc(vuc, vuc); // CHECK: call <16 x i8> @llvm.s390.vscbib(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vscbib vus = vec_subc(vus, vus); // CHECK: call <8 x i16> @llvm.s390.vscbih(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vscbih vui = vec_subc(vui, vui); // CHECK: call <4 x i32> @llvm.s390.vscbif(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vscbif vul = vec_subc(vul, vul); // CHECK: call <2 x i64> @llvm.s390.vscbig(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vscbig vuc = vec_sub_u128(vuc, vuc); // CHECK: call <16 x i8> @llvm.s390.vsq(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsq vuc = vec_subc_u128(vuc, vuc); // CHECK: call <16 x i8> @llvm.s390.vscbiq(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vscbiq vuc = vec_sube_u128(vuc, vuc, vuc); // CHECK: call <16 x i8> @llvm.s390.vsbiq(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsbiq vuc = vec_subec_u128(vuc, vuc, vuc); // CHECK: call <16 x i8> @llvm.s390.vsbcbiq(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsbcbiq vui = vec_sum4(vuc, vuc); // CHECK: call <4 x i32> @llvm.s390.vsumb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsumb vui = vec_sum4(vus, vus); // CHECK: call <4 x i32> @llvm.s390.vsumh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vsumh vul = vec_sum2(vus, vus); // CHECK: call <2 x i64> @llvm.s390.vsumgh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vsumgh vul = vec_sum2(vui, vui); // CHECK: call <2 x i64> @llvm.s390.vsumgf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vsumgf vuc = vec_sum_u128(vui, vui); // CHECK: call <16 x i8> @llvm.s390.vsumqf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vsumqf vuc = vec_sum_u128(vul, vul); // CHECK: call <16 x i8> @llvm.s390.vsumqg(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK-ASM: vsumqg idx = vec_test_mask(vsc, vuc); // CHECK: call i32 @llvm.s390.vtm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vtm idx = vec_test_mask(vuc, vuc); // CHECK: call i32 @llvm.s390.vtm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vtm idx = vec_test_mask(vss, vus); // CHECK: call i32 @llvm.s390.vtm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vtm idx = vec_test_mask(vus, vus); // CHECK: call i32 @llvm.s390.vtm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vtm idx = vec_test_mask(vsi, vui); // CHECK: call i32 @llvm.s390.vtm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vtm idx = vec_test_mask(vui, vui); // CHECK: call i32 @llvm.s390.vtm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vtm idx = vec_test_mask(vsl, vul); // CHECK: call i32 @llvm.s390.vtm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vtm idx = vec_test_mask(vul, vul); // CHECK: call i32 @llvm.s390.vtm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vtm idx = vec_test_mask(vd, vul); // CHECK: call i32 @llvm.s390.vtm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vtm } void test_string(void) { + // CHECK-ASM-LABEL: test_string + vsc = vec_cp_until_zero(vsc); // CHECK: call <16 x i8> @llvm.s390.vistrb(<16 x i8> %{{.*}}) + // CHECK-ASM: vistrb vuc = vec_cp_until_zero(vuc); // CHECK: call <16 x i8> @llvm.s390.vistrb(<16 x i8> %{{.*}}) + // CHECK-ASM: vistrb vbc = vec_cp_until_zero(vbc); // CHECK: call <16 x i8> @llvm.s390.vistrb(<16 x i8> %{{.*}}) + // CHECK-ASM: vistrb vss = vec_cp_until_zero(vss); // CHECK: call <8 x i16> @llvm.s390.vistrh(<8 x i16> %{{.*}}) + // CHECK-ASM: vistrh vus = vec_cp_until_zero(vus); // CHECK: call <8 x i16> @llvm.s390.vistrh(<8 x i16> %{{.*}}) + // CHECK-ASM: vistrh vbs = vec_cp_until_zero(vbs); // CHECK: call <8 x i16> @llvm.s390.vistrh(<8 x i16> %{{.*}}) + // CHECK-ASM: vistrh vsi = vec_cp_until_zero(vsi); // CHECK: call <4 x i32> @llvm.s390.vistrf(<4 x i32> %{{.*}}) + // CHECK-ASM: vistrf vui = vec_cp_until_zero(vui); // CHECK: call <4 x i32> @llvm.s390.vistrf(<4 x i32> %{{.*}}) + // CHECK-ASM: vistrf vbi = vec_cp_until_zero(vbi); // CHECK: call <4 x i32> @llvm.s390.vistrf(<4 x i32> %{{.*}}) + // CHECK-ASM: vistrf vsc = vec_cp_until_zero_cc(vsc, &cc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vistrbs(<16 x i8> %{{.*}}) + // CHECK-ASM: vistrbs vuc = vec_cp_until_zero_cc(vuc, &cc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vistrbs(<16 x i8> %{{.*}}) + // CHECK-ASM: vistrbs vbc = vec_cp_until_zero_cc(vbc, &cc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vistrbs(<16 x i8> %{{.*}}) + // CHECK-ASM: vistrbs vss = vec_cp_until_zero_cc(vss, &cc); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vistrhs(<8 x i16> %{{.*}}) + // CHECK-ASM: vistrhs vus = vec_cp_until_zero_cc(vus, &cc); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vistrhs(<8 x i16> %{{.*}}) + // CHECK-ASM: vistrhs vbs = vec_cp_until_zero_cc(vbs, &cc); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vistrhs(<8 x i16> %{{.*}}) + // CHECK-ASM: vistrhs vsi = vec_cp_until_zero_cc(vsi, &cc); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vistrfs(<4 x i32> %{{.*}}) + // CHECK-ASM: vistrfs vui = vec_cp_until_zero_cc(vui, &cc); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vistrfs(<4 x i32> %{{.*}}) + // CHECK-ASM: vistrfs vbi = vec_cp_until_zero_cc(vbi, &cc); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vistrfs(<4 x i32> %{{.*}}) + // CHECK-ASM: vistrfs vsc = vec_cmpeq_idx(vsc, vsc); // CHECK: call <16 x i8> @llvm.s390.vfeeb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vfeeb vuc = vec_cmpeq_idx(vuc, vuc); // CHECK: call <16 x i8> @llvm.s390.vfeeb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vfeeb vuc = vec_cmpeq_idx(vbc, vbc); // CHECK: call <16 x i8> @llvm.s390.vfeeb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vfeeb vss = vec_cmpeq_idx(vss, vss); // CHECK: call <8 x i16> @llvm.s390.vfeeh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vfeeh vus = vec_cmpeq_idx(vus, vus); // CHECK: call <8 x i16> @llvm.s390.vfeeh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vfeeh vus = vec_cmpeq_idx(vbs, vbs); // CHECK: call <8 x i16> @llvm.s390.vfeeh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vfeeh vsi = vec_cmpeq_idx(vsi, vsi); // CHECK: call <4 x i32> @llvm.s390.vfeef(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vfeef vui = vec_cmpeq_idx(vui, vui); // CHECK: call <4 x i32> @llvm.s390.vfeef(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vfeef vui = vec_cmpeq_idx(vbi, vbi); // CHECK: call <4 x i32> @llvm.s390.vfeef(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vfeef vsc = vec_cmpeq_idx_cc(vsc, vsc, &cc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vfeebs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vfeebs vuc = vec_cmpeq_idx_cc(vuc, vuc, &cc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vfeebs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vfeebs vuc = vec_cmpeq_idx_cc(vbc, vbc, &cc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vfeebs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vfeebs vss = vec_cmpeq_idx_cc(vss, vss, &cc); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vfeehs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vfeehs vus = vec_cmpeq_idx_cc(vus, vus, &cc); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vfeehs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vfeehs vus = vec_cmpeq_idx_cc(vbs, vbs, &cc); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vfeehs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vfeehs vsi = vec_cmpeq_idx_cc(vsi, vsi, &cc); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfeefs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vfeefs vui = vec_cmpeq_idx_cc(vui, vui, &cc); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfeefs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vfeefs vui = vec_cmpeq_idx_cc(vbi, vbi, &cc); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfeefs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vfeefs vsc = vec_cmpeq_or_0_idx(vsc, vsc); // CHECK: call <16 x i8> @llvm.s390.vfeezb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vfeezb vuc = vec_cmpeq_or_0_idx(vuc, vuc); // CHECK: call <16 x i8> @llvm.s390.vfeezb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vfeezb vuc = vec_cmpeq_or_0_idx(vbc, vbc); // CHECK: call <16 x i8> @llvm.s390.vfeezb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vfeezb vss = vec_cmpeq_or_0_idx(vss, vss); // CHECK: call <8 x i16> @llvm.s390.vfeezh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vfeezh vus = vec_cmpeq_or_0_idx(vus, vus); // CHECK: call <8 x i16> @llvm.s390.vfeezh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vfeezh vus = vec_cmpeq_or_0_idx(vbs, vbs); // CHECK: call <8 x i16> @llvm.s390.vfeezh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vfeezh vsi = vec_cmpeq_or_0_idx(vsi, vsi); // CHECK: call <4 x i32> @llvm.s390.vfeezf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vfeezf vui = vec_cmpeq_or_0_idx(vui, vui); // CHECK: call <4 x i32> @llvm.s390.vfeezf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vfeezf vui = vec_cmpeq_or_0_idx(vbi, vbi); // CHECK: call <4 x i32> @llvm.s390.vfeezf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vfeezf vsc = vec_cmpeq_or_0_idx_cc(vsc, vsc, &cc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vfeezbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vfeezbs vuc = vec_cmpeq_or_0_idx_cc(vuc, vuc, &cc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vfeezbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vfeezbs vuc = vec_cmpeq_or_0_idx_cc(vbc, vbc, &cc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vfeezbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vfeezbs vss = vec_cmpeq_or_0_idx_cc(vss, vss, &cc); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vfeezhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vfeezhs vus = vec_cmpeq_or_0_idx_cc(vus, vus, &cc); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vfeezhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vfeezhs vus = vec_cmpeq_or_0_idx_cc(vbs, vbs, &cc); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vfeezhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vfeezhs vsi = vec_cmpeq_or_0_idx_cc(vsi, vsi, &cc); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfeezfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vfeezfs vui = vec_cmpeq_or_0_idx_cc(vui, vui, &cc); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfeezfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vfeezfs vui = vec_cmpeq_or_0_idx_cc(vbi, vbi, &cc); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfeezfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vfeezfs vsc = vec_cmpne_idx(vsc, vsc); // CHECK: call <16 x i8> @llvm.s390.vfeneb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vfeneb vuc = vec_cmpne_idx(vuc, vuc); // CHECK: call <16 x i8> @llvm.s390.vfeneb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vfeneb vuc = vec_cmpne_idx(vbc, vbc); // CHECK: call <16 x i8> @llvm.s390.vfeneb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vfeneb vss = vec_cmpne_idx(vss, vss); // CHECK: call <8 x i16> @llvm.s390.vfeneh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vfeneh vus = vec_cmpne_idx(vus, vus); // CHECK: call <8 x i16> @llvm.s390.vfeneh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vfeneh vus = vec_cmpne_idx(vbs, vbs); // CHECK: call <8 x i16> @llvm.s390.vfeneh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vfeneh vsi = vec_cmpne_idx(vsi, vsi); // CHECK: call <4 x i32> @llvm.s390.vfenef(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vfenef vui = vec_cmpne_idx(vui, vui); // CHECK: call <4 x i32> @llvm.s390.vfenef(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vfenef vui = vec_cmpne_idx(vbi, vbi); // CHECK: call <4 x i32> @llvm.s390.vfenef(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vfenef vsc = vec_cmpne_idx_cc(vsc, vsc, &cc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vfenebs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vfenebs vuc = vec_cmpne_idx_cc(vuc, vuc, &cc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vfenebs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vfenebs vuc = vec_cmpne_idx_cc(vbc, vbc, &cc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vfenebs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vfenebs vss = vec_cmpne_idx_cc(vss, vss, &cc); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vfenehs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vfenehs vus = vec_cmpne_idx_cc(vus, vus, &cc); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vfenehs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vfenehs vus = vec_cmpne_idx_cc(vbs, vbs, &cc); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vfenehs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vfenehs vsi = vec_cmpne_idx_cc(vsi, vsi, &cc); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfenefs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vfenefs vui = vec_cmpne_idx_cc(vui, vui, &cc); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfenefs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vfenefs vui = vec_cmpne_idx_cc(vbi, vbi, &cc); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfenefs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vfenefs vsc = vec_cmpne_or_0_idx(vsc, vsc); // CHECK: call <16 x i8> @llvm.s390.vfenezb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vfenezb vuc = vec_cmpne_or_0_idx(vuc, vuc); // CHECK: call <16 x i8> @llvm.s390.vfenezb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vfenezb vuc = vec_cmpne_or_0_idx(vbc, vbc); // CHECK: call <16 x i8> @llvm.s390.vfenezb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vfenezb vss = vec_cmpne_or_0_idx(vss, vss); // CHECK: call <8 x i16> @llvm.s390.vfenezh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vfenezh vus = vec_cmpne_or_0_idx(vus, vus); // CHECK: call <8 x i16> @llvm.s390.vfenezh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vfenezh vus = vec_cmpne_or_0_idx(vbs, vbs); // CHECK: call <8 x i16> @llvm.s390.vfenezh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vfenezh vsi = vec_cmpne_or_0_idx(vsi, vsi); // CHECK: call <4 x i32> @llvm.s390.vfenezf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vfenezf vui = vec_cmpne_or_0_idx(vui, vui); // CHECK: call <4 x i32> @llvm.s390.vfenezf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vfenezf vui = vec_cmpne_or_0_idx(vbi, vbi); // CHECK: call <4 x i32> @llvm.s390.vfenezf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vfenezf vsc = vec_cmpne_or_0_idx_cc(vsc, vsc, &cc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vfenezbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vfenezbs vuc = vec_cmpne_or_0_idx_cc(vuc, vuc, &cc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vfenezbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vfenezbs vuc = vec_cmpne_or_0_idx_cc(vbc, vbc, &cc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vfenezbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vfenezbs vss = vec_cmpne_or_0_idx_cc(vss, vss, &cc); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vfenezhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vfenezhs vus = vec_cmpne_or_0_idx_cc(vus, vus, &cc); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vfenezhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vfenezhs vus = vec_cmpne_or_0_idx_cc(vbs, vbs, &cc); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vfenezhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK-ASM: vfenezhs vsi = vec_cmpne_or_0_idx_cc(vsi, vsi, &cc); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfenezfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vfenezfs vui = vec_cmpne_or_0_idx_cc(vui, vui, &cc); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfenezfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vfenezfs vui = vec_cmpne_or_0_idx_cc(vbi, vbi, &cc); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfenezfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK-ASM: vfenezfs vbc = vec_cmprg(vuc, vuc, vuc); // CHECK: call <16 x i8> @llvm.s390.vstrcb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 4) + // CHECK-ASM: vstrcb vbs = vec_cmprg(vus, vus, vus); // CHECK: call <8 x i16> @llvm.s390.vstrch(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 4) + // CHECK-ASM: vstrch vbi = vec_cmprg(vui, vui, vui); // CHECK: call <4 x i32> @llvm.s390.vstrcf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 4) + // CHECK-ASM: vstrcf vbc = vec_cmprg_cc(vuc, vuc, vuc, &cc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vstrcbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 4) + // CHECK-ASM: vstrcbs vbs = vec_cmprg_cc(vus, vus, vus, &cc); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vstrchs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 4) + // CHECK-ASM: vstrchs vbi = vec_cmprg_cc(vui, vui, vui, &cc); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vstrcfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 4) + // CHECK-ASM: vstrcfs vuc = vec_cmprg_idx(vuc, vuc, vuc); // CHECK: call <16 x i8> @llvm.s390.vstrcb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0) + // CHECK-ASM: vstrcb vus = vec_cmprg_idx(vus, vus, vus); // CHECK: call <8 x i16> @llvm.s390.vstrch(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 0) + // CHECK-ASM: vstrch vui = vec_cmprg_idx(vui, vui, vui); // CHECK: call <4 x i32> @llvm.s390.vstrcf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 0) + // CHECK-ASM: vstrcf vuc = vec_cmprg_idx_cc(vuc, vuc, vuc, &cc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vstrcbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0) + // CHECK-ASM: vstrcbs vus = vec_cmprg_idx_cc(vus, vus, vus, &cc); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vstrchs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 0) + // CHECK-ASM: vstrchs vui = vec_cmprg_idx_cc(vui, vui, vui, &cc); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vstrcfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 0) + // CHECK-ASM: vstrcfs vuc = vec_cmprg_or_0_idx(vuc, vuc, vuc); // CHECK: call <16 x i8> @llvm.s390.vstrczb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0) + // CHECK-ASM: vstrczb vus = vec_cmprg_or_0_idx(vus, vus, vus); // CHECK: call <8 x i16> @llvm.s390.vstrczh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 0) + // CHECK-ASM: vstrczh vui = vec_cmprg_or_0_idx(vui, vui, vui); // CHECK: call <4 x i32> @llvm.s390.vstrczf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 0) + // CHECK-ASM: vstrczf vuc = vec_cmprg_or_0_idx_cc(vuc, vuc, vuc, &cc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vstrczbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0) + // CHECK-ASM: vstrczbs vus = vec_cmprg_or_0_idx_cc(vus, vus, vus, &cc); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vstrczhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 0) + // CHECK-ASM: vstrczhs vui = vec_cmprg_or_0_idx_cc(vui, vui, vui, &cc); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vstrczfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 0) + // CHECK-ASM: vstrczfs vbc = vec_cmpnrg(vuc, vuc, vuc); // CHECK: call <16 x i8> @llvm.s390.vstrcb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 12) + // CHECK-ASM: vstrcb vbs = vec_cmpnrg(vus, vus, vus); // CHECK: call <8 x i16> @llvm.s390.vstrch(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 12) + // CHECK-ASM: vstrch vbi = vec_cmpnrg(vui, vui, vui); // CHECK: call <4 x i32> @llvm.s390.vstrcf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 12) + // CHECK-ASM: vstrcf vbc = vec_cmpnrg_cc(vuc, vuc, vuc, &cc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vstrcbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 12) + // CHECK-ASM: vstrcbs vbs = vec_cmpnrg_cc(vus, vus, vus, &cc); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vstrchs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 12) + // CHECK-ASM: vstrchs vbi = vec_cmpnrg_cc(vui, vui, vui, &cc); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vstrcfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 12) + // CHECK-ASM: vstrcfs vuc = vec_cmpnrg_idx(vuc, vuc, vuc); // CHECK: call <16 x i8> @llvm.s390.vstrcb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 8) + // CHECK-ASM: vstrcb vus = vec_cmpnrg_idx(vus, vus, vus); // CHECK: call <8 x i16> @llvm.s390.vstrch(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 8) + // CHECK-ASM: vstrch vui = vec_cmpnrg_idx(vui, vui, vui); // CHECK: call <4 x i32> @llvm.s390.vstrcf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 8) + // CHECK-ASM: vstrcf vuc = vec_cmpnrg_idx_cc(vuc, vuc, vuc, &cc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vstrcbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 8) + // CHECK-ASM: vstrcbs vus = vec_cmpnrg_idx_cc(vus, vus, vus, &cc); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vstrchs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 8) + // CHECK-ASM: vstrchs vui = vec_cmpnrg_idx_cc(vui, vui, vui, &cc); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vstrcfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 8) + // CHECK-ASM: vstrcfs vuc = vec_cmpnrg_or_0_idx(vuc, vuc, vuc); // CHECK: call <16 x i8> @llvm.s390.vstrczb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 8) + // CHECK-ASM: vstrczb vus = vec_cmpnrg_or_0_idx(vus, vus, vus); // CHECK: call <8 x i16> @llvm.s390.vstrczh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 8) + // CHECK-ASM: vstrczh vui = vec_cmpnrg_or_0_idx(vui, vui, vui); // CHECK: call <4 x i32> @llvm.s390.vstrczf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 8) + // CHECK-ASM: vstrczf vuc = vec_cmpnrg_or_0_idx_cc(vuc, vuc, vuc, &cc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vstrczbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 8) + // CHECK-ASM: vstrczbs vus = vec_cmpnrg_or_0_idx_cc(vus, vus, vus, &cc); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vstrczhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 8) + // CHECK-ASM: vstrczhs vui = vec_cmpnrg_or_0_idx_cc(vui, vui, vui, &cc); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vstrczfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 8) + // CHECK-ASM: vstrczfs vbc = vec_find_any_eq(vsc, vsc); // CHECK: call <16 x i8> @llvm.s390.vfaeb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 4) + // CHECK-ASM: vfaeb vbc = vec_find_any_eq(vuc, vuc); // CHECK: call <16 x i8> @llvm.s390.vfaeb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 4) + // CHECK-ASM: vfaeb vbc = vec_find_any_eq(vbc, vbc); // CHECK: call <16 x i8> @llvm.s390.vfaeb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 4) + // CHECK-ASM: vfaeb vbs = vec_find_any_eq(vss, vss); // CHECK: call <8 x i16> @llvm.s390.vfaeh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 4) + // CHECK-ASM: vfaeh vbs = vec_find_any_eq(vus, vus); // CHECK: call <8 x i16> @llvm.s390.vfaeh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 4) + // CHECK-ASM: vfaeh vbs = vec_find_any_eq(vbs, vbs); // CHECK: call <8 x i16> @llvm.s390.vfaeh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 4) + // CHECK-ASM: vfaeh vbi = vec_find_any_eq(vsi, vsi); // CHECK: call <4 x i32> @llvm.s390.vfaef(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 4) + // CHECK-ASM: vfaef vbi = vec_find_any_eq(vui, vui); // CHECK: call <4 x i32> @llvm.s390.vfaef(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 4) + // CHECK-ASM: vfaef vbi = vec_find_any_eq(vbi, vbi); // CHECK: call <4 x i32> @llvm.s390.vfaef(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 4) + // CHECK-ASM: vfaef vbc = vec_find_any_eq_cc(vsc, vsc, &cc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vfaebs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 4) + // CHECK-ASM: vfaebs vbc = vec_find_any_eq_cc(vuc, vuc, &cc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vfaebs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 4) + // CHECK-ASM: vfaebs vbc = vec_find_any_eq_cc(vbc, vbc, &cc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vfaebs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 4) + // CHECK-ASM: vfaebs vbs = vec_find_any_eq_cc(vss, vss, &cc); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vfaehs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 4) + // CHECK-ASM: vfaehs vbs = vec_find_any_eq_cc(vus, vus, &cc); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vfaehs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 4) + // CHECK-ASM: vfaehs vbs = vec_find_any_eq_cc(vbs, vbs, &cc); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vfaehs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 4) + // CHECK-ASM: vfaehs vbi = vec_find_any_eq_cc(vsi, vsi, &cc); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfaefs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 4) + // CHECK-ASM: vfaefs vbi = vec_find_any_eq_cc(vui, vui, &cc); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfaefs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 4) + // CHECK-ASM: vfaefs vbi = vec_find_any_eq_cc(vbi, vbi, &cc); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfaefs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 4) + // CHECK-ASM: vfaefs vsc = vec_find_any_eq_idx(vsc, vsc); // CHECK: call <16 x i8> @llvm.s390.vfaeb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0) + // CHECK-ASM: vfaeb vuc = vec_find_any_eq_idx(vuc, vuc); // CHECK: call <16 x i8> @llvm.s390.vfaeb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0) + // CHECK-ASM: vfaeb vuc = vec_find_any_eq_idx(vbc, vbc); // CHECK: call <16 x i8> @llvm.s390.vfaeb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0) + // CHECK-ASM: vfaeb vss = vec_find_any_eq_idx(vss, vss); // CHECK: call <8 x i16> @llvm.s390.vfaeh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 0) + // CHECK-ASM: vfaeh vus = vec_find_any_eq_idx(vus, vus); // CHECK: call <8 x i16> @llvm.s390.vfaeh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 0) + // CHECK-ASM: vfaeh vus = vec_find_any_eq_idx(vbs, vbs); // CHECK: call <8 x i16> @llvm.s390.vfaeh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 0) + // CHECK-ASM: vfaeh vsi = vec_find_any_eq_idx(vsi, vsi); // CHECK: call <4 x i32> @llvm.s390.vfaef(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 0) + // CHECK-ASM: vfaef vui = vec_find_any_eq_idx(vui, vui); // CHECK: call <4 x i32> @llvm.s390.vfaef(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 0) + // CHECK-ASM: vfaef vui = vec_find_any_eq_idx(vbi, vbi); // CHECK: call <4 x i32> @llvm.s390.vfaef(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 0) + // CHECK-ASM: vfaef vsc = vec_find_any_eq_idx_cc(vsc, vsc, &cc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vfaebs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0) + // CHECK-ASM: vfaebs vuc = vec_find_any_eq_idx_cc(vuc, vuc, &cc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vfaebs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0) + // CHECK-ASM: vfaebs vuc = vec_find_any_eq_idx_cc(vbc, vbc, &cc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vfaebs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0) + // CHECK-ASM: vfaebs vss = vec_find_any_eq_idx_cc(vss, vss, &cc); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vfaehs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 0) + // CHECK-ASM: vfaehs vus = vec_find_any_eq_idx_cc(vus, vus, &cc); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vfaehs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 0) + // CHECK-ASM: vfaehs vus = vec_find_any_eq_idx_cc(vbs, vbs, &cc); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vfaehs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 0) + // CHECK-ASM: vfaehs vsi = vec_find_any_eq_idx_cc(vsi, vsi, &cc); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfaefs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 0) + // CHECK-ASM: vfaefs vui = vec_find_any_eq_idx_cc(vui, vui, &cc); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfaefs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 0) + // CHECK-ASM: vfaefs vui = vec_find_any_eq_idx_cc(vbi, vbi, &cc); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfaefs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 0) + // CHECK-ASM: vfaefs vsc = vec_find_any_eq_or_0_idx(vsc, vsc); // CHECK: call <16 x i8> @llvm.s390.vfaezb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0) + // CHECK-ASM: vfaezb vuc = vec_find_any_eq_or_0_idx(vuc, vuc); // CHECK: call <16 x i8> @llvm.s390.vfaezb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0) + // CHECK-ASM: vfaezb vuc = vec_find_any_eq_or_0_idx(vbc, vbc); // CHECK: call <16 x i8> @llvm.s390.vfaezb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0) + // CHECK-ASM: vfaezb vss = vec_find_any_eq_or_0_idx(vss, vss); // CHECK: call <8 x i16> @llvm.s390.vfaezh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 0) + // CHECK-ASM: vfaezh vus = vec_find_any_eq_or_0_idx(vus, vus); // CHECK: call <8 x i16> @llvm.s390.vfaezh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 0) + // CHECK-ASM: vfaezh vus = vec_find_any_eq_or_0_idx(vbs, vbs); // CHECK: call <8 x i16> @llvm.s390.vfaezh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 0) + // CHECK-ASM: vfaezh vsi = vec_find_any_eq_or_0_idx(vsi, vsi); // CHECK: call <4 x i32> @llvm.s390.vfaezf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 0) + // CHECK-ASM: vfaezf vui = vec_find_any_eq_or_0_idx(vui, vui); // CHECK: call <4 x i32> @llvm.s390.vfaezf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 0) + // CHECK-ASM: vfaezf vui = vec_find_any_eq_or_0_idx(vbi, vbi); // CHECK: call <4 x i32> @llvm.s390.vfaezf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 0) + // CHECK-ASM: vfaezf vsc = vec_find_any_eq_or_0_idx_cc(vsc, vsc, &cc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vfaezbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0) + // CHECK-ASM: vfaezbs vuc = vec_find_any_eq_or_0_idx_cc(vuc, vuc, &cc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vfaezbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0) + // CHECK-ASM: vfaezbs vuc = vec_find_any_eq_or_0_idx_cc(vbc, vbc, &cc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vfaezbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0) + // CHECK-ASM: vfaezbs vss = vec_find_any_eq_or_0_idx_cc(vss, vss, &cc); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vfaezhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 0) + // CHECK-ASM: vfaezhs vus = vec_find_any_eq_or_0_idx_cc(vus, vus, &cc); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vfaezhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 0) + // CHECK-ASM: vfaezhs vus = vec_find_any_eq_or_0_idx_cc(vbs, vbs, &cc); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vfaezhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 0) + // CHECK-ASM: vfaezhs vsi = vec_find_any_eq_or_0_idx_cc(vsi, vsi, &cc); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfaezfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 0) + // CHECK-ASM: vfaezfs vui = vec_find_any_eq_or_0_idx_cc(vui, vui, &cc); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfaezfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 0) + // CHECK-ASM: vfaezfs vui = vec_find_any_eq_or_0_idx_cc(vbi, vbi, &cc); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfaezfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 0) + // CHECK-ASM: vfaezfs vbc = vec_find_any_ne(vsc, vsc); // CHECK: call <16 x i8> @llvm.s390.vfaeb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 12) + // CHECK-ASM: vfaeb vbc = vec_find_any_ne(vuc, vuc); // CHECK: call <16 x i8> @llvm.s390.vfaeb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 12) + // CHECK-ASM: vfaeb vbc = vec_find_any_ne(vbc, vbc); // CHECK: call <16 x i8> @llvm.s390.vfaeb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 12) + // CHECK-ASM: vfaeb vbs = vec_find_any_ne(vss, vss); // CHECK: call <8 x i16> @llvm.s390.vfaeh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 12) + // CHECK-ASM: vfaeh vbs = vec_find_any_ne(vus, vus); // CHECK: call <8 x i16> @llvm.s390.vfaeh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 12) + // CHECK-ASM: vfaeh vbs = vec_find_any_ne(vbs, vbs); // CHECK: call <8 x i16> @llvm.s390.vfaeh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 12) + // CHECK-ASM: vfaeh vbi = vec_find_any_ne(vsi, vsi); // CHECK: call <4 x i32> @llvm.s390.vfaef(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 12) + // CHECK-ASM: vfaef vbi = vec_find_any_ne(vui, vui); // CHECK: call <4 x i32> @llvm.s390.vfaef(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 12) + // CHECK-ASM: vfaef vbi = vec_find_any_ne(vbi, vbi); // CHECK: call <4 x i32> @llvm.s390.vfaef(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 12) + // CHECK-ASM: vfaef vbc = vec_find_any_ne_cc(vsc, vsc, &cc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vfaebs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 12) + // CHECK-ASM: vfaebs vbc = vec_find_any_ne_cc(vuc, vuc, &cc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vfaebs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 12) + // CHECK-ASM: vfaebs vbc = vec_find_any_ne_cc(vbc, vbc, &cc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vfaebs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 12) + // CHECK-ASM: vfaebs vbs = vec_find_any_ne_cc(vss, vss, &cc); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vfaehs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 12) + // CHECK-ASM: vfaehs vbs = vec_find_any_ne_cc(vus, vus, &cc); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vfaehs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 12) + // CHECK-ASM: vfaehs vbs = vec_find_any_ne_cc(vbs, vbs, &cc); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vfaehs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 12) + // CHECK-ASM: vfaehs vbi = vec_find_any_ne_cc(vsi, vsi, &cc); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfaefs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 12) + // CHECK-ASM: vfaefs vbi = vec_find_any_ne_cc(vui, vui, &cc); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfaefs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 12) + // CHECK-ASM: vfaefs vbi = vec_find_any_ne_cc(vbi, vbi, &cc); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfaefs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 12) + // CHECK-ASM: vfaefs vsc = vec_find_any_ne_idx(vsc, vsc); // CHECK: call <16 x i8> @llvm.s390.vfaeb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 8) + // CHECK-ASM: vfaeb vuc = vec_find_any_ne_idx(vuc, vuc); // CHECK: call <16 x i8> @llvm.s390.vfaeb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 8) + // CHECK-ASM: vfaeb vuc = vec_find_any_ne_idx(vbc, vbc); // CHECK: call <16 x i8> @llvm.s390.vfaeb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 8) + // CHECK-ASM: vfaeb vss = vec_find_any_ne_idx(vss, vss); // CHECK: call <8 x i16> @llvm.s390.vfaeh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 8) + // CHECK-ASM: vfaeh vus = vec_find_any_ne_idx(vus, vus); // CHECK: call <8 x i16> @llvm.s390.vfaeh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 8) + // CHECK-ASM: vfaeh vus = vec_find_any_ne_idx(vbs, vbs); // CHECK: call <8 x i16> @llvm.s390.vfaeh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 8) + // CHECK-ASM: vfaeh vsi = vec_find_any_ne_idx(vsi, vsi); // CHECK: call <4 x i32> @llvm.s390.vfaef(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 8) + // CHECK-ASM: vfaef vui = vec_find_any_ne_idx(vui, vui); // CHECK: call <4 x i32> @llvm.s390.vfaef(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 8) + // CHECK-ASM: vfaef vui = vec_find_any_ne_idx(vbi, vbi); // CHECK: call <4 x i32> @llvm.s390.vfaef(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 8) + // CHECK-ASM: vfaef vsc = vec_find_any_ne_idx_cc(vsc, vsc, &cc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vfaebs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 8) + // CHECK-ASM: vfaebs vuc = vec_find_any_ne_idx_cc(vuc, vuc, &cc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vfaebs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 8) + // CHECK-ASM: vfaebs vuc = vec_find_any_ne_idx_cc(vbc, vbc, &cc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vfaebs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 8) + // CHECK-ASM: vfaebs vss = vec_find_any_ne_idx_cc(vss, vss, &cc); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vfaehs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 8) + // CHECK-ASM: vfaehs vus = vec_find_any_ne_idx_cc(vus, vus, &cc); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vfaehs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 8) + // CHECK-ASM: vfaehs vus = vec_find_any_ne_idx_cc(vbs, vbs, &cc); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vfaehs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 8) + // CHECK-ASM: vfaehs vsi = vec_find_any_ne_idx_cc(vsi, vsi, &cc); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfaefs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 8) + // CHECK-ASM: vfaefs vui = vec_find_any_ne_idx_cc(vui, vui, &cc); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfaefs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 8) + // CHECK-ASM: vfaefs vui = vec_find_any_ne_idx_cc(vbi, vbi, &cc); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfaefs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 8) + // CHECK-ASM: vfaefs vsc = vec_find_any_ne_or_0_idx(vsc, vsc); // CHECK: call <16 x i8> @llvm.s390.vfaezb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 8) + // CHECK-ASM: vfaezb vuc = vec_find_any_ne_or_0_idx(vuc, vuc); // CHECK: call <16 x i8> @llvm.s390.vfaezb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 8) + // CHECK-ASM: vfaezb vuc = vec_find_any_ne_or_0_idx(vbc, vbc); // CHECK: call <16 x i8> @llvm.s390.vfaezb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 8) + // CHECK-ASM: vfaezb vss = vec_find_any_ne_or_0_idx(vss, vss); // CHECK: call <8 x i16> @llvm.s390.vfaezh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 8) + // CHECK-ASM: vfaezh vus = vec_find_any_ne_or_0_idx(vus, vus); // CHECK: call <8 x i16> @llvm.s390.vfaezh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 8) + // CHECK-ASM: vfaezh vus = vec_find_any_ne_or_0_idx(vbs, vbs); // CHECK: call <8 x i16> @llvm.s390.vfaezh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 8) + // CHECK-ASM: vfaezh vsi = vec_find_any_ne_or_0_idx(vsi, vsi); // CHECK: call <4 x i32> @llvm.s390.vfaezf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 8) + // CHECK-ASM: vfaezf vui = vec_find_any_ne_or_0_idx(vui, vui); // CHECK: call <4 x i32> @llvm.s390.vfaezf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 8) + // CHECK-ASM: vfaezf vui = vec_find_any_ne_or_0_idx(vbi, vbi); // CHECK: call <4 x i32> @llvm.s390.vfaezf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 8) + // CHECK-ASM: vfaezf vsc = vec_find_any_ne_or_0_idx_cc(vsc, vsc, &cc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vfaezbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 8) + // CHECK-ASM: vfaezbs vuc = vec_find_any_ne_or_0_idx_cc(vuc, vuc, &cc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vfaezbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 8) + // CHECK-ASM: vfaezbs vuc = vec_find_any_ne_or_0_idx_cc(vbc, vbc, &cc); // CHECK: call { <16 x i8>, i32 } @llvm.s390.vfaezbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 8) + // CHECK-ASM: vfaezbs vss = vec_find_any_ne_or_0_idx_cc(vss, vss, &cc); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vfaezhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 8) + // CHECK-ASM: vfaezhs vus = vec_find_any_ne_or_0_idx_cc(vus, vus, &cc); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vfaezhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 8) + // CHECK-ASM: vfaezhs vus = vec_find_any_ne_or_0_idx_cc(vbs, vbs, &cc); // CHECK: call { <8 x i16>, i32 } @llvm.s390.vfaezhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 8) + // CHECK-ASM: vfaezhs vsi = vec_find_any_ne_or_0_idx_cc(vsi, vsi, &cc); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfaezfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 8) + // CHECK-ASM: vfaezfs vui = vec_find_any_ne_or_0_idx_cc(vui, vui, &cc); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfaezfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 8) + // CHECK-ASM: vfaezfs vui = vec_find_any_ne_or_0_idx_cc(vbi, vbi, &cc); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfaezfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 8) + // CHECK-ASM: vfaezfs } void test_float(void) { + // CHECK-ASM-LABEL: test_float + vd = vec_abs(vd); // CHECK: call <2 x double> @llvm.fabs.v2f64(<2 x double> %{{.*}}) + // CHECK-ASM: vflpdb vd = vec_nabs(vd); // CHECK: [[ABS:%[^ ]+]] = tail call <2 x double> @llvm.fabs.v2f64(<2 x double> %{{.*}}) // CHECK-NEXT: fsub <2 x double> , [[ABS]] + // CHECK-ASM: vflndb vd = vec_madd(vd, vd, vd); // CHECK: call <2 x double> @llvm.fma.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x double> %{{.*}}) + // CHECK-ASM: vfmadb vd = vec_msub(vd, vd, vd); // CHECK: [[NEG:%[^ ]+]] = fsub <2 x double> , %{{.*}} // CHECK: call <2 x double> @llvm.fma.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x double> [[NEG]]) + // CHECK-ASM: vfmsdb vd = vec_sqrt(vd); // CHECK: call <2 x double> @llvm.sqrt.v2f64(<2 x double> %{{.*}}) + // CHECK-ASM: vfsqdb vd = vec_ld2f(cptrf); // CHECK: [[VAL:%[^ ]+]] = load <2 x float>, <2 x float>* %{{.*}} // CHECK: fpext <2 x float> [[VAL]] to <2 x double> + // (emulated) vec_st2f(vd, ptrf); // CHECK: [[VAL:%[^ ]+]] = fptrunc <2 x double> %{{.*}} to <2 x float> // CHECK: store <2 x float> [[VAL]], <2 x float>* %{{.*}} + // (emulated) vd = vec_ctd(vsl, 0); // CHECK: sitofp <2 x i64> %{{.*}} to <2 x double> + // (emulated) vd = vec_ctd(vul, 0); // CHECK: uitofp <2 x i64> %{{.*}} to <2 x double> + // (emulated) vd = vec_ctd(vsl, 1); // CHECK: [[VAL:%[^ ]+]] = sitofp <2 x i64> %{{.*}} to <2 x double> // CHECK: fmul <2 x double> [[VAL]], + // (emulated) vd = vec_ctd(vul, 1); // CHECK: [[VAL:%[^ ]+]] = uitofp <2 x i64> %{{.*}} to <2 x double> // CHECK: fmul <2 x double> [[VAL]], + // (emulated) vd = vec_ctd(vsl, 31); // CHECK: [[VAL:%[^ ]+]] = sitofp <2 x i64> %{{.*}} to <2 x double> // CHECK: fmul <2 x double> [[VAL]], + // (emulated) vd = vec_ctd(vul, 31); // CHECK: [[VAL:%[^ ]+]] = uitofp <2 x i64> %{{.*}} to <2 x double> // CHECK: fmul <2 x double> [[VAL]], + // (emulated) vsl = vec_ctsl(vd, 0); // CHECK: fptosi <2 x double> %{{.*}} to <2 x i64> + // (emulated) vul = vec_ctul(vd, 0); // CHECK: fptoui <2 x double> %{{.*}} to <2 x i64> + // (emulated) vsl = vec_ctsl(vd, 1); // CHECK: [[VAL:%[^ ]+]] = fmul <2 x double> %{{.*}}, // CHECK: fptosi <2 x double> [[VAL]] to <2 x i64> + // (emulated) vul = vec_ctul(vd, 1); // CHECK: [[VAL:%[^ ]+]] = fmul <2 x double> %{{.*}}, // CHECK: fptoui <2 x double> [[VAL]] to <2 x i64> + // (emulated) vsl = vec_ctsl(vd, 31); // CHECK: [[VAL:%[^ ]+]] = fmul <2 x double> %{{.*}}, // CHECK: fptosi <2 x double> [[VAL]] to <2 x i64> + // (emulated) vul = vec_ctul(vd, 31); // CHECK: [[VAL:%[^ ]+]] = fmul <2 x double> %{{.*}}, // CHECK: fptoui <2 x double> [[VAL]] to <2 x i64> + // (emulated) vd = vec_double(vsl); // CHECK: sitofp <2 x i64> %{{.*}} to <2 x double> + // CHECK-ASM: vcdgb vd = vec_double(vul); // CHECK: uitofp <2 x i64> %{{.*}} to <2 x double> + // CHECK-ASM: vcdlgb vsl = vec_signed(vd); // CHECK: fptosi <2 x double> %{{.*}} to <2 x i64> + // CHECK-ASM: vcgdb vul = vec_unsigned(vd); // CHECK: fptoui <2 x double> %{{.*}} to <2 x i64> + // CHECK-ASM: vclgdb vd = vec_roundp(vd); // CHECK: call <2 x double> @llvm.ceil.v2f64(<2 x double> %{{.*}}) + // CHECK-ASM: vfidb %{{.*}}, %{{.*}}, 4, 6 vd = vec_ceil(vd); // CHECK: call <2 x double> @llvm.ceil.v2f64(<2 x double> %{{.*}}) + // CHECK-ASM: vfidb %{{.*}}, %{{.*}}, 4, 6 vd = vec_roundm(vd); // CHECK: call <2 x double> @llvm.floor.v2f64(<2 x double> %{{.*}}) + // CHECK-ASM: vfidb %{{.*}}, %{{.*}}, 4, 7 vd = vec_floor(vd); // CHECK: call <2 x double> @llvm.floor.v2f64(<2 x double> %{{.*}}) + // CHECK-ASM: vfidb %{{.*}}, %{{.*}}, 4, 7 vd = vec_roundz(vd); // CHECK: call <2 x double> @llvm.trunc.v2f64(<2 x double> %{{.*}}) + // CHECK-ASM: vfidb %{{.*}}, %{{.*}}, 4, 5 vd = vec_trunc(vd); // CHECK: call <2 x double> @llvm.trunc.v2f64(<2 x double> %{{.*}}) + // CHECK-ASM: vfidb %{{.*}}, %{{.*}}, 4, 5 vd = vec_roundc(vd); // CHECK: call <2 x double> @llvm.nearbyint.v2f64(<2 x double> %{{.*}}) + // CHECK-ASM: vfidb %{{.*}}, %{{.*}}, 4, 0 vd = vec_rint(vd); // CHECK: call <2 x double> @llvm.rint.v2f64(<2 x double> %{{.*}}) + // CHECK-ASM: vfidb %{{.*}}, %{{.*}}, 0, 0 vd = vec_round(vd); // CHECK: call <2 x double> @llvm.s390.vfidb(<2 x double> %{{.*}}, i32 4, i32 4) + // CHECK-ASM: vfidb %{{.*}}, %{{.*}}, 4, 4 vbl = vec_fp_test_data_class(vd, 0, &cc); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 0) + // CHECK-ASM: vftcidb vbl = vec_fp_test_data_class(vd, 4095, &cc); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 4095) + // CHECK-ASM: vftcidb vbl = vec_fp_test_data_class(vd, __VEC_CLASS_FP_ZERO_P, &cc); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 2048) + // CHECK-ASM: vftcidb vbl = vec_fp_test_data_class(vd, __VEC_CLASS_FP_ZERO_N, &cc); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 1024) + // CHECK-ASM: vftcidb vbl = vec_fp_test_data_class(vd, __VEC_CLASS_FP_ZERO, &cc); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 3072) + // CHECK-ASM: vftcidb vbl = vec_fp_test_data_class(vd, __VEC_CLASS_FP_NORMAL_P, &cc); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 512) + // CHECK-ASM: vftcidb vbl = vec_fp_test_data_class(vd, __VEC_CLASS_FP_NORMAL_N, &cc); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 256) + // CHECK-ASM: vftcidb vbl = vec_fp_test_data_class(vd, __VEC_CLASS_FP_NORMAL, &cc); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 768) + // CHECK-ASM: vftcidb vbl = vec_fp_test_data_class(vd, __VEC_CLASS_FP_SUBNORMAL_P, &cc); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 128) + // CHECK-ASM: vftcidb vbl = vec_fp_test_data_class(vd, __VEC_CLASS_FP_SUBNORMAL_N, &cc); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 64) + // CHECK-ASM: vftcidb vbl = vec_fp_test_data_class(vd, __VEC_CLASS_FP_SUBNORMAL, &cc); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 192) + // CHECK-ASM: vftcidb vbl = vec_fp_test_data_class(vd, __VEC_CLASS_FP_INFINITY_P, &cc); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 32) + // CHECK-ASM: vftcidb vbl = vec_fp_test_data_class(vd, __VEC_CLASS_FP_INFINITY_N, &cc); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 16) + // CHECK-ASM: vftcidb vbl = vec_fp_test_data_class(vd, __VEC_CLASS_FP_INFINITY, &cc); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 48) + // CHECK-ASM: vftcidb vbl = vec_fp_test_data_class(vd, __VEC_CLASS_FP_QNAN_P, &cc); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 8) + // CHECK-ASM: vftcidb vbl = vec_fp_test_data_class(vd, __VEC_CLASS_FP_QNAN_N, &cc); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 4) + // CHECK-ASM: vftcidb vbl = vec_fp_test_data_class(vd, __VEC_CLASS_FP_QNAN, &cc); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 12) + // CHECK-ASM: vftcidb vbl = vec_fp_test_data_class(vd, __VEC_CLASS_FP_SNAN_P, &cc); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 2) + // CHECK-ASM: vftcidb vbl = vec_fp_test_data_class(vd, __VEC_CLASS_FP_SNAN_N, &cc); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 1) + // CHECK-ASM: vftcidb vbl = vec_fp_test_data_class(vd, __VEC_CLASS_FP_SNAN, &cc); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 3) + // CHECK-ASM: vftcidb vbl = vec_fp_test_data_class(vd, __VEC_CLASS_FP_NAN, &cc); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 15) + // CHECK-ASM: vftcidb vbl = vec_fp_test_data_class(vd, __VEC_CLASS_FP_NOT_NORMAL, &cc); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 3327) + // CHECK-ASM: vftcidb } diff --git a/test/CodeGen/builtins-systemz-zvector2.c b/test/CodeGen/builtins-systemz-zvector2.c index acdaebd7a5..c89cf399a4 100644 --- a/test/CodeGen/builtins-systemz-zvector2.c +++ b/test/CodeGen/builtins-systemz-zvector2.c @@ -2,6 +2,9 @@ // RUN: %clang_cc1 -target-cpu z14 -triple s390x-linux-gnu \ // RUN: -O -fzvector -fno-lax-vector-conversions \ // RUN: -Wall -Wno-unused -Werror -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -target-cpu z14 -triple s390x-linux-gnu \ +// RUN: -O -fzvector -fno-lax-vector-conversions \ +// RUN: -Wall -Wno-unused -Werror -S %s -o - | FileCheck %s --check-prefix=CHECK-ASM #include @@ -60,486 +63,774 @@ volatile int idx; int cc; void test_core(void) { + // CHECK-ASM-LABEL: test_core + vector float vf2; + vector double vd2; + + f = vec_extract(vf, 0); + // CHECK: extractelement <4 x float> %{{.*}}, i32 0 + // CHECK-ASM: vstef f = vec_extract(vf, idx); // CHECK: extractelement <4 x float> %{{.*}}, i32 %{{.*}} + // CHECK-ASM: vlgvf + d = vec_extract(vd, 0); + // CHECK: extractelement <2 x double> %{{.*}}, i32 0 + // CHECK-ASM: vsteg d = vec_extract(vd, idx); // CHECK: extractelement <2 x double> %{{.*}}, i32 %{{.*}} - + // CHECK-ASM: vlgvg + + vf2 = vf; + vf = vec_insert(f, vf2, 0); + // CHECK: insertelement <4 x float> %{{.*}}, float %{{.*}}, i32 0 + // CHECK-ASM: vlef + vf = vec_insert(0.0f, vf, 1); + // CHECK: insertelement <4 x float> %{{.*}}, float 0.000000e+00, i32 1 + // CHECK-ASM: vleif %{{.*}}, 0, 1 vf = vec_insert(f, vf, idx); // CHECK: insertelement <4 x float> %{{.*}}, float %{{.*}}, i32 %{{.*}} + // CHECK-ASM: vlvgf + vd2 = vd; + vd = vec_insert(d, vd2, 0); + // CHECK: insertelement <2 x double> %{{.*}}, double %{{.*}}, i32 0 + // CHECK-ASM: vleg + vd = vec_insert(0.0, vd, 1); + // CHECK: insertelement <2 x double> %{{.*}}, double 0.000000e+00, i32 1 + // CHECK-ASM: vleig %{{.*}}, 0, 1 vd = vec_insert(d, vd, idx); // CHECK: insertelement <2 x double> %{{.*}}, double %{{.*}}, i32 %{{.*}} + // CHECK-ASM: vlvgg vf = vec_promote(f, idx); // CHECK: insertelement <4 x float> undef, float %{{.*}}, i32 %{{.*}} + // CHECK-ASM: vlvgf vd = vec_promote(d, idx); // CHECK: insertelement <2 x double> undef, double %{{.*}}, i32 %{{.*}} + // CHECK-ASM: vlvgg vf = vec_insert_and_zero(cptrf); // CHECK: insertelement <4 x float> , float %{{.*}}, i32 1 + // CHECK-ASM: vllezf vd = vec_insert_and_zero(cptrd); // CHECK: insertelement <2 x double> , double %{{.*}}, i32 0 + // CHECK-ASM: vllezg vf = vec_perm(vf, vf, vuc); // CHECK: call <16 x i8> @llvm.s390.vperm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vperm vd = vec_perm(vd, vd, vuc); // CHECK: call <16 x i8> @llvm.s390.vperm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vperm vul = vec_bperm_u128(vuc, vuc); // CHECK: call <2 x i64> @llvm.s390.vbperm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vbperm vf = vec_sel(vf, vf, vui); + // CHECK-ASM: vsel vf = vec_sel(vf, vf, vbi); + // CHECK-ASM: vsel vd = vec_sel(vd, vd, vul); + // CHECK-ASM: vsel vd = vec_sel(vd, vd, vbl); + // CHECK-ASM: vsel vf = vec_gather_element(vf, vui, cptrf, 0); + // CHECK-ASM: vgef %{{.*}}, 0(%{{.*}},%{{.*}}), 0 vf = vec_gather_element(vf, vui, cptrf, 1); + // CHECK-ASM: vgef %{{.*}}, 0(%{{.*}},%{{.*}}), 1 vf = vec_gather_element(vf, vui, cptrf, 2); + // CHECK-ASM: vgef %{{.*}}, 0(%{{.*}},%{{.*}}), 2 vf = vec_gather_element(vf, vui, cptrf, 3); + // CHECK-ASM: vgef %{{.*}}, 0(%{{.*}},%{{.*}}), 3 vd = vec_gather_element(vd, vul, cptrd, 0); + // CHECK-ASM: vgeg %{{.*}}, 0(%{{.*}},%{{.*}}), 0 vd = vec_gather_element(vd, vul, cptrd, 1); + // CHECK-ASM: vgeg %{{.*}}, 0(%{{.*}},%{{.*}}), 1 vec_scatter_element(vf, vui, ptrf, 0); + // CHECK-ASM: vscef %{{.*}}, 0(%{{.*}},%{{.*}}), 0 vec_scatter_element(vf, vui, ptrf, 1); + // CHECK-ASM: vscef %{{.*}}, 0(%{{.*}},%{{.*}}), 1 vec_scatter_element(vf, vui, ptrf, 2); + // CHECK-ASM: vscef %{{.*}}, 0(%{{.*}},%{{.*}}), 2 vec_scatter_element(vf, vui, ptrf, 3); + // CHECK-ASM: vscef %{{.*}}, 0(%{{.*}},%{{.*}}), 3 vec_scatter_element(vd, vul, ptrd, 0); + // CHECK-ASM: vsceg %{{.*}}, 0(%{{.*}},%{{.*}}), 0 vec_scatter_element(vd, vul, ptrd, 1); + // CHECK-ASM: vsceg %{{.*}}, 0(%{{.*}},%{{.*}}), 1 vf = vec_xl(idx, cptrf); + // CHECK-ASM: vl vd = vec_xl(idx, cptrd); + // CHECK-ASM: vl vec_xst(vf, idx, ptrf); + // CHECK-ASM: vst vec_xst(vd, idx, ptrd); + // CHECK-ASM: vst vd = vec_load_bndry(cptrd, 64); // CHECK: call <16 x i8> @llvm.s390.vlbb(i8* %{{.*}}, i32 0) + // CHECK-ASM: vlbb vf = vec_load_bndry(cptrf, 64); // CHECK: call <16 x i8> @llvm.s390.vlbb(i8* %{{.*}}, i32 0) + // CHECK-ASM: vlbb vf = vec_load_bndry(cptrf, 128); // CHECK: call <16 x i8> @llvm.s390.vlbb(i8* %{{.*}}, i32 1) + // CHECK-ASM: vlbb vf = vec_load_bndry(cptrf, 256); // CHECK: call <16 x i8> @llvm.s390.vlbb(i8* %{{.*}}, i32 2) + // CHECK-ASM: vlbb vf = vec_load_bndry(cptrf, 512); // CHECK: call <16 x i8> @llvm.s390.vlbb(i8* %{{.*}}, i32 3) + // CHECK-ASM: vlbb vf = vec_load_bndry(cptrf, 1024); // CHECK: call <16 x i8> @llvm.s390.vlbb(i8* %{{.*}}, i32 4) + // CHECK-ASM: vlbb vf = vec_load_bndry(cptrf, 2048); // CHECK: call <16 x i8> @llvm.s390.vlbb(i8* %{{.*}}, i32 5) + // CHECK-ASM: vlbb vf = vec_load_bndry(cptrf, 4096); // CHECK: call <16 x i8> @llvm.s390.vlbb(i8* %{{.*}}, i32 6) + // CHECK-ASM: vlbb vf = vec_load_len(cptrf, idx); // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, i8* %{{.*}}) + // CHECK-ASM: vll vd = vec_load_len(cptrd, idx); // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, i8* %{{.*}}) + // CHECK-ASM: vll vec_store_len(vf, ptrf, idx); // CHECK: call void @llvm.s390.vstl(<16 x i8> %{{.*}}, i32 %{{.*}}, i8* %{{.*}}) + // CHECK-ASM: vstl vec_store_len(vd, ptrd, idx); // CHECK: call void @llvm.s390.vstl(<16 x i8> %{{.*}}, i32 %{{.*}}, i8* %{{.*}}) + // CHECK-ASM: vstl + vuc = vec_load_len_r(cptruc, 0); + // CHECK: call <16 x i8> @llvm.s390.vlrl(i32 0, i8* %{{.*}}) + // CHECK-ASM: vlrl %{{.*}}, 0(%{{.*}}), 0 vuc = vec_load_len_r(cptruc, idx); // CHECK: call <16 x i8> @llvm.s390.vlrl(i32 %{{.*}}, i8* %{{.*}}) + // CHECK-ASM: vlrlr + vec_store_len_r(vuc, ptruc, 0); + // CHECK: call void @llvm.s390.vstrl(<16 x i8> %{{.*}}, i32 0, i8* %{{.*}}) + // CHECK-ASM: vstrl %{{.*}}, 0(%{{.*}}), 0 vec_store_len_r(vuc, ptruc, idx); // CHECK: call void @llvm.s390.vstrl(<16 x i8> %{{.*}}, i32 %{{.*}}, i8* %{{.*}}) + // CHECK-ASM: vstrlr vf = vec_splat(vf, 0); // CHECK: shufflevector <4 x float> %{{.*}}, <4 x float> undef, <4 x i32> zeroinitializer + // CHECK-ASM: vrepf vf = vec_splat(vf, 1); // CHECK: shufflevector <4 x float> %{{.*}}, <4 x float> undef, <4 x i32> + // CHECK-ASM: vrepf vd = vec_splat(vd, 0); // CHECK: shufflevector <2 x double> %{{.*}}, <2 x double> undef, <2 x i32> zeroinitializer + // CHECK-ASM: vrepg vd = vec_splat(vd, 1); // CHECK: shufflevector <2 x double> %{{.*}}, <2 x double> undef, <2 x i32> + // CHECK-ASM: vrepg vf = vec_splats(f); // CHECK: shufflevector <4 x float> %{{.*}}, <4 x float> undef, <4 x i32> zeroinitializer + // CHECK-ASM: vlrepf vd = vec_splats(d); // CHECK: shufflevector <2 x double> %{{.*}}, <2 x double> undef, <2 x i32> zeroinitializer + // CHECK-ASM: vlrepg vf = vec_mergeh(vf, vf); // shufflevector <4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x i32> + // CHECK-ASM: vmrhf vd = vec_mergeh(vd, vd); // shufflevector <2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x i32> + // CHECK-ASM: vmrhg vf = vec_mergel(vf, vf); // shufflevector <4 x float> %{{.*}}, <4 x float> %{{.*}}, + // CHECK-ASM: vmrlf vd = vec_mergel(vd, vd); // shufflevector <2 x double> %{{.*}}, <2 x double> %{{.*}}, + // CHECK-ASM: vmrlg } void test_compare(void) { + // CHECK-ASM-LABEL: test_compare + vbi = vec_cmpeq(vf, vf); // CHECK: fcmp oeq <4 x float> %{{.*}}, %{{.*}} + // CHECK-ASM: vfcesb vbl = vec_cmpeq(vd, vd); // CHECK: fcmp oeq <2 x double> %{{.*}}, %{{.*}} + // CHECK-ASM: vfcedb vbi = vec_cmpge(vf, vf); // CHECK: fcmp oge <4 x float> %{{.*}}, %{{.*}} + // CHECK-ASM: vfchesb vbl = vec_cmpge(vd, vd); // CHECK: fcmp oge <2 x double> %{{.*}}, %{{.*}} + // CHECK-ASM: vfchedb vbi = vec_cmpgt(vf, vf); // CHECK: fcmp ogt <4 x float> %{{.*}}, %{{.*}} + // CHECK-ASM: vfchsb vbl = vec_cmpgt(vd, vd); // CHECK: fcmp ogt <2 x double> %{{.*}}, %{{.*}} + // CHECK-ASM: vfchdb vbi = vec_cmple(vf, vf); // CHECK: fcmp ole <4 x float> %{{.*}}, %{{.*}} + // CHECK-ASM: vfchesb vbl = vec_cmple(vd, vd); // CHECK: fcmp ole <2 x double> %{{.*}}, %{{.*}} + // CHECK-ASM: vfchedb vbi = vec_cmplt(vf, vf); // CHECK: fcmp olt <4 x float> %{{.*}}, %{{.*}} + // CHECK-ASM: vfchsb vbl = vec_cmplt(vd, vd); // CHECK: fcmp olt <2 x double> %{{.*}}, %{{.*}} + // CHECK-ASM: vfchdb idx = vec_all_eq(vf, vf); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfcesbs(<4 x float> %{{.*}}, <4 x float> %{{.*}}) + // CHECK-ASM: vfcesbs idx = vec_all_eq(vd, vd); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfcedbs(<2 x double> %{{.*}}, <2 x double> %{{.*}}) + // CHECK-ASM: vfcedbs idx = vec_all_ne(vf, vf); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfcesbs(<4 x float> %{{.*}}, <4 x float> %{{.*}}) + // CHECK-ASM: vfcesbs idx = vec_all_ne(vd, vd); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfcedbs(<2 x double> %{{.*}}, <2 x double> %{{.*}}) + // CHECK-ASM: vfcedbs idx = vec_all_ge(vf, vf); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfchesbs(<4 x float> %{{.*}}, <4 x float> %{{.*}}) + // CHECK-ASM: vfchesbs idx = vec_all_ge(vd, vd); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchedbs(<2 x double> %{{.*}}, <2 x double> %{{.*}}) + // CHECK-ASM: vfchedbs idx = vec_all_gt(vf, vf); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfchsbs(<4 x float> %{{.*}}, <4 x float> %{{.*}}) + // CHECK-ASM: vfchsbs idx = vec_all_gt(vd, vd); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchdbs(<2 x double> %{{.*}}, <2 x double> %{{.*}}) + // CHECK-ASM: vfchdbs idx = vec_all_le(vf, vf); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfchesbs(<4 x float> %{{.*}}, <4 x float> %{{.*}}) + // CHECK-ASM: vfchesbs idx = vec_all_le(vd, vd); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchedbs(<2 x double> %{{.*}}, <2 x double> %{{.*}}) + // CHECK-ASM: vfchedbs idx = vec_all_lt(vf, vf); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfchsbs(<4 x float> %{{.*}}, <4 x float> %{{.*}}) + // CHECK-ASM: vfchsbs idx = vec_all_lt(vd, vd); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchdbs(<2 x double> %{{.*}}, <2 x double> %{{.*}}) + // CHECK-ASM: vfchdbs idx = vec_all_nge(vf, vf); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfchesbs(<4 x float> %{{.*}}, <4 x float> %{{.*}}) + // CHECK-ASM: vfchesbs idx = vec_all_nge(vd, vd); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchedbs(<2 x double> %{{.*}}, <2 x double> %{{.*}}) + // CHECK-ASM: vfchedbs idx = vec_all_ngt(vf, vf); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfchsbs(<4 x float> %{{.*}}, <4 x float> %{{.*}}) + // CHECK-ASM: vfchsbs idx = vec_all_ngt(vd, vd); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchdbs(<2 x double> %{{.*}}, <2 x double> %{{.*}}) + // CHECK-ASM: vfchdbs idx = vec_all_nle(vf, vf); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfchesbs(<4 x float> %{{.*}}, <4 x float> %{{.*}}) + // CHECK-ASM: vfchesbs idx = vec_all_nle(vd, vd); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchedbs(<2 x double> %{{.*}}, <2 x double> %{{.*}}) + // CHECK-ASM: vfchedbs idx = vec_all_nlt(vf, vf); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfchsbs(<4 x float> %{{.*}}, <4 x float> %{{.*}}) + // CHECK-ASM: vfchsbs idx = vec_all_nlt(vd, vd); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchdbs(<2 x double> %{{.*}}, <2 x double> %{{.*}}) + // CHECK-ASM: vfchdbs idx = vec_all_nan(vf); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vftcisb(<4 x float> %{{.*}}, i32 15) + // CHECK-ASM: vftcisb idx = vec_all_nan(vd); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 15) + // CHECK-ASM: vftcidb idx = vec_all_numeric(vf); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vftcisb(<4 x float> %{{.*}}, i32 15) + // CHECK-ASM: vftcisb idx = vec_all_numeric(vd); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 15) + // CHECK-ASM: vftcidb idx = vec_any_eq(vf, vf); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfcesbs(<4 x float> %{{.*}}, <4 x float> %{{.*}}) + // CHECK-ASM: vfcesbs idx = vec_any_eq(vd, vd); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfcedbs(<2 x double> %{{.*}}, <2 x double> %{{.*}}) + // CHECK-ASM: vfcedbs idx = vec_any_ne(vf, vf); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfcesbs(<4 x float> %{{.*}}, <4 x float> %{{.*}}) + // CHECK-ASM: vfcesbs idx = vec_any_ne(vd, vd); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfcedbs(<2 x double> %{{.*}}, <2 x double> %{{.*}}) + // CHECK-ASM: vfcedbs idx = vec_any_ge(vf, vf); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfchesbs(<4 x float> %{{.*}}, <4 x float> %{{.*}}) + // CHECK-ASM: vfchesbs idx = vec_any_ge(vd, vd); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchedbs(<2 x double> %{{.*}}, <2 x double> %{{.*}}) + // CHECK-ASM: vfchedbs idx = vec_any_gt(vf, vf); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfchsbs(<4 x float> %{{.*}}, <4 x float> %{{.*}}) + // CHECK-ASM: vfchsbs idx = vec_any_gt(vd, vd); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchdbs(<2 x double> %{{.*}}, <2 x double> %{{.*}}) + // CHECK-ASM: vfchdbs idx = vec_any_le(vf, vf); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfchesbs(<4 x float> %{{.*}}, <4 x float> %{{.*}}) + // CHECK-ASM: vfchesbs idx = vec_any_le(vd, vd); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchedbs(<2 x double> %{{.*}}, <2 x double> %{{.*}}) + // CHECK-ASM: vfchedbs idx = vec_any_lt(vf, vf); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfchsbs(<4 x float> %{{.*}}, <4 x float> %{{.*}}) + // CHECK-ASM: vfchsbs idx = vec_any_lt(vd, vd); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchdbs(<2 x double> %{{.*}}, <2 x double> %{{.*}}) + // CHECK-ASM: vfchdbs idx = vec_any_nge(vf, vf); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfchesbs(<4 x float> %{{.*}}, <4 x float> %{{.*}}) + // CHECK-ASM: vfchesbs idx = vec_any_nge(vd, vd); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchedbs(<2 x double> %{{.*}}, <2 x double> %{{.*}}) + // CHECK-ASM: vfchedbs idx = vec_any_ngt(vf, vf); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfchsbs(<4 x float> %{{.*}}, <4 x float> %{{.*}}) + // CHECK-ASM: vfchsbs idx = vec_any_ngt(vd, vd); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchdbs(<2 x double> %{{.*}}, <2 x double> %{{.*}}) + // CHECK-ASM: vfchdbs idx = vec_any_nle(vf, vf); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfchesbs(<4 x float> %{{.*}}, <4 x float> %{{.*}}) + // CHECK-ASM: vfchesbs idx = vec_any_nle(vd, vd); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchedbs(<2 x double> %{{.*}}, <2 x double> %{{.*}}) + // CHECK-ASM: vfchedbs idx = vec_any_nlt(vf, vf); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfchsbs(<4 x float> %{{.*}}, <4 x float> %{{.*}}) + // CHECK-ASM: vfchsbs idx = vec_any_nlt(vd, vd); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchdbs(<2 x double> %{{.*}}, <2 x double> %{{.*}}) + // CHECK-ASM: vfchdbs idx = vec_any_nan(vf); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vftcisb(<4 x float> %{{.*}}, i32 15) + // CHECK-ASM: vftcisb idx = vec_any_nan(vd); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 15) + // CHECK-ASM: vftcidb idx = vec_any_numeric(vf); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vftcisb(<4 x float> %{{.*}}, i32 15) + // CHECK-ASM: vftcisb idx = vec_any_numeric(vd); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 15) + // CHECK-ASM: vftcidb } void test_integer(void) { + // CHECK-ASM-LABEL: test_integer + vf = vec_andc(vf, vf); + // CHECK-ASM: vnc vd = vec_andc(vd, vd); + // CHECK-ASM: vnc vf = vec_nor(vf, vf); + // CHECK-ASM: vno vd = vec_nor(vd, vd); + // CHECK-ASM: vno vsc = vec_nand(vsc, vsc); + // CHECK-ASM: vnn vuc = vec_nand(vuc, vuc); + // CHECK-ASM: vnn vbc = vec_nand(vbc, vbc); + // CHECK-ASM: vnn vss = vec_nand(vss, vss); + // CHECK-ASM: vnn vus = vec_nand(vus, vus); + // CHECK-ASM: vnn vbs = vec_nand(vbs, vbs); + // CHECK-ASM: vnn vsi = vec_nand(vsi, vsi); + // CHECK-ASM: vnn vui = vec_nand(vui, vui); + // CHECK-ASM: vnn vbi = vec_nand(vbi, vbi); + // CHECK-ASM: vnn vsl = vec_nand(vsl, vsl); + // CHECK-ASM: vnn vul = vec_nand(vul, vul); + // CHECK-ASM: vnn vbl = vec_nand(vbl, vbl); + // CHECK-ASM: vnn vf = vec_nand(vf, vf); + // CHECK-ASM: vnn vd = vec_nand(vd, vd); + // CHECK-ASM: vnn vsc = vec_orc(vsc, vsc); + // CHECK-ASM: voc vuc = vec_orc(vuc, vuc); + // CHECK-ASM: voc vbc = vec_orc(vbc, vbc); + // CHECK-ASM: voc vss = vec_orc(vss, vss); + // CHECK-ASM: voc vus = vec_orc(vus, vus); + // CHECK-ASM: voc vbs = vec_orc(vbs, vbs); + // CHECK-ASM: voc vsi = vec_orc(vsi, vsi); + // CHECK-ASM: voc vui = vec_orc(vui, vui); + // CHECK-ASM: voc vbi = vec_orc(vbi, vbi); + // CHECK-ASM: voc vsl = vec_orc(vsl, vsl); + // CHECK-ASM: voc vul = vec_orc(vul, vul); + // CHECK-ASM: voc vbl = vec_orc(vbl, vbl); + // CHECK-ASM: voc vf = vec_orc(vf, vf); + // CHECK-ASM: voc vd = vec_orc(vd, vd); + // CHECK-ASM: voc vsc = vec_eqv(vsc, vsc); + // CHECK-ASM: vnx vuc = vec_eqv(vuc, vuc); + // CHECK-ASM: vnx vbc = vec_eqv(vbc, vbc); + // CHECK-ASM: vnx vss = vec_eqv(vss, vss); + // CHECK-ASM: vnx vus = vec_eqv(vus, vus); + // CHECK-ASM: vnx vbs = vec_eqv(vbs, vbs); + // CHECK-ASM: vnx vsi = vec_eqv(vsi, vsi); + // CHECK-ASM: vnx vui = vec_eqv(vui, vui); + // CHECK-ASM: vnx vbi = vec_eqv(vbi, vbi); + // CHECK-ASM: vnx vsl = vec_eqv(vsl, vsl); + // CHECK-ASM: vnx vul = vec_eqv(vul, vul); + // CHECK-ASM: vnx vbl = vec_eqv(vbl, vbl); + // CHECK-ASM: vnx vf = vec_eqv(vf, vf); + // CHECK-ASM: vnx vd = vec_eqv(vd, vd); + // CHECK-ASM: vnx + + vuc = vec_popcnt(vsc); + // CHECK: call <16 x i8> @llvm.ctpop.v16i8(<16 x i8> %{{.*}}) + // CHECK-ASM: vpopctb + vuc = vec_popcnt(vuc); + // CHECK: call <16 x i8> @llvm.ctpop.v16i8(<16 x i8> %{{.*}}) + // CHECK-ASM: vpopctb + vus = vec_popcnt(vss); + // CHECK: call <8 x i16> @llvm.ctpop.v8i16(<8 x i16> %{{.*}}) + // CHECK-ASM: vpopcth + vus = vec_popcnt(vus); + // CHECK: call <8 x i16> @llvm.ctpop.v8i16(<8 x i16> %{{.*}}) + // CHECK-ASM: vpopcth + vui = vec_popcnt(vsi); + // CHECK: call <4 x i32> @llvm.ctpop.v4i32(<4 x i32> %{{.*}}) + // CHECK-ASM: vpopctf + vui = vec_popcnt(vui); + // CHECK: call <4 x i32> @llvm.ctpop.v4i32(<4 x i32> %{{.*}}) + // CHECK-ASM: vpopctf + vul = vec_popcnt(vsl); + // CHECK: call <2 x i64> @llvm.ctpop.v2i64(<2 x i64> %{{.*}}) + // CHECK-ASM: vpopctg + vul = vec_popcnt(vul); + // CHECK: call <2 x i64> @llvm.ctpop.v2i64(<2 x i64> %{{.*}}) + // CHECK-ASM: vpopctg vf = vec_slb(vf, vsi); // CHECK: call <16 x i8> @llvm.s390.vslb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vslb vf = vec_slb(vf, vui); // CHECK: call <16 x i8> @llvm.s390.vslb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vslb vd = vec_slb(vd, vsl); // CHECK: call <16 x i8> @llvm.s390.vslb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vslb vd = vec_slb(vd, vul); // CHECK: call <16 x i8> @llvm.s390.vslb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vslb vf = vec_sld(vf, vf, 0); // CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0) + // CHECK-ASM: vsldb vf = vec_sld(vf, vf, 15); // CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 15) + // CHECK-ASM: vsldb vd = vec_sld(vd, vd, 0); // CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0) + // CHECK-ASM: vsldb vd = vec_sld(vd, vd, 15); // CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 15) + // CHECK-ASM: vsldb vf = vec_srab(vf, vsi); // CHECK: call <16 x i8> @llvm.s390.vsrab(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrab vf = vec_srab(vf, vui); // CHECK: call <16 x i8> @llvm.s390.vsrab(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrab vd = vec_srab(vd, vsl); // CHECK: call <16 x i8> @llvm.s390.vsrab(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrab vd = vec_srab(vd, vul); // CHECK: call <16 x i8> @llvm.s390.vsrab(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrab vf = vec_srb(vf, vsi); // CHECK: call <16 x i8> @llvm.s390.vsrlb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrlb vf = vec_srb(vf, vui); // CHECK: call <16 x i8> @llvm.s390.vsrlb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrlb vd = vec_srb(vd, vsl); // CHECK: call <16 x i8> @llvm.s390.vsrlb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrlb vd = vec_srb(vd, vul); // CHECK: call <16 x i8> @llvm.s390.vsrlb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vsrlb idx = vec_test_mask(vf, vui); // CHECK: call i32 @llvm.s390.vtm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vtm idx = vec_test_mask(vd, vul); // CHECK: call i32 @llvm.s390.vtm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK-ASM: vtm vuc = vec_msum_u128(vul, vul, vuc, 0); // CHECK: call <16 x i8> @llvm.s390.vmslg(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <16 x i8> %{{.*}}, i32 0) + // CHECK-ASM: vmslg vuc = vec_msum_u128(vul, vul, vuc, 4); // CHECK: call <16 x i8> @llvm.s390.vmslg(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <16 x i8> %{{.*}}, i32 4) + // CHECK-ASM: vmslg vuc = vec_msum_u128(vul, vul, vuc, 8); // CHECK: call <16 x i8> @llvm.s390.vmslg(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <16 x i8> %{{.*}}, i32 8) + // CHECK-ASM: vmslg vuc = vec_msum_u128(vul, vul, vuc, 12); // CHECK: call <16 x i8> @llvm.s390.vmslg(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <16 x i8> %{{.*}}, i32 12) + // CHECK-ASM: vmslg } void test_float(void) { + // CHECK-ASM-LABEL: test_float + vf = vec_abs(vf); // CHECK: call <4 x float> @llvm.fabs.v4f32(<4 x float> %{{.*}}) + // CHECK-ASM: vflpsb vd = vec_abs(vd); // CHECK: call <2 x double> @llvm.fabs.v2f64(<2 x double> %{{.*}}) + // CHECK-ASM: vflpdb vf = vec_nabs(vf); // CHECK: [[ABS:%[^ ]+]] = tail call <4 x float> @llvm.fabs.v4f32(<4 x float> %{{.*}}) // CHECK-NEXT: fsub <4 x float> , [[ABS]] + // CHECK-ASM: vflnsb vd = vec_nabs(vd); // CHECK: [[ABS:%[^ ]+]] = tail call <2 x double> @llvm.fabs.v2f64(<2 x double> %{{.*}}) // CHECK-NEXT: fsub <2 x double> , [[ABS]] + // CHECK-ASM: vflndb vf = vec_max(vf, vf); // CHECK: call <4 x float> @llvm.s390.vfmaxsb(<4 x float> %{{.*}}, <4 x float> %{{.*}}, i32 0) + // CHECK-ASM: vfmaxsb vd = vec_max(vd, vd); // CHECK: call <2 x double> @llvm.s390.vfmaxdb(<2 x double> %{{.*}}, <2 x double> %{{.*}}, i32 0) + // CHECK-ASM: vfmaxdb vf = vec_min(vf, vf); // CHECK: call <4 x float> @llvm.s390.vfminsb(<4 x float> %{{.*}}, <4 x float> %{{.*}}, i32 0) + // CHECK-ASM: vfminsb vd = vec_min(vd, vd); // CHECK: call <2 x double> @llvm.s390.vfmindb(<2 x double> %{{.*}}, <2 x double> %{{.*}}, i32 0) + // CHECK-ASM: vfmindb vf = vec_madd(vf, vf, vf); // CHECK: call <4 x float> @llvm.fma.v4f32(<4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}) + // CHECK-ASM: vfmasb vd = vec_madd(vd, vd, vd); // CHECK: call <2 x double> @llvm.fma.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x double> %{{.*}}) + // CHECK-ASM: vfmadb vf = vec_msub(vf, vf, vf); // CHECK: [[NEG:%[^ ]+]] = fsub <4 x float> , %{{.*}} // CHECK: call <4 x float> @llvm.fma.v4f32(<4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> [[NEG]]) + // CHECK-ASM: vfmssb vd = vec_msub(vd, vd, vd); // CHECK: [[NEG:%[^ ]+]] = fsub <2 x double> , %{{.*}} // CHECK: call <2 x double> @llvm.fma.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x double> [[NEG]]) + // CHECK-ASM: vfmsdb vf = vec_nmadd(vf, vf, vf); // CHECK: [[RES:%[^ ]+]] = tail call <4 x float> @llvm.fma.v4f32(<4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}) // CHECK: fsub <4 x float> , [[RES]] + // CHECK-ASM: vfnmasb vd = vec_nmadd(vd, vd, vd); // CHECK: [[RES:%[^ ]+]] = tail call <2 x double> @llvm.fma.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x double> %{{.*}}) // CHECK: fsub <2 x double> , [[RES]] + // CHECK-ASM: vfnmadb vf = vec_nmsub(vf, vf, vf); // CHECK: [[NEG:%[^ ]+]] = fsub <4 x float> , %{{.*}} // CHECK: [[RES:%[^ ]+]] = tail call <4 x float> @llvm.fma.v4f32(<4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> [[NEG]]) // CHECK: fsub <4 x float> , [[RES]] + // CHECK-ASM: vfnmssb vd = vec_nmsub(vd, vd, vd); // CHECK: [[NEG:%[^ ]+]] = fsub <2 x double> , %{{.*}} // CHECK: [[RES:%[^ ]+]] = tail call <2 x double> @llvm.fma.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x double> [[NEG]]) // CHECK: fsub <2 x double> , [[RES]] + // CHECK-ASM: vfnmsdb vf = vec_sqrt(vf); // CHECK: call <4 x float> @llvm.sqrt.v4f32(<4 x float> %{{.*}}) + // CHECK-ASM: vfsqsb vd = vec_sqrt(vd); // CHECK: call <2 x double> @llvm.sqrt.v2f64(<2 x double> %{{.*}}) + // CHECK-ASM: vfsqdb vd = vec_doublee(vf); // CHECK: fpext <2 x float> %{{.*}} to <2 x double> + // CHECK-ASM: vldeb vf = vec_floate(vd); // CHECK: fptrunc <2 x double> %{{.*}} to <2 x float> + // CHECK-ASM: vledb vd = vec_double(vsl); // CHECK: sitofp <2 x i64> %{{.*}} to <2 x double> + // CHECK-ASM: vcdgb vd = vec_double(vul); // CHECK: uitofp <2 x i64> %{{.*}} to <2 x double> + // CHECK-ASM: vcdlgb vsl = vec_signed(vd); // CHECK: fptosi <2 x double> %{{.*}} to <2 x i64> + // CHECK-ASM: vcgdb vul = vec_unsigned(vd); // CHECK: fptoui <2 x double> %{{.*}} to <2 x i64> + // CHECK-ASM: vclgdb vf = vec_roundp(vf); // CHECK: call <4 x float> @llvm.ceil.v4f32(<4 x float> %{{.*}}) + // CHECK-ASM: vfisb %{{.*}}, %{{.*}}, 4, 6 vf = vec_ceil(vf); // CHECK: call <4 x float> @llvm.ceil.v4f32(<4 x float> %{{.*}}) + // CHECK-ASM: vfisb %{{.*}}, %{{.*}}, 4, 6 vd = vec_roundp(vd); // CHECK: call <2 x double> @llvm.ceil.v2f64(<2 x double> %{{.*}}) + // CHECK-ASM: vfidb %{{.*}}, %{{.*}}, 4, 6 vd = vec_ceil(vd); // CHECK: call <2 x double> @llvm.ceil.v2f64(<2 x double> %{{.*}}) + // CHECK-ASM: vfidb %{{.*}}, %{{.*}}, 4, 6 vf = vec_roundm(vf); // CHECK: call <4 x float> @llvm.floor.v4f32(<4 x float> %{{.*}}) + // CHECK-ASM: vfisb %{{.*}}, %{{.*}}, 4, 7 vf = vec_floor(vf); // CHECK: call <4 x float> @llvm.floor.v4f32(<4 x float> %{{.*}}) + // CHECK-ASM: vfisb %{{.*}}, %{{.*}}, 4, 7 vd = vec_roundm(vd); // CHECK: call <2 x double> @llvm.floor.v2f64(<2 x double> %{{.*}}) + // CHECK-ASM: vfidb %{{.*}}, %{{.*}}, 4, 7 vd = vec_floor(vd); // CHECK: call <2 x double> @llvm.floor.v2f64(<2 x double> %{{.*}}) + // CHECK-ASM: vfidb %{{.*}}, %{{.*}}, 4, 7 vf = vec_roundz(vf); // CHECK: call <4 x float> @llvm.trunc.v4f32(<4 x float> %{{.*}}) + // CHECK-ASM: vfisb %{{.*}}, %{{.*}}, 4, 5 vf = vec_trunc(vf); // CHECK: call <4 x float> @llvm.trunc.v4f32(<4 x float> %{{.*}}) + // CHECK-ASM: vfisb %{{.*}}, %{{.*}}, 4, 5 vd = vec_roundz(vd); // CHECK: call <2 x double> @llvm.trunc.v2f64(<2 x double> %{{.*}}) + // CHECK-ASM: vfidb %{{.*}}, %{{.*}}, 4, 5 vd = vec_trunc(vd); // CHECK: call <2 x double> @llvm.trunc.v2f64(<2 x double> %{{.*}}) + // CHECK-ASM: vfidb %{{.*}}, %{{.*}}, 4, 5 vf = vec_roundc(vf); // CHECK: call <4 x float> @llvm.nearbyint.v4f32(<4 x float> %{{.*}}) + // CHECK-ASM: vfisb %{{.*}}, %{{.*}}, 4, 0 vd = vec_roundc(vd); // CHECK: call <2 x double> @llvm.nearbyint.v2f64(<2 x double> %{{.*}}) + // CHECK-ASM: vfidb %{{.*}}, %{{.*}}, 4, 0 vf = vec_rint(vf); // CHECK: call <4 x float> @llvm.rint.v4f32(<4 x float> %{{.*}}) + // CHECK-ASM: vfisb %{{.*}}, %{{.*}}, 0, 0 vd = vec_rint(vd); // CHECK: call <2 x double> @llvm.rint.v2f64(<2 x double> %{{.*}}) + // CHECK-ASM: vfidb %{{.*}}, %{{.*}}, 0, 0 vf = vec_round(vf); // CHECK: call <4 x float> @llvm.s390.vfisb(<4 x float> %{{.*}}, i32 4, i32 4) + // CHECK-ASM: vfisb %{{.*}}, %{{.*}}, 4, 4 vd = vec_round(vd); // CHECK: call <2 x double> @llvm.s390.vfidb(<2 x double> %{{.*}}, i32 4, i32 4) + // CHECK-ASM: vfidb %{{.*}}, %{{.*}}, 4, 4 vbi = vec_fp_test_data_class(vf, 0, &cc); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vftcisb(<4 x float> %{{.*}}, i32 0) + // CHECK-ASM: vftcisb vbi = vec_fp_test_data_class(vf, 4095, &cc); // CHECK: call { <4 x i32>, i32 } @llvm.s390.vftcisb(<4 x float> %{{.*}}, i32 4095) + // CHECK-ASM: vftcisb vbl = vec_fp_test_data_class(vd, 0, &cc); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 0) + // CHECK-ASM: vftcidb vbl = vec_fp_test_data_class(vd, 4095, &cc); // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 4095) + // CHECK-ASM: vftcidb } -- cgit v1.2.3 From 6fff73b28b8de3b2b5d80d5a629c8bab4016f9a2 Mon Sep 17 00:00:00 2001 From: Michal Gorny Date: Thu, 20 Dec 2018 13:27:37 +0000 Subject: [Driver] Fix accidentally reversed condition in r349752 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349754 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Driver/ToolChains/CommonArgs.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Driver/ToolChains/CommonArgs.cpp b/lib/Driver/ToolChains/CommonArgs.cpp index be7dc47f58..dcafc5d1ab 100644 --- a/lib/Driver/ToolChains/CommonArgs.cpp +++ b/lib/Driver/ToolChains/CommonArgs.cpp @@ -603,7 +603,7 @@ void tools::linkSanitizerRuntimeDeps(const ToolChain &TC, if (TC.getTriple().getOS() != llvm::Triple::RTEMS && !TC.getTriple().isAndroid()) { CmdArgs.push_back("-lpthread"); - if (TC.getTriple().isOSOpenBSD()) + if (!TC.getTriple().isOSOpenBSD()) CmdArgs.push_back("-lrt"); } CmdArgs.push_back("-lm"); -- cgit v1.2.3 From d1463435c93645b57ad82d2d41f2e442cb12fb28 Mon Sep 17 00:00:00 2001 From: Clement Courbet Date: Thu, 20 Dec 2018 13:30:40 +0000 Subject: [Sema][NFC] Add test for static_assert diagnistics with constexpr template functions. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349755 91177308-0d34-0410-b5e6-96231b3b80d8 --- test/SemaCXX/static-assert-cxx17.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/SemaCXX/static-assert-cxx17.cpp b/test/SemaCXX/static-assert-cxx17.cpp index 7fff59e7f8..fe02f8f299 100644 --- a/test/SemaCXX/static-assert-cxx17.cpp +++ b/test/SemaCXX/static-assert-cxx17.cpp @@ -14,6 +14,11 @@ struct S2 { static inline constexpr bool var = global_inline_var; }; +template +inline constexpr bool constexpr_return_false() { + return false; +} + template void foo() { static_assert(S1::value); @@ -92,6 +97,8 @@ void foo6() { // expected-error@-1{{static_assert failed due to requirement '(X const[0]){} == nullptr'}} static_assert(sizeof(X().X::~X())>) == 0); // expected-error@-1{{static_assert failed due to requirement 'sizeof(X) == 0'}} + static_assert(constexpr_return_false()); + // expected-error@-1{{static_assert failed due to requirement 'constexpr_return_false()'}} } template void foo6(); // expected-note@-1{{in instantiation of function template specialization 'foo6' requested here}} -- cgit v1.2.3 From 458cf3382a61a632ea3e47c877ab2a8623e54c2d Mon Sep 17 00:00:00 2001 From: Aaron Ballman Date: Thu, 20 Dec 2018 17:28:32 +0000 Subject: Correct the diagnose_if attribute documentation. Fixes PR35845. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349776 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/AttrDocs.td | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/clang/Basic/AttrDocs.td b/include/clang/Basic/AttrDocs.td index 5dc9a05f4e..9017a631f7 100644 --- a/include/clang/Basic/AttrDocs.td +++ b/include/clang/Basic/AttrDocs.td @@ -554,9 +554,9 @@ certain user-defined criteria. For example: .. code-block:: c - void abs(int a) + int abs(int a) __attribute__((diagnose_if(a >= 0, "Redundant abs call", "warning"))); - void must_abs(int a) + int must_abs(int a) __attribute__((diagnose_if(a >= 0, "Redundant abs call", "error"))); int val = abs(1); // warning: Redundant abs call -- cgit v1.2.3 From 826d0ec0c057137c2cfc2b8d60526c3ac6334568 Mon Sep 17 00:00:00 2001 From: Pete Cooper Date: Thu, 20 Dec 2018 18:05:41 +0000 Subject: Use @llvm.objc.clang.arc.use intrinsic instead of clang.arc.use function. Calls to this function are deleted in the ARC optimizer. However when the ARC optimizer was updated to use intrinsics instead of functions (r349534), the corresponding clang change (r349535) to use intrinsics missed this one so it wasn't being deleted. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349782 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGObjC.cpp | 7 ++----- test/CodeGenObjC/arc-blocks.m | 6 +++--- test/CodeGenObjC/arc-foreach.m | 8 ++++---- test/CodeGenObjC/arc-literals.m | 6 +++--- test/CodeGenObjC/arc-ternary-op.m | 2 +- test/CodeGenObjC/arc.m | 6 +++--- test/CodeGenObjC/os_log.m | 4 ++-- test/CodeGenObjCXX/arc.mm | 2 +- 8 files changed, 19 insertions(+), 22 deletions(-) diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp index 3747f4920a..bfb31337b2 100644 --- a/lib/CodeGen/CGObjC.cpp +++ b/lib/CodeGen/CGObjC.cpp @@ -1862,11 +1862,8 @@ llvm::Value *CodeGenFunction::EmitObjCExtendObjectLifetime(QualType type, /// being intrinsically used up until this point in the program. void CodeGenFunction::EmitARCIntrinsicUse(ArrayRef values) { llvm::Constant *&fn = CGM.getObjCEntrypoints().clang_arc_use; - if (!fn) { - llvm::FunctionType *fnType = - llvm::FunctionType::get(CGM.VoidTy, None, true); - fn = CGM.CreateRuntimeFunction(fnType, "clang.arc.use"); - } + if (!fn) + fn = CGM.getIntrinsic(llvm::Intrinsic::objc_clang_arc_use); // This isn't really a "runtime" function, but as an intrinsic it // doesn't really matter as long as we align things up. diff --git a/test/CodeGenObjC/arc-blocks.m b/test/CodeGenObjC/arc-blocks.m index 9181d21311..49da992f95 100644 --- a/test/CodeGenObjC/arc-blocks.m +++ b/test/CodeGenObjC/arc-blocks.m @@ -96,7 +96,7 @@ void test3(void (^sink)(id*)) { // CHECK-NEXT: call void [[F1]](i8* [[BLOCK]], i8** [[TEMP]]) // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[TEMP]] // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retain(i8* [[T0]]) - // CHECK-NEXT: call void (...) @clang.arc.use(i8* [[V]]) [[NUW]] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.use(i8* [[V]]) [[NUW]] // CHECK-NEXT: [[T2:%.*]] = load i8*, i8** [[STRONG]] // CHECK-NEXT: store i8* [[T1]], i8** [[STRONG]] // CHECK-NEXT: call void @llvm.objc.release(i8* [[T2]]) @@ -303,7 +303,7 @@ void test7(void) { // CHECK-NEXT: bitcast [[BLOCK_T]]* [[BLOCK]] to // CHECK: call void @test8_helper( // CHECK-NEXT: [[T2:%.*]] = load [[TEST8]]*, [[TEST8]]** [[D0]] -// CHECK-NEXT: call void (...) @clang.arc.use([[TEST8]]* [[T2]]) +// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.use([[TEST8]]* [[T2]]) // CHECK: ret void extern void test8_helper(void (^)(void)); @@ -712,7 +712,7 @@ void test19(void (^b)(void)) { // CHECK: [[CAPTURED:%.*]] = load i8*, i8** [[XADDR]] // CHECK: store i8* [[CAPTURED]], i8** [[BLOCKCAPTURED]] // CHECK: [[CAPTURE:%.*]] = load i8*, i8** [[CAPTUREFIELD]] -// CHECK-NEXT: call void (...) @clang.arc.use(i8* [[CAPTURE]]) +// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.use(i8* [[CAPTURE]]) // CHECK-NEXT: [[X:%.*]] = load i8*, i8** [[XADDR]] // CHECK-NEXT: call void @llvm.objc.release(i8* [[X]]) // CHECK-NEXT: ret void diff --git a/test/CodeGenObjC/arc-foreach.m b/test/CodeGenObjC/arc-foreach.m index 65d517cc93..c8c7120bae 100644 --- a/test/CodeGenObjC/arc-foreach.m +++ b/test/CodeGenObjC/arc-foreach.m @@ -73,11 +73,11 @@ void test0(NSArray *array) { // CHECK-LP64-NEXT: [[BLOCK1:%.*]] = bitcast [[BLOCK_T]]* [[BLOCK]] // CHECK-LP64-NEXT: call void @use_block(void ()* [[BLOCK1]]) // CHECK-LP64-NEXT: call void @llvm.objc.storeStrong(i8** [[D0]], i8* null) -// CHECK-LP64-NOT: call void (...) @clang.arc.use(i8* [[CAPTURE]]) +// CHECK-LP64-NOT: call void (...) @llvm.objc.clang.arc.use(i8* [[CAPTURE]]) // CHECK-LP64-OPT: [[D0:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[BLOCK]], i64 0, i32 5 // CHECK-LP64-OPT: [[CAPTURE:%.*]] = load i8*, i8** [[D0]] -// CHECK-LP64-OPT: call void (...) @clang.arc.use(i8* [[CAPTURE]]) +// CHECK-LP64-OPT: call void (...) @llvm.objc.clang.arc.use(i8* [[CAPTURE]]) // CHECK-LP64: [[T0:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_ // CHECK-LP64-NEXT: [[T1:%.*]] = bitcast [[ARRAY_T]]* [[SAVED_ARRAY]] to i8* @@ -220,14 +220,14 @@ NSArray *array4; // CHECK-LP64: [[T5:%.*]] = bitcast [[TY]]** [[T0]] to i8** // CHECK-LP64: call void @llvm.objc.storeStrong(i8** [[T5]], i8* null) -// CHECK-LP64-NOT: call void (...) @clang.arc.use([[TY]]* [[T5]]) +// CHECK-LP64-NOT: call void (...) @llvm.objc.clang.arc.use([[TY]]* [[T5]]) // CHECK-LP64: switch i32 {{%.*}}, label %[[UNREACHABLE:.*]] [ // CHECK-LP64-NEXT: i32 0, label %[[CLEANUP_CONT:.*]] // CHECK-LP64-NEXT: i32 2, label %[[FORCOLL_END:.*]] // CHECK-LP64-NEXT: ] // CHECK-LP64-OPT: [[T5:%.*]] = load [[TY]]*, [[TY]]** [[T0]] -// CHECK-LP64-OPT: call void (...) @clang.arc.use([[TY]]* [[T5]]) +// CHECK-LP64-OPT: call void (...) @llvm.objc.clang.arc.use([[TY]]* [[T5]]) // CHECK-LP64: {{^|:}}[[CLEANUP_CONT]] // CHECK-LP64-NEXT: br label %[[FORCOLL_END]] diff --git a/test/CodeGenObjC/arc-literals.m b/test/CodeGenObjC/arc-literals.m index 3953787ea5..a9cb769138 100644 --- a/test/CodeGenObjC/arc-literals.m +++ b/test/CodeGenObjC/arc-literals.m @@ -60,7 +60,7 @@ void test_array(id a, id b) { // CHECK-NEXT: [[T2:%.*]] = bitcast [2 x i8*]* [[OBJECTS]] to i8** // CHECK-NEXT: [[T3:%.*]] = call i8* bitcast ({{.*@objc_msgSend.*}})(i8* [[T1]], i8* [[SEL]], i8** [[T2]], i64 2) // CHECK-NEXT: [[T4:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T3]]) - // CHECK: call void (...) @clang.arc.use(i8* [[V0]], i8* [[V1]]) + // CHECK: call void (...) @llvm.objc.clang.arc.use(i8* [[V0]], i8* [[V1]]) id arr = @[a, b]; // CHECK: call void @llvm.objc.release @@ -104,7 +104,7 @@ void test_dictionary(id k1, id o1, id k2, id o2) { // CHECK-NEXT: [[T3:%.*]] = bitcast [2 x i8*]* [[KEYS]] to i8** // CHECK-NEXT: [[T4:%.*]] = call i8* bitcast ({{.*@objc_msgSend.*}})(i8* [[T1]], i8* [[SEL]], i8** [[T2]], i8** [[T3]], i64 2) // CHECK-NEXT: [[T5:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T4]]) - // CHECK-NEXT: call void (...) @clang.arc.use(i8* [[V0]], i8* [[V1]], i8* [[V2]], i8* [[V3]]) + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.use(i8* [[V0]], i8* [[V1]], i8* [[V2]], i8* [[V3]]) id dict = @{ k1 : o1, k2 : o2 }; @@ -149,7 +149,7 @@ void test_property(B *b) { // CHECK-NEXT: [[T2:%.*]] = bitcast [1 x i8*]* [[OBJECTS]] to i8** // CHECK-NEXT: [[T3:%.*]] = call i8* bitcast ({{.*}} @objc_msgSend to {{.*}}(i8* [[T1]], i8* [[SEL]], i8** [[T2]], i64 1) // CHECK-NEXT: call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T3]]) - // CHECK-NEXT: call void (...) @clang.arc.use(i8* [[V1]]) + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.use(i8* [[V1]]) // CHECK-NEXT: bitcast // CHECK-NEXT: bitcast // CHECK-NEXT: store diff --git a/test/CodeGenObjC/arc-ternary-op.m b/test/CodeGenObjC/arc-ternary-op.m index 91ba6c4505..2be0462846 100644 --- a/test/CodeGenObjC/arc-ternary-op.m +++ b/test/CodeGenObjC/arc-ternary-op.m @@ -75,7 +75,7 @@ void test1(int cond) { // CHECK-NEXT: br i1 [[T0]], // CHECK: [[T0:%.*]] = load i8*, i8** [[TEMP1]] // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retain(i8* [[T0]]) - // CHECK-NEXT: call void (...) @clang.arc.use(i8* [[W]]) [[NUW]] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.use(i8* [[W]]) [[NUW]] // CHECK-NEXT: [[T2:%.*]] = load i8*, i8** [[ARG]] // CHECK-NEXT: store i8* [[T1]], i8** [[ARG]] // CHECK-NEXT: call void @llvm.objc.release(i8* [[T2]]) diff --git a/test/CodeGenObjC/arc.m b/test/CodeGenObjC/arc.m index fec6da56bd..cbdb03205a 100644 --- a/test/CodeGenObjC/arc.m +++ b/test/CodeGenObjC/arc.m @@ -922,7 +922,7 @@ void test33(Test33 *ptr) { // CHECK-NEXT: [[T1:%.*]] = bitcast [[A_T]]* [[T0]] to i8* // CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retain(i8* [[T1]]) // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[A_T]]* - // CHECK-NEXT: call void (...) @clang.arc.use([[A_T]]* [[W0]]) [[NUW]] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.use([[A_T]]* [[W0]]) [[NUW]] // CHECK-NEXT: [[T4:%.*]] = load [[A_T]]*, [[A_T]]** [[A]] // CHECK-NEXT: store [[A_T]]* [[T3]], [[A_T]]** [[A]] // CHECK-NEXT: [[T5:%.*]] = bitcast [[A_T]]* [[T4]] to i8* @@ -938,7 +938,7 @@ void test33(Test33 *ptr) { // CHECK-NEXT: [[T1:%.*]] = bitcast [[A_T]]* [[T0]] to i8* // CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retain(i8* [[T1]]) // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[A_T]]* - // CHECK-NEXT: call void (...) @clang.arc.use([[A_T]]* [[W0]]) [[NUW]] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.use([[A_T]]* [[W0]]) [[NUW]] // CHECK-NEXT: [[T4:%.*]] = load [[A_T]]*, [[A_T]]** [[A]] // CHECK-NEXT: store [[A_T]]* [[T3]], [[A_T]]** [[A]] // CHECK-NEXT: [[T5:%.*]] = bitcast [[A_T]]* [[T4]] to i8* @@ -1025,7 +1025,7 @@ void test37(void) { // CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST37]]* [[T1]] to i8* // CHECK-NEXT: [[T3:%.*]] = call i8* @llvm.objc.retain(i8* [[T2]]) // CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to [[TEST37]]* - // CHECK-NEXT: call void (...) @clang.arc.use(i8* [[W1]]) [[NUW]] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.use(i8* [[W1]]) [[NUW]] // CHECK-NEXT: [[T5:%.*]] = load [[TEST37]]*, [[TEST37]]** [[VAR]] // CHECK-NEXT: store [[TEST37]]* [[T4]], [[TEST37]]** [[VAR]] // CHECK-NEXT: [[T6:%.*]] = bitcast [[TEST37]]* [[T5]] to i8* diff --git a/test/CodeGenObjC/os_log.m b/test/CodeGenObjC/os_log.m index 34b62c7c33..6acd58304a 100644 --- a/test/CodeGenObjC/os_log.m +++ b/test/CodeGenObjC/os_log.m @@ -33,7 +33,7 @@ void *test_builtin_os_log(void *buf) { // CHECK: %[[ARGDATA_I:.*]] = getelementptr i8, i8* %[[BUF]], i64 4 // CHECK: %[[ARGDATACAST_I:.*]] = bitcast i8* %[[ARGDATA_I]] to i64* // CHECK: store i64 %[[V2]], i64* %[[ARGDATACAST_I]], align 1 - // CHECK: tail call void (...) @clang.arc.use(%[[TY0]]* %[[CALL]]) + // CHECK: tail call void (...) @llvm.objc.clang.arc.use(%[[TY0]]* %[[CALL]]) // CHECK: tail call void @llvm.objc.release(i8* %[[V0]]) // CHECK: ret i8* %[[BUF]] @@ -50,7 +50,7 @@ void *test_builtin_os_log(void *buf) { // CHECK-O0: %[[V4:.*]] = ptrtoint %[[TY0]]* %[[V3]] to i64 // CHECK-O0: call void @__os_log_helper_1_2_1_8_64(i8* %[[V0]], i64 %[[V4]]) // CHECK-O0: %[[V5:.*]] = bitcast %[[TY0]]* %[[V3]] to i8* - // CHECK-O0-NOT call void (...) @clang.arc.use({{.*}} + // CHECK-O0-NOT call void (...) @llvm.objc.clang.arc.use({{.*}} // CHECK-O0: call void @llvm.objc.release(i8* %[[V5]]) // CHECK-O0: ret i8* %[[V0]] } diff --git a/test/CodeGenObjCXX/arc.mm b/test/CodeGenObjCXX/arc.mm index b7f099d4e8..e32c1f8921 100644 --- a/test/CodeGenObjCXX/arc.mm +++ b/test/CodeGenObjCXX/arc.mm @@ -86,7 +86,7 @@ void test34(int cond) { // CHECK-NEXT: br i1 [[T0]], // CHECK: [[T0:%.*]] = load i8*, i8** [[TEMP1]] // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retain(i8* [[T0]]) - // CHECK-NEXT: call void (...) @clang.arc.use(i8* [[W0]]) + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.use(i8* [[W0]]) // CHECK-NEXT: [[T2:%.*]] = load i8*, i8** [[ARG]] // CHECK-NEXT: store i8* [[T1]], i8** [[ARG]] // CHECK-NEXT: call void @llvm.objc.release(i8* [[T2]]) -- cgit v1.2.3 From b27c4ef981e042f2003c16c2f2d7700a6a4a6c00 Mon Sep 17 00:00:00 2001 From: Simon Pilgrim Date: Thu, 20 Dec 2018 19:01:13 +0000 Subject: [X86] Auto upgrade XOP/AVX512 rotation intrinsics to generic funnel shift intrinsics (clang) This emits FSHL/FSHR generic intrinsics for the XOP VPROT and AVX512 VPROL/VPROR rotation intrinsics. LLVM counterpart: https://reviews.llvm.org/D55938 Differential Revision: https://reviews.llvm.org/D55937 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349796 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGBuiltin.cpp | 54 +++++++++++++++++++++- test/CodeGen/avx512f-builtins.c | 48 ++++++++++---------- test/CodeGen/avx512vl-builtins.c | 96 ++++++++++++++++++++-------------------- test/CodeGen/xop-builtins.c | 16 +++---- 4 files changed, 133 insertions(+), 81 deletions(-) diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp index d38e6b0262..8f53a83abe 100644 --- a/lib/CodeGen/CGBuiltin.cpp +++ b/lib/CodeGen/CGBuiltin.cpp @@ -9168,6 +9168,24 @@ static Value *EmitX86MaskLogic(CodeGenFunction &CGF, Instruction::BinaryOps Opc, Ops[0]->getType()); } +static Value *EmitX86FunnelShift(CodeGenFunction &CGF, Value *Op0, Value *Op1, + Value *Amt, bool IsRight) { + llvm::Type *Ty = Op0->getType(); + + // Amount may be scalar immediate, in which case create a splat vector. + // Funnel shifts amounts are treated as modulo and types are all power-of-2 so + // we only care about the lowest log2 bits anyway. + if (Amt->getType() != Ty) { + unsigned NumElts = Ty->getVectorNumElements(); + Amt = CGF.Builder.CreateIntCast(Amt, Ty->getScalarType(), false); + Amt = CGF.Builder.CreateVectorSplat(NumElts, Amt); + } + + unsigned IID = IsRight ? Intrinsic::fshr : Intrinsic::fshl; + Value *F = CGF.CGM.getIntrinsic(IID, Ty); + return CGF.Builder.CreateCall(F, {Op0, Op1, Amt}); +} + static Value *EmitX86Select(CodeGenFunction &CGF, Value *Mask, Value *Op0, Value *Op1) { @@ -10575,7 +10593,41 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID, SI->setAlignment(1); return SI; } - + // Rotate is a special case of funnel shift - 1st 2 args are the same. + case X86::BI__builtin_ia32_vprotb: + case X86::BI__builtin_ia32_vprotw: + case X86::BI__builtin_ia32_vprotd: + case X86::BI__builtin_ia32_vprotq: + case X86::BI__builtin_ia32_vprotbi: + case X86::BI__builtin_ia32_vprotwi: + case X86::BI__builtin_ia32_vprotdi: + case X86::BI__builtin_ia32_vprotqi: + case X86::BI__builtin_ia32_prold128: + case X86::BI__builtin_ia32_prold256: + case X86::BI__builtin_ia32_prold512: + case X86::BI__builtin_ia32_prolq128: + case X86::BI__builtin_ia32_prolq256: + case X86::BI__builtin_ia32_prolq512: + case X86::BI__builtin_ia32_prolvd128: + case X86::BI__builtin_ia32_prolvd256: + case X86::BI__builtin_ia32_prolvd512: + case X86::BI__builtin_ia32_prolvq128: + case X86::BI__builtin_ia32_prolvq256: + case X86::BI__builtin_ia32_prolvq512: + return EmitX86FunnelShift(*this, Ops[0], Ops[0], Ops[1], false); + case X86::BI__builtin_ia32_prord128: + case X86::BI__builtin_ia32_prord256: + case X86::BI__builtin_ia32_prord512: + case X86::BI__builtin_ia32_prorq128: + case X86::BI__builtin_ia32_prorq256: + case X86::BI__builtin_ia32_prorq512: + case X86::BI__builtin_ia32_prorvd128: + case X86::BI__builtin_ia32_prorvd256: + case X86::BI__builtin_ia32_prorvd512: + case X86::BI__builtin_ia32_prorvq128: + case X86::BI__builtin_ia32_prorvq256: + case X86::BI__builtin_ia32_prorvq512: + return EmitX86FunnelShift(*this, Ops[0], Ops[0], Ops[1], true); case X86::BI__builtin_ia32_selectb_128: case X86::BI__builtin_ia32_selectb_256: case X86::BI__builtin_ia32_selectb_512: diff --git a/test/CodeGen/avx512f-builtins.c b/test/CodeGen/avx512f-builtins.c index b8efbddd62..0f21bae6ab 100644 --- a/test/CodeGen/avx512f-builtins.c +++ b/test/CodeGen/avx512f-builtins.c @@ -4036,120 +4036,120 @@ __m512i test_mm512_maskz_cvtepu16_epi64(__mmask8 __U, __m128i __A) { __m512i test_mm512_rol_epi32(__m512i __A) { // CHECK-LABEL: @test_mm512_rol_epi32 - // CHECK: @llvm.x86.avx512.prol.d.512 + // CHECK: @llvm.fshl.v16i32 return _mm512_rol_epi32(__A, 5); } __m512i test_mm512_mask_rol_epi32(__m512i __W, __mmask16 __U, __m512i __A) { // CHECK-LABEL: @test_mm512_mask_rol_epi32 - // CHECK: @llvm.x86.avx512.prol.d.512 + // CHECK: @llvm.fshl.v16i32 // CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}} return _mm512_mask_rol_epi32(__W, __U, __A, 5); } __m512i test_mm512_maskz_rol_epi32(__mmask16 __U, __m512i __A) { // CHECK-LABEL: @test_mm512_maskz_rol_epi32 - // CHECK: @llvm.x86.avx512.prol.d.512 + // CHECK: @llvm.fshl.v16i32 // CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}} return _mm512_maskz_rol_epi32(__U, __A, 5); } __m512i test_mm512_rol_epi64(__m512i __A) { // CHECK-LABEL: @test_mm512_rol_epi64 - // CHECK: @llvm.x86.avx512.prol.q.512 + // CHECK: @llvm.fshl.v8i64 return _mm512_rol_epi64(__A, 5); } __m512i test_mm512_mask_rol_epi64(__m512i __W, __mmask8 __U, __m512i __A) { // CHECK-LABEL: @test_mm512_mask_rol_epi64 - // CHECK: @llvm.x86.avx512.prol.q.512 + // CHECK: @llvm.fshl.v8i64 // CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}} return _mm512_mask_rol_epi64(__W, __U, __A, 5); } __m512i test_mm512_maskz_rol_epi64(__mmask8 __U, __m512i __A) { // CHECK-LABEL: @test_mm512_maskz_rol_epi64 - // CHECK: @llvm.x86.avx512.prol.q.512 + // CHECK: @llvm.fshl.v8i64 // CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}} return _mm512_maskz_rol_epi64(__U, __A, 5); } __m512i test_mm512_rolv_epi32(__m512i __A, __m512i __B) { // CHECK-LABEL: @test_mm512_rolv_epi32 - // CHECK: @llvm.x86.avx512.prolv.d.512 + // CHECK: @llvm.fshl.v16i32 return _mm512_rolv_epi32(__A, __B); } __m512i test_mm512_mask_rolv_epi32(__m512i __W, __mmask16 __U, __m512i __A, __m512i __B) { // CHECK-LABEL: @test_mm512_mask_rolv_epi32 - // CHECK: @llvm.x86.avx512.prolv.d.512 + // CHECK: @llvm.fshl.v16i32 // CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}} return _mm512_mask_rolv_epi32(__W, __U, __A, __B); } __m512i test_mm512_maskz_rolv_epi32(__mmask16 __U, __m512i __A, __m512i __B) { // CHECK-LABEL: @test_mm512_maskz_rolv_epi32 - // CHECK: @llvm.x86.avx512.prolv.d.512 + // CHECK: @llvm.fshl.v16i32 // CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}} return _mm512_maskz_rolv_epi32(__U, __A, __B); } __m512i test_mm512_rolv_epi64(__m512i __A, __m512i __B) { // CHECK-LABEL: @test_mm512_rolv_epi64 - // CHECK: @llvm.x86.avx512.prolv.q.512 + // CHECK: @llvm.fshl.v8i64 return _mm512_rolv_epi64(__A, __B); } __m512i test_mm512_mask_rolv_epi64(__m512i __W, __mmask8 __U, __m512i __A, __m512i __B) { // CHECK-LABEL: @test_mm512_mask_rolv_epi64 - // CHECK: @llvm.x86.avx512.prolv.q.512 + // CHECK: @llvm.fshl.v8i64 // CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}} return _mm512_mask_rolv_epi64(__W, __U, __A, __B); } __m512i test_mm512_maskz_rolv_epi64(__mmask8 __U, __m512i __A, __m512i __B) { // CHECK-LABEL: @test_mm512_maskz_rolv_epi64 - // CHECK: @llvm.x86.avx512.prolv.q.512 + // CHECK: @llvm.fshl.v8i64 // CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}} return _mm512_maskz_rolv_epi64(__U, __A, __B); } __m512i test_mm512_ror_epi32(__m512i __A) { // CHECK-LABEL: @test_mm512_ror_epi32 - // CHECK: @llvm.x86.avx512.pror.d.512 + // CHECK: @llvm.fshr.v16i32 return _mm512_ror_epi32(__A, 5); } __m512i test_mm512_mask_ror_epi32(__m512i __W, __mmask16 __U, __m512i __A) { // CHECK-LABEL: @test_mm512_mask_ror_epi32 - // CHECK: @llvm.x86.avx512.pror.d.512 + // CHECK: @llvm.fshr.v16i32 // CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}} return _mm512_mask_ror_epi32(__W, __U, __A, 5); } __m512i test_mm512_maskz_ror_epi32(__mmask16 __U, __m512i __A) { // CHECK-LABEL: @test_mm512_maskz_ror_epi32 - // CHECK: @llvm.x86.avx512.pror.d.512 + // CHECK: @llvm.fshr.v16i32 // CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}} return _mm512_maskz_ror_epi32(__U, __A, 5); } __m512i test_mm512_ror_epi64(__m512i __A) { // CHECK-LABEL: @test_mm512_ror_epi64 - // CHECK: @llvm.x86.avx512.pror.q.512 + // CHECK: @llvm.fshr.v8i64 return _mm512_ror_epi64(__A, 5); } __m512i test_mm512_mask_ror_epi64(__m512i __W, __mmask8 __U, __m512i __A) { // CHECK-LABEL: @test_mm512_mask_ror_epi64 - // CHECK: @llvm.x86.avx512.pror.q.512 + // CHECK: @llvm.fshr.v8i64 // CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}} return _mm512_mask_ror_epi64(__W, __U, __A, 5); } __m512i test_mm512_maskz_ror_epi64(__mmask8 __U, __m512i __A) { // CHECK-LABEL: @test_mm512_maskz_ror_epi64 - // CHECK: @llvm.x86.avx512.pror.q.512 + // CHECK: @llvm.fshr.v8i64 // CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}} return _mm512_maskz_ror_epi64(__U, __A, 5); } @@ -4157,40 +4157,40 @@ __m512i test_mm512_maskz_ror_epi64(__mmask8 __U, __m512i __A) { __m512i test_mm512_rorv_epi32(__m512i __A, __m512i __B) { // CHECK-LABEL: @test_mm512_rorv_epi32 - // CHECK: @llvm.x86.avx512.prorv.d.512 + // CHECK: @llvm.fshr.v16i32 return _mm512_rorv_epi32(__A, __B); } __m512i test_mm512_mask_rorv_epi32(__m512i __W, __mmask16 __U, __m512i __A, __m512i __B) { // CHECK-LABEL: @test_mm512_mask_rorv_epi32 - // CHECK: @llvm.x86.avx512.prorv.d.512 + // CHECK: @llvm.fshr.v16i32 // CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}} return _mm512_mask_rorv_epi32(__W, __U, __A, __B); } __m512i test_mm512_maskz_rorv_epi32(__mmask16 __U, __m512i __A, __m512i __B) { // CHECK-LABEL: @test_mm512_maskz_rorv_epi32 - // CHECK: @llvm.x86.avx512.prorv.d.512 + // CHECK: @llvm.fshr.v16i32 // CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}} return _mm512_maskz_rorv_epi32(__U, __A, __B); } __m512i test_mm512_rorv_epi64(__m512i __A, __m512i __B) { // CHECK-LABEL: @test_mm512_rorv_epi64 - // CHECK: @llvm.x86.avx512.prorv.q.512 + // CHECK: @llvm.fshr.v8i64 return _mm512_rorv_epi64(__A, __B); } __m512i test_mm512_mask_rorv_epi64(__m512i __W, __mmask8 __U, __m512i __A, __m512i __B) { // CHECK-LABEL: @test_mm512_mask_rorv_epi64 - // CHECK: @llvm.x86.avx512.prorv.q.512 + // CHECK: @llvm.fshr.v8i64 // CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}} return _mm512_mask_rorv_epi64(__W, __U, __A, __B); } __m512i test_mm512_maskz_rorv_epi64(__mmask8 __U, __m512i __A, __m512i __B) { // CHECK-LABEL: @test_mm512_maskz_rorv_epi64 - // CHECK: @llvm.x86.avx512.prorv.q.512 + // CHECK: @llvm.fshr.v8i64 // CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}} return _mm512_maskz_rorv_epi64(__U, __A, __B); } diff --git a/test/CodeGen/avx512vl-builtins.c b/test/CodeGen/avx512vl-builtins.c index 57931ca437..eb69e1c0f1 100644 --- a/test/CodeGen/avx512vl-builtins.c +++ b/test/CodeGen/avx512vl-builtins.c @@ -5779,240 +5779,240 @@ __m256i test_mm256_maskz_cvtepu16_epi64(__mmask8 __U, __m128i __A) { __m128i test_mm_rol_epi32(__m128i __A) { // CHECK-LABEL: @test_mm_rol_epi32 - // CHECK: @llvm.x86.avx512.prol.d.128 + // CHECK: @llvm.fshl.v4i32 return _mm_rol_epi32(__A, 5); } __m128i test_mm_mask_rol_epi32(__m128i __W, __mmask8 __U, __m128i __A) { // CHECK-LABEL: @test_mm_mask_rol_epi32 - // CHECK: @llvm.x86.avx512.prol.d.128 + // CHECK: @llvm.fshl.v4i32 // CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}} return _mm_mask_rol_epi32(__W, __U, __A, 5); } __m128i test_mm_maskz_rol_epi32(__mmask8 __U, __m128i __A) { // CHECK-LABEL: @test_mm_maskz_rol_epi32 - // CHECK: @llvm.x86.avx512.prol.d.128 + // CHECK: @llvm.fshl.v4i32 // CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}} return _mm_maskz_rol_epi32(__U, __A, 5); } __m256i test_mm256_rol_epi32(__m256i __A) { // CHECK-LABEL: @test_mm256_rol_epi32 - // CHECK: @llvm.x86.avx512.prol.d.256 + // CHECK: @llvm.fshl.v8i32 return _mm256_rol_epi32(__A, 5); } __m256i test_mm256_mask_rol_epi32(__m256i __W, __mmask8 __U, __m256i __A) { // CHECK-LABEL: @test_mm256_mask_rol_epi32 - // CHECK: @llvm.x86.avx512.prol.d.256 + // CHECK: @llvm.fshl.v8i32 // CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}} return _mm256_mask_rol_epi32(__W, __U, __A, 5); } __m256i test_mm256_maskz_rol_epi32(__mmask8 __U, __m256i __A) { // CHECK-LABEL: @test_mm256_maskz_rol_epi32 - // CHECK: @llvm.x86.avx512.prol.d.256 + // CHECK: @llvm.fshl.v8i32 // CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}} return _mm256_maskz_rol_epi32(__U, __A, 5); } __m128i test_mm_rol_epi64(__m128i __A) { // CHECK-LABEL: @test_mm_rol_epi64 - // CHECK: @llvm.x86.avx512.prol.q.128 + // CHECK: @llvm.fshl.v2i64 return _mm_rol_epi64(__A, 5); } __m128i test_mm_mask_rol_epi64(__m128i __W, __mmask8 __U, __m128i __A) { // CHECK-LABEL: @test_mm_mask_rol_epi64 - // CHECK: @llvm.x86.avx512.prol.q.128 + // CHECK: @llvm.fshl.v2i64 // CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}} return _mm_mask_rol_epi64(__W, __U, __A, 5); } __m128i test_mm_maskz_rol_epi64(__mmask8 __U, __m128i __A) { // CHECK-LABEL: @test_mm_maskz_rol_epi64 - // CHECK: @llvm.x86.avx512.prol.q.128 + // CHECK: @llvm.fshl.v2i64 // CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}} return _mm_maskz_rol_epi64(__U, __A, 5); } __m256i test_mm256_rol_epi64(__m256i __A) { // CHECK-LABEL: @test_mm256_rol_epi64 - // CHECK: @llvm.x86.avx512.prol.q.256 + // CHECK: @llvm.fshl.v4i64 return _mm256_rol_epi64(__A, 5); } __m256i test_mm256_mask_rol_epi64(__m256i __W, __mmask8 __U, __m256i __A) { // CHECK-LABEL: @test_mm256_mask_rol_epi64 - // CHECK: @llvm.x86.avx512.prol.q.256 + // CHECK: @llvm.fshl.v4i64 // CHECK: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}} return _mm256_mask_rol_epi64(__W, __U, __A, 5); } __m256i test_mm256_maskz_rol_epi64(__mmask8 __U, __m256i __A) { // CHECK-LABEL: @test_mm256_maskz_rol_epi64 - // CHECK: @llvm.x86.avx512.prol.q.256 + // CHECK: @llvm.fshl.v4i64 // CHECK: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}} return _mm256_maskz_rol_epi64(__U, __A, 5); } __m128i test_mm_rolv_epi32(__m128i __A, __m128i __B) { // CHECK-LABEL: @test_mm_rolv_epi32 - // CHECK: @llvm.x86.avx512.prolv.d.128 + // CHECK: llvm.fshl.v4i32 return _mm_rolv_epi32(__A, __B); } __m128i test_mm_mask_rolv_epi32(__m128i __W, __mmask8 __U, __m128i __A, __m128i __B) { // CHECK-LABEL: @test_mm_mask_rolv_epi32 - // CHECK: @llvm.x86.avx512.prolv.d.128 + // CHECK: llvm.fshl.v4i32 // CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}} return _mm_mask_rolv_epi32(__W, __U, __A, __B); } __m128i test_mm_maskz_rolv_epi32(__mmask8 __U, __m128i __A, __m128i __B) { // CHECK-LABEL: @test_mm_maskz_rolv_epi32 - // CHECK: @llvm.x86.avx512.prolv.d.128 + // CHECK: llvm.fshl.v4i32 // CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}} return _mm_maskz_rolv_epi32(__U, __A, __B); } __m256i test_mm256_rolv_epi32(__m256i __A, __m256i __B) { // CHECK-LABEL: @test_mm256_rolv_epi32 - // CHECK: @llvm.x86.avx512.prolv.d.256 + // CHECK: @llvm.fshl.v8i32 return _mm256_rolv_epi32(__A, __B); } __m256i test_mm256_mask_rolv_epi32(__m256i __W, __mmask8 __U, __m256i __A, __m256i __B) { // CHECK-LABEL: @test_mm256_mask_rolv_epi32 - // CHECK: @llvm.x86.avx512.prolv.d.256 + // CHECK: @llvm.fshl.v8i32 // CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}} return _mm256_mask_rolv_epi32(__W, __U, __A, __B); } __m256i test_mm256_maskz_rolv_epi32(__mmask8 __U, __m256i __A, __m256i __B) { // CHECK-LABEL: @test_mm256_maskz_rolv_epi32 - // CHECK: @llvm.x86.avx512.prolv.d.256 + // CHECK: @llvm.fshl.v8i32 // CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}} return _mm256_maskz_rolv_epi32(__U, __A, __B); } __m128i test_mm_rolv_epi64(__m128i __A, __m128i __B) { // CHECK-LABEL: @test_mm_rolv_epi64 - // CHECK: @llvm.x86.avx512.prolv.q.128 + // CHECK: @llvm.fshl.v2i64 return _mm_rolv_epi64(__A, __B); } __m128i test_mm_mask_rolv_epi64(__m128i __W, __mmask8 __U, __m128i __A, __m128i __B) { // CHECK-LABEL: @test_mm_mask_rolv_epi64 - // CHECK: @llvm.x86.avx512.prolv.q.128 + // CHECK: @llvm.fshl.v2i64 // CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}} return _mm_mask_rolv_epi64(__W, __U, __A, __B); } __m128i test_mm_maskz_rolv_epi64(__mmask8 __U, __m128i __A, __m128i __B) { // CHECK-LABEL: @test_mm_maskz_rolv_epi64 - // CHECK: @llvm.x86.avx512.prolv.q.128 + // CHECK: @llvm.fshl.v2i64 // CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}} return _mm_maskz_rolv_epi64(__U, __A, __B); } __m256i test_mm256_rolv_epi64(__m256i __A, __m256i __B) { // CHECK-LABEL: @test_mm256_rolv_epi64 - // CHECK: @llvm.x86.avx512.prolv.q.256 + // CHECK: @llvm.fshl.v4i64 return _mm256_rolv_epi64(__A, __B); } __m256i test_mm256_mask_rolv_epi64(__m256i __W, __mmask8 __U, __m256i __A, __m256i __B) { // CHECK-LABEL: @test_mm256_mask_rolv_epi64 - // CHECK: @llvm.x86.avx512.prolv.q.256 + // CHECK: @llvm.fshl.v4i64 // CHECK: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}} return _mm256_mask_rolv_epi64(__W, __U, __A, __B); } __m256i test_mm256_maskz_rolv_epi64(__mmask8 __U, __m256i __A, __m256i __B) { // CHECK-LABEL: @test_mm256_maskz_rolv_epi64 - // CHECK: @llvm.x86.avx512.prolv.q.256 + // CHECK: @llvm.fshl.v4i64 // CHECK: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}} return _mm256_maskz_rolv_epi64(__U, __A, __B); } __m128i test_mm_ror_epi32(__m128i __A) { // CHECK-LABEL: @test_mm_ror_epi32 - // CHECK: @llvm.x86.avx512.pror.d.128 + // CHECK: @llvm.fshr.v4i32 return _mm_ror_epi32(__A, 5); } __m128i test_mm_mask_ror_epi32(__m128i __W, __mmask8 __U, __m128i __A) { // CHECK-LABEL: @test_mm_mask_ror_epi32 - // CHECK: @llvm.x86.avx512.pror.d.128 + // CHECK: @llvm.fshr.v4i32 // CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}} return _mm_mask_ror_epi32(__W, __U, __A, 5); } __m128i test_mm_maskz_ror_epi32(__mmask8 __U, __m128i __A) { // CHECK-LABEL: @test_mm_maskz_ror_epi32 - // CHECK: @llvm.x86.avx512.pror.d.128 + // CHECK: @llvm.fshr.v4i32 // CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}} return _mm_maskz_ror_epi32(__U, __A, 5); } __m256i test_mm256_ror_epi32(__m256i __A) { // CHECK-LABEL: @test_mm256_ror_epi32 - // CHECK: @llvm.x86.avx512.pror.d.256 + // CHECK: @llvm.fshr.v8i32 return _mm256_ror_epi32(__A, 5); } __m256i test_mm256_mask_ror_epi32(__m256i __W, __mmask8 __U, __m256i __A) { // CHECK-LABEL: @test_mm256_mask_ror_epi32 - // CHECK: @llvm.x86.avx512.pror.d.256 + // CHECK: @llvm.fshr.v8i32 // CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}} return _mm256_mask_ror_epi32(__W, __U, __A, 5); } __m256i test_mm256_maskz_ror_epi32(__mmask8 __U, __m256i __A) { // CHECK-LABEL: @test_mm256_maskz_ror_epi32 - // CHECK: @llvm.x86.avx512.pror.d.256 + // CHECK: @llvm.fshr.v8i32 // CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}} return _mm256_maskz_ror_epi32(__U, __A, 5); } __m128i test_mm_ror_epi64(__m128i __A) { // CHECK-LABEL: @test_mm_ror_epi64 - // CHECK: @llvm.x86.avx512.pror.q.128 + // CHECK: @llvm.fshr.v2i64 return _mm_ror_epi64(__A, 5); } __m128i test_mm_mask_ror_epi64(__m128i __W, __mmask8 __U, __m128i __A) { // CHECK-LABEL: @test_mm_mask_ror_epi64 - // CHECK: @llvm.x86.avx512.pror.q.128 + // CHECK: @llvm.fshr.v2i64 // CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}} return _mm_mask_ror_epi64(__W, __U, __A, 5); } __m128i test_mm_maskz_ror_epi64(__mmask8 __U, __m128i __A) { // CHECK-LABEL: @test_mm_maskz_ror_epi64 - // CHECK: @llvm.x86.avx512.pror.q.128 + // CHECK: @llvm.fshr.v2i64 // CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}} return _mm_maskz_ror_epi64(__U, __A, 5); } __m256i test_mm256_ror_epi64(__m256i __A) { // CHECK-LABEL: @test_mm256_ror_epi64 - // CHECK: @llvm.x86.avx512.pror.q.256 + // CHECK: @llvm.fshr.v4i64 return _mm256_ror_epi64(__A, 5); } __m256i test_mm256_mask_ror_epi64(__m256i __W, __mmask8 __U, __m256i __A) { // CHECK-LABEL: @test_mm256_mask_ror_epi64 - // CHECK: @llvm.x86.avx512.pror.q.256 + // CHECK: @llvm.fshr.v4i64 // CHECK: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}} return _mm256_mask_ror_epi64(__W, __U, __A,5); } __m256i test_mm256_maskz_ror_epi64(__mmask8 __U, __m256i __A) { // CHECK-LABEL: @test_mm256_maskz_ror_epi64 - // CHECK: @llvm.x86.avx512.pror.q.256 + // CHECK: @llvm.fshr.v4i64 // CHECK: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}} return _mm256_maskz_ror_epi64(__U, __A, 5); } @@ -6020,80 +6020,80 @@ __m256i test_mm256_maskz_ror_epi64(__mmask8 __U, __m256i __A) { __m128i test_mm_rorv_epi32(__m128i __A, __m128i __B) { // CHECK-LABEL: @test_mm_rorv_epi32 - // CHECK: @llvm.x86.avx512.prorv.d.128 + // CHECK: @llvm.fshr.v4i32 return _mm_rorv_epi32(__A, __B); } __m128i test_mm_mask_rorv_epi32(__m128i __W, __mmask8 __U, __m128i __A, __m128i __B) { // CHECK-LABEL: @test_mm_mask_rorv_epi32 - // CHECK: @llvm.x86.avx512.prorv.d.128 + // CHECK: @llvm.fshr.v4i32 // CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}} return _mm_mask_rorv_epi32(__W, __U, __A, __B); } __m128i test_mm_maskz_rorv_epi32(__mmask8 __U, __m128i __A, __m128i __B) { // CHECK-LABEL: @test_mm_maskz_rorv_epi32 - // CHECK: @llvm.x86.avx512.prorv.d.128 + // CHECK: @llvm.fshr.v4i32 // CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}} return _mm_maskz_rorv_epi32(__U, __A, __B); } __m256i test_mm256_rorv_epi32(__m256i __A, __m256i __B) { // CHECK-LABEL: @test_mm256_rorv_epi32 - // CHECK: @llvm.x86.avx512.prorv.d.256 + // CHECK: @llvm.fshr.v8i32 return _mm256_rorv_epi32(__A, __B); } __m256i test_mm256_mask_rorv_epi32(__m256i __W, __mmask8 __U, __m256i __A, __m256i __B) { // CHECK-LABEL: @test_mm256_mask_rorv_epi32 - // CHECK: @llvm.x86.avx512.prorv.d.256 + // CHECK: @llvm.fshr.v8i32 // CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}} return _mm256_mask_rorv_epi32(__W, __U, __A, __B); } __m256i test_mm256_maskz_rorv_epi32(__mmask8 __U, __m256i __A, __m256i __B) { // CHECK-LABEL: @test_mm256_maskz_rorv_epi32 - // CHECK: @llvm.x86.avx512.prorv.d.256 + // CHECK: @llvm.fshr.v8i32 // CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}} return _mm256_maskz_rorv_epi32(__U, __A, __B); } __m128i test_mm_rorv_epi64(__m128i __A, __m128i __B) { // CHECK-LABEL: @test_mm_rorv_epi64 - // CHECK: @llvm.x86.avx512.prorv.q.128 + // CHECK: @llvm.fshr.v2i64 return _mm_rorv_epi64(__A, __B); } __m128i test_mm_mask_rorv_epi64(__m128i __W, __mmask8 __U, __m128i __A, __m128i __B) { // CHECK-LABEL: @test_mm_mask_rorv_epi64 - // CHECK: @llvm.x86.avx512.prorv.q.128 + // CHECK: @llvm.fshr.v2i64 // CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}} return _mm_mask_rorv_epi64(__W, __U, __A, __B); } __m128i test_mm_maskz_rorv_epi64(__mmask8 __U, __m128i __A, __m128i __B) { // CHECK-LABEL: @test_mm_maskz_rorv_epi64 - // CHECK: @llvm.x86.avx512.prorv.q.128 + // CHECK: @llvm.fshr.v2i64 // CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}} return _mm_maskz_rorv_epi64(__U, __A, __B); } __m256i test_mm256_rorv_epi64(__m256i __A, __m256i __B) { // CHECK-LABEL: @test_mm256_rorv_epi64 - // CHECK: @llvm.x86.avx512.prorv.q.256 + // CHECK: @llvm.fshr.v4i64 return _mm256_rorv_epi64(__A, __B); } __m256i test_mm256_mask_rorv_epi64(__m256i __W, __mmask8 __U, __m256i __A, __m256i __B) { // CHECK-LABEL: @test_mm256_mask_rorv_epi64 - // CHECK: @llvm.x86.avx512.prorv.q.256 + // CHECK: @llvm.fshr.v4i64 // CHECK: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}} return _mm256_mask_rorv_epi64(__W, __U, __A, __B); } __m256i test_mm256_maskz_rorv_epi64(__mmask8 __U, __m256i __A, __m256i __B) { // CHECK-LABEL: @test_mm256_maskz_rorv_epi64 - // CHECK: @llvm.x86.avx512.prorv.q.256 + // CHECK: @llvm.fshr.v4i64 // CHECK: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}} return _mm256_maskz_rorv_epi64(__U, __A, __B); } diff --git a/test/CodeGen/xop-builtins.c b/test/CodeGen/xop-builtins.c index 5302b9ab8f..e6a09007f7 100644 --- a/test/CodeGen/xop-builtins.c +++ b/test/CodeGen/xop-builtins.c @@ -194,49 +194,49 @@ __m128i test_mm_perm_epi8(__m128i a, __m128i b, __m128i c) { __m128i test_mm_rot_epi8(__m128i a, __m128i b) { // CHECK-LABEL: test_mm_rot_epi8 - // CHECK: call <16 x i8> @llvm.x86.xop.vprotb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK: call <16 x i8> @llvm.fshl.v16i8(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}) return _mm_rot_epi8(a, b); } __m128i test_mm_rot_epi16(__m128i a, __m128i b) { // CHECK-LABEL: test_mm_rot_epi16 - // CHECK: call <8 x i16> @llvm.x86.xop.vprotw(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK: call <8 x i16> @llvm.fshl.v8i16(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}) return _mm_rot_epi16(a, b); } __m128i test_mm_rot_epi32(__m128i a, __m128i b) { // CHECK-LABEL: test_mm_rot_epi32 - // CHECK: call <4 x i32> @llvm.x86.xop.vprotd(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK: call <4 x i32> @llvm.fshl.v4i32(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}) return _mm_rot_epi32(a, b); } __m128i test_mm_rot_epi64(__m128i a, __m128i b) { // CHECK-LABEL: test_mm_rot_epi64 - // CHECK: call <2 x i64> @llvm.x86.xop.vprotq(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK: call <2 x i64> @llvm.fshl.v2i64(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}}) return _mm_rot_epi64(a, b); } __m128i test_mm_roti_epi8(__m128i a) { // CHECK-LABEL: test_mm_roti_epi8 - // CHECK: call <16 x i8> @llvm.x86.xop.vprotbi(<16 x i8> %{{.*}}, i8 1) + // CHECK: call <16 x i8> @llvm.fshl.v16i8(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> ) return _mm_roti_epi8(a, 1); } __m128i test_mm_roti_epi16(__m128i a) { // CHECK-LABEL: test_mm_roti_epi16 - // CHECK: call <8 x i16> @llvm.x86.xop.vprotwi(<8 x i16> %{{.*}}, i8 50) + // CHECK: call <8 x i16> @llvm.fshl.v8i16(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> ) return _mm_roti_epi16(a, 50); } __m128i test_mm_roti_epi32(__m128i a) { // CHECK-LABEL: test_mm_roti_epi32 - // CHECK: call <4 x i32> @llvm.x86.xop.vprotdi(<4 x i32> %{{.*}}, i8 -30) + // CHECK: call <4 x i32> @llvm.fshl.v4i32(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> ) return _mm_roti_epi32(a, -30); } __m128i test_mm_roti_epi64(__m128i a) { // CHECK-LABEL: test_mm_roti_epi64 - // CHECK: call <2 x i64> @llvm.x86.xop.vprotqi(<2 x i64> %{{.*}}, i8 100) + // CHECK: call <2 x i64> @llvm.fshl.v2i64(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> ) return _mm_roti_epi64(a, 100); } -- cgit v1.2.3 From fa2b3e0b28771f4c8f6793b62b0630c6f39bcfe1 Mon Sep 17 00:00:00 2001 From: Artem Dergachev Date: Thu, 20 Dec 2018 19:36:06 +0000 Subject: Revert "[analyzer] pr38668: Do not attempt to cast loaded values..." This reverts commit r349701. The patch was incorrect. The whole point of CastRetrievedVal() is to handle the case in which the type from which the cast is made (i.e., the "type" of value `V`) has nothing to do with the type of the region it was loaded from (i.e., `R->getValueType()`). Differential Revision: https://reviews.llvm.org/D55875 rdar://problem/45062567 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349798 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/StaticAnalyzer/Core/Store.cpp | 26 ++++++-------------------- test/Analysis/casts.c | 11 ----------- test/Analysis/pointer-to-member.cpp | 7 ++++--- 3 files changed, 10 insertions(+), 34 deletions(-) diff --git a/lib/StaticAnalyzer/Core/Store.cpp b/lib/StaticAnalyzer/Core/Store.cpp index ac9cb4bc42..794fd84364 100644 --- a/lib/StaticAnalyzer/Core/Store.cpp +++ b/lib/StaticAnalyzer/Core/Store.cpp @@ -394,28 +394,14 @@ SVal StoreManager::attemptDownCast(SVal Base, QualType TargetType, return UnknownVal(); } -static bool isScalarEnoughToAttemptACast(QualType T) { - return T->isIntegralOrEnumerationType() || T->isAnyPointerType() || - T->isReferenceType(); -} - /// CastRetrievedVal - Used by subclasses of StoreManager to implement /// implicit casts that arise from loads from regions that are reinterpreted /// as another region. SVal StoreManager::CastRetrievedVal(SVal V, const TypedValueRegion *R, - QualType CastTy) { - if (CastTy.isNull() || V.isUnknownOrUndef()) + QualType castTy) { + if (castTy.isNull() || V.isUnknownOrUndef()) return V; - QualType OrigTy = R->getValueType(); - - if (!isScalarEnoughToAttemptACast(OrigTy) || - !isScalarEnoughToAttemptACast(CastTy)) { - if (OrigTy.getUnqualifiedType() == CastTy.getUnqualifiedType()) - return V; - return UnknownVal(); - } - // When retrieving symbolic pointer and expecting a non-void pointer, // wrap them into element regions of the expected type if necessary. // SValBuilder::dispatchCast() doesn't do that, but it is necessary to @@ -424,13 +410,13 @@ SVal StoreManager::CastRetrievedVal(SVal V, const TypedValueRegion *R, // We might need to do that for non-void pointers as well. // FIXME: We really need a single good function to perform casts for us // correctly every time we need it. - if (CastTy->isPointerType() && !CastTy->isVoidPointerType()) + if (castTy->isPointerType() && !castTy->isVoidPointerType()) if (const auto *SR = dyn_cast_or_null(V.getAsRegion())) if (SR->getSymbol()->getType().getCanonicalType() != - CastTy.getCanonicalType()) - return loc::MemRegionVal(castRegion(SR, CastTy)); + castTy.getCanonicalType()) + return loc::MemRegionVal(castRegion(SR, castTy)); - return svalBuilder.dispatchCast(V, CastTy); + return svalBuilder.dispatchCast(V, castTy); } SVal StoreManager::getLValueFieldOrIvar(const Decl *D, SVal Base) { diff --git a/test/Analysis/casts.c b/test/Analysis/casts.c index dd14b8a6e3..45ce1940df 100644 --- a/test/Analysis/casts.c +++ b/test/Analysis/casts.c @@ -213,14 +213,3 @@ void no_crash_on_symsym_cast_to_long() { } #endif - -char no_crash_SymbolCast_of_float_type_aux(int *p) { - *p += 1; - return *p; -} - -void no_crash_SymbolCast_of_float_type() { - extern float x; - char (*f)() = no_crash_SymbolCast_of_float_type_aux; - f(&x); -} diff --git a/test/Analysis/pointer-to-member.cpp b/test/Analysis/pointer-to-member.cpp index 7f19655840..65882527d2 100644 --- a/test/Analysis/pointer-to-member.cpp +++ b/test/Analysis/pointer-to-member.cpp @@ -253,10 +253,11 @@ void test() { clang_analyzer_eval(&A::y); // expected-warning{{TRUE}} clang_analyzer_eval(&A::z); // expected-warning{{TRUE}} + // FIXME: These should be true. int A::*l = &A::x, A::*m = &A::y, A::*n = &A::z; - clang_analyzer_eval(l); // expected-warning{{TRUE}} - clang_analyzer_eval(m); // expected-warning{{TRUE}} - clang_analyzer_eval(n); // expected-warning{{TRUE}} + clang_analyzer_eval(l); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(m); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(n); // expected-warning{{UNKNOWN}} // FIXME: These should be true as well. A a; -- cgit v1.2.3 From 55c8757afeec96e545a596dee786d8d392e6a053 Mon Sep 17 00:00:00 2001 From: Bruno Ricci Date: Thu, 20 Dec 2018 20:05:11 +0000 Subject: [Sema] Don't try to account for the size of an incomplete type in CheckArrayAccess When checking that the array access is not out-of-bounds in CheckArrayAccess it is possible that the type of the base expression after IgnoreParenCasts is incomplete, even though the type of the base expression before IgnoreParenCasts is complete. In this case we have no information about whether the array access is out-of-bounds and we should just bail-out instead. This fixes PR39746 which was caused by trying to obtain the size of an incomplete type. Differential Revision: https://reviews.llvm.org/D55862 Reviewed By: efriedma git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349811 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaChecking.cpp | 12 ++++++++++-- test/SemaCXX/array-bounds.cpp | 9 +++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index b06f793b17..9fe65c1dce 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -12379,10 +12379,19 @@ void Sema::CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr, BaseExpr->getType()->getPointeeOrArrayElementType(); BaseExpr = BaseExpr->IgnoreParenCasts(); const ConstantArrayType *ArrayTy = - Context.getAsConstantArrayType(BaseExpr->getType()); + Context.getAsConstantArrayType(BaseExpr->getType()); + if (!ArrayTy) return; + const Type *BaseType = ArrayTy->getElementType().getTypePtr(); + // It is possible that the type of the base expression after IgnoreParenCasts + // is incomplete, even though the type of the base expression before + // IgnoreParenCasts is complete (see PR39746 for an example). In this case we + // have no information about whether the array access is out-of-bounds. + if (BaseType->isIncompleteType()) + return; + Expr::EvalResult Result; if (!IndexExpr->EvaluateAsInt(Result, Context, Expr::SE_AllowSideEffects)) return; @@ -12402,7 +12411,6 @@ void Sema::CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr, if (!size.isStrictlyPositive()) return; - const Type *BaseType = BaseExpr->getType()->getPointeeOrArrayElementType(); if (BaseType != EffectiveType) { // Make sure we're comparing apples to apples when comparing index to size uint64_t ptrarith_typesize = Context.getTypeSize(EffectiveType); diff --git a/test/SemaCXX/array-bounds.cpp b/test/SemaCXX/array-bounds.cpp index a97f8e312a..3eb929b93e 100644 --- a/test/SemaCXX/array-bounds.cpp +++ b/test/SemaCXX/array-bounds.cpp @@ -284,3 +284,12 @@ struct multi_s multi2[4]; // expected-note {{array 'multi2' declared here}} int test_struct_multiarray() { return multi2[4].arr[0]; // expected-warning {{array index 4 is past the end of the array (which contains 4 elements)}} } + +namespace PR39746 { + struct S; + extern S xxx[2]; + class C {}; + + C &f() { return reinterpret_cast(xxx)[1]; } // no-warning + C &g() { return reinterpret_cast(xxx)[2]; } // no-warning +} -- cgit v1.2.3 From 26ec99a2842fa89c76982a63803cf51eb0b6ee1a Mon Sep 17 00:00:00 2001 From: Aaron Ballman Date: Thu, 20 Dec 2018 20:20:20 +0000 Subject: Allow direct navigation to static analysis checker documentation through SARIF exports. This adds anchors to all of the documented checks so that you can directly link to a check by a stable name. This is useful because the SARIF file format has a field for specifying a URI to documentation for a rule and some viewers, like CodeSonar, make use of this information. These links are then exposed through the SARIF exporter. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349812 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Driver/CC1Options.td | 2 +- .../Checkers/BuiltinCheckerRegistration.h | 2 +- .../clang/StaticAnalyzer/Checkers/CheckerBase.td | 13 + include/clang/StaticAnalyzer/Checkers/Checkers.td | 429 ++++++++++++++------- .../StaticAnalyzer/Frontend/CheckerRegistry.h | 15 +- lib/StaticAnalyzer/Core/AnalyzerOptions.cpp | 2 +- lib/StaticAnalyzer/Core/SarifDiagnostics.cpp | 21 +- lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp | 14 +- .../sarif-multi-diagnostic-test.c.sarif | 2 + utils/TableGen/ClangSACheckersEmitter.cpp | 38 +- www/analyzer/alpha_checks.html | 234 +++++------ www/analyzer/available_checks.html | 284 +++++++------- 12 files changed, 635 insertions(+), 421 deletions(-) diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td index 742787bf0c..c0e73e56d7 100644 --- a/include/clang/Driver/CC1Options.td +++ b/include/clang/Driver/CC1Options.td @@ -108,7 +108,7 @@ def analyzer_checker : Separate<["-"], "analyzer-checker">, ValuesCode<[{ const char *Values = #define GET_CHECKERS - #define CHECKER(FULLNAME, CLASS, HT) FULLNAME "," + #define CHECKER(FULLNAME, CLASS, HT, DOC_URI) FULLNAME "," #include "clang/StaticAnalyzer/Checkers/Checkers.inc" #undef GET_CHECKERS #define GET_PACKAGES diff --git a/include/clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h b/include/clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h index cd42cd6cd3..192ac1261c 100644 --- a/include/clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h +++ b/include/clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h @@ -24,7 +24,7 @@ class CheckerManager; class CheckerRegistry; #define GET_CHECKERS -#define CHECKER(FULLNAME, CLASS, HELPTEXT) \ +#define CHECKER(FULLNAME, CLASS, HELPTEXT, DOC_URI) \ void register##CLASS(CheckerManager &mgr); #include "clang/StaticAnalyzer/Checkers/Checkers.inc" #undef CHECKER diff --git a/include/clang/StaticAnalyzer/Checkers/CheckerBase.td b/include/clang/StaticAnalyzer/Checkers/CheckerBase.td index 15034fc689..453e189fcc 100644 --- a/include/clang/StaticAnalyzer/Checkers/CheckerBase.td +++ b/include/clang/StaticAnalyzer/Checkers/CheckerBase.td @@ -32,6 +32,18 @@ class ParentPackage { Package ParentPackage = P; } /// a '-help'-like command line option. class HelpText { string HelpText = text; } +/// Describes what kind of documentation exists for the checker. +class DocumentationEnum val> { + bits<2> Documentation = val; +} +def NotDocumented : DocumentationEnum<0>; +def HasDocumentation : DocumentationEnum<1>; +def HasAlphaDocumentation : DocumentationEnum<2>; + +class Documentation { + bits<2> Documentation = val.Documentation; +} + /// Describes a checker. Every builtin checker has to be registered with the use /// of this class (out-of-trunk checkers loaded from plugins obviously don't). /// Note that a checker has a name (e.g.: 'NullDereference'), and a fullname, @@ -40,5 +52,6 @@ class HelpText { string HelpText = text; } class Checker { string CheckerName = name; string HelpText; + bits<2> Documentation; Package ParentPackage; } diff --git a/include/clang/StaticAnalyzer/Checkers/Checkers.td b/include/clang/StaticAnalyzer/Checkers/Checkers.td index 0d16de1ccc..1bb3da7a24 100644 --- a/include/clang/StaticAnalyzer/Checkers/Checkers.td +++ b/include/clang/StaticAnalyzer/Checkers/Checkers.td @@ -102,84 +102,106 @@ def CloneDetectionAlpha : Package<"clone">, ParentPackage; let ParentPackage = Core in { def DereferenceChecker : Checker<"NullDereference">, - HelpText<"Check for dereferences of null pointers">; + HelpText<"Check for dereferences of null pointers">, + Documentation; def CallAndMessageChecker : Checker<"CallAndMessage">, HelpText<"Check for logical errors for function calls and Objective-C " "message expressions (e.g., uninitialized arguments, null function " - "pointers)">; + "pointers)">, + Documentation; def NonNullParamChecker : Checker<"NonNullParamChecker">, HelpText<"Check for null pointers passed as arguments to a function whose " - "arguments are references or marked with the 'nonnull' attribute">; + "arguments are references or marked with the 'nonnull' attribute">, + Documentation; def VLASizeChecker : Checker<"VLASize">, - HelpText<"Check for declarations of VLA of undefined or zero size">; + HelpText<"Check for declarations of VLA of undefined or zero size">, + Documentation; def DivZeroChecker : Checker<"DivideZero">, - HelpText<"Check for division by zero">; + HelpText<"Check for division by zero">, + Documentation; def UndefResultChecker : Checker<"UndefinedBinaryOperatorResult">, - HelpText<"Check for undefined results of binary operators">; + HelpText<"Check for undefined results of binary operators">, + Documentation; def StackAddrEscapeChecker : Checker<"StackAddressEscape">, - HelpText<"Check that addresses to stack memory do not escape the function">; + HelpText<"Check that addresses to stack memory do not escape the function">, + Documentation; def DynamicTypePropagation : Checker<"DynamicTypePropagation">, - HelpText<"Generate dynamic type information">; + HelpText<"Generate dynamic type information">, + Documentation; def NonnullGlobalConstantsChecker: Checker<"NonnilStringConstants">, - HelpText<"Assume that const string-like globals are non-null">; + HelpText<"Assume that const string-like globals are non-null">, + Documentation; } // end "core" let ParentPackage = CoreAlpha in { def BoolAssignmentChecker : Checker<"BoolAssignment">, - HelpText<"Warn about assigning non-{0,1} values to Boolean variables">; + HelpText<"Warn about assigning non-{0,1} values to Boolean variables">, + Documentation; def CastSizeChecker : Checker<"CastSize">, HelpText<"Check when casting a malloc'ed type T, whether the size is a " - "multiple of the size of T">; + "multiple of the size of T">, + Documentation; def CastToStructChecker : Checker<"CastToStruct">, - HelpText<"Check for cast from non-struct pointer to struct pointer">; + HelpText<"Check for cast from non-struct pointer to struct pointer">, + Documentation; def ConversionChecker : Checker<"Conversion">, - HelpText<"Loss of sign/precision in implicit conversions">; + HelpText<"Loss of sign/precision in implicit conversions">, + Documentation; def IdenticalExprChecker : Checker<"IdenticalExpr">, - HelpText<"Warn about unintended use of identical expressions in operators">; + HelpText<"Warn about unintended use of identical expressions in operators">, + Documentation; def FixedAddressChecker : Checker<"FixedAddr">, - HelpText<"Check for assignment of a fixed address to a pointer">; + HelpText<"Check for assignment of a fixed address to a pointer">, + Documentation; def PointerArithChecker : Checker<"PointerArithm">, HelpText<"Check for pointer arithmetic on locations other than array " - "elements">; + "elements">, + Documentation; def PointerSubChecker : Checker<"PointerSub">, HelpText<"Check for pointer subtractions on two pointers pointing to " - "different memory chunks">; + "different memory chunks">, + Documentation; def SizeofPointerChecker : Checker<"SizeofPtr">, - HelpText<"Warn about unintended use of sizeof() on pointer expressions">; + HelpText<"Warn about unintended use of sizeof() on pointer expressions">, + Documentation; def CallAndMessageUnInitRefArg : Checker<"CallAndMessageUnInitRefArg">, HelpText<"Check for logical errors for function calls and Objective-C " "message expressions (e.g., uninitialized arguments, null function " - "pointers, and pointer to undefined variables)">; + "pointers, and pointer to undefined variables)">, + Documentation; def TestAfterDivZeroChecker : Checker<"TestAfterDivZero">, HelpText<"Check for division by variable that is later compared against 0. " - "Either the comparison is useless or there is division by zero.">; + "Either the comparison is useless or there is division by zero.">, + Documentation; def DynamicTypeChecker : Checker<"DynamicTypeChecker">, HelpText<"Check for cases where the dynamic and the static type of an object " - "are unrelated.">; + "are unrelated.">, + Documentation; def StackAddrAsyncEscapeChecker : Checker<"StackAddressAsyncEscape">, - HelpText<"Check that addresses to stack memory do not escape the function">; + HelpText<"Check that addresses to stack memory do not escape the function">, + Documentation; } // end "alpha.core" @@ -187,33 +209,40 @@ let ParentPackage = Nullability in { def NullPassedToNonnullChecker : Checker<"NullPassedToNonnull">, HelpText<"Warns when a null pointer is passed to a pointer which has a " - "_Nonnull type.">; + "_Nonnull type.">, + Documentation; def NullReturnedFromNonnullChecker : Checker<"NullReturnedFromNonnull">, HelpText<"Warns when a null pointer is returned from a function that has " - "_Nonnull return type.">; + "_Nonnull return type.">, + Documentation; def NullableDereferencedChecker : Checker<"NullableDereferenced">, - HelpText<"Warns when a nullable pointer is dereferenced.">; + HelpText<"Warns when a nullable pointer is dereferenced.">, + Documentation; def NullablePassedToNonnullChecker : Checker<"NullablePassedToNonnull">, HelpText<"Warns when a nullable pointer is passed to a pointer which has a " - "_Nonnull type.">; + "_Nonnull type.">, + Documentation; def NullableReturnedFromNonnullChecker : Checker<"NullableReturnedFromNonnull">, HelpText<"Warns when a nullable pointer is returned from a function that has " - "_Nonnull return type.">; + "_Nonnull return type.">, + Documentation; } // end "nullability" let ParentPackage = APIModeling in { def StdCLibraryFunctionsChecker : Checker<"StdCLibraryFunctions">, - HelpText<"Improve modeling of the C standard library functions">; + HelpText<"Improve modeling of the C standard library functions">, + Documentation; def TrustNonnullChecker : Checker<"TrustNonnull">, HelpText<"Trust that returns from framework methods annotated with _Nonnull " - "are not null">; + "are not null">, + Documentation; } // end "apiModeling" @@ -225,10 +254,12 @@ let ParentPackage = CoreBuiltin in { def NoReturnFunctionChecker : Checker<"NoReturnFunctions">, HelpText<"Evaluate \"panic\" functions that are known to not return to the " - "caller">; + "caller">, + Documentation; def BuiltinFunctionChecker : Checker<"BuiltinFunctions">, - HelpText<"Evaluate compiler builtin functions (e.g., alloca())">; + HelpText<"Evaluate compiler builtin functions (e.g., alloca())">, + Documentation; } // end "core.builtin" @@ -239,19 +270,24 @@ def BuiltinFunctionChecker : Checker<"BuiltinFunctions">, let ParentPackage = CoreUninitialized in { def UndefinedArraySubscriptChecker : Checker<"ArraySubscript">, - HelpText<"Check for uninitialized values used as array subscripts">; + HelpText<"Check for uninitialized values used as array subscripts">, + Documentation; def UndefinedAssignmentChecker : Checker<"Assign">, - HelpText<"Check for assigning uninitialized values">; + HelpText<"Check for assigning uninitialized values">, + Documentation; def UndefBranchChecker : Checker<"Branch">, - HelpText<"Check for uninitialized values used as branch conditions">; + HelpText<"Check for uninitialized values used as branch conditions">, + Documentation; def UndefCapturedBlockVarChecker : Checker<"CapturedBlockVariable">, - HelpText<"Check for blocks that capture uninitialized values">; + HelpText<"Check for blocks that capture uninitialized values">, + Documentation; def ReturnUndefChecker : Checker<"UndefReturn">, - HelpText<"Check for uninitialized values being returned to the caller">; + HelpText<"Check for uninitialized values being returned to the caller">, + Documentation; } // end "core.uninitialized" @@ -263,27 +299,33 @@ let ParentPackage = Cplusplus in { def InnerPointerChecker : Checker<"InnerPointer">, HelpText<"Check for inner pointers of C++ containers used after " - "re/deallocation">; + "re/deallocation">, + Documentation; def NewDeleteChecker : Checker<"NewDelete">, HelpText<"Check for double-free and use-after-free problems. Traces memory " - "managed by new/delete.">; + "managed by new/delete.">, + Documentation; def NewDeleteLeaksChecker : Checker<"NewDeleteLeaks">, - HelpText<"Check for memory leaks. Traces memory managed by new/delete.">; + HelpText<"Check for memory leaks. Traces memory managed by new/delete.">, + Documentation; def CXXSelfAssignmentChecker : Checker<"SelfAssignment">, - HelpText<"Checks C++ copy and move assignment operators for self assignment">; + HelpText<"Checks C++ copy and move assignment operators for self assignment">, + Documentation; def MoveChecker: Checker<"Move">, - HelpText<"Find use-after-move bugs in C++">; + HelpText<"Find use-after-move bugs in C++">, + Documentation; } // end: "cplusplus" let ParentPackage = CplusplusOptIn in { def VirtualCallChecker : Checker<"VirtualCall">, - HelpText<"Check virtual function calls during construction or destruction">; + HelpText<"Check virtual function calls during construction or destruction">, + Documentation; } // end: "optin.cplusplus" @@ -291,23 +333,29 @@ let ParentPackage = CplusplusAlpha in { def DeleteWithNonVirtualDtorChecker : Checker<"DeleteWithNonVirtualDtor">, HelpText<"Reports destructions of polymorphic objects with a non-virtual " - "destructor in their base class">; + "destructor in their base class">, + Documentation; def EnumCastOutOfRangeChecker : Checker<"EnumCastOutOfRange">, - HelpText<"Check integer to enumeration casts for out of range values">; + HelpText<"Check integer to enumeration casts for out of range values">, + Documentation; def InvalidatedIteratorChecker : Checker<"InvalidatedIterator">, - HelpText<"Check for use of invalidated iterators">; + HelpText<"Check for use of invalidated iterators">, + Documentation; def IteratorRangeChecker : Checker<"IteratorRange">, - HelpText<"Check for iterators used outside their valid ranges">; + HelpText<"Check for iterators used outside their valid ranges">, + Documentation; def MismatchedIteratorChecker : Checker<"MismatchedIterator">, HelpText<"Check for use of iterators of different containers where iterators " - "of the same container are expected">; + "of the same container are expected">, + Documentation; def UninitializedObjectChecker: Checker<"UninitializedObject">, - HelpText<"Reports uninitialized fields after object construction">; + HelpText<"Reports uninitialized fields after object construction">, + Documentation; } // end: "alpha.cplusplus" @@ -319,13 +367,16 @@ def UninitializedObjectChecker: Checker<"UninitializedObject">, let ParentPackage = Valist in { def UninitializedChecker : Checker<"Uninitialized">, - HelpText<"Check for usages of uninitialized (or already released) va_lists.">; + HelpText<"Check for usages of uninitialized (or already released) va_lists.">, + Documentation; def UnterminatedChecker : Checker<"Unterminated">, - HelpText<"Check for va_lists which are not released by a va_end call.">; + HelpText<"Check for va_lists which are not released by a va_end call.">, + Documentation; def CopyToSelfChecker : Checker<"CopyToSelf">, - HelpText<"Check for va_lists which are copied onto itself.">; + HelpText<"Check for va_lists which are copied onto itself.">, + Documentation; } // end : "valist" @@ -337,14 +388,16 @@ let ParentPackage = DeadCode in { def DeadStoresChecker : Checker<"DeadStores">, HelpText<"Check for values stored to variables that are never read " - "afterwards">; + "afterwards">, + Documentation; } // end DeadCode let ParentPackage = DeadCodeAlpha in { def UnreachableCodeChecker : Checker<"UnreachableCode">, - HelpText<"Check unreachable code">; + HelpText<"Check unreachable code">, + Documentation; } // end "alpha.deadcode" @@ -355,7 +408,8 @@ def UnreachableCodeChecker : Checker<"UnreachableCode">, let ParentPackage = Performance in { def PaddingChecker : Checker<"Padding">, - HelpText<"Check for excessively padded structs.">; + HelpText<"Check for excessively padded structs.">, + Documentation; } // end: "padding" @@ -366,29 +420,40 @@ def PaddingChecker : Checker<"Padding">, let ParentPackage = InsecureAPI in { def bcmp : Checker<"bcmp">, - HelpText<"Warn on uses of the 'bcmp' function">; + HelpText<"Warn on uses of the 'bcmp' function">, + Documentation; def bcopy : Checker<"bcopy">, - HelpText<"Warn on uses of the 'bcopy' function">; + HelpText<"Warn on uses of the 'bcopy' function">, + Documentation; def bzero : Checker<"bzero">, - HelpText<"Warn on uses of the 'bzero' function">; + HelpText<"Warn on uses of the 'bzero' function">, + Documentation; def gets : Checker<"gets">, - HelpText<"Warn on uses of the 'gets' function">; + HelpText<"Warn on uses of the 'gets' function">, + Documentation; def getpw : Checker<"getpw">, - HelpText<"Warn on uses of the 'getpw' function">; + HelpText<"Warn on uses of the 'getpw' function">, + Documentation; def mktemp : Checker<"mktemp">, - HelpText<"Warn on uses of the 'mktemp' function">; + HelpText<"Warn on uses of the 'mktemp' function">, + Documentation; def mkstemp : Checker<"mkstemp">, HelpText<"Warn when 'mkstemp' is passed fewer than 6 X's in the format " - "string">; + "string">, + Documentation; def rand : Checker<"rand">, - HelpText<"Warn on uses of the 'rand', 'random', and related functions">; + HelpText<"Warn on uses of the 'rand', 'random', and related functions">, + Documentation; def strcpy : Checker<"strcpy">, - HelpText<"Warn on uses of the 'strcpy' and 'strcat' functions">; + HelpText<"Warn on uses of the 'strcpy' and 'strcat' functions">, + Documentation; def vfork : Checker<"vfork">, - HelpText<"Warn on uses of the 'vfork' function">; + HelpText<"Warn on uses of the 'vfork' function">, + Documentation; def UncheckedReturn : Checker<"UncheckedReturn">, HelpText<"Warn on uses of functions whose return values must be always " - "checked">; + "checked">, + Documentation; } // end "security.insecureAPI" @@ -396,29 +461,35 @@ let ParentPackage = Security in { def FloatLoopCounter : Checker<"FloatLoopCounter">, HelpText<"Warn on using a floating point value as a loop counter (CERT: " - "FLP30-C, FLP30-CPP)">; + "FLP30-C, FLP30-CPP)">, + Documentation; } // end "security" let ParentPackage = SecurityAlpha in { def ArrayBoundChecker : Checker<"ArrayBound">, - HelpText<"Warn about buffer overflows (older checker)">; + HelpText<"Warn about buffer overflows (older checker)">, + Documentation; def ArrayBoundCheckerV2 : Checker<"ArrayBoundV2">, - HelpText<"Warn about buffer overflows (newer checker)">; + HelpText<"Warn about buffer overflows (newer checker)">, + Documentation; def ReturnPointerRangeChecker : Checker<"ReturnPtrRange">, - HelpText<"Check for an out-of-bound pointer being returned to callers">; + HelpText<"Check for an out-of-bound pointer being returned to callers">, + Documentation; def MallocOverflowSecurityChecker : Checker<"MallocOverflow">, - HelpText<"Check for overflows in the arguments to malloc()">; + HelpText<"Check for overflows in the arguments to malloc()">, + Documentation; // Operating systems specific PROT_READ/PROT_WRITE values is not implemented, // the defaults are correct for several common operating systems though, // but may need to be overridden via the related analyzer-config flags. def MmapWriteExecChecker : Checker<"MmapWriteExec">, - HelpText<"Warn on mmap() calls that are both writable and executable">; + HelpText<"Warn on mmap() calls that are both writable and executable">, + Documentation; } // end "alpha.security" @@ -429,7 +500,8 @@ def MmapWriteExecChecker : Checker<"MmapWriteExec">, let ParentPackage = Taint in { def GenericTaintChecker : Checker<"TaintPropagation">, - HelpText<"Generate taint information used by other checkers">; + HelpText<"Generate taint information used by other checkers">, + Documentation; } // end "alpha.security.taint" @@ -440,39 +512,49 @@ def GenericTaintChecker : Checker<"TaintPropagation">, let ParentPackage = Unix in { def UnixAPIMisuseChecker : Checker<"API">, - HelpText<"Check calls to various UNIX/Posix functions">; + HelpText<"Check calls to various UNIX/Posix functions">, + Documentation; def MallocChecker: Checker<"Malloc">, HelpText<"Check for memory leaks, double free, and use-after-free problems. " - "Traces memory managed by malloc()/free().">; + "Traces memory managed by malloc()/free().">, + Documentation; def MallocSizeofChecker : Checker<"MallocSizeof">, - HelpText<"Check for dubious malloc arguments involving sizeof">; + HelpText<"Check for dubious malloc arguments involving sizeof">, + Documentation; def MismatchedDeallocatorChecker : Checker<"MismatchedDeallocator">, - HelpText<"Check for mismatched deallocators.">; + HelpText<"Check for mismatched deallocators.">, + Documentation; def VforkChecker : Checker<"Vfork">, - HelpText<"Check for proper usage of vfork">; + HelpText<"Check for proper usage of vfork">, + Documentation; } // end "unix" let ParentPackage = UnixAlpha in { def ChrootChecker : Checker<"Chroot">, - HelpText<"Check improper use of chroot">; + HelpText<"Check improper use of chroot">, + Documentation; def PthreadLockChecker : Checker<"PthreadLock">, - HelpText<"Simple lock -> unlock checker">; + HelpText<"Simple lock -> unlock checker">, + Documentation; def StreamChecker : Checker<"Stream">, - HelpText<"Check stream handling functions">; + HelpText<"Check stream handling functions">, + Documentation; def SimpleStreamChecker : Checker<"SimpleStream">, - HelpText<"Check for misuses of stream APIs">; + HelpText<"Check for misuses of stream APIs">, + Documentation; def BlockInCriticalSectionChecker : Checker<"BlockInCriticalSection">, - HelpText<"Check for calls to blocking functions inside a critical section">; + HelpText<"Check for calls to blocking functions inside a critical section">, + Documentation; } // end "alpha.unix" @@ -480,24 +562,29 @@ let ParentPackage = CString in { def CStringNullArg : Checker<"NullArg">, HelpText<"Check for null pointers being passed as arguments to C string " - "functions">; + "functions">, + Documentation; def CStringSyntaxChecker : Checker<"BadSizeArg">, HelpText<"Check the size argument passed into C string functions for common " - "erroneous patterns">; + "erroneous patterns">, + Documentation; } // end "unix.cstring" let ParentPackage = CStringAlpha in { def CStringOutOfBounds : Checker<"OutOfBounds">, - HelpText<"Check for out-of-bounds access in string functions">; + HelpText<"Check for out-of-bounds access in string functions">, + Documentation; def CStringBufferOverlap : Checker<"BufferOverlap">, - HelpText<"Checks for overlap in two buffer arguments">; + HelpText<"Checks for overlap in two buffer arguments">, + Documentation; def CStringNotNullTerm : Checker<"NotNullTerminated">, - HelpText<"Check for arguments which are not null-terminating strings">; + HelpText<"Check for arguments which are not null-terminating strings">, + Documentation; } // end "alpha.unix.cstring" @@ -509,19 +596,24 @@ let ParentPackage = OSX in { def NumberObjectConversionChecker : Checker<"NumberObjectConversion">, HelpText<"Check for erroneous conversions of objects representing numbers " - "into numbers">; + "into numbers">, + Documentation; def MacOSXAPIChecker : Checker<"API">, - HelpText<"Check for proper uses of various Apple APIs">; + HelpText<"Check for proper uses of various Apple APIs">, + Documentation; def MacOSKeychainAPIChecker : Checker<"SecKeychainAPI">, - HelpText<"Check for proper uses of Secure Keychain APIs">; + HelpText<"Check for proper uses of Secure Keychain APIs">, + Documentation; def ObjCPropertyChecker : Checker<"ObjCProperty">, - HelpText<"Check for proper uses of Objective-C properties">; + HelpText<"Check for proper uses of Objective-C properties">, + Documentation; def OSObjectRetainCountChecker : Checker<"OSObjectRetainCount">, - HelpText<"Check for leaks and improper reference count management for OSObject">; + HelpText<"Check for leaks and improper reference count management for OSObject">, + Documentation; } // end "osx" @@ -529,66 +621,84 @@ let ParentPackage = Cocoa in { def RunLoopAutoreleaseLeakChecker : Checker<"RunLoopAutoreleaseLeak">, HelpText<"Check for leaked memory in autorelease pools that will never be " - "drained">; + "drained">, + Documentation; def ObjCAtSyncChecker : Checker<"AtSync">, - HelpText<"Check for nil pointers used as mutexes for @synchronized">; + HelpText<"Check for nil pointers used as mutexes for @synchronized">, + Documentation; def NilArgChecker : Checker<"NilArg">, - HelpText<"Check for prohibited nil arguments to ObjC method calls">; + HelpText<"Check for prohibited nil arguments to ObjC method calls">, + Documentation; def ClassReleaseChecker : Checker<"ClassRelease">, HelpText<"Check for sending 'retain', 'release', or 'autorelease' directly " - "to a Class">; + "to a Class">, + Documentation; def VariadicMethodTypeChecker : Checker<"VariadicMethodTypes">, HelpText<"Check for passing non-Objective-C types to variadic collection " - "initialization methods that expect only Objective-C types">; + "initialization methods that expect only Objective-C types">, + Documentation; def NSAutoreleasePoolChecker : Checker<"NSAutoreleasePool">, HelpText<"Warn for suboptimal uses of NSAutoreleasePool in Objective-C GC " - "mode">; + "mode">, + Documentation; def ObjCMethSigsChecker : Checker<"IncompatibleMethodTypes">, HelpText<"Warn about Objective-C method signatures with type " - "incompatibilities">; + "incompatibilities">, + Documentation; def ObjCUnusedIvarsChecker : Checker<"UnusedIvars">, - HelpText<"Warn about private ivars that are never used">; + HelpText<"Warn about private ivars that are never used">, + Documentation; def ObjCSelfInitChecker : Checker<"SelfInit">, HelpText<"Check that 'self' is properly initialized inside an initializer " - "method">; + "method">, + Documentation; def ObjCLoopChecker : Checker<"Loops">, - HelpText<"Improved modeling of loops using Cocoa collection types">; + HelpText<"Improved modeling of loops using Cocoa collection types">, + Documentation; def ObjCNonNilReturnValueChecker : Checker<"NonNilReturnValue">, - HelpText<"Model the APIs that are guaranteed to return a non-nil value">; + HelpText<"Model the APIs that are guaranteed to return a non-nil value">, + Documentation; def ObjCSuperCallChecker : Checker<"MissingSuperCall">, HelpText<"Warn about Objective-C methods that lack a necessary call to " - "super">; + "super">, + Documentation; def NSErrorChecker : Checker<"NSError">, - HelpText<"Check usage of NSError** parameters">; + HelpText<"Check usage of NSError** parameters">, + Documentation; def RetainCountChecker : Checker<"RetainCount">, - HelpText<"Check for leaks and improper reference count management">; + HelpText<"Check for leaks and improper reference count management">, + Documentation; def ObjCGenericsChecker : Checker<"ObjCGenerics">, - HelpText<"Check for type errors when using Objective-C generics">; + HelpText<"Check for type errors when using Objective-C generics">, + Documentation; def ObjCDeallocChecker : Checker<"Dealloc">, HelpText<"Warn about Objective-C classes that lack a correct implementation " - "of -dealloc">; + "of -dealloc">, + Documentation; def ObjCSuperDeallocChecker : Checker<"SuperDealloc">, - HelpText<"Warn about improper use of '[super dealloc]' in Objective-C">; + HelpText<"Warn about improper use of '[super dealloc]' in Objective-C">, + Documentation; def AutoreleaseWriteChecker : Checker<"AutoreleaseWrite">, HelpText<"Warn about potentially crashing writes to autoreleasing objects " - "from different autoreleasing pools in Objective-C">; + "from different autoreleasing pools in Objective-C">, + Documentation; } // end "osx.cocoa" @@ -596,39 +706,47 @@ let ParentPackage = Performance in { def GCDAntipattern : Checker<"GCDAntipattern">, HelpText<"Check for performance anti-patterns when using Grand Central " - "Dispatch">; + "Dispatch">, + Documentation; } // end "optin.performance" let ParentPackage = CocoaAlpha in { def InstanceVariableInvalidation : Checker<"InstanceVariableInvalidation">, HelpText<"Check that the invalidatable instance variables are invalidated in " - "the methods annotated with objc_instance_variable_invalidator">; + "the methods annotated with objc_instance_variable_invalidator">, + Documentation; def MissingInvalidationMethod : Checker<"MissingInvalidationMethod">, HelpText<"Check that the invalidation methods are present in classes that " - "contain invalidatable instance variables">; + "contain invalidatable instance variables">, + Documentation; def DirectIvarAssignment : Checker<"DirectIvarAssignment">, - HelpText<"Check for direct assignments to instance variables">; + HelpText<"Check for direct assignments to instance variables">, + Documentation; def DirectIvarAssignmentForAnnotatedFunctions : Checker<"DirectIvarAssignmentForAnnotatedFunctions">, HelpText<"Check for direct assignments to instance variables in the methods " - "annotated with objc_no_direct_instance_variable_assignment">; + "annotated with objc_no_direct_instance_variable_assignment">, + Documentation; } // end "alpha.osx.cocoa" let ParentPackage = CoreFoundation in { def CFNumberChecker : Checker<"CFNumber">, - HelpText<"Check for proper uses of CFNumber APIs">; + HelpText<"Check for proper uses of CFNumber APIs">, + Documentation; def CFRetainReleaseChecker : Checker<"CFRetainRelease">, - HelpText<"Check for null arguments to CFRetain/CFRelease/CFMakeCollectable">; + HelpText<"Check for null arguments to CFRetain/CFRelease/CFMakeCollectable">, + Documentation; def CFErrorChecker : Checker<"CFError">, - HelpText<"Check usage of CFErrorRef* parameters">; + HelpText<"Check usage of CFErrorRef* parameters">, + Documentation; } // end "osx.coreFoundation" @@ -636,10 +754,12 @@ let ParentPackage = Containers in { def ObjCContainersASTChecker : Checker<"PointerSizedValues">, HelpText<"Warns if 'CFArray', 'CFDictionary', 'CFSet' are created with " - "non-pointer-size values">; + "non-pointer-size values">, + Documentation; def ObjCContainersChecker : Checker<"OutOfBounds">, - HelpText<"Checks for index out-of-bounds when using 'CFArray' API">; + HelpText<"Checks for index out-of-bounds when using 'CFArray' API">, + Documentation; } // end "osx.coreFoundation.containers" @@ -647,11 +767,13 @@ let ParentPackage = LocalizabilityOptIn in { def NonLocalizedStringChecker : Checker<"NonLocalizedStringChecker">, HelpText<"Warns about uses of non-localized NSStrings passed to UI methods " - "expecting localized NSStrings">; + "expecting localized NSStrings">, + Documentation; def EmptyLocalizationContextChecker : Checker<"EmptyLocalizationContextChecker">, - HelpText<"Check that NSLocalizedString macros include a comment for context">; + HelpText<"Check that NSLocalizedString macros include a comment for context">, + Documentation; } // end "optin.osx.cocoa.localizability" @@ -659,14 +781,16 @@ let ParentPackage = LocalizabilityAlpha in { def PluralMisuseChecker : Checker<"PluralMisuseChecker">, HelpText<"Warns against using one vs. many plural pattern in code when " - "generating localized strings.">; + "generating localized strings.">, + Documentation; } // end "alpha.osx.cocoa.localizability" let ParentPackage = MPI in { def MPIChecker : Checker<"MPI-Checker">, - HelpText<"Checks MPI code">; + HelpText<"Checks MPI code">, + Documentation; } // end "optin.mpi" @@ -677,7 +801,8 @@ def MPIChecker : Checker<"MPI-Checker">, let ParentPackage = LLVMAlpha in { def LLVMConventionsChecker : Checker<"Conventions">, - HelpText<"Check code for LLVM codebase conventions">; + HelpText<"Check code for LLVM codebase conventions">, + Documentation; } // end "llvm" @@ -688,7 +813,8 @@ def LLVMConventionsChecker : Checker<"Conventions">, let ParentPackage = GoogleAPIModeling in { def GTestChecker : Checker<"GTest">, - HelpText<"Model gtest assertion APIs">; + HelpText<"Model gtest assertion APIs">, + Documentation; } // end "apiModeling.google" @@ -699,49 +825,64 @@ def GTestChecker : Checker<"GTest">, let ParentPackage = Debug in { def AnalysisOrderChecker : Checker<"AnalysisOrder">, - HelpText<"Print callbacks that are called during analysis in order">; + HelpText<"Print callbacks that are called during analysis in order">, + Documentation; def DominatorsTreeDumper : Checker<"DumpDominators">, - HelpText<"Print the dominance tree for a given CFG">; + HelpText<"Print the dominance tree for a given CFG">, + Documentation; def LiveVariablesDumper : Checker<"DumpLiveVars">, - HelpText<"Print results of live variable analysis">; + HelpText<"Print results of live variable analysis">, + Documentation; def LiveStatementsDumper : Checker<"DumpLiveStmts">, - HelpText<"Print results of live statement analysis">; + HelpText<"Print results of live statement analysis">, + Documentation; def CFGViewer : Checker<"ViewCFG">, - HelpText<"View Control-Flow Graphs using GraphViz">; + HelpText<"View Control-Flow Graphs using GraphViz">, + Documentation; def CFGDumper : Checker<"DumpCFG">, - HelpText<"Display Control-Flow Graphs">; + HelpText<"Display Control-Flow Graphs">, + Documentation; def CallGraphViewer : Checker<"ViewCallGraph">, - HelpText<"View Call Graph using GraphViz">; + HelpText<"View Call Graph using GraphViz">, + Documentation; def CallGraphDumper : Checker<"DumpCallGraph">, - HelpText<"Display Call Graph">; + HelpText<"Display Call Graph">, + Documentation; def ConfigDumper : Checker<"ConfigDumper">, - HelpText<"Dump config table">; + HelpText<"Dump config table">, + Documentation; def TraversalDumper : Checker<"DumpTraversal">, - HelpText<"Print branch conditions as they are traversed by the engine">; + HelpText<"Print branch conditions as they are traversed by the engine">, + Documentation; def CallDumper : Checker<"DumpCalls">, - HelpText<"Print calls as they are traversed by the engine">; + HelpText<"Print calls as they are traversed by the engine">, + Documentation; def AnalyzerStatsChecker : Checker<"Stats">, - HelpText<"Emit warnings with analyzer statistics">; + HelpText<"Emit warnings with analyzer statistics">, + Documentation; def TaintTesterChecker : Checker<"TaintTest">, - HelpText<"Mark tainted symbols as such.">; + HelpText<"Mark tainted symbols as such.">, + Documentation; def ExprInspectionChecker : Checker<"ExprInspection">, - HelpText<"Check the analyzer's understanding of expressions">; + HelpText<"Check the analyzer's understanding of expressions">, + Documentation; def ExplodedGraphViewer : Checker<"ViewExplodedGraph">, - HelpText<"View Exploded Graphs using GraphViz">; + HelpText<"View Exploded Graphs using GraphViz">, + Documentation; } // end "debug" @@ -753,7 +894,8 @@ def ExplodedGraphViewer : Checker<"ViewExplodedGraph">, let ParentPackage = CloneDetectionAlpha in { def CloneChecker : Checker<"CloneChecker">, - HelpText<"Reports similar pieces of code.">; + HelpText<"Reports similar pieces of code.">, + Documentation; } // end "clone" @@ -764,6 +906,7 @@ def CloneChecker : Checker<"CloneChecker">, let ParentPackage = PortabilityOptIn in { def UnixAPIPortabilityChecker : Checker<"UnixAPI">, - HelpText<"Finds implementation-defined behavior in UNIX/Posix functions">; + HelpText<"Finds implementation-defined behavior in UNIX/Posix functions">, + Documentation; } // end optin.portability diff --git a/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h b/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h index 3599833d2c..966234492f 100644 --- a/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h +++ b/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h @@ -91,9 +91,12 @@ public: InitializationFunction Initialize; StringRef FullName; StringRef Desc; + StringRef DocumentationUri; - CheckerInfo(InitializationFunction fn, StringRef name, StringRef desc) - : Initialize(fn), FullName(name), Desc(desc) {} + CheckerInfo(InitializationFunction Fn, StringRef Name, StringRef Desc, + StringRef DocsUri) + : Initialize(Fn), FullName(Name), Desc(Desc), + DocumentationUri(DocsUri) {} }; using CheckerInfoList = std::vector; @@ -108,16 +111,16 @@ private: public: /// Adds a checker to the registry. Use this non-templated overload when your /// checker requires custom initialization. - void addChecker(InitializationFunction fn, StringRef fullName, - StringRef desc); + void addChecker(InitializationFunction Fn, StringRef FullName, StringRef Desc, + StringRef DocsUri); /// Adds a checker to the registry. Use this templated overload when your /// checker does not require any custom initialization. template - void addChecker(StringRef fullName, StringRef desc) { + void addChecker(StringRef FullName, StringRef Desc, StringRef DocsUri) { // Avoid MSVC's Compiler Error C2276: // http://msdn.microsoft.com/en-us/library/850cstw1(v=VS.80).aspx - addChecker(&CheckerRegistry::initializeManager, fullName, desc); + addChecker(&CheckerRegistry::initializeManager, FullName, Desc, DocsUri); } /// Initializes a CheckerManager by calling the initialization functions for diff --git a/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp b/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp index d9b63c209d..0588c2bd3d 100644 --- a/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp +++ b/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp @@ -34,7 +34,7 @@ std::vector AnalyzerOptions::getRegisteredCheckers(bool IncludeExperimental /* = false */) { static const StringRef StaticAnalyzerChecks[] = { #define GET_CHECKERS -#define CHECKER(FULLNAME, CLASS, HELPTEXT) \ +#define CHECKER(FULLNAME, CLASS, HELPTEXT, DOC_URI) \ FULLNAME, #include "clang/StaticAnalyzer/Checkers/Checkers.inc" #undef CHECKER diff --git a/lib/StaticAnalyzer/Core/SarifDiagnostics.cpp b/lib/StaticAnalyzer/Core/SarifDiagnostics.cpp index 36046f0cfd..9e9690ca0b 100644 --- a/lib/StaticAnalyzer/Core/SarifDiagnostics.cpp +++ b/lib/StaticAnalyzer/Core/SarifDiagnostics.cpp @@ -257,7 +257,7 @@ static json::Object createResult(const PathDiagnostic &Diag, json::Array &Files, static StringRef getRuleDescription(StringRef CheckName) { return llvm::StringSwitch(CheckName) #define GET_CHECKERS -#define CHECKER(FULLNAME, CLASS, HELPTEXT) \ +#define CHECKER(FULLNAME, CLASS, HELPTEXT, DOC_URI) \ .Case(FULLNAME, HELPTEXT) #include "clang/StaticAnalyzer/Checkers/Checkers.inc" #undef CHECKER @@ -265,12 +265,29 @@ static StringRef getRuleDescription(StringRef CheckName) { ; } +static StringRef getRuleHelpURIStr(StringRef CheckName) { + return llvm::StringSwitch(CheckName) +#define GET_CHECKERS +#define CHECKER(FULLNAME, CLASS, HELPTEXT, DOC_URI) \ + .Case(FULLNAME, DOC_URI) +#include "clang/StaticAnalyzer/Checkers/Checkers.inc" +#undef CHECKER +#undef GET_CHECKERS + ; +} + static json::Object createRule(const PathDiagnostic &Diag) { StringRef CheckName = Diag.getCheckName(); - return json::Object{ + json::Object Ret{ {"fullDescription", createMessage(getRuleDescription(CheckName))}, {"name", createMessage(CheckName)}, {"id", CheckName}}; + + std::string RuleURI = getRuleHelpURIStr(CheckName); + if (!RuleURI.empty()) + Ret["helpURI"] = RuleURI; + + return Ret; } static json::Array createRules(std::vector &Diags, diff --git a/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp b/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp index 86cf62a163..620c0e5889 100644 --- a/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp +++ b/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp @@ -42,8 +42,8 @@ static bool isCompatibleAPIVersion(const char *versionString) { CheckerRegistry::CheckerRegistry(ArrayRef plugins, DiagnosticsEngine &diags) : Diags(diags) { #define GET_CHECKERS -#define CHECKER(FULLNAME, CLASS, HELPTEXT) \ - addChecker(register##CLASS, FULLNAME, HELPTEXT); +#define CHECKER(FULLNAME, CLASS, HELPTEXT, DOC_URI) \ + addChecker(register##CLASS, FULLNAME, HELPTEXT, DOC_URI); #include "clang/StaticAnalyzer/Checkers/Checkers.inc" #undef CHECKER #undef GET_CHECKERS @@ -115,7 +115,7 @@ CheckerRegistry::CheckerInfoSet CheckerRegistry::getEnabledCheckers( for (const std::pair &opt : Opts.CheckersControlList) { // Use a binary search to find the possible start of the package. - CheckerRegistry::CheckerInfo packageInfo(nullptr, opt.first, ""); + CheckerRegistry::CheckerInfo packageInfo(nullptr, opt.first, "", ""); auto firstRelatedChecker = std::lower_bound(Checkers.cbegin(), end, packageInfo, checkerNameLT); @@ -147,13 +147,13 @@ CheckerRegistry::CheckerInfoSet CheckerRegistry::getEnabledCheckers( return enabledCheckers; } -void CheckerRegistry::addChecker(InitializationFunction fn, StringRef name, - StringRef desc) { - Checkers.push_back(CheckerInfo(fn, name, desc)); +void CheckerRegistry::addChecker(InitializationFunction Fn, StringRef Name, + StringRef Desc, StringRef DocsUri) { + Checkers.emplace_back(Fn, Name, Desc, DocsUri); // Record the presence of the checker in its packages. StringRef packageName, leafName; - std::tie(packageName, leafName) = name.rsplit(PackageSeparator); + std::tie(packageName, leafName) = Name.rsplit(PackageSeparator); while (!leafName.empty()) { Packages[packageName] += 1; std::tie(packageName, leafName) = packageName.rsplit(PackageSeparator); diff --git a/test/Analysis/diagnostics/Inputs/expected-sarif/sarif-multi-diagnostic-test.c.sarif b/test/Analysis/diagnostics/Inputs/expected-sarif/sarif-multi-diagnostic-test.c.sarif index 4b581b2e0f..15880baa4e 100644 --- a/test/Analysis/diagnostics/Inputs/expected-sarif/sarif-multi-diagnostic-test.c.sarif +++ b/test/Analysis/diagnostics/Inputs/expected-sarif/sarif-multi-diagnostic-test.c.sarif @@ -29,6 +29,7 @@ "fullDescription": { "text": "Check for logical errors for function calls and Objective-C message expressions (e.g., uninitialized arguments, null function pointers)" }, + "helpURI": "https://clang-analyzer.llvm.org/available_checks.html#core.CallAndMessage", "id": "core.CallAndMessage", "name": { "text": "core.CallAndMessage" @@ -38,6 +39,7 @@ "fullDescription": { "text": "Check for division by zero" }, + "helpURI": "https://clang-analyzer.llvm.org/available_checks.html#core.DivideZero", "id": "core.DivideZero", "name": { "text": "core.DivideZero" diff --git a/utils/TableGen/ClangSACheckersEmitter.cpp b/utils/TableGen/ClangSACheckersEmitter.cpp index e01d55c527..4f20274334 100644 --- a/utils/TableGen/ClangSACheckersEmitter.cpp +++ b/utils/TableGen/ClangSACheckersEmitter.cpp @@ -57,6 +57,36 @@ static std::string getStringValue(const Record &R, StringRef field) { return std::string(); } +// Calculates the integer value representing the BitsInit object +static inline uint64_t getValueFromBitsInit(const BitsInit *B) { + assert(B->getNumBits() <= sizeof(uint64_t) * 8 && "BitInits' too long!"); + + uint64_t Value = 0; + for (unsigned i = 0, e = B->getNumBits(); i != e; ++i) { + const auto *Bit = cast(B->getBit(i)); + Value |= uint64_t(Bit->getValue()) << i; + } + return Value; +} + +static std::string getCheckerDocs(const Record &R) { + StringRef LandingPage; + if (BitsInit *BI = R.getValueAsBitsInit("Documentation")) { + uint64_t V = getValueFromBitsInit(BI); + if (V == 1) + LandingPage = "available_checks.html"; + else if (V == 2) + LandingPage = "alpha_checks.html"; + } + + if (LandingPage.empty()) + return ""; + + return (llvm::Twine("https://clang-analyzer.llvm.org/") + LandingPage + "#" + + getCheckerFullName(&R)) + .str(); +} + namespace clang { void EmitClangSACheckers(RecordKeeper &Records, raw_ostream &OS) { std::vector checkers = Records.getAllDerivedDefinitions("Checker"); @@ -64,6 +94,9 @@ void EmitClangSACheckers(RecordKeeper &Records, raw_ostream &OS) { using SortedRecords = llvm::StringMap; + OS << "// This file is automatically generated. Do not edit this file by " + "hand.\n"; + OS << "\n#ifdef GET_PACKAGES\n"; { SortedRecords sortedPackages; @@ -89,7 +122,10 @@ void EmitClangSACheckers(RecordKeeper &Records, raw_ostream &OS) { OS.write_escaped(getCheckerFullName(&R)) << "\", "; OS << R.getName() << ", "; OS << "\""; - OS.write_escaped(getStringValue(R, "HelpText")) << '\"'; + OS.write_escaped(getStringValue(R, "HelpText")) << "\", "; + OS << "\""; + OS.write_escaped(getCheckerDocs(R)); + OS << "\""; OS << ")\n"; } OS << "#endif // GET_CHECKERS\n\n"; diff --git a/www/analyzer/alpha_checks.html b/www/analyzer/alpha_checks.html index a9a30b2d36..beab87b6b3 100644 --- a/www/analyzer/alpha_checks.html +++ b/www/analyzer/alpha_checks.html @@ -43,10 +43,10 @@ Patches welcome! Name, DescriptionExample - - - - - - - - - - - - @@ -329,12 +329,12 @@ void test(int x) { - - - - - - -
- - - - - - - - @@ -935,7 +935,7 @@ void test() { - + - -
@@ -1037,7 +1037,7 @@ void test() { - - - - void test() { int y = strlen((char *)&test); // warn } - + - co - - - - - - - - - -
- - - - - - - - - - -
 @interface Test : UIViewController
 @end
@@ -891,11 +891,11 @@ that haven't yet adopted this attribute.)
- - - - - - - - - - - - - - - - - - - - - - +rand_r - -
 int test() {
   return strlen(0); // warn
-- 
cgit v1.2.3


From b74c1614cf412f100657fdce3535f4897ebfdbd6 Mon Sep 17 00:00:00 2001
From: Aaron Ballman 
Date: Thu, 20 Dec 2018 20:32:59 +0000
Subject: Fix build failures from r349812 due to a missing argument.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349815 91177308-0d34-0410-b5e6-96231b3b80d8
---
 unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp b/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp
index c18121df17..0dbf3ae451 100644
--- a/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp
+++ b/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp
@@ -59,7 +59,8 @@ public:
     Compiler.getAnalyzerOpts()->CheckersControlList = {
         {"custom.CustomChecker", true}};
     AnalysisConsumer->AddCheckerRegistrationFn([](CheckerRegistry &Registry) {
-      Registry.addChecker("custom.CustomChecker", "Description");
+      Registry.addChecker("custom.CustomChecker", "Description",
+                                         "");
     });
     return std::move(AnalysisConsumer);
   }
-- 
cgit v1.2.3


From ca5c6563fcc86cc39cf50e0c0126c1724efeee1d Mon Sep 17 00:00:00 2001
From: Aaron Ballman 
Date: Thu, 20 Dec 2018 20:35:01 +0000
Subject: Fix the example checker plugin after r349812.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349816 91177308-0d34-0410-b5e6-96231b3b80d8
---
 examples/analyzer-plugin/MainCallChecker.cpp | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/examples/analyzer-plugin/MainCallChecker.cpp b/examples/analyzer-plugin/MainCallChecker.cpp
index adb4e7da30..77316d696d 100644
--- a/examples/analyzer-plugin/MainCallChecker.cpp
+++ b/examples/analyzer-plugin/MainCallChecker.cpp
@@ -45,7 +45,9 @@ void MainCallChecker::checkPreStmt(const CallExpr *CE, CheckerContext &C) const
 // Register plugin!
 extern "C"
 void clang_registerCheckers (CheckerRegistry ®istry) {
-  registry.addChecker("example.MainCallChecker", "Disallows calls to functions called main");
+  registry.addChecker(
+      "example.MainCallChecker", "Disallows calls to functions called main",
+      "");
 }
 
 extern "C"
-- 
cgit v1.2.3


From 3410781dffff51e89751a2494bd8dfe7e7d83541 Mon Sep 17 00:00:00 2001
From: Richard Smith 
Date: Thu, 20 Dec 2018 20:58:53 +0000
Subject: Make the "too many braces in scalar initialization" extension cause
 SFINAE failures.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349820 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/Basic/DiagnosticSemaKinds.td |  2 +-
 test/SemaCXX/cxx0x-initializer-scalars.cpp | 23 +++++++++++++++++++++++
 2 files changed, 24 insertions(+), 1 deletion(-)

diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 9ab263fcfe..91df49b80c 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -4880,7 +4880,7 @@ def warn_braces_around_scalar_init : Warning<
   "braces around scalar initializer">, InGroup>;
 def ext_many_braces_around_scalar_init : ExtWarn<
   "too many braces around scalar initializer">,
-  InGroup>;
+  InGroup>, SFINAEFailure;
 def ext_complex_component_init : Extension<
   "complex initialization specifying real and imaginary components "
   "is an extension">, InGroup>;
diff --git a/test/SemaCXX/cxx0x-initializer-scalars.cpp b/test/SemaCXX/cxx0x-initializer-scalars.cpp
index 90b11f3a9e..a13aa238de 100644
--- a/test/SemaCXX/cxx0x-initializer-scalars.cpp
+++ b/test/SemaCXX/cxx0x-initializer-scalars.cpp
@@ -127,3 +127,26 @@ namespace PR12118 {
     static_assert(sizeof(f({0})) == sizeof(one), "bad overload");
   }
 }
+
+namespace excess_braces_sfinae {
+  using valid = int&;
+  using invalid = float&;
+
+  template valid braces1(decltype(T{0})*);
+  template invalid braces1(...);
+
+  template valid braces2(decltype(T{{0}})*);
+  template invalid braces2(...);
+
+  template valid braces3(decltype(T{{{0}}})*);
+  template invalid braces3(...);
+
+  valid a = braces1(0);
+  invalid b = braces2(0);
+  invalid c = braces3(0);
+
+  struct X { int n; };
+  valid d = braces1(0);
+  valid e = braces2(0);
+  invalid f = braces3(0);
+}
-- 
cgit v1.2.3


From dc3613c1b01d62520ff1a0d96f88657adc9e8fc5 Mon Sep 17 00:00:00 2001
From: Michael Kruse 
Date: Thu, 20 Dec 2018 21:24:54 +0000
Subject: [CodeGen] Generate llvm.loop.parallel_accesses instead of
 llvm.mem.parallel_loop_access metadata.

Instead of generating llvm.mem.parallel_loop_access metadata, generate
llvm.access.group on instructions and llvm.loop.parallel_accesses on
loops. There is one access group per generated loop.

This is clang part of D52116/r349725.

Differential Revision: https://reviews.llvm.org/D52117

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349823 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/CodeGen/CGLoopInfo.cpp                         |  40 ++--
 lib/CodeGen/CGLoopInfo.h                           |   5 +
 .../pragma-loop-safety-imperfectly_nested.cpp      |  32 ++++
 test/CodeGenCXX/pragma-loop-safety-nested.cpp      |  18 +-
 test/CodeGenCXX/pragma-loop-safety-outer.cpp       |  12 +-
 test/CodeGenCXX/pragma-loop-safety.cpp             |  32 ++--
 test/OpenMP/for_codegen.cpp                        |  14 +-
 test/OpenMP/for_simd_codegen.cpp                   |  16 +-
 test/OpenMP/loops_explicit_clauses_codegen.cpp     |  32 ++--
 test/OpenMP/ordered_codegen.cpp                    |  12 +-
 test/OpenMP/parallel_for_simd_codegen.cpp          |  16 +-
 test/OpenMP/schedule_codegen.cpp                   |  84 ++++-----
 test/OpenMP/simd_codegen.cpp                       | 204 ++++++++++-----------
 test/OpenMP/simd_metadata.c                        |  29 +--
 test/OpenMP/target_parallel_for_simd_codegen.cpp   |   2 +-
 test/OpenMP/target_simd_codegen.cpp                |   2 +-
 test/OpenMP/taskloop_simd_codegen.cpp              |  38 ++--
 17 files changed, 326 insertions(+), 262 deletions(-)
 create mode 100644 test/CodeGenCXX/pragma-loop-safety-imperfectly_nested.cpp

diff --git a/lib/CodeGen/CGLoopInfo.cpp b/lib/CodeGen/CGLoopInfo.cpp
index 169ae4fcde..6cbf801ae6 100644
--- a/lib/CodeGen/CGLoopInfo.cpp
+++ b/lib/CodeGen/CGLoopInfo.cpp
@@ -21,7 +21,7 @@ using namespace llvm;
 
 static MDNode *createMetadata(LLVMContext &Ctx, const LoopAttributes &Attrs,
                               const llvm::DebugLoc &StartLoc,
-                              const llvm::DebugLoc &EndLoc) {
+                              const llvm::DebugLoc &EndLoc, MDNode *&AccGroup) {
 
   if (!Attrs.IsParallel && Attrs.VectorizeWidth == 0 &&
       Attrs.InterleaveCount == 0 && Attrs.UnrollCount == 0 &&
@@ -122,6 +122,12 @@ static MDNode *createMetadata(LLVMContext &Ctx, const LoopAttributes &Attrs,
     Args.push_back(MDNode::get(Ctx, Vals));
   }
 
+  if (Attrs.IsParallel) {
+    AccGroup = MDNode::getDistinct(Ctx, {});
+    Args.push_back(MDNode::get(
+        Ctx, {MDString::get(Ctx, "llvm.loop.parallel_accesses"), AccGroup}));
+  }
+
   // Set the first operand to itself.
   MDNode *LoopID = MDNode::get(Ctx, Args);
   LoopID->replaceOperandWith(0, LoopID);
@@ -150,7 +156,8 @@ void LoopAttributes::clear() {
 LoopInfo::LoopInfo(BasicBlock *Header, const LoopAttributes &Attrs,
                    const llvm::DebugLoc &StartLoc, const llvm::DebugLoc &EndLoc)
     : LoopID(nullptr), Header(Header), Attrs(Attrs) {
-  LoopID = createMetadata(Header->getContext(), Attrs, StartLoc, EndLoc);
+  LoopID =
+      createMetadata(Header->getContext(), Attrs, StartLoc, EndLoc, AccGroup);
 }
 
 void LoopInfoStack::push(BasicBlock *Header, const llvm::DebugLoc &StartLoc,
@@ -328,6 +335,21 @@ void LoopInfoStack::pop() {
 }
 
 void LoopInfoStack::InsertHelper(Instruction *I) const {
+  if (I->mayReadOrWriteMemory()) {
+    SmallVector AccessGroups;
+    for (const LoopInfo &AL : Active) {
+      // Here we assume that every loop that has an access group is parallel.
+      if (MDNode *Group = AL.getAccessGroup())
+        AccessGroups.push_back(Group);
+    }
+    MDNode *UnionMD = nullptr;
+    if (AccessGroups.size() == 1)
+      UnionMD = cast(AccessGroups[0]);
+    else if (AccessGroups.size() >= 2)
+      UnionMD = MDNode::get(I->getContext(), AccessGroups);
+    I->setMetadata("llvm.access.group", UnionMD);
+  }
+
   if (!hasInfo())
     return;
 
@@ -343,18 +365,4 @@ void LoopInfoStack::InsertHelper(Instruction *I) const {
       }
     return;
   }
-
-  if (I->mayReadOrWriteMemory()) {
-    SmallVector ParallelLoopIDs;
-    for (const LoopInfo &AL : Active)
-      if (AL.getAttributes().IsParallel)
-        ParallelLoopIDs.push_back(AL.getLoopID());
-
-    MDNode *ParallelMD = nullptr;
-    if (ParallelLoopIDs.size() == 1)
-      ParallelMD = cast(ParallelLoopIDs[0]);
-    else if (ParallelLoopIDs.size() >= 2)
-      ParallelMD = MDNode::get(I->getContext(), ParallelLoopIDs);
-    I->setMetadata("llvm.mem.parallel_loop_access", ParallelMD);
-  }
 }
diff --git a/lib/CodeGen/CGLoopInfo.h b/lib/CodeGen/CGLoopInfo.h
index 466fdc9fed..201cbb7894 100644
--- a/lib/CodeGen/CGLoopInfo.h
+++ b/lib/CodeGen/CGLoopInfo.h
@@ -84,6 +84,9 @@ public:
   /// Get the set of attributes active for this loop.
   const LoopAttributes &getAttributes() const { return Attrs; }
 
+  /// Return this loop's access group or nullptr if it does not have one.
+  llvm::MDNode *getAccessGroup() const { return AccGroup; }
+
 private:
   /// Loop ID metadata.
   llvm::MDNode *LoopID;
@@ -91,6 +94,8 @@ private:
   llvm::BasicBlock *Header;
   /// The attributes for this loop.
   LoopAttributes Attrs;
+  /// The access group for memory accesses parallel to this loop.
+  llvm::MDNode *AccGroup = nullptr;
 };
 
 /// A stack of loop information corresponding to loop nesting levels.
diff --git a/test/CodeGenCXX/pragma-loop-safety-imperfectly_nested.cpp b/test/CodeGenCXX/pragma-loop-safety-imperfectly_nested.cpp
new file mode 100644
index 0000000000..da060f7902
--- /dev/null
+++ b/test/CodeGenCXX/pragma-loop-safety-imperfectly_nested.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm -o - %s | FileCheck %s
+
+// Verify that the outer loop has the llvm.access.group property for the
+// accesses outside and inside the inner loop, even when the inner loop
+// is not perfectly nested.
+void vectorize_imperfectly_nested_test(int *List, int Length) {
+#pragma clang loop vectorize(assume_safety) interleave(disable) unroll(disable)
+  for (int i = 0; i < Length; ++i) {
+    List[i * Length] = 42;
+#pragma clang loop vectorize(assume_safety) interleave(disable) unroll(disable)
+    for (int j = 1; j < Length - 1; ++j)
+      List[i * Length + j] = (i + j) * 2;
+    List[(i + 1) * Length - 1] = 21;
+  }
+}
+
+
+// CHECK: load i32, i32* %Length.addr, align 4, !llvm.access.group ![[ACCESS_GROUP_2:[0-9]+]]
+
+// CHECK: %[[MUL:.+]] = mul nsw i32 %add, 2
+// CHECK: store i32 %[[MUL]], i32* %{{.+}}, !llvm.access.group ![[ACCESS_GROUP_3:[0-9]+]]
+// CHECK: br label %{{.+}}, !llvm.loop ![[INNER_LOOPID:[0-9]+]]
+// CHECK: store i32 21, i32* %{{.+}}, !llvm.access.group ![[ACCESS_GROUP_2]]
+// CHECK: br label %{{.+}}, !llvm.loop ![[OUTER_LOOPID:[0-9]+]]
+
+// CHECK: ![[ACCESS_GROUP_2]] = distinct !{}
+// CHECK: ![[ACCESS_GROUP_LIST_3:[0-9]+]]  = !{![[ACCESS_GROUP_2]], ![[ACCESS_GROUP_4:[0-9]+]]}
+// CHECK: ![[ACCESS_GROUP_4]] = distinct !{}
+// CHECK: ![[INNER_LOOPID]] = distinct !{![[INNER_LOOPID]], {{.*}} ![[PARALLEL_ACCESSES_8:[0-9]+]]}
+// CHECK: ![[PARALLEL_ACCESSES_8]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_4]]}
+// CHECK: ![[OUTER_LOOPID]] = distinct !{![[OUTER_LOOPID]], {{.*}} ![[PARALLEL_ACCESSES_10:[0-9]+]]}
+// CHECK: ![[PARALLEL_ACCESSES_10]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_2]]}
diff --git a/test/CodeGenCXX/pragma-loop-safety-nested.cpp b/test/CodeGenCXX/pragma-loop-safety-nested.cpp
index 4641c953ee..deec06bbc8 100644
--- a/test/CodeGenCXX/pragma-loop-safety-nested.cpp
+++ b/test/CodeGenCXX/pragma-loop-safety-nested.cpp
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm -o - %s | FileCheck %s
 
-// Verify that the inner access is tagged with a parallel_loop_access
-// for the inner and outer loop using a list.
+// Verify that the outer loop has the llvm.access.group property for the
+// accesses outside and inside the inner loop.
 void vectorize_nested_test(int *List, int Length) {
 #pragma clang loop vectorize(assume_safety) interleave(disable) unroll(disable)
   for (int i = 0; i < Length; ++i) {
@@ -11,11 +11,17 @@ void vectorize_nested_test(int *List, int Length) {
   }
 }
 
+
+// CHECK: load i32, i32* %Length.addr, align 4, !llvm.access.group ![[ACCESS_GROUP_2:[0-9]+]]
 // CHECK: %[[MUL:.+]] = mul
-// CHECK: store i32 %[[MUL]], i32* %{{.+}}, !llvm.mem.parallel_loop_access ![[PARALLEL_LIST:[0-9]+]]
+// CHECK: store i32 %[[MUL]], i32* %{{.+}}, !llvm.access.group ![[ACCESS_GROUP_LIST_3:[0-9]+]]
 // CHECK: br label %{{.+}}, !llvm.loop ![[INNER_LOOPID:[0-9]+]]
 // CHECK: br label %{{.+}}, !llvm.loop ![[OUTER_LOOPID:[0-9]+]]
 
-// CHECK: ![[OUTER_LOOPID]] = distinct !{![[OUTER_LOOPID]],
-// CHECK: ![[PARALLEL_LIST]] = !{![[OUTER_LOOPID]], ![[INNER_LOOPID]]}
-// CHECK: ![[INNER_LOOPID]] = distinct !{![[INNER_LOOPID]],
+// CHECK: ![[ACCESS_GROUP_2]] = distinct !{}
+// CHECK: ![[ACCESS_GROUP_LIST_3]] = !{![[ACCESS_GROUP_2]], ![[ACCESS_GROUP_4:[0-9]+]]}
+// CHECK: ![[ACCESS_GROUP_4]] = distinct !{}
+// CHECK: ![[INNER_LOOPID]] = distinct !{![[INNER_LOOPID]], {{.*}} ![[PARALLEL_ACCESSES_8:[0-9]+]]}
+// CHECK: ![[PARALLEL_ACCESSES_8]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_4]]}
+// CHECK: ![[OUTER_LOOPID]] = distinct !{![[OUTER_LOOPID]], {{.*}} ![[PARALLEL_ACCESSES_10:[0-9]+]]}
+// CHECK: ![[PARALLEL_ACCESSES_10]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_2]]}
diff --git a/test/CodeGenCXX/pragma-loop-safety-outer.cpp b/test/CodeGenCXX/pragma-loop-safety-outer.cpp
index 83f534e651..d99b86ffe2 100644
--- a/test/CodeGenCXX/pragma-loop-safety-outer.cpp
+++ b/test/CodeGenCXX/pragma-loop-safety-outer.cpp
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm -o - %s | FileCheck %s
 
-// Verify that the inner access is tagged with a parallel_loop_access
-// for the outer loop.
+// Verify that the outer loop has the inner loop's access in its
+// llvm.loop.parallel_accesses property.
 void vectorize_outer_test(int *List, int Length) {
 #pragma clang loop vectorize(assume_safety) interleave(disable) unroll(disable)
   for (int i = 0; i < Length; i += 2) {
@@ -12,9 +12,11 @@ void vectorize_outer_test(int *List, int Length) {
 }
 
 // CHECK: %[[MUL:.+]] = mul
-// CHECK: store i32 %[[MUL]], i32* %{{.+}}, !llvm.mem.parallel_loop_access ![[OUTER_LOOPID:[0-9]+]]
+// CHECK: store i32 %[[MUL]], i32* %{{.+}}, !llvm.access.group ![[ACCESS_GROUP_2:[0-9]+]]
 // CHECK: br label %{{.+}}, !llvm.loop ![[INNER_LOOPID:[0-9]+]]
-// CHECK: br label %{{.+}}, !llvm.loop ![[OUTER_LOOPID]]
+// CHECK: br label %{{.+}}, !llvm.loop ![[OUTER_LOOPID:[0-9]+]]
 
-// CHECK: ![[OUTER_LOOPID]] = distinct !{![[OUTER_LOOPID]],
+// CHECK: ![[ACCESS_GROUP_2]] = distinct !{}
 // CHECK: ![[INNER_LOOPID]] = distinct !{![[INNER_LOOPID]],
+// CHECK: ![[OUTER_LOOPID]] = distinct !{![[OUTER_LOOPID]], {{.*}} ![[PARALLEL_ACCESSES_9:[0-9]+]]}
+// CHECK: ![[PARALLEL_ACCESSES_9]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_2]]}
diff --git a/test/CodeGenCXX/pragma-loop-safety.cpp b/test/CodeGenCXX/pragma-loop-safety.cpp
index c6ce82737d..c0b10b0a6b 100644
--- a/test/CodeGenCXX/pragma-loop-safety.cpp
+++ b/test/CodeGenCXX/pragma-loop-safety.cpp
@@ -3,19 +3,19 @@
 // Verify assume_safety vectorization is recognized.
 void vectorize_test(int *List, int Length) {
 // CHECK: define {{.*}} @_Z14vectorize_test
-// CHECK: [[LOAD1_IV:.+]] = load i32, i32* [[IV1:[^,]+]], {{.*}}!llvm.mem.parallel_loop_access ![[LOOP1_ID:[0-9]+]]
-// CHECK-NEXT: [[LOAD1_LEN:.+]] = load i32, i32* [[LEN1:.+]], {{.*}}!llvm.mem.parallel_loop_access ![[LOOP1_ID]]
+// CHECK: [[LOAD1_IV:.+]] = load i32, i32* [[IV1:[^,]+]], {{.*}}!llvm.access.group ![[ACCESS_GROUP_2:[0-9]+]]
+// CHECK-NEXT: [[LOAD1_LEN:.+]] = load i32, i32* [[LEN1:.+]], {{.*}}!llvm.access.group ![[ACCESS_GROUP_2]]
 // CHECK-NEXT: [[CMP1:.+]] = icmp slt i32[[LOAD1_IV]],[[LOAD1_LEN]]
 // CHECK-NEXT: br i1[[CMP1]], label %[[LOOP1_BODY:[^,]+]], label %[[LOOP1_END:[^,]+]]
 #pragma clang loop vectorize(assume_safety) interleave(disable) unroll(disable)
   for (int i = 0; i < Length; i++) {
-    // CHECK: [[RHIV1:.+]] = load i32, i32* [[IV1]], {{.*}}!llvm.mem.parallel_loop_access ![[LOOP1_ID]]
+    // CHECK: [[RHIV1:.+]] = load i32, i32* [[IV1]], {{.*}}!llvm.access.group ![[ACCESS_GROUP_2]]
     // CHECK-DAG: [[CALC1:.+]] = mul nsw i32[[RHIV1]], 2
-    // CHECK-DAG: [[SIV1:.+]] = load i32, i32* [[IV1]]{{.*}}!llvm.mem.parallel_loop_access ![[LOOP1_ID]]
+    // CHECK-DAG: [[SIV1:.+]] = load i32, i32* [[IV1]]{{.*}}!llvm.access.group ![[ACCESS_GROUP_2]]
     // CHECK-DAG: [[INDEX1:.+]] = sext i32[[SIV1]] to i64
-    // CHECK-DAG: [[ARRAY1:.+]] = load i32*, i32** [[LIST1:.*]], {{.*}}!llvm.mem.parallel_loop_access ![[LOOP1_ID]]
+    // CHECK-DAG: [[ARRAY1:.+]] = load i32*, i32** [[LIST1:.*]], {{.*}}!llvm.access.group ![[ACCESS_GROUP_2]]
     // CHECK-DAG: [[PTR1:.+]] = getelementptr inbounds i32, i32*[[ARRAY1]], i64[[INDEX1]]
-    // CHECK: store i32[[CALC1]], i32*[[PTR1]], {{.*}}!llvm.mem.parallel_loop_access ![[LOOP1_ID]]
+    // CHECK: store i32[[CALC1]], i32*[[PTR1]], {{.*}}!llvm.access.group ![[ACCESS_GROUP_2]]
     // CHECK-NEXT: br label [[LOOP1_INC:[^,]+]]
     List[i] = i * 2;
 
@@ -26,19 +26,19 @@ void vectorize_test(int *List, int Length) {
 // Verify assume_safety interleaving is recognized.
 void interleave_test(int *List, int Length) {
 // CHECK: define {{.*}} @_Z15interleave_test
-// CHECK: [[LOAD2_IV:.+]] = load i32, i32* [[IV2:[^,]+]], {{.*}}!llvm.mem.parallel_loop_access ![[LOOP2_ID:[0-9]+]]
-// CHECK-NEXT: [[LOAD2_LEN:.+]] = load i32, i32* [[LEN2:.+]], {{.*}}!llvm.mem.parallel_loop_access ![[LOOP2_ID]]
+// CHECK: [[LOAD2_IV:.+]] = load i32, i32* [[IV2:[^,]+]], {{.*}}!llvm.access.group ![[ACCESS_GROUP_8:[0-9]+]]
+// CHECK-NEXT: [[LOAD2_LEN:.+]] = load i32, i32* [[LEN2:.+]], {{.*}}!llvm.access.group ![[ACCESS_GROUP_8]]
 // CHECK-NEXT: [[CMP2:.+]] = icmp slt i32[[LOAD2_IV]],[[LOAD2_LEN]]
 // CHECK-NEXT: br i1[[CMP2]], label %[[LOOP2_BODY:[^,]+]], label %[[LOOP2_END:[^,]+]]
 #pragma clang loop interleave(assume_safety) vectorize(disable) unroll(disable)
   for (int i = 0; i < Length; i++) {
-    // CHECK: [[RHIV2:.+]] = load i32, i32* [[IV2]], {{.*}}!llvm.mem.parallel_loop_access ![[LOOP2_ID]]
+    // CHECK: [[RHIV2:.+]] = load i32, i32* [[IV2]], {{.*}}!llvm.access.group ![[ACCESS_GROUP_8]]
     // CHECK-DAG: [[CALC2:.+]] = mul nsw i32[[RHIV2]], 2
-    // CHECK-DAG: [[SIV2:.+]] = load i32, i32* [[IV2]]{{.*}}!llvm.mem.parallel_loop_access ![[LOOP2_ID]]
+    // CHECK-DAG: [[SIV2:.+]] = load i32, i32* [[IV2]]{{.*}}!llvm.access.group ![[ACCESS_GROUP_8]]
     // CHECK-DAG: [[INDEX2:.+]] = sext i32[[SIV2]] to i64
-    // CHECK-DAG: [[ARRAY2:.+]] = load i32*, i32** [[LIST2:.*]], {{.*}}!llvm.mem.parallel_loop_access ![[LOOP2_ID]]
+    // CHECK-DAG: [[ARRAY2:.+]] = load i32*, i32** [[LIST2:.*]], {{.*}}!llvm.access.group ![[ACCESS_GROUP_8]]
     // CHECK-DAG: [[PTR2:.+]] = getelementptr inbounds i32, i32*[[ARRAY2]], i64[[INDEX2]]
-    // CHECK: store i32[[CALC2]], i32*[[PTR2]], {{.*}}!llvm.mem.parallel_loop_access ![[LOOP2_ID]]
+    // CHECK: store i32[[CALC2]], i32*[[PTR2]], {{.*}}!llvm.access.group ![[ACCESS_GROUP_8]]
     // CHECK-NEXT: br label [[LOOP2_INC:[^,]+]]
     List[i] = i * 2;
 
@@ -46,9 +46,13 @@ void interleave_test(int *List, int Length) {
   }
 }
 
-// CHECK: ![[LOOP1_HINTS]] = distinct !{![[LOOP1_HINTS]], ![[INTERLEAVE_1:[0-9]+]], ![[INTENABLE_1:[0-9]+]], ![[UNROLL_DISABLE:[0-9]+]]}
+// CHECK: ![[ACCESS_GROUP_2]] = distinct !{}
+// CHECK: ![[LOOP1_HINTS]] = distinct !{![[LOOP1_HINTS]], ![[INTERLEAVE_1:[0-9]+]], ![[INTENABLE_1:[0-9]+]], ![[UNROLL_DISABLE:[0-9]+]], ![[PARALLEL_ACCESSES_7:[0-9]+]]}
 // CHECK: ![[INTERLEAVE_1]] = !{!"llvm.loop.interleave.count", i32 1}
 // CHCCK: ![[INTENABLE_1]] = !{!"llvm.loop.vectorize.enable", i1 true}
 // CHECK: ![[UNROLL_DISABLE]] = !{!"llvm.loop.unroll.disable"}
-// CHECK: ![[LOOP2_HINTS]] = distinct !{![[LOOP2_HINTS]], ![[WIDTH_1:[0-9]+]], ![[INTENABLE_1]], ![[UNROLL_DISABLE]]}
+// CHECK: ![[PARALLEL_ACCESSES_7]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_2]]}
+// CHECK: ![[ACCESS_GROUP_8]] = distinct !{}
+// CHECK: ![[LOOP2_HINTS]] = distinct !{![[LOOP2_HINTS]], ![[WIDTH_1:[0-9]+]], ![[INTENABLE_1]], ![[UNROLL_DISABLE]], ![[PARALLEL_ACCESSES_11:[0-9]+]]}
 // CHECK: ![[WIDTH_1]] = !{!"llvm.loop.vectorize.width", i32 1}
+// CHECK: ![[PARALLEL_ACCESSES_11]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_8]]}
diff --git a/test/OpenMP/for_codegen.cpp b/test/OpenMP/for_codegen.cpp
index 364b9f12ea..aab6606d7a 100644
--- a/test/OpenMP/for_codegen.cpp
+++ b/test/OpenMP/for_codegen.cpp
@@ -73,7 +73,7 @@ void without_schedule_clause(float *a, float *b, float *c, float *d) {
 // ... loop body ...
 // End of body: store into a[i]:
 // CHECK: store float [[RESULT:%.+]], float* {{%.+}}
-// CHECK-NOT: !llvm.mem.parallel_loop_access
+// CHECK-NOT: !llvm.access.group
     a[i] = b[i] * c[i] * d[i];
 // CHECK: [[IV1_2:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}
 // CHECK-NEXT: [[ADD1_2:%.+]] = add nsw i32 [[IV1_2]], 1
@@ -114,7 +114,7 @@ void static_not_chunked(float *a, float *b, float *c, float *d) {
 // ... loop body ...
 // End of body: store into a[i]:
 // CHECK: store float [[RESULT:%.+]], float* {{%.+}}
-// CHECK-NOT: !llvm.mem.parallel_loop_access
+// CHECK-NOT: !llvm.access.group
     a[i] = b[i] * c[i] * d[i];
 // CHECK: [[IV1_2:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}
 // CHECK-NEXT: [[ADD1_2:%.+]] = add nsw i32 [[IV1_2]], 1
@@ -163,7 +163,7 @@ void static_chunked(float *a, float *b, float *c, float *d) {
 // ... loop body ...
 // End of body: store into a[i]:
 // CHECK: store float [[RESULT:%.+]], float* {{%.+}}
-// CHECK-NOT: !llvm.mem.parallel_loop_access
+// CHECK-NOT: !llvm.access.group
     a[i] = b[i] * c[i] * d[i];
 // CHECK: [[IV1_2:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}
 // CHECK-NEXT: [[ADD1_2:%.+]] = add i32 [[IV1_2]], 1
@@ -215,7 +215,7 @@ void dynamic1(float *a, float *b, float *c, float *d) {
 // CHECK-NEXT: store i64 [[CALC_I_2]], i64* [[LC_I:.+]]
 // ... loop body ...
 // End of body: store into a[i]:
-// CHECK: store float [[RESULT:%.+]], float* {{%.+}}!llvm.mem.parallel_loop_access
+// CHECK: store float [[RESULT:%.+]], float* {{%.+}}!llvm.access.group
     a[i] = b[i] * c[i] * d[i];
 // CHECK: [[IV1_2:%.+]] = load i64, i64* [[OMP_IV]]{{.*}}
 // CHECK-NEXT: [[ADD1_2:%.+]] = add i64 [[IV1_2]], 1
@@ -256,7 +256,7 @@ void guided7(float *a, float *b, float *c, float *d) {
 // CHECK-NEXT: store i64 [[CALC_I_2]], i64* [[LC_I:.+]]
 // ... loop body ...
 // End of body: store into a[i]:
-// CHECK: store float [[RESULT:%.+]], float* {{%.+}}!llvm.mem.parallel_loop_access
+// CHECK: store float [[RESULT:%.+]], float* {{%.+}}!llvm.access.group
     a[i] = b[i] * c[i] * d[i];
 // CHECK: [[IV1_2:%.+]] = load i64, i64* [[OMP_IV]]{{.*}}
 // CHECK-NEXT: [[ADD1_2:%.+]] = add i64 [[IV1_2]], 1
@@ -301,7 +301,7 @@ void test_auto(float *a, float *b, float *c, float *d) {
 // ... loop body ...
 // End of body: store into a[i]:
 // CHECK: store float [[RESULT:%.+]], float* {{%.+}}
-// CHECK-NOT: !llvm.mem.parallel_loop_access
+// CHECK-NOT: !llvm.access.group
     a[i] = b[i] * c[i] * d[i];
 // CHECK: [[IV1_2:%.+]] = load i64, i64* [[OMP_IV]]{{.*}}
 // CHECK-NEXT: [[ADD1_2:%.+]] = add nsw i64 [[IV1_2]], 1
@@ -343,7 +343,7 @@ void runtime(float *a, float *b, float *c, float *d) {
 // ... loop body ...
 // End of body: store into a[i]:
 // CHECK: store float [[RESULT:%.+]], float* {{%.+}}
-// CHECK-NOT: !llvm.mem.parallel_loop_access
+// CHECK-NOT: !llvm.access.group
     a[i] = b[i] * c[i] * d[i];
 // CHECK: [[IV1_2:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}
 // CHECK-NEXT: [[ADD1_2:%.+]] = add nsw i32 [[IV1_2]], 1
diff --git a/test/OpenMP/for_simd_codegen.cpp b/test/OpenMP/for_simd_codegen.cpp
index 7e540e263b..a4c148e7d2 100644
--- a/test/OpenMP/for_simd_codegen.cpp
+++ b/test/OpenMP/for_simd_codegen.cpp
@@ -73,21 +73,21 @@ void simple(float *a, float *b, float *c, float *d) {
 // CHECK: [[LB_VAL:%.+]] = load i32, i32* [[LB]],
 // CHECK: store i32 [[LB_VAL]], i32* [[OMP_IV2:%[^,]+]],
 
-// CHECK: [[IV2:%.+]] = load i32, i32* [[OMP_IV2]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP2_ID:[0-9]+]]
-// CHECK: [[UB_VAL:%.+]] = load i32, i32* [[UB]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP2_ID]]
+// CHECK: [[IV2:%.+]] = load i32, i32* [[OMP_IV2]]{{.*}}!llvm.access.group
+// CHECK: [[UB_VAL:%.+]] = load i32, i32* [[UB]]{{.*}}!llvm.access.group
 // CHECK-NEXT: [[CMP2:%.+]] = icmp sle i32 [[IV2]], [[UB_VAL]]
 // CHECK-NEXT: br i1 [[CMP2]], label %[[SIMPLE_LOOP2_BODY:.+]], label %[[SIMPLE_LOOP2_END:[^,]+]]
   for (int i = 10; i > 1; i--) {
 // CHECK: [[SIMPLE_LOOP2_BODY]]:
 // Start of body: calculate i from IV:
-// CHECK: [[IV2_0:%.+]] = load i32, i32* [[OMP_IV2]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP2_ID]]
+// CHECK: [[IV2_0:%.+]] = load i32, i32* [[OMP_IV2]]{{.*}}!llvm.access.group
 // FIXME: It is interesting, why the following "mul 1" was not constant folded?
 // CHECK-NEXT: [[IV2_1:%.+]] = mul nsw i32 [[IV2_0]], 1
 // CHECK-NEXT: [[LC_I_1:%.+]] = sub nsw i32 10, [[IV2_1]]
-// CHECK-NEXT: store i32 [[LC_I_1]], i32* {{.+}}, !llvm.mem.parallel_loop_access ![[SIMPLE_LOOP2_ID]]
+// CHECK-NEXT: store i32 [[LC_I_1]], i32* {{.+}}, !llvm.access.group
 //
-// CHECK-NEXT: [[LIN0_1:%.+]] = load i64, i64* [[LIN0]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP2_ID]]
-// CHECK-NEXT: [[IV2_2:%.+]] = load i32, i32* [[OMP_IV2]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP2_ID]]
+// CHECK-NEXT: [[LIN0_1:%.+]] = load i64, i64* [[LIN0]]{{.*}}!llvm.access.group
+// CHECK-NEXT: [[IV2_2:%.+]] = load i32, i32* [[OMP_IV2]]{{.*}}!llvm.access.group
 // CHECK-NEXT: [[LIN_MUL1:%.+]] = mul nsw i32 [[IV2_2]], 3
 // CHECK-NEXT: [[LIN_EXT1:%.+]] = sext i32 [[LIN_MUL1]] to i64
 // CHECK-NEXT: [[LIN_ADD1:%.+]] = add nsw i64 [[LIN0_1]], [[LIN_EXT1]]
@@ -95,9 +95,9 @@ void simple(float *a, float *b, float *c, float *d) {
 // CHECK-NEXT: store i64 [[LIN_ADD1]], i64* [[K_PRIVATIZED:%[^,]+]]
     a[k]++;
     k = k + 3;
-// CHECK: [[IV2_2:%.+]] = load i32, i32* [[OMP_IV2]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP2_ID]]
+// CHECK: [[IV2_2:%.+]] = load i32, i32* [[OMP_IV2]]{{.*}}!llvm.access.group
 // CHECK-NEXT: [[ADD2_2:%.+]] = add nsw i32 [[IV2_2]], 1
-// CHECK-NEXT: store i32 [[ADD2_2]], i32* [[OMP_IV2]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP2_ID]]
+// CHECK-NEXT: store i32 [[ADD2_2]], i32* [[OMP_IV2]]{{.*}}!llvm.access.group
 // br label {{.+}}, !llvm.loop ![[SIMPLE_LOOP2_ID]]
   }
 // CHECK: [[SIMPLE_LOOP2_END]]:
diff --git a/test/OpenMP/loops_explicit_clauses_codegen.cpp b/test/OpenMP/loops_explicit_clauses_codegen.cpp
index 43fbd56b59..5cc69b9df3 100644
--- a/test/OpenMP/loops_explicit_clauses_codegen.cpp
+++ b/test/OpenMP/loops_explicit_clauses_codegen.cpp
@@ -39,18 +39,18 @@ int main(int argc, char **argv) {
       ;
   foo();
 // CHECK: @{{.+}}foo
-// CHECK-NOT: @k{{.+}}!llvm.mem.parallel_loop_access
-// CHECK: i32 @{{.+}}bar{{.+}}!llvm.mem.parallel_loop_access
-// CHECK-NOT: @k{{.+}}!llvm.mem.parallel_loop_access
+// CHECK-NOT: @k{{.+}}!llvm.access.group
+// CHECK: i32 @{{.+}}bar{{.+}}!llvm.access.group
+// CHECK-NOT: @k{{.+}}!llvm.access.group
 // CHECK: sdiv i32
 // CHECK: store i32 %{{.+}}, i32* @k,
 #pragma omp simd linear(k : 2)
   for (k = 0; k < argc; k++)
     bar();
 // CHECK: @{{.+}}foo
-// CHECK-NOT: @k{{.+}}!llvm.mem.parallel_loop_access
-// CHECK: i32 @{{.+}}bar{{.+}}!llvm.mem.parallel_loop_access
-// CHECK-NOT: @k{{.+}}!llvm.mem.parallel_loop_access
+// CHECK-NOT: @k{{.+}}!llvm.access.group
+// CHECK: i32 @{{.+}}bar{{.+}}!llvm.access.group
+// CHECK-NOT: @k{{.+}}!llvm.access.group
 // CHECK: sdiv i32
 // CHECK: store i32 %{{.+}}, i32* @k,
   foo();
@@ -60,9 +60,9 @@ int main(int argc, char **argv) {
      bar() ;
   foo();
 // CHECK: @{{.+}}foo
-// CHECK-NOT: @k{{.+}}!llvm.mem.parallel_loop_access
-// CHECK: i32 @{{.+}}bar{{.+}}!llvm.mem.parallel_loop_access
-// CHECK-NOT: @k{{.+}}!llvm.mem.parallel_loop_access
+// CHECK-NOT: @k{{.+}}!llvm.access.group
+// CHECK: i32 @{{.+}}bar{{.+}}!llvm.access.group
+// CHECK-NOT: @k{{.+}}!llvm.access.group
 // CHECK: sdiv i32
 // CHECK: store i32 %{{.+}}, i32* @k,
 #pragma omp simd
@@ -70,9 +70,9 @@ int main(int argc, char **argv) {
     bar();
   foo();
 // CHECK: @{{.+}}foo
-// CHECK-NOT: @k{{.+}}!llvm.mem.parallel_loop_access
-// CHECK: i32 @{{.+}}bar{{.+}}!llvm.mem.parallel_loop_access
-// CHECK-NOT: @k{{.+}}!llvm.mem.parallel_loop_access
+// CHECK-NOT: @k{{.+}}!llvm.access.group
+// CHECK: i32 @{{.+}}bar{{.+}}!llvm.access.group
+// CHECK-NOT: @k{{.+}}!llvm.access.group
 // CHECK: sdiv i32
 // CHECK: store i32 %{{.+}}, i32* @k,
 #pragma omp simd collapse(2)
@@ -110,7 +110,7 @@ struct S {
 // CHECK: getelementptr inbounds %struct.S, %struct.S* %{{.+}}, i32 0, i32 0
 // CHECK: br i1
 // CHECK-NOT: getelementptr inbounds %struct.S, %struct.S* %{{.+}}, i32 0, i32 0
-// CHECK: i32 @{{.+}}bar{{.+}}!llvm.mem.parallel_loop_access
+// CHECK: i32 @{{.+}}bar{{.+}}!llvm.access.group
 // CHECK-NOT: getelementptr inbounds %struct.S, %struct.S* %{{.+}}, i32 0, i32 0
 // CHECK: add nsw i32 %{{.+}}, 1
 // CHECK: br label {{.+}}, !llvm.loop
@@ -123,7 +123,7 @@ struct S {
 // CHECK: getelementptr inbounds %struct.S, %struct.S* %{{.+}}, i32 0, i32 0
 // CHECK: br i1
 // CHECK-NOT: getelementptr inbounds %struct.S, %struct.S* %{{.+}}, i32 0, i32 0
-// CHECK: i32 @{{.+}}bar{{.+}}!llvm.mem.parallel_loop_access
+// CHECK: i32 @{{.+}}bar{{.+}}!llvm.access.group
 // CHECK-NOT: getelementptr inbounds %struct.S, %struct.S* %{{.+}}, i32 0, i32 0
 // CHECK: add nsw i64 %{{.+}}, 1
 // CHECK: br label {{.+}}, !llvm.loop
@@ -137,7 +137,7 @@ struct S {
 // CHECK-NOT: getelementptr inbounds %struct.S, %struct.S* %{{.+}}, i32 0, i32 0
 // CHECK: br i1
 // CHECK-NOT: getelementptr inbounds %struct.S, %struct.S* %{{.+}}, i32 0, i32 0
-// CHECK: i32 @{{.+}}bar{{.+}}!llvm.mem.parallel_loop_access
+// CHECK: i32 @{{.+}}bar{{.+}}!llvm.access.group
 // CHECK-NOT: getelementptr inbounds %struct.S, %struct.S* %{{.+}}, i32 0, i32 0
 // CHECK: add nsw i32 %{{.+}}, 1
 // CHECK: br label {{.+}}, !llvm.loop
@@ -150,7 +150,7 @@ struct S {
 // CHECK-NOT: getelementptr inbounds %struct.S, %struct.S* %{{.+}}, i32 0, i32 0
 // CHECK: br i1
 // CHECK-NOT: getelementptr inbounds %struct.S, %struct.S* %{{.+}}, i32 0, i32 0
-// CHECK: i32 @{{.+}}bar{{.+}}!llvm.mem.parallel_loop_access
+// CHECK: i32 @{{.+}}bar{{.+}}!llvm.access.group
 // CHECK-NOT: getelementptr inbounds %struct.S, %struct.S* %{{.+}}, i32 0, i32 0
 // CHECK: add nsw i64 %{{.+}}, 1
 // CHECK: br label {{.+}}, !llvm.loop
diff --git a/test/OpenMP/ordered_codegen.cpp b/test/OpenMP/ordered_codegen.cpp
index 8c970dc517..ef7d39dfd0 100644
--- a/test/OpenMP/ordered_codegen.cpp
+++ b/test/OpenMP/ordered_codegen.cpp
@@ -44,7 +44,7 @@ void static_not_chunked(float *a, float *b, float *c, float *d) {
 // ... loop body ...
 // End of body: store into a[i]:
 // CHECK: store float [[RESULT:%.+]], float* {{%.+}}
-// CHECK-NOT: !llvm.mem.parallel_loop_access
+// CHECK-NOT: !llvm.access.group
 // CHECK-NEXT: call void @__kmpc_end_ordered([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]])
 // ... end of ordered region ...
     #pragma omp ordered
@@ -93,7 +93,7 @@ void dynamic1(float *a, float *b, float *c, float *d) {
 // ... loop body ...
 // End of body: store into a[i]:
 // CHECK: store float [[RESULT:%.+]], float* {{%.+}}
-// CHECK-NOT: !llvm.mem.parallel_loop_access
+// CHECK-NOT: !llvm.access.group
 // CHECK-NEXT: call void @__kmpc_end_ordered([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]])
 // ... end of ordered region ...
     #pragma omp ordered threads
@@ -147,7 +147,7 @@ void test_auto(float *a, float *b, float *c, float *d) {
 // ... loop body ...
 // End of body: store into a[i]:
 // CHECK: store float [[RESULT:%.+]], float* {{%.+}}
-// CHECK-NOT: !llvm.mem.parallel_loop_access
+// CHECK-NOT: !llvm.access.group
 // CHECK-NEXT: call void @__kmpc_end_ordered([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]])
 // ... end of ordered region ...
     #pragma omp ordered
@@ -198,7 +198,7 @@ void runtime(float *a, float *b, float *c, float *d) {
 // ... loop body ...
 // End of body: store into a[i]:
 // CHECK: store float [[RESULT:%.+]], float* {{%.+}}
-// CHECK-NOT: !llvm.mem.parallel_loop_access
+// CHECK-NOT: !llvm.access.group
 // CHECK-NEXT: call void @__kmpc_end_ordered([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]])
 // ... end of ordered region ...
     #pragma omp ordered threads
@@ -220,8 +220,8 @@ void runtime(float *a, float *b, float *c, float *d) {
 float f[10];
 // CHECK-LABEL: foo_simd
 void foo_simd(int low, int up) {
-  // CHECK: store float 0.000000e+00, float* %{{.+}}, align {{[0-9]+}}, !llvm.mem.parallel_loop_access !
-  // CHECK-NEXT: call void [[CAP_FUNC:@.+]](i32* %{{.+}}), !llvm.mem.parallel_loop_access !
+  // CHECK: store float 0.000000e+00, float* %{{.+}}, align {{[0-9]+}}, !llvm.access.group !
+  // CHECK-NEXT: call void [[CAP_FUNC:@.+]](i32* %{{.+}}), !llvm.access.group !
 #pragma omp simd
   for (int i = low; i < up; ++i) {
     f[i] = 0.0;
diff --git a/test/OpenMP/parallel_for_simd_codegen.cpp b/test/OpenMP/parallel_for_simd_codegen.cpp
index e8cb651e2b..680d7a3556 100644
--- a/test/OpenMP/parallel_for_simd_codegen.cpp
+++ b/test/OpenMP/parallel_for_simd_codegen.cpp
@@ -83,21 +83,21 @@ void simple(float *a, float *b, float *c, float *d) {
 // CHECK: [[LB_VAL:%.+]] = load i32, i32* [[LB]],
 // CHECK: store i32 [[LB_VAL]], i32* [[OMP_IV2:%[^,]+]],
 
-// CHECK: [[IV2:%.+]] = load i32, i32* [[OMP_IV2]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP2_ID:[0-9]+]]
-// CHECK: [[UB_VAL:%.+]] = load i32, i32* [[UB]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP2_ID]]
+// CHECK: [[IV2:%.+]] = load i32, i32* [[OMP_IV2]]{{.*}}!llvm.access.group
+// CHECK: [[UB_VAL:%.+]] = load i32, i32* [[UB]]{{.*}}!llvm.access.group
 // CHECK-NEXT: [[CMP2:%.+]] = icmp sle i32 [[IV2]], [[UB_VAL]]
 // CHECK-NEXT: br i1 [[CMP2]], label %[[SIMPLE_LOOP2_BODY:.+]], label %[[SIMPLE_LOOP2_END:[^,]+]]
   for (int i = 10; i > 1; i--) {
 // CHECK: [[SIMPLE_LOOP2_BODY]]:
 // Start of body: calculate i from IV:
-// CHECK: [[IV2_0:%.+]] = load i32, i32* [[OMP_IV2]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP2_ID]]
+// CHECK: [[IV2_0:%.+]] = load i32, i32* [[OMP_IV2]]{{.*}}!llvm.access.group
 // FIXME: It is interesting, why the following "mul 1" was not constant folded?
 // CHECK-NEXT: [[IV2_1:%.+]] = mul nsw i32 [[IV2_0]], 1
 // CHECK-NEXT: [[LC_I_1:%.+]] = sub nsw i32 10, [[IV2_1]]
-// CHECK-NEXT: store i32 [[LC_I_1]], i32* {{.+}}, !llvm.mem.parallel_loop_access ![[SIMPLE_LOOP2_ID]]
+// CHECK-NEXT: store i32 [[LC_I_1]], i32* {{.+}}, !llvm.access.group
 //
-// CHECK-NEXT: [[LIN0_1:%.+]] = load i64, i64* [[LIN0]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP2_ID]]
-// CHECK-NEXT: [[IV2_2:%.+]] = load i32, i32* [[OMP_IV2]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP2_ID]]
+// CHECK-NEXT: [[LIN0_1:%.+]] = load i64, i64* [[LIN0]]{{.*}}!llvm.access.group
+// CHECK-NEXT: [[IV2_2:%.+]] = load i32, i32* [[OMP_IV2]]{{.*}}!llvm.access.group
 // CHECK-NEXT: [[LIN_MUL1:%.+]] = mul nsw i32 [[IV2_2]], 3
 // CHECK-NEXT: [[LIN_EXT1:%.+]] = sext i32 [[LIN_MUL1]] to i64
 // CHECK-NEXT: [[LIN_ADD1:%.+]] = add nsw i64 [[LIN0_1]], [[LIN_EXT1]]
@@ -105,9 +105,9 @@ void simple(float *a, float *b, float *c, float *d) {
 // CHECK-NEXT: store i64 [[LIN_ADD1]], i64* [[K_PRIVATIZED:%[^,]+]]
     a[k]++;
     k = k + 3;
-// CHECK: [[IV2_2:%.+]] = load i32, i32* [[OMP_IV2]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP2_ID]]
+// CHECK: [[IV2_2:%.+]] = load i32, i32* [[OMP_IV2]]{{.*}}!llvm.access.group
 // CHECK-NEXT: [[ADD2_2:%.+]] = add nsw i32 [[IV2_2]], 1
-// CHECK-NEXT: store i32 [[ADD2_2]], i32* [[OMP_IV2]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP2_ID]]
+// CHECK-NEXT: store i32 [[ADD2_2]], i32* [[OMP_IV2]]{{.*}}!llvm.access.group
 // br label {{.+}}, !llvm.loop ![[SIMPLE_LOOP2_ID]]
   }
 // CHECK: [[SIMPLE_LOOP2_END]]:
diff --git a/test/OpenMP/schedule_codegen.cpp b/test/OpenMP/schedule_codegen.cpp
index 394eae4a55..f1f40cb1fa 100644
--- a/test/OpenMP/schedule_codegen.cpp
+++ b/test/OpenMP/schedule_codegen.cpp
@@ -5,191 +5,191 @@
 
 int main() {
 // CHECK: @__kmpc_for_static_init
-// CHECK-NOT: !llvm.mem.parallel_loop_access
+// CHECK-NOT: !llvm.access.group
 // CHECK: @__kmpc_for_static_fini
 #pragma omp for
   for(int i = 0; i < 10; ++i);
 // CHECK: @__kmpc_for_static_init
-// CHECK-NOT: !llvm.mem.parallel_loop_access
+// CHECK-NOT: !llvm.access.group
 // CHECK: @__kmpc_for_static_fini
 #pragma omp for simd
   for(int i = 0; i < 10; ++i);
 // CHECK: @__kmpc_for_static_init
-// CHECK-NOT: !llvm.mem.parallel_loop_access
+// CHECK-NOT: !llvm.access.group
 // CHECK: @__kmpc_for_static_fini
 #pragma omp for schedule(static)
   for(int i = 0; i < 10; ++i);
 // CHECK: @__kmpc_for_static_init
-// CHECK-NOT: !llvm.mem.parallel_loop_access
+// CHECK-NOT: !llvm.access.group
 // CHECK: @__kmpc_for_static_fini
 #pragma omp for simd schedule(static)
   for(int i = 0; i < 10; ++i);
 // CHECK: @__kmpc_for_static_init
-// CHECK-NOT: !llvm.mem.parallel_loop_access
+// CHECK-NOT: !llvm.access.group
 // CHECK: @__kmpc_for_static_fini
 #pragma omp for schedule(static, 2)
   for(int i = 0; i < 10; ++i);
 // CHECK: @__kmpc_for_static_init
-// CHECK-NOT: !llvm.mem.parallel_loop_access
+// CHECK-NOT: !llvm.access.group
 // CHECK: @__kmpc_for_static_fini
 #pragma omp for simd schedule(static, 2)
   for(int i = 0; i < 10; ++i);
 // CHECK: @__kmpc_dispatch_init
-// CHECK: !llvm.mem.parallel_loop_access
+// CHECK: !llvm.access.group
 #pragma omp for schedule(auto)
   for(int i = 0; i < 10; ++i);
 // CHECK: @__kmpc_dispatch_init
-// CHECK: !llvm.mem.parallel_loop_access
+// CHECK: !llvm.access.group
 #pragma omp for simd schedule(auto)
   for(int i = 0; i < 10; ++i);
 // CHECK: @__kmpc_dispatch_init
-// CHECK: !llvm.mem.parallel_loop_access
+// CHECK: !llvm.access.group
 #pragma omp for schedule(runtime)
   for(int i = 0; i < 10; ++i);
 // CHECK: @__kmpc_dispatch_init
-// CHECK: !llvm.mem.parallel_loop_access
+// CHECK: !llvm.access.group
 #pragma omp for simd schedule(runtime)
   for(int i = 0; i < 10; ++i);
 // CHECK: @__kmpc_dispatch_init
-// CHECK: !llvm.mem.parallel_loop_access
+// CHECK: !llvm.access.group
 #pragma omp for schedule(guided)
   for(int i = 0; i < 10; ++i);
 // CHECK: @__kmpc_dispatch_init
-// CHECK: !llvm.mem.parallel_loop_access
+// CHECK: !llvm.access.group
 #pragma omp for simd schedule(guided)
   for(int i = 0; i < 10; ++i);
 // CHECK: @__kmpc_dispatch_init
-// CHECK: !llvm.mem.parallel_loop_access
+// CHECK: !llvm.access.group
 #pragma omp for schedule(dynamic)
   for(int i = 0; i < 10; ++i);
 // CHECK: @__kmpc_dispatch_init
-// CHECK: !llvm.mem.parallel_loop_access
+// CHECK: !llvm.access.group
 #pragma omp for simd schedule(dynamic)
   for(int i = 0; i < 10; ++i);
 // CHECK: @__kmpc_for_static_init
-// CHECK-NOT: !llvm.mem.parallel_loop_access
+// CHECK-NOT: !llvm.access.group
 // CHECK: @__kmpc_for_static_fini
 #pragma omp for schedule(monotonic: static)
   for(int i = 0; i < 10; ++i);
 // CHECK: @__kmpc_for_static_init
-// CHECK-NOT: !llvm.mem.parallel_loop_access
+// CHECK-NOT: !llvm.access.group
 // CHECK: @__kmpc_for_static_fini
 #pragma omp for simd schedule(monotonic: static)
   for(int i = 0; i < 10; ++i);
 // CHECK: @__kmpc_for_static_init
-// CHECK-NOT: !llvm.mem.parallel_loop_access
+// CHECK-NOT: !llvm.access.group
 // CHECK: @__kmpc_for_static_fini
 #pragma omp for schedule(monotonic: static, 2)
   for(int i = 0; i < 10; ++i);
 // CHECK: @__kmpc_for_static_init
-// CHECK-NOT: !llvm.mem.parallel_loop_access
+// CHECK-NOT: !llvm.access.group
 // CHECK: @__kmpc_for_static_fini
 #pragma omp for simd schedule(monotonic: static, 2)
   for(int i = 0; i < 10; ++i);
 // CHECK: @__kmpc_dispatch_init
-// CHECK-NOT: !llvm.mem.parallel_loop_access
+// CHECK-NOT: !llvm.access.group
 #pragma omp for schedule(monotonic: auto)
   for(int i = 0; i < 10; ++i);
 // CHECK: @__kmpc_dispatch_init
-// CHECK-NOT: !llvm.mem.parallel_loop_access
+// CHECK-NOT: !llvm.access.group
 #pragma omp for simd schedule(monotonic: auto)
   for(int i = 0; i < 10; ++i);
 // CHECK: @__kmpc_dispatch_init
-// CHECK-NOT: !llvm.mem.parallel_loop_access
+// CHECK-NOT: !llvm.access.group
 #pragma omp for schedule(monotonic: runtime)
   for(int i = 0; i < 10; ++i);
 // CHECK: @__kmpc_dispatch_init
-// CHECK-NOT: !llvm.mem.parallel_loop_access
+// CHECK-NOT: !llvm.access.group
 #pragma omp for simd schedule(monotonic: runtime)
   for(int i = 0; i < 10; ++i);
 // CHECK: @__kmpc_dispatch_init
-// CHECK-NOT: !llvm.mem.parallel_loop_access
+// CHECK-NOT: !llvm.access.group
 #pragma omp for schedule(monotonic: guided)
   for(int i = 0; i < 10; ++i);
 // CHECK: @__kmpc_dispatch_init
-// CHECK-NOT: !llvm.mem.parallel_loop_access
+// CHECK-NOT: !llvm.access.group
 #pragma omp for simd schedule(monotonic: guided)
   for(int i = 0; i < 10; ++i);
 // CHECK: @__kmpc_dispatch_init
-// CHECK-NOT: !llvm.mem.parallel_loop_access
+// CHECK-NOT: !llvm.access.group
 #pragma omp for schedule(monotonic: dynamic)
   for(int i = 0; i < 10; ++i);
 // CHECK: @__kmpc_dispatch_init
-// CHECK-NOT: !llvm.mem.parallel_loop_access
+// CHECK-NOT: !llvm.access.group
 #pragma omp for simd schedule(monotonic: dynamic)
   for(int i = 0; i < 10; ++i);
 // CHECK: @__kmpc_dispatch_init
-// CHECK: !llvm.mem.parallel_loop_access
+// CHECK: !llvm.access.group
 #pragma omp for schedule(nonmonotonic: guided)
   for(int i = 0; i < 10; ++i);
 // CHECK: @__kmpc_dispatch_init
-// CHECK: !llvm.mem.parallel_loop_access
+// CHECK: !llvm.access.group
 #pragma omp for simd schedule(nonmonotonic: guided)
   for(int i = 0; i < 10; ++i);
 // CHECK: @__kmpc_dispatch_init
-// CHECK: !llvm.mem.parallel_loop_access
+// CHECK: !llvm.access.group
 #pragma omp for schedule(nonmonotonic: dynamic)
   for(int i = 0; i < 10; ++i);
 // CHECK: @__kmpc_dispatch_init
-// CHECK: !llvm.mem.parallel_loop_access
+// CHECK: !llvm.access.group
 #pragma omp for simd schedule(nonmonotonic: dynamic)
   for(int i = 0; i < 10; ++i);
 // CHECK: @__kmpc_dispatch_init
-// CHECK-NOT: !llvm.mem.parallel_loop_access
+// CHECK-NOT: !llvm.access.group
 // CHECK: @__kmpc_dispatch_next
 #pragma omp for schedule(static) ordered
   for(int i = 0; i < 10; ++i);
 // CHECK: @__kmpc_dispatch_init
-// CHECK-NOT: !llvm.mem.parallel_loop_access
+// CHECK-NOT: !llvm.access.group
 // CHECK: @__kmpc_dispatch_next
 #pragma omp for simd schedule(static) ordered
   for(int i = 0; i < 10; ++i);
 // CHECK: @__kmpc_dispatch_init
-// CHECK-NOT: !llvm.mem.parallel_loop_access
+// CHECK-NOT: !llvm.access.group
 // CHECK: @__kmpc_dispatch_next
 #pragma omp for schedule(static, 2) ordered(1)
   for(int i = 0; i < 10; ++i);
 // CHECK: @__kmpc_dispatch_init
-// CHECK-NOT: !llvm.mem.parallel_loop_access
+// CHECK-NOT: !llvm.access.group
 // CHECK: @__kmpc_dispatch_next
 #pragma omp for simd schedule(static, 2) ordered
   for(int i = 0; i < 10; ++i);
 // CHECK: @__kmpc_dispatch_init
-// CHECK-NOT: !llvm.mem.parallel_loop_access
+// CHECK-NOT: !llvm.access.group
 // CHECK: @__kmpc_dispatch_next
 #pragma omp for schedule(auto) ordered(1)
   for(int i = 0; i < 10; ++i);
 // CHECK: @__kmpc_dispatch_init
-// CHECK-NOT: !llvm.mem.parallel_loop_access
+// CHECK-NOT: !llvm.access.group
 #pragma omp for simd schedule(auto) ordered
   for(int i = 0; i < 10; ++i);
 // CHECK: @__kmpc_dispatch_init
-// CHECK-NOT: !llvm.mem.parallel_loop_access
+// CHECK-NOT: !llvm.access.group
 // CHECK: @__kmpc_dispatch_next
 #pragma omp for schedule(runtime) ordered
   for(int i = 0; i < 10; ++i);
 // CHECK: @__kmpc_dispatch_init
-// CHECK-NOT: !llvm.mem.parallel_loop_access
+// CHECK-NOT: !llvm.access.group
 // CHECK: @__kmpc_dispatch_next
 #pragma omp for simd schedule(runtime) ordered
   for(int i = 0; i < 10; ++i);
 // CHECK: @__kmpc_dispatch_init
-// CHECK-NOT: !llvm.mem.parallel_loop_access
+// CHECK-NOT: !llvm.access.group
 // CHECK: @__kmpc_dispatch_next
 #pragma omp for schedule(guided) ordered(1)
   for(int i = 0; i < 10; ++i);
 // CHECK: @__kmpc_dispatch_init
-// CHECK-NOT: !llvm.mem.parallel_loop_access
+// CHECK-NOT: !llvm.access.group
 // CHECK: @__kmpc_dispatch_next
 #pragma omp for simd schedule(guided) ordered
   for(int i = 0; i < 10; ++i);
 // CHECK: @__kmpc_dispatch_init
-// CHECK-NOT: !llvm.mem.parallel_loop_access
+// CHECK-NOT: !llvm.access.group
 // CHECK: @__kmpc_dispatch_next
 #pragma omp for schedule(dynamic) ordered(1)
   for(int i = 0; i < 10; ++i);
 // CHECK: @__kmpc_dispatch_init
-// CHECK-NOT: !llvm.mem.parallel_loop_access
+// CHECK-NOT: !llvm.access.group
 // CHECK: @__kmpc_dispatch_next
 #pragma omp for simd schedule(dynamic)
   for(int i = 0; i < 10; ++i);
diff --git a/test/OpenMP/simd_codegen.cpp b/test/OpenMP/simd_codegen.cpp
index 883273099a..9ac71b1dbb 100644
--- a/test/OpenMP/simd_codegen.cpp
+++ b/test/OpenMP/simd_codegen.cpp
@@ -21,23 +21,23 @@ void simple(float *a, float *b, float *c, float *d) {
   #pragma omp simd
 // CHECK: store i32 0, i32* [[OMP_IV:%[^,]+]]
 
-// CHECK: [[IV:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP1_ID:[0-9]+]]
+// CHECK: [[IV:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}!llvm.access.group
 // CHECK-NEXT: [[CMP:%.+]] = icmp slt i32 [[IV]], 6
 // CHECK-NEXT: br i1 [[CMP]], label %[[SIMPLE_LOOP1_BODY:.+]], label %[[SIMPLE_LOOP1_END:[^,]+]]
   for (int i = 3; i < 32; i += 5) {
 // CHECK: [[SIMPLE_LOOP1_BODY]]:
 // Start of body: calculate i from IV:
-// CHECK: [[IV1_1:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP1_ID]]
+// CHECK: [[IV1_1:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}!llvm.access.group
 // CHECK: [[CALC_I_1:%.+]] = mul nsw i32 [[IV1_1]], 5
 // CHECK-NEXT: [[CALC_I_2:%.+]] = add nsw i32 3, [[CALC_I_1]]
-// CHECK-NEXT: store i32 [[CALC_I_2]], i32* [[LC_I:.+]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP1_ID]]
+// CHECK-NEXT: store i32 [[CALC_I_2]], i32* [[LC_I:.+]]{{.*}}!llvm.access.group
 // ... loop body ...
 // End of body: store into a[i]:
-// CHECK: store float [[RESULT:%.+]], float* {{%.+}}{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP1_ID]]
+// CHECK: store float [[RESULT:%.+]], float* {{%.+}}{{.*}}!llvm.access.group
     a[i] = b[i] * c[i] * d[i];
-// CHECK: [[IV1_2:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP1_ID]]
+// CHECK: [[IV1_2:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}!llvm.access.group
 // CHECK-NEXT: [[ADD1_2:%.+]] = add nsw i32 [[IV1_2]], 1
-// CHECK-NEXT: store i32 [[ADD1_2]], i32* [[OMP_IV]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP1_ID]]
+// CHECK-NEXT: store i32 [[ADD1_2]], i32* [[OMP_IV]]{{.*}}!llvm.access.group
 // br label %{{.+}}, !llvm.loop !{{.+}}
   }
 // CHECK: [[SIMPLE_LOOP1_END]]:
@@ -51,20 +51,20 @@ void simple(float *a, float *b, float *c, float *d) {
 // CHECK: [[K0LOAD:%.+]] = load i64, i64* [[K_VAR]]
 // CHECK-NEXT: store i64 [[K0LOAD]], i64* [[LIN0:%[^,]+]]
 
-// CHECK: [[IV2:%.+]] = load i32, i32* [[OMP_IV2]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP2_ID:[0-9]+]]
+// CHECK: [[IV2:%.+]] = load i32, i32* [[OMP_IV2]]{{.*}}!llvm.access.group
 // CHECK-NEXT: [[CMP2:%.+]] = icmp slt i32 [[IV2]], 9
 // CHECK-NEXT: br i1 [[CMP2]], label %[[SIMPLE_LOOP2_BODY:.+]], label %[[SIMPLE_LOOP2_END:[^,]+]]
   for (int i = 10; i > 1; i--) {
 // CHECK: [[SIMPLE_LOOP2_BODY]]:
 // Start of body: calculate i from IV:
-// CHECK: [[IV2_0:%.+]] = load i32, i32* [[OMP_IV2]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP2_ID]]
+// CHECK: [[IV2_0:%.+]] = load i32, i32* [[OMP_IV2]]{{.*}}!llvm.access.group
 // FIXME: It is interesting, why the following "mul 1" was not constant folded?
 // CHECK-NEXT: [[IV2_1:%.+]] = mul nsw i32 [[IV2_0]], 1
 // CHECK-NEXT: [[LC_I_1:%.+]] = sub nsw i32 10, [[IV2_1]]
-// CHECK-NEXT: store i32 [[LC_I_1]], i32* {{.+}}, !llvm.mem.parallel_loop_access ![[SIMPLE_LOOP2_ID]]
+// CHECK-NEXT: store i32 [[LC_I_1]], i32* {{.+}}, !llvm.access.group
 //
-// CHECK-NEXT: [[LIN0_1:%.+]] = load i64, i64* [[LIN0]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP2_ID]]
-// CHECK-NEXT: [[IV2_2:%.+]] = load i32, i32* [[OMP_IV2]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP2_ID]]
+// CHECK-NEXT: [[LIN0_1:%.+]] = load i64, i64* [[LIN0]]{{.*}}!llvm.access.group
+// CHECK-NEXT: [[IV2_2:%.+]] = load i32, i32* [[OMP_IV2]]{{.*}}!llvm.access.group
 // CHECK-NEXT: [[LIN_MUL1:%.+]] = mul nsw i32 [[IV2_2]], 3
 // CHECK-NEXT: [[LIN_EXT1:%.+]] = sext i32 [[LIN_MUL1]] to i64
 // CHECK-NEXT: [[LIN_ADD1:%.+]] = add nsw i64 [[LIN0_1]], [[LIN_EXT1]]
@@ -72,9 +72,9 @@ void simple(float *a, float *b, float *c, float *d) {
 // CHECK-NEXT: store i64 [[LIN_ADD1]], i64* [[K_PRIVATIZED:%[^,]+]]
     a[k]++;
     k = k + 3;
-// CHECK: [[IV2_2:%.+]] = load i32, i32* [[OMP_IV2]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP2_ID]]
+// CHECK: [[IV2_2:%.+]] = load i32, i32* [[OMP_IV2]]{{.*}}!llvm.access.group
 // CHECK-NEXT: [[ADD2_2:%.+]] = add nsw i32 [[IV2_2]], 1
-// CHECK-NEXT: store i32 [[ADD2_2]], i32* [[OMP_IV2]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP2_ID]]
+// CHECK-NEXT: store i32 [[ADD2_2]], i32* [[OMP_IV2]]{{.*}}!llvm.access.group
 // br label {{.+}}, !llvm.loop ![[SIMPLE_LOOP2_ID]]
   }
 // CHECK: [[SIMPLE_LOOP2_END]]:
@@ -101,35 +101,35 @@ void simple(float *a, float *b, float *c, float *d) {
 // CHECK: [[GLIN_LOAD:%.+]] = load double*, double** [[GLIN_VAR:@[^,]+]]
 // CHECK-NEXT: store double* [[GLIN_LOAD]], double** [[GLIN_START:%[^,]+]]
 
-// CHECK: [[IV3:%.+]] = load i64, i64* [[OMP_IV3]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP3_ID:[0-9]+]]
+// CHECK: [[IV3:%.+]] = load i64, i64* [[OMP_IV3]]{{.*}}!llvm.access.group
 // CHECK-NEXT: [[CMP3:%.+]] = icmp ult i64 [[IV3]], 4
 // CHECK-NEXT: br i1 [[CMP3]], label %[[SIMPLE_LOOP3_BODY:.+]], label %[[SIMPLE_LOOP3_END:[^,]+]]
   for (unsigned long long it = 2000; it >= 600; it-=400) {
 // CHECK: [[SIMPLE_LOOP3_BODY]]:
 // Start of body: calculate it from IV:
-// CHECK: [[IV3_0:%.+]] = load i64, i64* [[OMP_IV3]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP3_ID]]
+// CHECK: [[IV3_0:%.+]] = load i64, i64* [[OMP_IV3]]{{.*}}!llvm.access.group
 // CHECK-NEXT: [[LC_IT_1:%.+]] = mul i64 [[IV3_0]], 400
 // CHECK-NEXT: [[LC_IT_2:%.+]] = sub i64 2000, [[LC_IT_1]]
-// CHECK-NEXT: store i64 [[LC_IT_2]], i64* {{.+}}, !llvm.mem.parallel_loop_access ![[SIMPLE_LOOP3_ID]]
+// CHECK-NEXT: store i64 [[LC_IT_2]], i64* {{.+}}, !llvm.access.group
 //
 // Linear start and step are used to calculate current value of the linear variable.
-// CHECK: [[LINSTART:.+]] = load i32, i32* [[LIN_START]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP3_ID]]
-// CHECK: [[LINSTEP:.+]] = load i64, i64* [[LIN_STEP]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP3_ID]]
-// CHECK-NOT: store i32 {{.+}}, i32* [[LIN_VAR]],{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP3_ID]]
-// CHECK: [[GLINSTART:.+]] = load double*, double** [[GLIN_START]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP3_ID]]
-// CHECK-NEXT: [[IV3_1:%.+]] = load i64, i64* [[OMP_IV3]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP3_ID]]
+// CHECK: [[LINSTART:.+]] = load i32, i32* [[LIN_START]]{{.*}}!llvm.access.group
+// CHECK: [[LINSTEP:.+]] = load i64, i64* [[LIN_STEP]]{{.*}}!llvm.access.group
+// CHECK-NOT: store i32 {{.+}}, i32* [[LIN_VAR]],{{.*}}!llvm.access.group
+// CHECK: [[GLINSTART:.+]] = load double*, double** [[GLIN_START]]{{.*}}!llvm.access.group
+// CHECK-NEXT: [[IV3_1:%.+]] = load i64, i64* [[OMP_IV3]]{{.*}}!llvm.access.group
 // CHECK-NEXT: [[MUL:%.+]] = mul i64 [[IV3_1]], 1
 // CHECK: [[GEP:%.+]] = getelementptr{{.*}}[[GLINSTART]]
-// CHECK-NEXT: store double* [[GEP]], double** [[G_PTR_CUR:%[^,]+]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP3_ID]]
+// CHECK-NEXT: store double* [[GEP]], double** [[G_PTR_CUR:%[^,]+]]{{.*}}!llvm.access.group
     *g_ptr++ = 0.0;
-// CHECK: [[GEP_VAL:%.+]] = load double{{.*}}[[G_PTR_CUR]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP3_ID]]
-// CHECK: store double{{.*}}[[GEP_VAL]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP3_ID]]
+// CHECK: [[GEP_VAL:%.+]] = load double{{.*}}[[G_PTR_CUR]]{{.*}}!llvm.access.group
+// CHECK: store double{{.*}}[[GEP_VAL]]{{.*}}!llvm.access.group
     a[it + lin]++;
 // CHECK: [[FLT_INC:%.+]] = fadd float
-// CHECK-NEXT: store float [[FLT_INC]],{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP3_ID]]
-// CHECK: [[IV3_2:%.+]] = load i64, i64* [[OMP_IV3]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP3_ID]]
+// CHECK-NEXT: store float [[FLT_INC]],{{.*}}!llvm.access.group
+// CHECK: [[IV3_2:%.+]] = load i64, i64* [[OMP_IV3]]{{.*}}!llvm.access.group
 // CHECK-NEXT: [[ADD3_2:%.+]] = add i64 [[IV3_2]], 1
-// CHECK-NEXT: store i64 [[ADD3_2]], i64* [[OMP_IV3]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP3_ID]]
+// CHECK-NEXT: store i64 [[ADD3_2]], i64* [[OMP_IV3]]{{.*}}!llvm.access.group
   }
 // CHECK: [[SIMPLE_LOOP3_END]]:
 //
@@ -143,42 +143,42 @@ void simple(float *a, float *b, float *c, float *d) {
   #pragma omp simd
 // CHECK: store i32 0, i32* [[OMP_IV4:%[^,]+]]
 
-// CHECK: [[IV4:%.+]] = load i32, i32* [[OMP_IV4]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP4_ID:[0-9]+]]
+// CHECK: [[IV4:%.+]] = load i32, i32* [[OMP_IV4]]{{.*}}!llvm.access.group
 // CHECK-NEXT: [[CMP4:%.+]] = icmp slt i32 [[IV4]], 4
 // CHECK-NEXT: br i1 [[CMP4]], label %[[SIMPLE_LOOP4_BODY:.+]], label %[[SIMPLE_LOOP4_END:[^,]+]]
   for (short it = 6; it <= 20; it-=-4) {
 // CHECK: [[SIMPLE_LOOP4_BODY]]:
 // Start of body: calculate it from IV:
-// CHECK: [[IV4_0:%.+]] = load i32, i32* [[OMP_IV4]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP4_ID]]
+// CHECK: [[IV4_0:%.+]] = load i32, i32* [[OMP_IV4]]{{.*}}!llvm.access.group
 // CHECK-NEXT: [[LC_IT_1:%.+]] = mul nsw i32 [[IV4_0]], 4
 // CHECK-NEXT: [[LC_IT_2:%.+]] = add nsw i32 6, [[LC_IT_1]]
 // CHECK-NEXT: [[LC_IT_3:%.+]] = trunc i32 [[LC_IT_2]] to i16
-// CHECK-NEXT: store i16 [[LC_IT_3]], i16* {{.+}}, !llvm.mem.parallel_loop_access ![[SIMPLE_LOOP4_ID]]
+// CHECK-NEXT: store i16 [[LC_IT_3]], i16* {{.+}}, !llvm.access.group
 
-// CHECK: [[IV4_2:%.+]] = load i32, i32* [[OMP_IV4]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP4_ID]]
+// CHECK: [[IV4_2:%.+]] = load i32, i32* [[OMP_IV4]]{{.*}}!llvm.access.group
 // CHECK-NEXT: [[ADD4_2:%.+]] = add nsw i32 [[IV4_2]], 1
-// CHECK-NEXT: store i32 [[ADD4_2]], i32* [[OMP_IV4]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP4_ID]]
+// CHECK-NEXT: store i32 [[ADD4_2]], i32* [[OMP_IV4]]{{.*}}!llvm.access.group
   }
 // CHECK: [[SIMPLE_LOOP4_END]]:
 
   #pragma omp simd
 // CHECK: store i32 0, i32* [[OMP_IV5:%[^,]+]]
 
-// CHECK: [[IV5:%.+]] = load i32, i32* [[OMP_IV5]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP5_ID:[0-9]+]]
+// CHECK: [[IV5:%.+]] = load i32, i32* [[OMP_IV5]]{{.*}}!llvm.access.group
 // CHECK-NEXT: [[CMP5:%.+]] = icmp slt i32 [[IV5]], 26
 // CHECK-NEXT: br i1 [[CMP5]], label %[[SIMPLE_LOOP5_BODY:.+]], label %[[SIMPLE_LOOP5_END:[^,]+]]
   for (unsigned char it = 'z'; it >= 'a'; it+=-1) {
 // CHECK: [[SIMPLE_LOOP5_BODY]]:
 // Start of body: calculate it from IV:
-// CHECK: [[IV5_0:%.+]] = load i32, i32* [[OMP_IV5]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP5_ID]]
+// CHECK: [[IV5_0:%.+]] = load i32, i32* [[OMP_IV5]]{{.*}}!llvm.access.group
 // CHECK-NEXT: [[IV5_1:%.+]] = mul nsw i32 [[IV5_0]], 1
 // CHECK-NEXT: [[LC_IT_1:%.+]] = sub nsw i32 122, [[IV5_1]]
 // CHECK-NEXT: [[LC_IT_2:%.+]] = trunc i32 [[LC_IT_1]] to i8
-// CHECK-NEXT: store i8 [[LC_IT_2]], i8* {{.+}}, !llvm.mem.parallel_loop_access ![[SIMPLE_LOOP5_ID]]
+// CHECK-NEXT: store i8 [[LC_IT_2]], i8* {{.+}}, !llvm.access.group
 
-// CHECK: [[IV5_2:%.+]] = load i32, i32* [[OMP_IV5]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP5_ID]]
+// CHECK: [[IV5_2:%.+]] = load i32, i32* [[OMP_IV5]]{{.*}}!llvm.access.group
 // CHECK-NEXT: [[ADD5_2:%.+]] = add nsw i32 [[IV5_2]], 1
-// CHECK-NEXT: store i32 [[ADD5_2]], i32* [[OMP_IV5]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP5_ID]]
+// CHECK-NEXT: store i32 [[ADD5_2]], i32* [[OMP_IV5]]{{.*}}!llvm.access.group
   }
 // CHECK: [[SIMPLE_LOOP5_END]]:
 
@@ -194,23 +194,23 @@ void simple(float *a, float *b, float *c, float *d) {
 // CHECK: store i64 0, i64* [[OMP_IV7:%[^,]+]]
 // CHECK: br label %[[SIMD_LOOP7_COND:[^,]+]]
 // CHECK: [[SIMD_LOOP7_COND]]:
-// CHECK-NEXT: [[IV7:%.+]] = load i64, i64* [[OMP_IV7]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP7_ID:[0-9]+]]
+// CHECK-NEXT: [[IV7:%.+]] = load i64, i64* [[OMP_IV7]]{{.*}}!llvm.access.group
 // CHECK-NEXT: [[CMP7:%.+]] = icmp slt i64 [[IV7]], 7
 // CHECK-NEXT: br i1 [[CMP7]], label %[[SIMPLE_LOOP7_BODY:.+]], label %[[SIMPLE_LOOP7_END:[^,]+]]
   for (long long i = -10; i < 10; i += 3) {
 // CHECK: [[SIMPLE_LOOP7_BODY]]:
 // Start of body: calculate i from IV:
-// CHECK: [[IV7_0:%.+]] = load i64, i64* [[OMP_IV7]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP7_ID]]
+// CHECK: [[IV7_0:%.+]] = load i64, i64* [[OMP_IV7]]{{.*}}!llvm.access.group
 // CHECK-NEXT: [[LC_IT_1:%.+]] = mul nsw i64 [[IV7_0]], 3
 // CHECK-NEXT: [[LC_IT_2:%.+]] = add nsw i64 -10, [[LC_IT_1]]
-// CHECK-NEXT: store i64 [[LC_IT_2]], i64* [[LC:%[^,]+]],{{.+}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP7_ID]]
-// CHECK-NEXT: [[LC_VAL:%.+]] = load i64, i64* [[LC]]{{.+}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP7_ID]]
+// CHECK-NEXT: store i64 [[LC_IT_2]], i64* [[LC:%[^,]+]],{{.+}}!llvm.access.group
+// CHECK-NEXT: [[LC_VAL:%.+]] = load i64, i64* [[LC]]{{.+}}!llvm.access.group
 // CHECK-NEXT: [[CONV:%.+]] = trunc i64 [[LC_VAL]] to i32
-// CHECK-NEXT: store i32 [[CONV]], i32* [[A_PRIV:%[^,]+]],{{.+}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP7_ID]]
+// CHECK-NEXT: store i32 [[CONV]], i32* [[A_PRIV:%[^,]+]],{{.+}}!llvm.access.group
     A = i;
-// CHECK: [[IV7_2:%.+]] = load i64, i64* [[OMP_IV7]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP7_ID]]
+// CHECK: [[IV7_2:%.+]] = load i64, i64* [[OMP_IV7]]{{.*}}!llvm.access.group
 // CHECK-NEXT: [[ADD7_2:%.+]] = add nsw i64 [[IV7_2]], 1
-// CHECK-NEXT: store i64 [[ADD7_2]], i64* [[OMP_IV7]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP7_ID]]
+// CHECK-NEXT: store i64 [[ADD7_2]], i64* [[OMP_IV7]]{{.*}}!llvm.access.group
   }
 // CHECK: [[SIMPLE_LOOP7_END]]:
 // CHECK-NEXT: store i64 11, i64*
@@ -224,22 +224,22 @@ void simple(float *a, float *b, float *c, float *d) {
   #pragma omp simd reduction(*:R)
 // CHECK: br label %[[SIMD_LOOP8_COND:[^,]+]]
 // CHECK: [[SIMD_LOOP8_COND]]:
-// CHECK-NEXT: [[IV8:%.+]] = load i64, i64* [[OMP_IV8]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP8_ID:[0-9]+]]
+// CHECK-NEXT: [[IV8:%.+]] = load i64, i64* [[OMP_IV8]]{{.*}}!llvm.access.group
 // CHECK-NEXT: [[CMP8:%.+]] = icmp slt i64 [[IV8]], 7
 // CHECK-NEXT: br i1 [[CMP8]], label %[[SIMPLE_LOOP8_BODY:.+]], label %[[SIMPLE_LOOP8_END:[^,]+]]
   for (long long i = -10; i < 10; i += 3) {
 // CHECK: [[SIMPLE_LOOP8_BODY]]:
 // Start of body: calculate i from IV:
-// CHECK: [[IV8_0:%.+]] = load i64, i64* [[OMP_IV8]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP8_ID]]
+// CHECK: [[IV8_0:%.+]] = load i64, i64* [[OMP_IV8]]{{.*}}!llvm.access.group
 // CHECK-NEXT: [[LC_IT_1:%.+]] = mul nsw i64 [[IV8_0]], 3
 // CHECK-NEXT: [[LC_IT_2:%.+]] = add nsw i64 -10, [[LC_IT_1]]
-// CHECK-NEXT: store i64 [[LC_IT_2]], i64* [[LC:%[^,]+]],{{.+}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP8_ID]]
-// CHECK-NEXT: [[LC_VAL:%.+]] = load i64, i64* [[LC]]{{.+}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP8_ID]]
-// CHECK: store i32 %{{.+}}, i32* [[R_PRIV]],{{.+}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP8_ID]]
+// CHECK-NEXT: store i64 [[LC_IT_2]], i64* [[LC:%[^,]+]],{{.+}}!llvm.access.group
+// CHECK-NEXT: [[LC_VAL:%.+]] = load i64, i64* [[LC]]{{.+}}!llvm.access.group
+// CHECK: store i32 %{{.+}}, i32* [[R_PRIV]],{{.+}}!llvm.access.group
     R *= i;
-// CHECK: [[IV8_2:%.+]] = load i64, i64* [[OMP_IV8]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP8_ID]]
+// CHECK: [[IV8_2:%.+]] = load i64, i64* [[OMP_IV8]]{{.*}}!llvm.access.group
 // CHECK-NEXT: [[ADD8_2:%.+]] = add nsw i64 [[IV8_2]], 1
-// CHECK-NEXT: store i64 [[ADD8_2]], i64* [[OMP_IV8]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP8_ID]]
+// CHECK-NEXT: store i64 [[ADD8_2]], i64* [[OMP_IV8]]{{.*}}!llvm.access.group
   }
 // CHECK: [[SIMPLE_LOOP8_END]]:
 // CHECK-DAG: [[R_VAL:%.+]] = load i32, i32* [[R]],
@@ -266,26 +266,26 @@ int templ1(T a, T *z) {
 // CHECK-LABEL: define {{.*i32}} @{{.*}}templ1{{.*}}(float {{.+}}, float* {{.+}})
 // CHECK: store i64 0, i64* [[T1_OMP_IV:[^,]+]]
 // ...
-// CHECK: [[IV:%.+]] = load i64, i64* [[T1_OMP_IV]]{{.*}}!llvm.mem.parallel_loop_access ![[T1_ID:[0-9]+]]
+// CHECK: [[IV:%.+]] = load i64, i64* [[T1_OMP_IV]]{{.*}}!llvm.access.group
 // CHECK-NEXT: [[CMP1:%.+]] = icmp slt i64 [[IV]], 16
 // CHECK-NEXT: br i1 [[CMP1]], label %[[T1_BODY:.+]], label %[[T1_END:[^,]+]]
 // CHECK: [[T1_BODY]]:
 // Loop counters i and j updates:
-// CHECK: [[IV1:%.+]] = load i64, i64* [[T1_OMP_IV]]{{.*}}!llvm.mem.parallel_loop_access ![[T1_ID]]
+// CHECK: [[IV1:%.+]] = load i64, i64* [[T1_OMP_IV]]{{.*}}!llvm.access.group
 // CHECK-NEXT: [[I_1:%.+]] = sdiv i64 [[IV1]], 4
 // CHECK-NEXT: [[I_1_MUL1:%.+]] = mul nsw i64 [[I_1]], 1
 // CHECK-NEXT: [[I_1_ADD0:%.+]] = add nsw i64 0, [[I_1_MUL1]]
 // CHECK-NEXT: [[I_2:%.+]] = trunc i64 [[I_1_ADD0]] to i32
-// CHECK-NEXT: store i32 [[I_2]], i32* {{%.+}}{{.*}}!llvm.mem.parallel_loop_access ![[T1_ID]]
-// CHECK: [[IV2:%.+]] = load i64, i64* [[T1_OMP_IV]]{{.*}}!llvm.mem.parallel_loop_access ![[T1_ID]]
+// CHECK-NEXT: store i32 [[I_2]], i32* {{%.+}}{{.*}}!llvm.access.group
+// CHECK: [[IV2:%.+]] = load i64, i64* [[T1_OMP_IV]]{{.*}}!llvm.access.group
 // CHECK-NEXT: [[J_1:%.+]] = srem i64 [[IV2]], 4
 // CHECK-NEXT: [[J_2:%.+]] = mul nsw i64 [[J_1]], 2
 // CHECK-NEXT: [[J_2_ADD0:%.+]] = add nsw i64 0, [[J_2]]
-// CHECK-NEXT: store i64 [[J_2_ADD0]], i64* {{%.+}}{{.*}}!llvm.mem.parallel_loop_access ![[T1_ID]]
+// CHECK-NEXT: store i64 [[J_2_ADD0]], i64* {{%.+}}{{.*}}!llvm.access.group
 // simd.for.inc:
-// CHECK: [[IV3:%.+]] = load i64, i64* [[T1_OMP_IV]]{{.*}}!llvm.mem.parallel_loop_access ![[T1_ID]]
+// CHECK: [[IV3:%.+]] = load i64, i64* [[T1_OMP_IV]]{{.*}}!llvm.access.group
 // CHECK-NEXT: [[INC:%.+]] = add nsw i64 [[IV3]], 1
-// CHECK-NEXT: store i64 [[INC]], i64* [[T1_OMP_IV]]{{.*}}!llvm.mem.parallel_loop_access ![[T1_ID]]
+// CHECK-NEXT: store i64 [[INC]], i64* [[T1_OMP_IV]]{{.*}}!llvm.access.group
 // CHECK-NEXT: br label {{%.+}}
 // CHECK: [[T1_END]]:
 // CHECK: ret i32 0
@@ -338,15 +338,15 @@ void iter_simple(IterDouble ia, IterDouble ib, IterDouble ic) {
 // CHECK: store i32 0, i32* [[IT_OMP_IV:%[^,]+]]
   #pragma omp simd
 
-// CHECK: [[IV:%.+]] = load i32, i32* [[IT_OMP_IV]]{{.+}} !llvm.mem.parallel_loop_access ![[ITER_LOOP_ID:[0-9]+]]
-// CHECK-NEXT: [[LAST_IT:%.+]] = load i32, i32* [[OMP_LAST_IT]]{{.+}}!llvm.mem.parallel_loop_access ![[ITER_LOOP_ID]]
+// CHECK: [[IV:%.+]] = load i32, i32* [[IT_OMP_IV]]{{.+}} !llvm.access.group
+// CHECK-NEXT: [[LAST_IT:%.+]] = load i32, i32* [[OMP_LAST_IT]]{{.+}}!llvm.access.group
 // CHECK-NEXT: [[NUM_IT:%.+]] = add nsw i32 [[LAST_IT]], 1
 // CHECK-NEXT: [[CMP:%.+]] = icmp slt i32 [[IV]], [[NUM_IT]]
 // CHECK-NEXT: br i1 [[CMP]], label %[[IT_BODY:[^,]+]], label %[[IT_END:[^,]+]]
   for (IterDouble i = ia; i < ib; ++i) {
 // CHECK: [[IT_BODY]]:
 // Start of body: calculate i from index:
-// CHECK: [[IV1:%.+]] = load i32, i32* [[IT_OMP_IV]]{{.+}}!llvm.mem.parallel_loop_access ![[ITER_LOOP_ID]]
+// CHECK: [[IV1:%.+]] = load i32, i32* [[IT_OMP_IV]]{{.+}}!llvm.access.group
 // Call of operator+ (i, IV).
 // CHECK: {{%.+}} = invoke {{.+}} @{{.*}}IterDouble{{.*}}
 // ... loop body ...
@@ -354,12 +354,12 @@ void iter_simple(IterDouble ia, IterDouble ib, IterDouble ic) {
 // Float multiply and save result.
 // CHECK: [[MULR:%.+]] = fmul double {{%.+}}, 5.000000e-01
 // CHECK-NEXT: invoke {{.+}} @{{.*}}IterDouble{{.*}}
-// CHECK: store double [[MULR:%.+]], double* [[RESULT_ADDR:%.+]], !llvm.mem.parallel_loop_access ![[ITER_LOOP_ID]]
+// CHECK: store double [[MULR:%.+]], double* [[RESULT_ADDR:%.+]], !llvm.access.group
    ++ic;
 //
-// CHECK: [[IV2:%.+]] = load i32, i32* [[IT_OMP_IV]]{{.+}}!llvm.mem.parallel_loop_access ![[ITER_LOOP_ID]]
+// CHECK: [[IV2:%.+]] = load i32, i32* [[IT_OMP_IV]]{{.+}}!llvm.access.group
 // CHECK-NEXT: [[ADD2:%.+]] = add nsw i32 [[IV2]], 1
-// CHECK-NEXT: store i32 [[ADD2]], i32* [[IT_OMP_IV]]{{.+}}!llvm.mem.parallel_loop_access ![[ITER_LOOP_ID]]
+// CHECK-NEXT: store i32 [[ADD2]], i32* [[IT_OMP_IV]]{{.+}}!llvm.access.group
 // br label %{{.*}}, !llvm.loop ![[ITER_LOOP_ID]]
   }
 // CHECK: [[IT_END]]:
@@ -377,7 +377,7 @@ void collapsed(float *a, float *b, float *c, float *d) {
 //
   #pragma omp simd collapse(4)
 
-// CHECK: [[IV:%.+]] = load i32, i32* [[OMP_IV]]{{.+}}!llvm.mem.parallel_loop_access ![[COLL1_LOOP_ID:[0-9]+]]
+// CHECK: [[IV:%.+]] = load i32, i32* [[OMP_IV]]{{.+}}!llvm.access.group
 // CHECK-NEXT: [[CMP:%.+]] = icmp ult i32 [[IV]], 120
 // CHECK-NEXT: br i1 [[CMP]], label %[[COLL1_BODY:[^,]+]], label %[[COLL1_END:[^,]+]]
   for (i = 1; i < 3; i++) // 2 iterations
@@ -387,25 +387,25 @@ void collapsed(float *a, float *b, float *c, float *d) {
         {
 // CHECK: [[COLL1_BODY]]:
 // Start of body: calculate i from index:
-// CHECK: [[IV1:%.+]] = load i32, i32* [[OMP_IV]]{{.+}}!llvm.mem.parallel_loop_access ![[COLL1_LOOP_ID]]
+// CHECK: [[IV1:%.+]] = load i32, i32* [[OMP_IV]]{{.+}}!llvm.access.group
 // Calculation of the loop counters values.
 // CHECK: [[CALC_I_1:%.+]] = udiv i32 [[IV1]], 60
 // CHECK-NEXT: [[CALC_I_1_MUL1:%.+]] = mul i32 [[CALC_I_1]], 1
 // CHECK-NEXT: [[CALC_I_2:%.+]] = add i32 1, [[CALC_I_1_MUL1]]
 // CHECK-NEXT: store i32 [[CALC_I_2]], i32* [[LC_I:.+]]
-// CHECK: [[IV1_2:%.+]] = load i32, i32* [[OMP_IV]]{{.+}}!llvm.mem.parallel_loop_access ![[COLL1_LOOP_ID]]
+// CHECK: [[IV1_2:%.+]] = load i32, i32* [[OMP_IV]]{{.+}}!llvm.access.group
 // CHECK-NEXT: [[CALC_J_1:%.+]] = udiv i32 [[IV1_2]], 20
 // CHECK-NEXT: [[CALC_J_2:%.+]] = urem i32 [[CALC_J_1]], 3
 // CHECK-NEXT: [[CALC_J_2_MUL1:%.+]] = mul i32 [[CALC_J_2]], 1
 // CHECK-NEXT: [[CALC_J_3:%.+]] = add i32 2, [[CALC_J_2_MUL1]]
 // CHECK-NEXT: store i32 [[CALC_J_3]], i32* [[LC_J:.+]]
-// CHECK: [[IV1_3:%.+]] = load i32, i32* [[OMP_IV]]{{.+}}!llvm.mem.parallel_loop_access ![[COLL1_LOOP_ID]]
+// CHECK: [[IV1_3:%.+]] = load i32, i32* [[OMP_IV]]{{.+}}!llvm.access.group
 // CHECK-NEXT: [[CALC_K_1:%.+]] = udiv i32 [[IV1_3]], 5
 // CHECK-NEXT: [[CALC_K_2:%.+]] = urem i32 [[CALC_K_1]], 4
 // CHECK-NEXT: [[CALC_K_2_MUL1:%.+]] = mul i32 [[CALC_K_2]], 1
 // CHECK-NEXT: [[CALC_K_3:%.+]] = add i32 3, [[CALC_K_2_MUL1]]
 // CHECK-NEXT: store i32 [[CALC_K_3]], i32* [[LC_K:.+]]
-// CHECK: [[IV1_4:%.+]] = load i32, i32* [[OMP_IV]]{{.+}}!llvm.mem.parallel_loop_access ![[COLL1_LOOP_ID]]
+// CHECK: [[IV1_4:%.+]] = load i32, i32* [[OMP_IV]]{{.+}}!llvm.access.group
 // CHECK-NEXT: [[CALC_L_1:%.+]] = urem i32 [[IV1_4]], 5
 // CHECK-NEXT: [[CALC_L_1_MUL1:%.+]] = mul i32 [[CALC_L_1]], 1
 // CHECK-NEXT: [[CALC_L_2:%.+]] = add i32 4, [[CALC_L_1_MUL1]]
@@ -413,12 +413,12 @@ void collapsed(float *a, float *b, float *c, float *d) {
 // CHECK-NEXT: store i16 [[CALC_L_3]], i16* [[LC_L:.+]]
 // ... loop body ...
 // End of body: store into a[i]:
-// CHECK: store float [[RESULT:%.+]], float* [[RESULT_ADDR:%.+]]{{.+}}!llvm.mem.parallel_loop_access ![[COLL1_LOOP_ID]]
+// CHECK: store float [[RESULT:%.+]], float* [[RESULT_ADDR:%.+]]{{.+}}!llvm.access.group
     float res = b[j] * c[k];
     a[i] = res * d[l];
-// CHECK: [[IV2:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}!llvm.mem.parallel_loop_access ![[COLL1_LOOP_ID]]
+// CHECK: [[IV2:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}!llvm.access.group
 // CHECK-NEXT: [[ADD2:%.+]] = add i32 [[IV2]], 1
-// CHECK-NEXT: store i32 [[ADD2]], i32* [[OMP_IV]]{{.*}}!llvm.mem.parallel_loop_access ![[COLL1_LOOP_ID]]
+// CHECK-NEXT: store i32 [[ADD2]], i32* [[OMP_IV]]{{.*}}!llvm.access.group
 // br label %{{[^,]+}}, !llvm.loop ![[COLL1_LOOP_ID]]
 // CHECK: [[COLL1_END]]:
   }
@@ -445,8 +445,8 @@ void widened(float *a, float *b, float *c, float *d) {
 //
   #pragma omp simd collapse(2) private(globalfloat, localint)
 
-// CHECK: [[IV:%.+]] = load i64, i64* [[OMP_IV]]{{.+}}!llvm.mem.parallel_loop_access ![[WIDE1_LOOP_ID:[0-9]+]]
-// CHECK-NEXT: [[LI:%.+]] = load i64, i64* [[OMP_LI:%[^,]+]]{{.+}}!llvm.mem.parallel_loop_access ![[WIDE1_LOOP_ID]]
+// CHECK: [[IV:%.+]] = load i64, i64* [[OMP_IV]]{{.+}}!llvm.access.group
+// CHECK-NEXT: [[LI:%.+]] = load i64, i64* [[OMP_LI:%[^,]+]]{{.+}}!llvm.access.group
 // CHECK-NEXT: [[NUMIT:%.+]] = add nsw i64 [[LI]], 1
 // CHECK-NEXT: [[CMP:%.+]] = icmp slt i64 [[IV]], [[NUMIT]]
 // CHECK-NEXT: br i1 [[CMP]], label %[[WIDE1_BODY:[^,]+]], label %[[WIDE1_END:[^,]+]]
@@ -455,10 +455,10 @@ void widened(float *a, float *b, float *c, float *d) {
   {
 // CHECK: [[WIDE1_BODY]]:
 // Start of body: calculate i from index:
-// CHECK: [[IV1:%.+]] = load i64, i64* [[OMP_IV]]{{.+}}!llvm.mem.parallel_loop_access ![[WIDE1_LOOP_ID]]
+// CHECK: [[IV1:%.+]] = load i64, i64* [[OMP_IV]]{{.+}}!llvm.access.group
 // Calculation of the loop counters values...
 // CHECK: store i32 {{[^,]+}}, i32* [[LC_I:.+]]
-// CHECK: [[IV1_2:%.+]] = load i64, i64* [[OMP_IV]]{{.+}}!llvm.mem.parallel_loop_access ![[WIDE1_LOOP_ID]]
+// CHECK: [[IV1_2:%.+]] = load i64, i64* [[OMP_IV]]{{.+}}!llvm.access.group
 // CHECK: store i16 {{[^,]+}}, i16* [[LC_J:.+]]
 // ... loop body ...
 //
@@ -467,14 +467,14 @@ void widened(float *a, float *b, float *c, float *d) {
     globalfloat = (float)j/i;
     float res = b[j] * c[j];
 // Store into a[i]:
-// CHECK: store float [[RESULT:%.+]], float* [[RESULT_ADDR:%.+]]{{.+}}!llvm.mem.parallel_loop_access ![[WIDE1_LOOP_ID]]
+// CHECK: store float [[RESULT:%.+]], float* [[RESULT_ADDR:%.+]]{{.+}}!llvm.access.group
     a[i] = res * d[i];
 // Then there's a store into private var localint:
-// CHECK: store i32 {{.+}}, i32* [[LOCALINT:%[^,]+]]{{.+}}!llvm.mem.parallel_loop_access ![[WIDE1_LOOP_ID]]
+// CHECK: store i32 {{.+}}, i32* [[LOCALINT:%[^,]+]]{{.+}}!llvm.access.group
     localint = (int)j;
-// CHECK: [[IV2:%.+]] = load i64, i64* [[OMP_IV]]{{.*}}!llvm.mem.parallel_loop_access ![[WIDE1_LOOP_ID]]
+// CHECK: [[IV2:%.+]] = load i64, i64* [[OMP_IV]]{{.*}}!llvm.access.group
 // CHECK-NEXT: [[ADD2:%.+]] = add nsw i64 [[IV2]], 1
-// CHECK-NEXT: store i64 [[ADD2]], i64* [[OMP_IV]]{{.*}}!llvm.mem.parallel_loop_access ![[WIDE1_LOOP_ID]]
+// CHECK-NEXT: store i64 [[ADD2]], i64* [[OMP_IV]]{{.*}}!llvm.access.group
 //
 // br label %{{[^,]+}}, !llvm.loop ![[WIDE1_LOOP_ID]]
 // CHECK: [[WIDE1_END]]:
@@ -505,20 +505,20 @@ void linear(float *a) {
 // CHECK: [[K0LOAD:%.+]] = load i64, i64* [[K_REF]]
 // CHECK-NEXT: store i64 [[K0LOAD]], i64* [[LIN0:%[^,]+]]
 
-// CHECK: [[IV:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP_ID:[0-9]+]]
+// CHECK: [[IV:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}!llvm.access.group
 // CHECK-NEXT: [[CMP2:%.+]] = icmp slt i32 [[IV]], 9
 // CHECK-NEXT: br i1 [[CMP2]], label %[[SIMPLE_LOOP_BODY:.+]], label %[[SIMPLE_LOOP_END:[^,]+]]
   for (int i = 10; i > 1; i--) {
 // CHECK: [[SIMPLE_LOOP_BODY]]:
 // Start of body: calculate i from IV:
-// CHECK: [[IV_0:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP_ID]]
+// CHECK: [[IV_0:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}!llvm.access.group
 // FIXME: It is interesting, why the following "mul 1" was not constant folded?
 // CHECK-NEXT: [[IV_1:%.+]] = mul nsw i32 [[IV_0]], 1
 // CHECK-NEXT: [[LC_I_1:%.+]] = sub nsw i32 10, [[IV_1]]
-// CHECK-NEXT: store i32 [[LC_I_1]], i32* {{.+}}, !llvm.mem.parallel_loop_access ![[SIMPLE_LOOP_ID]]
+// CHECK-NEXT: store i32 [[LC_I_1]], i32* {{.+}}, !llvm.access.group
 //
-// CHECK-NEXT: [[LIN0_1:%.+]] = load i64, i64* [[LIN0]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP_ID]]
-// CHECK-NEXT: [[IV_2:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP_ID]]
+// CHECK-NEXT: [[LIN0_1:%.+]] = load i64, i64* [[LIN0]]{{.*}}!llvm.access.group
+// CHECK-NEXT: [[IV_2:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}!llvm.access.group
 // CHECK-NEXT: [[LIN_MUL1:%.+]] = mul nsw i32 [[IV_2]], 3
 // CHECK-NEXT: [[LIN_EXT1:%.+]] = sext i32 [[LIN_MUL1]] to i64
 // CHECK-NEXT: [[LIN_ADD1:%.+]] = add nsw i64 [[LIN0_1]], [[LIN_EXT1]]
@@ -526,9 +526,9 @@ void linear(float *a) {
 // CHECK-NEXT: store i64 [[LIN_ADD1]], i64* [[K_PRIVATIZED:%[^,]+]]
     a[k]++;
     k = k + 3;
-// CHECK: [[IV_2:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP_ID]]
+// CHECK: [[IV_2:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}!llvm.access.group
 // CHECK-NEXT: [[ADD2_2:%.+]] = add nsw i32 [[IV_2]], 1
-// CHECK-NEXT: store i32 [[ADD2_2]], i32* [[OMP_IV]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP_ID]]
+// CHECK-NEXT: store i32 [[ADD2_2]], i32* [[OMP_IV]]{{.*}}!llvm.access.group
 // br label {{.+}}, !llvm.loop ![[SIMPLE_LOOP_ID]]
   }
 // CHECK: [[SIMPLE_LOOP_END]]:
@@ -550,20 +550,20 @@ void linear(float *a) {
 // CHECK: [[K0LOAD:%.+]] = load i64, i64* [[K_REF]]
 // CHECK-NEXT: store i64 [[K0LOAD]], i64* [[LIN0:%[^,]+]]
 
-// CHECK: [[IV:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP_ID:[0-9]+]]
+// CHECK: [[IV:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}!llvm.access.group
 // CHECK-NEXT: [[CMP2:%.+]] = icmp slt i32 [[IV]], 9
 // CHECK-NEXT: br i1 [[CMP2]], label %[[SIMPLE_LOOP_BODY:.+]], label %[[SIMPLE_LOOP_END:[^,]+]]
   for (int i = 10; i > 1; i--) {
 // CHECK: [[SIMPLE_LOOP_BODY]]:
 // Start of body: calculate i from IV:
-// CHECK: [[IV_0:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP_ID]]
+// CHECK: [[IV_0:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}!llvm.access.group
 // FIXME: It is interesting, why the following "mul 1" was not constant folded?
 // CHECK-NEXT: [[IV_1:%.+]] = mul nsw i32 [[IV_0]], 1
 // CHECK-NEXT: [[LC_I_1:%.+]] = sub nsw i32 10, [[IV_1]]
-// CHECK-NEXT: store i32 [[LC_I_1]], i32* {{.+}}, !llvm.mem.parallel_loop_access ![[SIMPLE_LOOP_ID]]
+// CHECK-NEXT: store i32 [[LC_I_1]], i32* {{.+}}, !llvm.access.group
 //
-// CHECK-NEXT: [[LIN0_1:%.+]] = load i64, i64* [[LIN0]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP_ID]]
-// CHECK-NEXT: [[IV_2:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP_ID]]
+// CHECK-NEXT: [[LIN0_1:%.+]] = load i64, i64* [[LIN0]]{{.*}}!llvm.access.group
+// CHECK-NEXT: [[IV_2:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}!llvm.access.group
 // CHECK-NEXT: [[LIN_MUL1:%.+]] = mul nsw i32 [[IV_2]], 3
 // CHECK-NEXT: [[LIN_EXT1:%.+]] = sext i32 [[LIN_MUL1]] to i64
 // CHECK-NEXT: [[LIN_ADD1:%.+]] = add nsw i64 [[LIN0_1]], [[LIN_EXT1]]
@@ -571,9 +571,9 @@ void linear(float *a) {
 // CHECK-NEXT: store i64 [[LIN_ADD1]], i64* [[K_PRIVATIZED:%[^,]+]]
     a[k]++;
     k = k + 3;
-// CHECK: [[IV_2:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP_ID]]
+// CHECK: [[IV_2:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}!llvm.access.group
 // CHECK-NEXT: [[ADD2_2:%.+]] = add nsw i32 [[IV_2]], 1
-// CHECK-NEXT: store i32 [[ADD2_2]], i32* [[OMP_IV]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP_ID]]
+// CHECK-NEXT: store i32 [[ADD2_2]], i32* [[OMP_IV]]{{.*}}!llvm.access.group
 // br label {{.+}}, !llvm.loop ![[SIMPLE_LOOP_ID]]
   }
 // CHECK: [[SIMPLE_LOOP_END]]:
@@ -591,20 +591,20 @@ void linear(float *a) {
 // CHECK: [[K0LOAD:%.+]] = load i64, i64* [[VAL_ADDR]]
 // CHECK-NEXT: store i64 [[K0LOAD]], i64* [[LIN0:%[^,]+]]
 
-// CHECK: [[IV:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP_ID:[0-9]+]]
+// CHECK: [[IV:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}!llvm.access.group
 // CHECK-NEXT: [[CMP2:%.+]] = icmp slt i32 [[IV]], 9
 // CHECK-NEXT: br i1 [[CMP2]], label %[[SIMPLE_LOOP_BODY:.+]], label %[[SIMPLE_LOOP_END:[^,]+]]
   for (int i = 10; i > 1; i--) {
 // CHECK: [[SIMPLE_LOOP_BODY]]:
 // Start of body: calculate i from IV:
-// CHECK: [[IV_0:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP_ID]]
+// CHECK: [[IV_0:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}!llvm.access.group
 // FIXME: It is interesting, why the following "mul 1" was not constant folded?
 // CHECK-NEXT: [[IV_1:%.+]] = mul nsw i32 [[IV_0]], 1
 // CHECK-NEXT: [[LC_I_1:%.+]] = sub nsw i32 10, [[IV_1]]
-// CHECK-NEXT: store i32 [[LC_I_1]], i32* {{.+}}, !llvm.mem.parallel_loop_access ![[SIMPLE_LOOP_ID]]
+// CHECK-NEXT: store i32 [[LC_I_1]], i32* {{.+}}, !llvm.access.group
 //
-// CHECK-NEXT: [[LIN0_1:%.+]] = load i64, i64* [[LIN0]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP_ID]]
-// CHECK-NEXT: [[IV_2:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP_ID]]
+// CHECK-NEXT: [[LIN0_1:%.+]] = load i64, i64* [[LIN0]]{{.*}}!llvm.access.group
+// CHECK-NEXT: [[IV_2:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}!llvm.access.group
 // CHECK-NEXT: [[LIN_MUL1:%.+]] = mul nsw i32 [[IV_2]], 3
 // CHECK-NEXT: [[LIN_EXT1:%.+]] = sext i32 [[LIN_MUL1]] to i64
 // CHECK-NEXT: [[LIN_ADD1:%.+]] = add nsw i64 [[LIN0_1]], [[LIN_EXT1]]
@@ -612,9 +612,9 @@ void linear(float *a) {
 // CHECK-NEXT: store i64 [[LIN_ADD1]], i64* [[K_PRIVATIZED:%[^,]+]]
     a[k]++;
     k = k + 3;
-// CHECK: [[IV_2:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP_ID]]
+// CHECK: [[IV_2:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}!llvm.access.group
 // CHECK-NEXT: [[ADD2_2:%.+]] = add nsw i32 [[IV_2]], 1
-// CHECK-NEXT: store i32 [[ADD2_2]], i32* [[OMP_IV]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP_ID]]
+// CHECK-NEXT: store i32 [[ADD2_2]], i32* [[OMP_IV]]{{.*}}!llvm.access.group
 // br label {{.+}}, !llvm.loop ![[SIMPLE_LOOP_ID]]
   }
 // CHECK: [[SIMPLE_LOOP_END]]:
@@ -635,7 +635,7 @@ void parallel_simd(float *a) {
 #pragma omp simd
   // TERM_DEBUG-NOT: __kmpc_global_thread_num
   // TERM_DEBUG:     invoke i32 {{.*}}bar{{.*}}()
-  // TERM_DEBUG:     unwind label %[[TERM_LPAD:.+]],
+  // TERM_DEBUG:     unwind label %[[TERM_LPAD:[^,]+]],
   // TERM_DEBUG-NOT: __kmpc_global_thread_num
   // TERM_DEBUG:     [[TERM_LPAD]]
   // TERM_DEBUG:     call void @__clang_call_terminate
diff --git a/test/OpenMP/simd_metadata.c b/test/OpenMP/simd_metadata.c
index 8fdc306930..44a7e901a0 100644
--- a/test/OpenMP/simd_metadata.c
+++ b/test/OpenMP/simd_metadata.c
@@ -49,8 +49,8 @@ void h1(float *c, float *a, double b[], int size)
     c[i] = a[i] * a[i] + b[i] * b[t];
     ++t;
   }
-// do not emit parallel_loop_access metadata due to usage of safelen clause.
-// CHECK-NOT: store float {{.+}}, float* {{.+}}, align {{.+}}, !llvm.mem.parallel_loop_access {{![0-9]+}}
+// do not emit llvm.access.group metadata due to usage of safelen clause.
+// CHECK-NOT: store float {{.+}}, float* {{.+}}, align {{.+}}, !llvm.access.group {{![0-9]+}}
 #pragma omp simd safelen(16) linear(t) aligned(c:32) aligned(a,b) simdlen(8)
 // CHECK:         [[C_PTRINT:%.+]] = ptrtoint
 // CHECK-NEXT:    [[C_MASKEDPTR:%.+]] = and i{{[0-9]+}} [[C_PTRINT]], 31
@@ -80,8 +80,8 @@ void h1(float *c, float *a, double b[], int size)
     c[i] = a[i] * a[i] + b[i] * b[t];
     ++t;
   }
-// do not emit parallel_loop_access metadata due to usage of safelen clause.
-// CHECK-NOT: store float {{.+}}, float* {{.+}}, align {{.+}}, !llvm.mem.parallel_loop_access {{![0-9]+}}
+// do not emit llvm.access.group metadata due to usage of safelen clause.
+// CHECK-NOT: store float {{.+}}, float* {{.+}}, align {{.+}}, !llvm.access.group {{![0-9]+}}
 #pragma omp simd linear(t) aligned(c:32) aligned(a,b) simdlen(8)
 // CHECK:         [[C_PTRINT:%.+]] = ptrtoint
 // CHECK-NEXT:    [[C_MASKEDPTR:%.+]] = and i{{[0-9]+}} [[C_PTRINT]], 31
@@ -110,7 +110,7 @@ void h1(float *c, float *a, double b[], int size)
   for (int i = 0; i < size; ++i) {
     c[i] = a[i] * a[i] + b[i] * b[t];
     ++t;
-// CHECK: store float {{.+}}, float* {{.+}}, align {{.+}}, !llvm.mem.parallel_loop_access {{![0-9]+}}
+// CHECK: store float {{.+}}, float* {{.+}}, align {{.+}}, !llvm.access.group ![[ACCESS_GROUP_7:[0-9]+]]
   }
 }
 
@@ -122,8 +122,9 @@ void h2(float *c, float *a, float *b, int size)
   for (int i = 0; i < size; ++i) {
     c[i] = a[i] * a[i] + b[i] * b[t];
     ++t;
-// CHECK: store float {{.+}}, float* {{.+}}, align {{.+}}, !llvm.mem.parallel_loop_access [[LOOP_H2_HEADER:![0-9]+]]
+// CHECK: store float {{.+}}, float* {{.+}}, align {{.+}}, !llvm.access.group ![[ACCESS_GROUP_10:[0-9]+]]
   }
+// CHECK: br label %{{.+}}, !llvm.loop [[LOOP_H2_HEADER:![0-9]+]]
 }
 
 void h3(float *c, float *a, float *b, int size)
@@ -134,9 +135,9 @@ void h3(float *c, float *a, float *b, int size)
     for (int j = 0; j < size; ++j) {
       c[j*i] = a[i] * b[j];
     }
+// CHECK: store float {{.+}}, float* {{.+}}, align {{.+}}, !llvm.access.group ![[ACCESS_GROUP_13:[0-9]+]]
   }
-// do not emit parallel_loop_access for nested loop.
-// CHECK-NOT: store float {{.+}}, float* {{.+}}, align {{.+}}, !llvm.mem.parallel_loop_access {{![0-9]+}}
+// CHECK: br label %{{.+}}, !llvm.loop [[LOOP_H3_HEADER:![0-9]+]]
 }
 
 // Metadata for h1:
@@ -145,11 +146,17 @@ void h3(float *c, float *a, float *b, int size)
 // CHECK: [[LOOP_VEC_ENABLE]] = !{!"llvm.loop.vectorize.enable", i1 true}
 // CHECK: [[LOOP_H1_HEADER:![0-9]+]] = distinct !{[[LOOP_H1_HEADER]], [[LOOP_WIDTH_8:![0-9]+]], [[LOOP_VEC_ENABLE]]}
 // CHECK: [[LOOP_WIDTH_8]] = !{!"llvm.loop.vectorize.width", i32 8}
-// CHECK: [[LOOP_H1_HEADER:![0-9]+]] = distinct !{[[LOOP_H1_HEADER]], [[LOOP_WIDTH_8]], [[LOOP_VEC_ENABLE]]}
+// CHECK: ![[ACCESS_GROUP_7]] = distinct !{}
+// CHECK: [[LOOP_H1_HEADER:![0-9]+]] = distinct !{[[LOOP_H1_HEADER]], [[LOOP_WIDTH_8]], [[LOOP_VEC_ENABLE]], ![[PARALLEL_ACCESSES_9:[0-9]+]]}
+// CHECK: ![[PARALLEL_ACCESSES_9]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_7]]}
 //
 // Metadata for h2:
-// CHECK: [[LOOP_H2_HEADER]] = distinct !{[[LOOP_H2_HEADER]], [[LOOP_VEC_ENABLE]]}
+// CHECK: ![[ACCESS_GROUP_10]] = distinct !{}
+// CHECK: [[LOOP_H2_HEADER]] = distinct !{[[LOOP_H2_HEADER]], [[LOOP_VEC_ENABLE]], ![[PARALLEL_ACCESSES_12:[0-9]+]]}
+// CHECK: ![[PARALLEL_ACCESSES_12]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_10]]}
 //
 // Metadata for h3:
-// CHECK: [[LOOP_H3_HEADER:![0-9]+]] = distinct !{[[LOOP_H3_HEADER]], [[LOOP_VEC_ENABLE]]}
+// CHECK: ![[ACCESS_GROUP_13]] = distinct !{}
+// CHECK: [[LOOP_H3_HEADER]] = distinct !{[[LOOP_H3_HEADER]], [[LOOP_VEC_ENABLE]], ![[PARALLEL_ACCESSES_15:[0-9]+]]}
+// CHECK: ![[PARALLEL_ACCESSES_15]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_13]]}
 //
diff --git a/test/OpenMP/target_parallel_for_simd_codegen.cpp b/test/OpenMP/target_parallel_for_simd_codegen.cpp
index f77eb72276..ce0851c65a 100644
--- a/test/OpenMP/target_parallel_for_simd_codegen.cpp
+++ b/test/OpenMP/target_parallel_for_simd_codegen.cpp
@@ -367,7 +367,7 @@ int foo(int n) {
 // CHECK-64:    [[AA_CADDR:%.+]] = bitcast i[[SZ]]* [[AA_ADDR]] to i32*
 // CHECK-64:    [[AA:%.+]] = load i32, i32* [[AA_CADDR]], align
 // CHECK-32:    [[AA:%.+]] = load i32, i32* [[AA_ADDR]], align
-// CHECK:       !llvm.mem.parallel_loop_access
+// CHECK:       !llvm.access.group
 // CHECK:       !llvm.loop
 // CHECK:       ret void
 // CHECK-NEXT:  }
diff --git a/test/OpenMP/target_simd_codegen.cpp b/test/OpenMP/target_simd_codegen.cpp
index 81ad403804..13504213c5 100644
--- a/test/OpenMP/target_simd_codegen.cpp
+++ b/test/OpenMP/target_simd_codegen.cpp
@@ -342,7 +342,7 @@ int foo(int n) {
 // CHECK-64:    [[AA_CADDR:%.+]] = bitcast i[[SZ]]* [[AA_ADDR]] to i32*
 // CHECK-64:    [[AA:%.+]] = load i32, i32* [[AA_CADDR]], align
 // CHECK-32:    [[AA:%.+]] = load i32, i32* [[AA_ADDR]], align
-// CHECK:       !llvm.mem.parallel_loop_access
+// CHECK:       !llvm.access.group
 // CHECK:       !llvm.loop
 // CHECK:       ret void
 // CHECK-NEXT:  }
diff --git a/test/OpenMP/taskloop_simd_codegen.cpp b/test/OpenMP/taskloop_simd_codegen.cpp
index 4da4eb85f4..4c84eccb4f 100644
--- a/test/OpenMP/taskloop_simd_codegen.cpp
+++ b/test/OpenMP/taskloop_simd_codegen.cpp
@@ -83,17 +83,17 @@ int main(int argc, char **argv) {
 // CHECK: [[LB_I32:%.+]] = trunc i64 [[LB_VAL]] to i32
 // CHECK: store i32 [[LB_I32]], i32* [[CNT:%.+]],
 // CHECK: br label
-// CHECK: [[VAL:%.+]] = load i32, i32* [[CNT]],{{.*}}!llvm.mem.parallel_loop_access [[LOOP1:!.+]]
+// CHECK: [[VAL:%.+]] = load i32, i32* [[CNT]],{{.*}}!llvm.access.group
 // CHECK: [[VAL_I64:%.+]] = sext i32 [[VAL]] to i64
-// CHECK: [[UB_VAL:%.+]] = load i64, i64* [[UB]],{{.*}}!llvm.mem.parallel_loop_access [[LOOP1]]
+// CHECK: [[UB_VAL:%.+]] = load i64, i64* [[UB]],{{.*}}!llvm.access.group
 // CHECK: [[CMP:%.+]] = icmp ule i64 [[VAL_I64]], [[UB_VAL]]
 // CHECK: br i1 [[CMP]], label %{{.+}}, label %{{.+}}
-// CHECK: load i32, i32* %{{.*}}!llvm.mem.parallel_loop_access [[LOOP1]]
-// CHECK: store i32 %{{.*}}!llvm.mem.parallel_loop_access [[LOOP1]]
-// CHECK: load i32, i32* %{{.*}}!llvm.mem.parallel_loop_access [[LOOP1]]
+// CHECK: load i32, i32* %{{.*}}!llvm.access.group
+// CHECK: store i32 %{{.*}}!llvm.access.group
+// CHECK: load i32, i32* %{{.*}}!llvm.access.group
 // CHECK: add nsw i32 %{{.+}}, 1
-// CHECK: store i32 %{{.+}}, i32* %{{.*}}!llvm.mem.parallel_loop_access [[LOOP1]]
-// CHECK: br label %{{.*}}!llvm.loop [[LOOP1]]
+// CHECK: store i32 %{{.+}}, i32* %{{.*}}!llvm.access.group
+// CHECK: br label %{{.*}}!llvm.loop
 // CHECK: ret i32 0
 
 // CHECK: define internal i32 [[TASK2]](
@@ -113,17 +113,17 @@ int main(int argc, char **argv) {
 // CHECK: [[LB_I32:%.+]] = trunc i64 [[LB_VAL]] to i32
 // CHECK: store i32 [[LB_I32]], i32* [[CNT:%.+]],
 // CHECK: br label
-// CHECK: [[VAL:%.+]] = load i32, i32* [[CNT]],{{.*}}!llvm.mem.parallel_loop_access [[LOOP2:!.+]]
+// CHECK: [[VAL:%.+]] = load i32, i32* [[CNT]],{{.*}}!llvm.access.group
 // CHECK: [[VAL_I64:%.+]] = sext i32 [[VAL]] to i64
-// CHECK: [[UB_VAL:%.+]] = load i64, i64* [[UB]],{{.*}}!llvm.mem.parallel_loop_access [[LOOP2]]
+// CHECK: [[UB_VAL:%.+]] = load i64, i64* [[UB]],{{.*}}!llvm.access.group
 // CHECK: [[CMP:%.+]] = icmp ule i64 [[VAL_I64]], [[UB_VAL]]
 // CHECK: br i1 [[CMP]], label %{{.+}}, label %{{.+}}
-// CHECK: load i32, i32* %{{.*}}!llvm.mem.parallel_loop_access [[LOOP2]]
-// CHECK: store i32 %{{.*}}!llvm.mem.parallel_loop_access [[LOOP2]]
-// CHECK: load i32, i32* %{{.*}}!llvm.mem.parallel_loop_access [[LOOP2]]
+// CHECK: load i32, i32* %{{.*}}!llvm.access.group
+// CHECK: store i32 %{{.*}}!llvm.access.group
+// CHECK: load i32, i32* %{{.*}}!llvm.access.group
 // CHECK: add nsw i32 %{{.+}}, 1
-// CHECK: store i32 %{{.+}}, i32* %{{.*}}!llvm.mem.parallel_loop_access [[LOOP2]]
-// CHECK: br label %{{.*}}!llvm.loop [[LOOP2]]
+// CHECK: store i32 %{{.+}}, i32* %{{.*}}!llvm.access.group
+// CHECK: br label %{{.*}}!llvm.loop
 // CHECK: ret i32 0
 
 // CHECK: define internal i32 [[TASK3]](
@@ -142,7 +142,7 @@ int main(int argc, char **argv) {
 // CHECK: [[LB_VAL:%.+]] = load i64, i64* [[LB]],
 // CHECK: store i64 [[LB_VAL]], i64* [[CNT:%.+]],
 // CHECK: br label
-// CHECK-NOT: !llvm.mem.parallel_loop_access
+// CHECK-NOT: !llvm.access.group
 // CHECK: br label %{{.*}}!llvm.loop
 // CHECK: ret i32 0
 
@@ -192,14 +192,14 @@ struct S {
 // CHECK: [[CMP:%.+]] = icmp ule i64 [[VAL_I64]], [[UB_VAL]]
 // CHECK: br i1 [[CMP]], label %{{.+}}, label %{{.+}}
 // CHECK: load i32, i32* %
-// CHECK-NOT: !llvm.mem.parallel_loop_access
+// CHECK-NOT: !llvm.access.group
 // CHECK: store i32 %
-// CHECK-NOT: !llvm.mem.parallel_loop_access
+// CHECK-NOT: !llvm.access.group
 // CHECK: load i32, i32* %
-// CHECK-NOT: !llvm.mem.parallel_loop_access
+// CHECK-NOT: !llvm.access.group
 // CHECK: add nsw i32 %{{.+}}, 1
 // CHECK: store i32 %{{.+}}, i32* %
-// CHECK-NOT: !llvm.mem.parallel_loop_access
+// CHECK-NOT: !llvm.access.group
 // CHECK: br label %{{.*}}!llvm.loop
 // CHECK: ret i32 0
 
-- 
cgit v1.2.3


From 0b2c3959f16c11f0689b747b905ef59a6075cdd2 Mon Sep 17 00:00:00 2001
From: Artem Dergachev 
Date: Thu, 20 Dec 2018 21:26:40 +0000
Subject: [driver] [analyzer] Fix a backward compatibility issue after r348038.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Since r348038 we emit an error every time an -analyzer-config option is not
found. The driver, however, suppresses this error with another flag,
-analyzer-config-compatibility-mode, so backwards compatibility is maintained,
while analyzer developers still enjoy the new typo-free experience.

The backwards compatibility turns out to be still broken when the -analyze
action is not specified; it is still possible to specify -analyzer-config
in that case. This should be fixed now.

Patch by Kristóf Umann!

Differential Revision: https://reviews.llvm.org/D55823

rdar://problem/46504165


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349824 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/Driver/ToolChains/Clang.cpp                   | 13 +++-
 test/Analysis/invalid-a-na-ly-zer-con-fig-value.c | 79 +++++++++++++++++++++++
 test/Analysis/invalid-analyzer-config-value.c     |  4 ++
 3 files changed, 93 insertions(+), 3 deletions(-)
 create mode 100644 test/Analysis/invalid-a-na-ly-zer-con-fig-value.c

diff --git a/lib/Driver/ToolChains/Clang.cpp b/lib/Driver/ToolChains/Clang.cpp
index d377b3c032..859c4b3d70 100644
--- a/lib/Driver/ToolChains/Clang.cpp
+++ b/lib/Driver/ToolChains/Clang.cpp
@@ -2360,9 +2360,6 @@ static void RenderAnalyzerOptions(const ArgList &Args, ArgStringList &CmdArgs,
   // Treat blocks as analysis entry points.
   CmdArgs.push_back("-analyzer-opt-analyze-nested-blocks");
 
-  // Enable compatilibily mode to avoid analyzer-config related errors.
-  CmdArgs.push_back("-analyzer-config-compatibility-mode=true");
-
   // Add default argument set.
   if (!Args.hasArg(options::OPT__analyzer_no_default_checks)) {
     CmdArgs.push_back("-analyzer-checker=core");
@@ -3738,6 +3735,16 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
   if (isa(JA))
     RenderAnalyzerOptions(Args, CmdArgs, Triple, Input);
 
+  // Enable compatilibily mode to avoid analyzer-config related errors.
+  // Since we can't access frontend flags through hasArg, let's manually iterate
+  // through them.
+  for (size_t Index = 0; Index < Args.size(); ++Index) {
+    if (StringRef(Args.getArgString(Index)).contains("-analyzer-config")) {
+      CmdArgs.push_back("-analyzer-config-compatibility-mode=true");
+      break;
+    }
+  }
+
   CheckCodeGenerationOptions(D, Args);
 
   unsigned FunctionAlignment = ParseFunctionAlignment(TC, Args);
diff --git a/test/Analysis/invalid-a-na-ly-zer-con-fig-value.c b/test/Analysis/invalid-a-na-ly-zer-con-fig-value.c
new file mode 100644
index 0000000000..38fb358a0d
--- /dev/null
+++ b/test/Analysis/invalid-a-na-ly-zer-con-fig-value.c
@@ -0,0 +1,79 @@
+// Same as invalid-analyzer-config-value.c but without -analyzer-config
+// in the file name, so that argument string pattern matching
+// didn't accidentally match it.
+
+// RUN: not %clang_analyze_cc1 -verify %s \
+// RUN:   -analyzer-checker=core \
+// RUN:   -analyzer-config notes-as-events=yesplease \
+// RUN:   2>&1 | FileCheck %s -check-prefix=CHECK-BOOL-INPUT
+
+// CHECK-BOOL-INPUT: (frontend): invalid input for analyzer-config option
+// CHECK-BOOL-INPUT-SAME:        'notes-as-events', that expects a boolean value
+
+// RUN: %clang_analyze_cc1 -verify %s \
+// RUN:   -analyzer-checker=core \
+// RUN:   -analyzer-config-compatibility-mode=true \
+// RUN:   -analyzer-config notes-as-events=yesplease
+
+
+// RUN: not %clang_analyze_cc1 -verify %s \
+// RUN:   -analyzer-checker=core \
+// RUN:   -analyzer-config max-inlinable-size=400km/h \
+// RUN:   2>&1 | FileCheck %s -check-prefix=CHECK-UINT-INPUT
+
+// CHECK-UINT-INPUT: (frontend): invalid input for analyzer-config option
+// CHECK-UINT-INPUT-SAME:        'max-inlinable-size', that expects an unsigned
+// CHECK-UINT-INPUT-SAME:        value
+
+// RUN: %clang_analyze_cc1 -verify %s \
+// RUN:   -analyzer-checker=core \
+// RUN:   -analyzer-config-compatibility-mode=true \
+// RUN:   -analyzer-config max-inlinable-size=400km/h
+
+
+// RUN: not %clang_analyze_cc1 -verify %s \
+// RUN:   -analyzer-checker=core \
+// RUN:   -analyzer-config ctu-dir=0123012301230123 \
+// RUN:   2>&1 | FileCheck %s -check-prefix=CHECK-FILENAME-INPUT
+
+// CHECK-FILENAME-INPUT: (frontend): invalid input for analyzer-config option
+// CHECK-FILENAME-INPUT-SAME:        'ctu-dir', that expects a filename
+// CHECK-FILENAME-INPUT-SAME:        value
+
+// RUN: %clang_analyze_cc1 -verify %s \
+// RUN:   -analyzer-checker=core \
+// RUN:   -analyzer-config-compatibility-mode=true \
+// RUN:   -analyzer-config ctu-dir=0123012301230123
+
+
+// RUN: not %clang_analyze_cc1 -verify %s \
+// RUN:   -analyzer-checker=core \
+// RUN:   -analyzer-config no-false-positives=true \
+// RUN:   2>&1 | FileCheck %s -check-prefix=CHECK-UNKNOWN-CFG
+
+// CHECK-UNKNOWN-CFG: (frontend): unknown analyzer-config 'no-false-positives'
+
+// RUN: %clang_analyze_cc1 -verify %s \
+// RUN:   -analyzer-checker=core \
+// RUN:   -analyzer-config-compatibility-mode=true \
+// RUN:   -analyzer-config no-false-positives=true
+
+
+// Test the driver properly using "analyzer-config-compatibility-mode=true",
+// no longer causing an error on input error.
+// RUN: %clang --analyze %s
+
+// RUN: not %clang --analyze %s \
+// RUN:   -Xclang -analyzer-config -Xclang no-false-positives=true \
+// RUN:   -Xclang -analyzer-config-compatibility-mode=false \
+// RUN:   2>&1 | FileCheck %s -check-prefix=CHECK-NO-COMPAT
+
+// CHECK-NO-COMPAT: error: unknown analyzer-config 'no-false-positives'
+
+// Test the driver properly using "analyzer-config-compatibility-mode=true",
+// even if -analyze isn't specified.
+// RUN: %clang -Xclang -analyzer-config -Xclang remember=TheVasa %s
+
+// expected-no-diagnostics
+
+int main() {}
diff --git a/test/Analysis/invalid-analyzer-config-value.c b/test/Analysis/invalid-analyzer-config-value.c
index 34a73a7f9d..7eb0d732db 100644
--- a/test/Analysis/invalid-analyzer-config-value.c
+++ b/test/Analysis/invalid-analyzer-config-value.c
@@ -66,6 +66,10 @@
 
 // CHECK-NO-COMPAT: error: unknown analyzer-config 'no-false-positives'
 
+// Test the driver properly using "analyzer-config-compatibility-mode=true",
+// even if -analyze isn't specified.
+// RUN: %clang -Xclang -analyzer-config -Xclang remember=TheVasa %s
+
 // expected-no-diagnostics
 
 int main() {}
-- 
cgit v1.2.3


From ec67fa58d2d4e4f803023a06c9faa02a7b124b9d Mon Sep 17 00:00:00 2001
From: Haibo Huang 
Date: Thu, 20 Dec 2018 21:33:59 +0000
Subject: Declares __cpu_model as dso local

__builtin_cpu_supports and __builtin_cpu_is use information in __cpu_model to decide cpu features. Before this change, __cpu_model was not declared as dso local. The generated code looks up the address in GOT when reading __cpu_model. This makes it impossible to use these functions in ifunc, because at that time GOT entries have not been relocated. This change makes it dso local.

Differential Revision: https://reviews.llvm.org/D53850



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349825 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/CodeGen/CGBuiltin.cpp           | 7 +++++++
 test/CodeGen/builtin-cpu-is.c       | 2 ++
 test/CodeGen/builtin-cpu-supports.c | 5 +++++
 3 files changed, 14 insertions(+)

diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp
index 8f53a83abe..93484f82c3 100644
--- a/lib/CodeGen/CGBuiltin.cpp
+++ b/lib/CodeGen/CGBuiltin.cpp
@@ -9537,6 +9537,7 @@ Value *CodeGenFunction::EmitX86CpuIs(StringRef CPUStr) {
 
   // Grab the global __cpu_model.
   llvm::Constant *CpuModel = CGM.CreateRuntimeVariable(STy, "__cpu_model");
+  cast(CpuModel)->setDSOLocal(true);
 
   // Calculate the index needed to access the correct field based on the
   // range. Also adjust the expected value.
@@ -9609,6 +9610,7 @@ llvm::Value *CodeGenFunction::EmitX86CpuSupports(uint64_t FeaturesMask) {
 
     // Grab the global __cpu_model.
     llvm::Constant *CpuModel = CGM.CreateRuntimeVariable(STy, "__cpu_model");
+    cast(CpuModel)->setDSOLocal(true);
 
     // Grab the first (0th) element from the field __cpu_features off of the
     // global in the struct STy.
@@ -9628,6 +9630,8 @@ llvm::Value *CodeGenFunction::EmitX86CpuSupports(uint64_t FeaturesMask) {
   if (Features2 != 0) {
     llvm::Constant *CpuFeatures2 = CGM.CreateRuntimeVariable(Int32Ty,
                                                              "__cpu_features2");
+    cast(CpuFeatures2)->setDSOLocal(true);
+
     Value *Features =
         Builder.CreateAlignedLoad(CpuFeatures2, CharUnits::fromQuantity(4));
 
@@ -9645,6 +9649,9 @@ Value *CodeGenFunction::EmitX86CpuInit() {
   llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy,
                                                     /*Variadic*/ false);
   llvm::Constant *Func = CGM.CreateRuntimeFunction(FTy, "__cpu_indicator_init");
+  cast(Func)->setDSOLocal(true);
+  cast(Func)->setDLLStorageClass(
+      llvm::GlobalValue::DefaultStorageClass);
   return Builder.CreateCall(Func);
 }
 
diff --git a/test/CodeGen/builtin-cpu-is.c b/test/CodeGen/builtin-cpu-is.c
index f2a5f54a0c..bff3544c13 100644
--- a/test/CodeGen/builtin-cpu-is.c
+++ b/test/CodeGen/builtin-cpu-is.c
@@ -4,6 +4,8 @@
 // global, the bit grab, and the icmp correct.
 extern void a(const char *);
 
+// CHECK: @__cpu_model = external dso_local global { i32, i32, i32, [1 x i32] }
+
 void intel() {
   if (__builtin_cpu_is("intel"))
     a("intel");
diff --git a/test/CodeGen/builtin-cpu-supports.c b/test/CodeGen/builtin-cpu-supports.c
index d384efbc20..761f00cf95 100644
--- a/test/CodeGen/builtin-cpu-supports.c
+++ b/test/CodeGen/builtin-cpu-supports.c
@@ -4,6 +4,9 @@
 // global, the bit grab, and the icmp correct.
 extern void a(const char *);
 
+// CHECK: @__cpu_model = external dso_local global { i32, i32, i32, [1 x i32] }
+// CHECK: @__cpu_features2 = external dso_local global i32
+
 int main() {
   __builtin_cpu_init();
 
@@ -25,3 +28,5 @@ int main() {
 
   return 0;
 }
+
+// CHECK: declare dso_local void @__cpu_indicator_init()
-- 
cgit v1.2.3


From c813afc04335906595b7504693680aa9c354b450 Mon Sep 17 00:00:00 2001
From: Artem Dergachev 
Date: Thu, 20 Dec 2018 21:45:33 +0000
Subject: [driver] [analyzer] Fix buildbots after r349824.

Buildbots can't find the linker, which we don't really need in our tests.

Differential Revision: https://reviews.llvm.org/D55823

rdar://problem/46504165


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349828 91177308-0d34-0410-b5e6-96231b3b80d8
---
 test/Analysis/invalid-a-na-ly-zer-con-fig-value.c | 2 +-
 test/Analysis/invalid-analyzer-config-value.c     | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/test/Analysis/invalid-a-na-ly-zer-con-fig-value.c b/test/Analysis/invalid-a-na-ly-zer-con-fig-value.c
index 38fb358a0d..965416200c 100644
--- a/test/Analysis/invalid-a-na-ly-zer-con-fig-value.c
+++ b/test/Analysis/invalid-a-na-ly-zer-con-fig-value.c
@@ -72,7 +72,7 @@
 
 // Test the driver properly using "analyzer-config-compatibility-mode=true",
 // even if -analyze isn't specified.
-// RUN: %clang -Xclang -analyzer-config -Xclang remember=TheVasa %s
+// RUN: %clang -c -Xclang -analyzer-config -Xclang remember=TheVasa %s
 
 // expected-no-diagnostics
 
diff --git a/test/Analysis/invalid-analyzer-config-value.c b/test/Analysis/invalid-analyzer-config-value.c
index 7eb0d732db..0d09c7449f 100644
--- a/test/Analysis/invalid-analyzer-config-value.c
+++ b/test/Analysis/invalid-analyzer-config-value.c
@@ -68,7 +68,7 @@
 
 // Test the driver properly using "analyzer-config-compatibility-mode=true",
 // even if -analyze isn't specified.
-// RUN: %clang -Xclang -analyzer-config -Xclang remember=TheVasa %s
+// RUN: %clang -c -Xclang -analyzer-config -Xclang remember=TheVasa %s
 
 // expected-no-diagnostics
 
-- 
cgit v1.2.3


From 75ee3609d2a0edf40e80ae5fba26209415976a9a Mon Sep 17 00:00:00 2001
From: Artem Dergachev 
Date: Thu, 20 Dec 2018 21:56:49 +0000
Subject: [driver] [analyzer] Fix redundant test output.

The -c flag causes a .o file to appear every time we run a test.
Remove it.

Differential Revision: https://reviews.llvm.org/D55823

rdar://problem/46504165


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349835 91177308-0d34-0410-b5e6-96231b3b80d8
---
 test/Analysis/invalid-a-na-ly-zer-con-fig-value.c | 3 ++-
 test/Analysis/invalid-analyzer-config-value.c     | 3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/test/Analysis/invalid-a-na-ly-zer-con-fig-value.c b/test/Analysis/invalid-a-na-ly-zer-con-fig-value.c
index 965416200c..1b6c97ad1e 100644
--- a/test/Analysis/invalid-a-na-ly-zer-con-fig-value.c
+++ b/test/Analysis/invalid-a-na-ly-zer-con-fig-value.c
@@ -72,7 +72,8 @@
 
 // Test the driver properly using "analyzer-config-compatibility-mode=true",
 // even if -analyze isn't specified.
-// RUN: %clang -c -Xclang -analyzer-config -Xclang remember=TheVasa %s
+// RUN: %clang -fsyntax-only -Xclang -analyzer-config\
+// RUN:                      -Xclang remember=TheVasa %s
 
 // expected-no-diagnostics
 
diff --git a/test/Analysis/invalid-analyzer-config-value.c b/test/Analysis/invalid-analyzer-config-value.c
index 0d09c7449f..4ddcfe8207 100644
--- a/test/Analysis/invalid-analyzer-config-value.c
+++ b/test/Analysis/invalid-analyzer-config-value.c
@@ -68,7 +68,8 @@
 
 // Test the driver properly using "analyzer-config-compatibility-mode=true",
 // even if -analyze isn't specified.
-// RUN: %clang -c -Xclang -analyzer-config -Xclang remember=TheVasa %s
+// RUN: %clang -fsyntax-only -Xclang -analyzer-config\
+// RUN:                      -Xclang remember=TheVasa %s
 
 // expected-no-diagnostics
 
-- 
cgit v1.2.3


From 7678da76438390480e87de11da4c22c503479675 Mon Sep 17 00:00:00 2001
From: Tom Stellard 
Date: Thu, 20 Dec 2018 22:04:36 +0000
Subject: cmake: Remove uses of add_llvm_loadable_module macro

This was removed from llvm in r349839.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349840 91177308-0d34-0410-b5e6-96231b3b80d8
---
 examples/AnnotateFunctions/CMakeLists.txt  | 2 +-
 examples/PrintFunctionNames/CMakeLists.txt | 2 +-
 examples/analyzer-plugin/CMakeLists.txt    | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/examples/AnnotateFunctions/CMakeLists.txt b/examples/AnnotateFunctions/CMakeLists.txt
index 5684abf238..44b6317e72 100644
--- a/examples/AnnotateFunctions/CMakeLists.txt
+++ b/examples/AnnotateFunctions/CMakeLists.txt
@@ -1,4 +1,4 @@
-add_llvm_loadable_module(AnnotateFunctions AnnotateFunctions.cpp PLUGIN_TOOL clang)
+add_llvm_library(AnnotateFunctions MODULE AnnotateFunctions.cpp PLUGIN_TOOL clang)
 
 if(LLVM_ENABLE_PLUGINS AND (WIN32 OR CYGWIN))
   target_link_libraries(AnnotateFunctions PRIVATE
diff --git a/examples/PrintFunctionNames/CMakeLists.txt b/examples/PrintFunctionNames/CMakeLists.txt
index e582b2c45a..68c6f76dff 100644
--- a/examples/PrintFunctionNames/CMakeLists.txt
+++ b/examples/PrintFunctionNames/CMakeLists.txt
@@ -9,7 +9,7 @@ if( NOT MSVC ) # MSVC mangles symbols differently, and
   endif()
 endif()
 
-add_llvm_loadable_module(PrintFunctionNames PrintFunctionNames.cpp PLUGIN_TOOL clang)
+add_llvm_library(PrintFunctionNames MODULE PrintFunctionNames.cpp PLUGIN_TOOL clang)
 
 if(LLVM_ENABLE_PLUGINS AND (WIN32 OR CYGWIN))
   target_link_libraries(PrintFunctionNames PRIVATE
diff --git a/examples/analyzer-plugin/CMakeLists.txt b/examples/analyzer-plugin/CMakeLists.txt
index 0d5b2754ca..7c7b2aec19 100644
--- a/examples/analyzer-plugin/CMakeLists.txt
+++ b/examples/analyzer-plugin/CMakeLists.txt
@@ -1,5 +1,5 @@
 set(LLVM_EXPORTED_SYMBOL_FILE ${CMAKE_CURRENT_SOURCE_DIR}/SampleAnalyzerPlugin.exports)
-add_llvm_loadable_module(SampleAnalyzerPlugin MainCallChecker.cpp PLUGIN_TOOL clang)
+add_llvm_library(SampleAnalyzerPlugin MODULE MainCallChecker.cpp PLUGIN_TOOL clang)
 
 if(LLVM_ENABLE_PLUGINS AND (WIN32 OR CYGWIN))
   target_link_libraries(SampleAnalyzerPlugin PRIVATE
-- 
cgit v1.2.3


From 3b4a406bc8086d1266de89ac122292b643d2d934 Mon Sep 17 00:00:00 2001
From: Alex Lorenz 
Date: Thu, 20 Dec 2018 22:11:11 +0000
Subject: [ObjC] Messages to 'self' in class methods that return 'instancetype'
 should use the pointer to the class as the result type of the message

Prior to this commit, messages to self in class methods were treated as instance
methods to a Class value. When these methods returned instancetype the compiler
only saw id through the instancetype, and not the Interface *. This caused
problems when that return value was a receiver in a message send, as the
compiler couldn't select the right method declaration and had to rely on a
selection from the global method pool.

This commit modifies the semantics of such message sends and uses class messages
that are dispatched to the interface that corresponds to the class that contains
the class method. This ensures that instancetypes are correctly interpreted by
the compiler. This change is safe under ARC (as self can't be reassigned),
however, it also applies to MRR code as we are assuming that the user isn't
doing anything unreasonable.

rdar://20940997

Differential Revision: https://reviews.llvm.org/D36790


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349841 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/Sema/Sema.h                          | 13 ++---
 lib/Sema/SemaExprObjC.cpp                          | 65 ++++++++++++++--------
 .../SemaObjC/multiple-method-names-in-class-self.m | 39 +++++++++++++
 3 files changed, 88 insertions(+), 29 deletions(-)
 create mode 100644 test/SemaObjC/multiple-method-names-in-class-self.m

diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index 7685b3f74a..fd83b374ad 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -9842,21 +9842,20 @@ public:
   /// \param Method - May be null.
   /// \param [out] ReturnType - The return type of the send.
   /// \return true iff there were any incompatible types.
-  bool CheckMessageArgumentTypes(QualType ReceiverType,
+  bool CheckMessageArgumentTypes(const Expr *Receiver, QualType ReceiverType,
                                  MultiExprArg Args, Selector Sel,
                                  ArrayRef SelectorLocs,
                                  ObjCMethodDecl *Method, bool isClassMessage,
-                                 bool isSuperMessage,
-                                 SourceLocation lbrac, SourceLocation rbrac,
-                                 SourceRange RecRange,
+                                 bool isSuperMessage, SourceLocation lbrac,
+                                 SourceLocation rbrac, SourceRange RecRange,
                                  QualType &ReturnType, ExprValueKind &VK);
 
   /// Determine the result of a message send expression based on
   /// the type of the receiver, the method expected to receive the message,
   /// and the form of the message send.
-  QualType getMessageSendResultType(QualType ReceiverType,
-                                    ObjCMethodDecl *Method,
-                                    bool isClassMessage, bool isSuperMessage);
+  QualType getMessageSendResultType(const Expr *Receiver, QualType ReceiverType,
+                                    ObjCMethodDecl *Method, bool isClassMessage,
+                                    bool isSuperMessage);
 
   /// If the given expression involves a message send to a method
   /// with a related result type, emit a note describing what happened.
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp
index 9eaf747ae7..ce80db7ca6 100644
--- a/lib/Sema/SemaExprObjC.cpp
+++ b/lib/Sema/SemaExprObjC.cpp
@@ -1346,7 +1346,8 @@ static QualType getBaseMessageSendResultType(Sema &S,
   return transferNullability(ReceiverType);
 }
 
-QualType Sema::getMessageSendResultType(QualType ReceiverType,
+QualType Sema::getMessageSendResultType(const Expr *Receiver,
+                                        QualType ReceiverType,
                                         ObjCMethodDecl *Method,
                                         bool isClassMessage,
                                         bool isSuperMessage) {
@@ -1357,8 +1358,33 @@ QualType Sema::getMessageSendResultType(QualType ReceiverType,
                                                      isSuperMessage);
 
   // If this is a class message, ignore the nullability of the receiver.
-  if (isClassMessage)
+  if (isClassMessage) {
+    // In a class method, class messages to 'self' that return instancetype can
+    // be typed as the current class.  We can safely do this in ARC because self
+    // can't be reassigned, and we do it unsafely outside of ARC because in
+    // practice people never reassign self in class methods and there's some
+    // virtue in not being aggressively pedantic.
+    if (Receiver && Receiver->isObjCSelfExpr()) {
+      assert(ReceiverType->isObjCClassType() && "expected a Class self");
+      QualType T = Method->getSendResultType(ReceiverType);
+      AttributedType::stripOuterNullability(T);
+      if (T == Context.getObjCInstanceType()) {
+        const ObjCMethodDecl *MD = cast(
+            cast(
+                cast(Receiver->IgnoreParenImpCasts())->getDecl())
+                ->getDeclContext());
+        assert(MD->isClassMethod() && "expected a class method");
+        QualType NewResultType = Context.getObjCObjectPointerType(
+            Context.getObjCInterfaceType(MD->getClassInterface()));
+        if (auto Nullability = resultType->getNullability(Context))
+          NewResultType = Context.getAttributedType(
+              AttributedType::getNullabilityAttrKind(*Nullability),
+              NewResultType, NewResultType);
+        return NewResultType;
+      }
+    }
     return resultType;
+  }
 
   // There is nothing left to do if the result type cannot have a nullability
   // specifier.
@@ -1505,15 +1531,12 @@ void Sema::EmitRelatedResultTypeNote(const Expr *E) {
     << MsgSend->getType();
 }
 
-bool Sema::CheckMessageArgumentTypes(QualType ReceiverType,
-                                     MultiExprArg Args,
-                                     Selector Sel,
-                                     ArrayRef SelectorLocs,
-                                     ObjCMethodDecl *Method,
-                                     bool isClassMessage, bool isSuperMessage,
-                                     SourceLocation lbrac, SourceLocation rbrac,
-                                     SourceRange RecRange,
-                                     QualType &ReturnType, ExprValueKind &VK) {
+bool Sema::CheckMessageArgumentTypes(
+    const Expr *Receiver, QualType ReceiverType, MultiExprArg Args,
+    Selector Sel, ArrayRef SelectorLocs, ObjCMethodDecl *Method,
+    bool isClassMessage, bool isSuperMessage, SourceLocation lbrac,
+    SourceLocation rbrac, SourceRange RecRange, QualType &ReturnType,
+    ExprValueKind &VK) {
   SourceLocation SelLoc;
   if (!SelectorLocs.empty() && SelectorLocs.front().isValid())
     SelLoc = SelectorLocs.front();
@@ -1590,8 +1613,8 @@ bool Sema::CheckMessageArgumentTypes(QualType ReceiverType,
     return false;
   }
 
-  ReturnType = getMessageSendResultType(ReceiverType, Method, isClassMessage,
-                                        isSuperMessage);
+  ReturnType = getMessageSendResultType(Receiver, ReceiverType, Method,
+                                        isClassMessage, isSuperMessage);
   VK = Expr::getValueKindForType(Method->getReturnType());
 
   unsigned NumNamedArgs = Sel.getNumArgs();
@@ -2482,12 +2505,10 @@ ExprResult Sema::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo,
 
   unsigned NumArgs = ArgsIn.size();
   Expr **Args = ArgsIn.data();
-  if (CheckMessageArgumentTypes(ReceiverType, MultiExprArg(Args, NumArgs),
-                                Sel, SelectorLocs,
-                                Method, true,
-                                SuperLoc.isValid(), LBracLoc, RBracLoc,
-                                SourceRange(),
-                                ReturnType, VK))
+  if (CheckMessageArgumentTypes(/*Receiver=*/nullptr, ReceiverType,
+                                MultiExprArg(Args, NumArgs), Sel, SelectorLocs,
+                                Method, true, SuperLoc.isValid(), LBracLoc,
+                                RBracLoc, SourceRange(), ReturnType, VK))
     return ExprError();
 
   if (Method && !Method->getReturnType()->isVoidType() &&
@@ -2982,9 +3003,9 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver,
   ExprValueKind VK = VK_RValue;
   bool ClassMessage = (ReceiverType->isObjCClassType() ||
                        ReceiverType->isObjCQualifiedClassType());
-  if (CheckMessageArgumentTypes(ReceiverType, MultiExprArg(Args, NumArgs),
-                                Sel, SelectorLocs, Method,
-                                ClassMessage, SuperLoc.isValid(),
+  if (CheckMessageArgumentTypes(Receiver, ReceiverType,
+                                MultiExprArg(Args, NumArgs), Sel, SelectorLocs,
+                                Method, ClassMessage, SuperLoc.isValid(),
                                 LBracLoc, RBracLoc, RecRange, ReturnType, VK))
     return ExprError();
 
diff --git a/test/SemaObjC/multiple-method-names-in-class-self.m b/test/SemaObjC/multiple-method-names-in-class-self.m
new file mode 100644
index 0000000000..47e1306d38
--- /dev/null
+++ b/test/SemaObjC/multiple-method-names-in-class-self.m
@@ -0,0 +1,39 @@
+// RUN: %clang_cc1 -Wobjc-multiple-method-names -x objective-c -verify %s
+// RUN: %clang_cc1 -Wobjc-multiple-method-names -x objective-c -verify -fobjc-arc %s
+// expected-no-diagnostics
+
+@interface NSObj
+
++ (instancetype) alloc;
+
++ (_Nonnull instancetype) globalObject;
+
+@end
+
+@interface SelfAllocReturn: NSObj
+
+- (instancetype)initWithFoo:(int)x;
+
+@end
+
+@interface SelfAllocReturn2: NSObj
+
+- (instancetype)initWithFoo:(SelfAllocReturn *)x;
+
+@end
+
+@implementation SelfAllocReturn
+
+- (instancetype)initWithFoo:(int)x {
+    return self;
+}
+
++ (instancetype) thingWithFoo:(int)x {
+    return [[self alloc] initWithFoo: x];
+}
+
++ (void) initGlobal {
+  (void)[[self globalObject] initWithFoo: 20];
+}
+
+@end
-- 
cgit v1.2.3


From 5faf6e9d41afa74a447da0b47349e4888e59e466 Mon Sep 17 00:00:00 2001
From: Artem Dergachev 
Date: Thu, 20 Dec 2018 22:29:49 +0000
Subject: Revert "[driver] [analyzer] Fix a backward compatibility issue after
 r348038."

This reverts commits r349824, r349828, r349835.

More buildbot failures were noticed.

Differential Revision: https://reviews.llvm.org/D55823

rdar://problem/46504165


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349843 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/Driver/ToolChains/Clang.cpp                   | 13 +---
 test/Analysis/invalid-a-na-ly-zer-con-fig-value.c | 80 -----------------------
 test/Analysis/invalid-analyzer-config-value.c     |  5 --
 3 files changed, 3 insertions(+), 95 deletions(-)
 delete mode 100644 test/Analysis/invalid-a-na-ly-zer-con-fig-value.c

diff --git a/lib/Driver/ToolChains/Clang.cpp b/lib/Driver/ToolChains/Clang.cpp
index 859c4b3d70..d377b3c032 100644
--- a/lib/Driver/ToolChains/Clang.cpp
+++ b/lib/Driver/ToolChains/Clang.cpp
@@ -2360,6 +2360,9 @@ static void RenderAnalyzerOptions(const ArgList &Args, ArgStringList &CmdArgs,
   // Treat blocks as analysis entry points.
   CmdArgs.push_back("-analyzer-opt-analyze-nested-blocks");
 
+  // Enable compatilibily mode to avoid analyzer-config related errors.
+  CmdArgs.push_back("-analyzer-config-compatibility-mode=true");
+
   // Add default argument set.
   if (!Args.hasArg(options::OPT__analyzer_no_default_checks)) {
     CmdArgs.push_back("-analyzer-checker=core");
@@ -3735,16 +3738,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
   if (isa(JA))
     RenderAnalyzerOptions(Args, CmdArgs, Triple, Input);
 
-  // Enable compatilibily mode to avoid analyzer-config related errors.
-  // Since we can't access frontend flags through hasArg, let's manually iterate
-  // through them.
-  for (size_t Index = 0; Index < Args.size(); ++Index) {
-    if (StringRef(Args.getArgString(Index)).contains("-analyzer-config")) {
-      CmdArgs.push_back("-analyzer-config-compatibility-mode=true");
-      break;
-    }
-  }
-
   CheckCodeGenerationOptions(D, Args);
 
   unsigned FunctionAlignment = ParseFunctionAlignment(TC, Args);
diff --git a/test/Analysis/invalid-a-na-ly-zer-con-fig-value.c b/test/Analysis/invalid-a-na-ly-zer-con-fig-value.c
deleted file mode 100644
index 1b6c97ad1e..0000000000
--- a/test/Analysis/invalid-a-na-ly-zer-con-fig-value.c
+++ /dev/null
@@ -1,80 +0,0 @@
-// Same as invalid-analyzer-config-value.c but without -analyzer-config
-// in the file name, so that argument string pattern matching
-// didn't accidentally match it.
-
-// RUN: not %clang_analyze_cc1 -verify %s \
-// RUN:   -analyzer-checker=core \
-// RUN:   -analyzer-config notes-as-events=yesplease \
-// RUN:   2>&1 | FileCheck %s -check-prefix=CHECK-BOOL-INPUT
-
-// CHECK-BOOL-INPUT: (frontend): invalid input for analyzer-config option
-// CHECK-BOOL-INPUT-SAME:        'notes-as-events', that expects a boolean value
-
-// RUN: %clang_analyze_cc1 -verify %s \
-// RUN:   -analyzer-checker=core \
-// RUN:   -analyzer-config-compatibility-mode=true \
-// RUN:   -analyzer-config notes-as-events=yesplease
-
-
-// RUN: not %clang_analyze_cc1 -verify %s \
-// RUN:   -analyzer-checker=core \
-// RUN:   -analyzer-config max-inlinable-size=400km/h \
-// RUN:   2>&1 | FileCheck %s -check-prefix=CHECK-UINT-INPUT
-
-// CHECK-UINT-INPUT: (frontend): invalid input for analyzer-config option
-// CHECK-UINT-INPUT-SAME:        'max-inlinable-size', that expects an unsigned
-// CHECK-UINT-INPUT-SAME:        value
-
-// RUN: %clang_analyze_cc1 -verify %s \
-// RUN:   -analyzer-checker=core \
-// RUN:   -analyzer-config-compatibility-mode=true \
-// RUN:   -analyzer-config max-inlinable-size=400km/h
-
-
-// RUN: not %clang_analyze_cc1 -verify %s \
-// RUN:   -analyzer-checker=core \
-// RUN:   -analyzer-config ctu-dir=0123012301230123 \
-// RUN:   2>&1 | FileCheck %s -check-prefix=CHECK-FILENAME-INPUT
-
-// CHECK-FILENAME-INPUT: (frontend): invalid input for analyzer-config option
-// CHECK-FILENAME-INPUT-SAME:        'ctu-dir', that expects a filename
-// CHECK-FILENAME-INPUT-SAME:        value
-
-// RUN: %clang_analyze_cc1 -verify %s \
-// RUN:   -analyzer-checker=core \
-// RUN:   -analyzer-config-compatibility-mode=true \
-// RUN:   -analyzer-config ctu-dir=0123012301230123
-
-
-// RUN: not %clang_analyze_cc1 -verify %s \
-// RUN:   -analyzer-checker=core \
-// RUN:   -analyzer-config no-false-positives=true \
-// RUN:   2>&1 | FileCheck %s -check-prefix=CHECK-UNKNOWN-CFG
-
-// CHECK-UNKNOWN-CFG: (frontend): unknown analyzer-config 'no-false-positives'
-
-// RUN: %clang_analyze_cc1 -verify %s \
-// RUN:   -analyzer-checker=core \
-// RUN:   -analyzer-config-compatibility-mode=true \
-// RUN:   -analyzer-config no-false-positives=true
-
-
-// Test the driver properly using "analyzer-config-compatibility-mode=true",
-// no longer causing an error on input error.
-// RUN: %clang --analyze %s
-
-// RUN: not %clang --analyze %s \
-// RUN:   -Xclang -analyzer-config -Xclang no-false-positives=true \
-// RUN:   -Xclang -analyzer-config-compatibility-mode=false \
-// RUN:   2>&1 | FileCheck %s -check-prefix=CHECK-NO-COMPAT
-
-// CHECK-NO-COMPAT: error: unknown analyzer-config 'no-false-positives'
-
-// Test the driver properly using "analyzer-config-compatibility-mode=true",
-// even if -analyze isn't specified.
-// RUN: %clang -fsyntax-only -Xclang -analyzer-config\
-// RUN:                      -Xclang remember=TheVasa %s
-
-// expected-no-diagnostics
-
-int main() {}
diff --git a/test/Analysis/invalid-analyzer-config-value.c b/test/Analysis/invalid-analyzer-config-value.c
index 4ddcfe8207..34a73a7f9d 100644
--- a/test/Analysis/invalid-analyzer-config-value.c
+++ b/test/Analysis/invalid-analyzer-config-value.c
@@ -66,11 +66,6 @@
 
 // CHECK-NO-COMPAT: error: unknown analyzer-config 'no-false-positives'
 
-// Test the driver properly using "analyzer-config-compatibility-mode=true",
-// even if -analyze isn't specified.
-// RUN: %clang -fsyntax-only -Xclang -analyzer-config\
-// RUN:                      -Xclang remember=TheVasa %s
-
 // expected-no-diagnostics
 
 int main() {}
-- 
cgit v1.2.3


From 5af7f70eef9405bdaa895370fc4702b47f0e953a Mon Sep 17 00:00:00 2001
From: Erik Pilkington 
Date: Thu, 20 Dec 2018 22:32:04 +0000
Subject: Add support for namespaces on #pragma clang attribute

Namespaces are introduced by adding an "identifier." before a
push/pop directive. Pop directives with namespaces can only pop a
attribute group that was pushed with the same namespace. Push and pop
directives that don't opt into namespaces have the same semantics.

This is necessary to prevent a pitfall of using multiple #pragma
clang attribute directives spread out in a large file, particularly
when macros are involved. It isn't easy to see which pop corripsonds
to which push, so its easy to inadvertently pop the wrong group.

Differential revision: https://reviews.llvm.org/D55628

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349845 91177308-0d34-0410-b5e6-96231b3b80d8
---
 docs/LanguageExtensions.rst                 | 30 +++++++++++++++++++
 include/clang/Basic/DiagnosticParseKinds.td |  7 +++++
 include/clang/Basic/DiagnosticSemaKinds.td  |  3 +-
 include/clang/Sema/Sema.h                   |  8 +++--
 lib/Parse/ParsePragma.cpp                   | 46 +++++++++++++++++++++++++----
 lib/Sema/SemaAttr.cpp                       | 40 ++++++++++++++++++-------
 test/Parser/pragma-attribute.cpp            |  2 +-
 test/Sema/pragma-attribute-namespace.c      | 37 +++++++++++++++++++++++
 8 files changed, 152 insertions(+), 21 deletions(-)
 create mode 100644 test/Sema/pragma-attribute-namespace.c

diff --git a/docs/LanguageExtensions.rst b/docs/LanguageExtensions.rst
index 0d358ad51a..7d878150de 100644
--- a/docs/LanguageExtensions.rst
+++ b/docs/LanguageExtensions.rst
@@ -2697,6 +2697,36 @@ The ``__declspec`` style syntax is also supported:
 A single push directive accepts only one attribute regardless of the syntax
 used.
 
+Because multiple push directives can be nested, if you're writing a macro that
+expands to ``_Pragma("clang attribute")`` it's good hygiene (though not
+required) to add a namespace to your push/pop directives. A pop directive with a
+namespace will pop the innermost push that has that same namespace. This will
+ensure that another macro's ``pop`` won't inadvertently pop your attribute. Note
+that an ``pop`` without a namespace will pop the innermost ``push`` without a
+namespace. ``push``es with a namespace can only be popped by ``pop`` with the
+same namespace. For instance:
+
+.. code-block:: c++
+
+   #define ASSUME_NORETURN_BEGIN _Pragma("clang attribute AssumeNoreturn.push ([[noreturn]], apply_to = function)")
+   #define ASSUME_NORETURN_END   _Pragma("clang attribute AssumeNoreturn.pop")
+
+   #define ASSUME_UNAVAILABLE_BEGIN _Pragma("clang attribute Unavailable.push (__attribute__((unavailable)), apply_to=function)")
+   #define ASSUME_UNAVAILABLE_END   _Pragma("clang attribute Unavailable.pop")
+
+
+   ASSUME_NORETURN_BEGIN
+   ASSUME_UNAVAILABLE_BEGIN
+   void function(); // function has [[noreturn]] and __attribute__((unavailable))
+   ASSUME_NORETURN_END
+   void other_function(); // function has __attribute__((unavailable))
+   ASSUME_UNAVAILABLE_END
+
+Without the namespaces on the macros, ``other_function`` will be annotated with
+``[[noreturn]]`` instead of ``__attribute__((unavailable))``. This may seem like
+a contrived example, but its very possible for this kind of situation to appear
+in real code if the pragmas are spread out accross a large file.
+
 Subject Match Rules
 -------------------
 
diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td
index 1e816bc5f2..bb5d2a18d4 100644
--- a/include/clang/Basic/DiagnosticParseKinds.td
+++ b/include/clang/Basic/DiagnosticParseKinds.td
@@ -1100,6 +1100,13 @@ def err_pragma_attribute_unknown_subject_sub_rule : Error<
   "sub-rules: %3}2">;
 def err_pragma_attribute_duplicate_subject : Error<
   "duplicate attribute subject matcher '%0'">;
+def err_pragma_attribute_expected_period : Error<
+  "expected '.' after pragma attribute namespace %0">;
+def err_pragma_attribute_namespace_on_attribute : Error<
+  "namespace can only apply to 'push' or 'pop' directives">;
+def note_pragma_attribute_namespace_on_attribute : Note<
+  "omit the namespace to add attributes to the most-recently"
+  " pushed attribute group">;
 
 def err_opencl_unroll_hint_on_non_loop : Error<
   "OpenCL only supports 'opencl_unroll_hint' attribute on for, while, and do statements">;
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 91df49b80c..46cf0a423e 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -815,7 +815,8 @@ def err_pragma_attribute_matcher_negated_subrule_contradicts_subrule : Error<
 def err_pragma_attribute_invalid_matchers : Error<
   "attribute %0 can't be applied to %1">;
 def err_pragma_attribute_stack_mismatch : Error<
-  "'#pragma clang attribute pop' with no matching '#pragma clang attribute push'">;
+  "'#pragma clang attribute %select{%1.|}0pop' with no matching"
+  " '#pragma clang attribute %select{%1.|}0push'">;
 def warn_pragma_attribute_unused : Warning<
   "unused attribute %0 in '#pragma clang attribute push' region">,
   InGroup;
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index fd83b374ad..2396b505cb 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -503,6 +503,8 @@ public:
   struct PragmaAttributeGroup {
     /// The location of the push attribute.
     SourceLocation Loc;
+    /// The namespace of this push group.
+    const IdentifierInfo *Namespace;
     SmallVector Entries;
   };
 
@@ -8494,10 +8496,12 @@ public:
   void ActOnPragmaAttributeAttribute(ParsedAttr &Attribute,
                                      SourceLocation PragmaLoc,
                                      attr::ParsedSubjectMatchRuleSet Rules);
-  void ActOnPragmaAttributeEmptyPush(SourceLocation PragmaLoc);
+  void ActOnPragmaAttributeEmptyPush(SourceLocation PragmaLoc,
+                                     const IdentifierInfo *Namespace);
 
   /// Called on well-formed '\#pragma clang attribute pop'.
-  void ActOnPragmaAttributePop(SourceLocation PragmaLoc);
+  void ActOnPragmaAttributePop(SourceLocation PragmaLoc,
+                               const IdentifierInfo *Namespace);
 
   /// Adds the attributes that have been specified using the
   /// '\#pragma clang attribute push' directives to the given declaration.
diff --git a/lib/Parse/ParsePragma.cpp b/lib/Parse/ParsePragma.cpp
index e476c9b0f9..3204cf08ec 100644
--- a/lib/Parse/ParsePragma.cpp
+++ b/lib/Parse/ParsePragma.cpp
@@ -1139,6 +1139,7 @@ struct PragmaAttributeInfo {
   enum ActionType { Push, Pop, Attribute };
   ParsedAttributes &Attributes;
   ActionType Action;
+  const IdentifierInfo *Namespace = nullptr;
   ArrayRef Tokens;
 
   PragmaAttributeInfo(ParsedAttributes &Attributes) : Attributes(Attributes) {}
@@ -1393,7 +1394,7 @@ void Parser::HandlePragmaAttribute() {
   auto *Info = static_cast(Tok.getAnnotationValue());
   if (Info->Action == PragmaAttributeInfo::Pop) {
     ConsumeAnnotationToken();
-    Actions.ActOnPragmaAttributePop(PragmaLoc);
+    Actions.ActOnPragmaAttributePop(PragmaLoc, Info->Namespace);
     return;
   }
   // Parse the actual attribute with its arguments.
@@ -1403,7 +1404,7 @@ void Parser::HandlePragmaAttribute() {
 
   if (Info->Action == PragmaAttributeInfo::Push && Info->Tokens.empty()) {
     ConsumeAnnotationToken();
-    Actions.ActOnPragmaAttributeEmptyPush(PragmaLoc);
+    Actions.ActOnPragmaAttributeEmptyPush(PragmaLoc, Info->Namespace);
     return;
   }
 
@@ -1555,7 +1556,7 @@ void Parser::HandlePragmaAttribute() {
 
   // Handle a mixed push/attribute by desurging to a push, then an attribute.
   if (Info->Action == PragmaAttributeInfo::Push)
-    Actions.ActOnPragmaAttributeEmptyPush(PragmaLoc);
+    Actions.ActOnPragmaAttributeEmptyPush(PragmaLoc, Info->Namespace);
 
   Actions.ActOnPragmaAttributeAttribute(Attribute, PragmaLoc,
                                         std::move(SubjectMatchRules));
@@ -3118,12 +3119,22 @@ void PragmaForceCUDAHostDeviceHandler::HandlePragma(
 ///
 /// The syntax is:
 /// \code
-///  #pragma clang attribute push(attribute, subject-set)
+///  #pragma clang attribute push (attribute, subject-set)
 ///  #pragma clang attribute push
 ///  #pragma clang attribute (attribute, subject-set)
 ///  #pragma clang attribute pop
 /// \endcode
 ///
+/// There are also 'namespace' variants of push and pop directives. The bare
+/// '#pragma clang attribute (attribute, subject-set)' version doesn't require a
+/// namespace, since it always applies attributes to the most recently pushed
+/// group, regardless of namespace.
+/// \code
+///  #pragma clang attribute namespace.push (attribute, subject-set)
+///  #pragma clang attribute namespace.push
+///  #pragma clang attribute namespace.pop
+/// \endcode
+///
 /// The subject-set clause defines the set of declarations which receive the
 /// attribute. Its exact syntax is described in the LanguageExtensions document
 /// in Clang's documentation.
@@ -3139,6 +3150,22 @@ void PragmaAttributeHandler::HandlePragma(Preprocessor &PP,
   auto *Info = new (PP.getPreprocessorAllocator())
       PragmaAttributeInfo(AttributesForPragmaAttribute);
 
+  // Parse the optional namespace followed by a period.
+  if (Tok.is(tok::identifier)) {
+    IdentifierInfo *II = Tok.getIdentifierInfo();
+    if (!II->isStr("push") && !II->isStr("pop")) {
+      Info->Namespace = II;
+      PP.Lex(Tok);
+
+      if (!Tok.is(tok::period)) {
+        PP.Diag(Tok.getLocation(), diag::err_pragma_attribute_expected_period)
+            << II;
+        return;
+      }
+      PP.Lex(Tok);
+    }
+  }
+
   if (!Tok.isOneOf(tok::identifier, tok::l_paren)) {
     PP.Diag(Tok.getLocation(),
             diag::err_pragma_attribute_expected_push_pop_paren);
@@ -3146,9 +3173,16 @@ void PragmaAttributeHandler::HandlePragma(Preprocessor &PP,
   }
 
   // Determine what action this pragma clang attribute represents.
-  if (Tok.is(tok::l_paren))
+  if (Tok.is(tok::l_paren)) {
+    if (Info->Namespace) {
+      PP.Diag(Tok.getLocation(),
+              diag::err_pragma_attribute_namespace_on_attribute);
+      PP.Diag(Tok.getLocation(),
+              diag::note_pragma_attribute_namespace_on_attribute);
+      return;
+    }
     Info->Action = PragmaAttributeInfo::Attribute;
-  else {
+  } else {
     const IdentifierInfo *II = Tok.getIdentifierInfo();
     if (II->isStr("push"))
       Info->Action = PragmaAttributeInfo::Push;
diff --git a/lib/Sema/SemaAttr.cpp b/lib/Sema/SemaAttr.cpp
index f6ac9b44a8..2bc1b769f7 100644
--- a/lib/Sema/SemaAttr.cpp
+++ b/lib/Sema/SemaAttr.cpp
@@ -631,28 +631,46 @@ void Sema::ActOnPragmaAttributeAttribute(
       {PragmaLoc, &Attribute, std::move(SubjectMatchRules), /*IsUsed=*/false});
 }
 
-void Sema::ActOnPragmaAttributeEmptyPush(SourceLocation PragmaLoc) {
+void Sema::ActOnPragmaAttributeEmptyPush(SourceLocation PragmaLoc,
+                                         const IdentifierInfo *Namespace) {
   PragmaAttributeStack.emplace_back();
   PragmaAttributeStack.back().Loc = PragmaLoc;
+  PragmaAttributeStack.back().Namespace = Namespace;
 }
 
-void Sema::ActOnPragmaAttributePop(SourceLocation PragmaLoc) {
+void Sema::ActOnPragmaAttributePop(SourceLocation PragmaLoc,
+                                   const IdentifierInfo *Namespace) {
   if (PragmaAttributeStack.empty()) {
-    Diag(PragmaLoc, diag::err_pragma_attribute_stack_mismatch);
+    Diag(PragmaLoc, diag::err_pragma_attribute_stack_mismatch) << 1;
     return;
   }
 
-  for (const PragmaAttributeEntry &Entry :
-       PragmaAttributeStack.back().Entries) {
-    if (!Entry.IsUsed) {
-      assert(Entry.Attribute && "Expected an attribute");
-      Diag(Entry.Attribute->getLoc(), diag::warn_pragma_attribute_unused)
-          << Entry.Attribute->getName();
-      Diag(PragmaLoc, diag::note_pragma_attribute_region_ends_here);
+  // Dig back through the stack trying to find the most recently pushed group
+  // that in Namespace. Note that this works fine if no namespace is present,
+  // think of push/pops without namespaces as having an implicit "nullptr"
+  // namespace.
+  for (size_t Index = PragmaAttributeStack.size(); Index;) {
+    --Index;
+    if (PragmaAttributeStack[Index].Namespace == Namespace) {
+      for (const PragmaAttributeEntry &Entry :
+           PragmaAttributeStack[Index].Entries) {
+        if (!Entry.IsUsed) {
+          assert(Entry.Attribute && "Expected an attribute");
+          Diag(Entry.Attribute->getLoc(), diag::warn_pragma_attribute_unused)
+              << *Entry.Attribute;
+          Diag(PragmaLoc, diag::note_pragma_attribute_region_ends_here);
+        }
+      }
+      PragmaAttributeStack.erase(PragmaAttributeStack.begin() + Index);
+      return;
     }
   }
 
-  PragmaAttributeStack.pop_back();
+  if (Namespace)
+    Diag(PragmaLoc, diag::err_pragma_attribute_stack_mismatch)
+        << 0 << Namespace->getName();
+  else
+    Diag(PragmaLoc, diag::err_pragma_attribute_stack_mismatch) << 1;
 }
 
 void Sema::AddPragmaAttributes(Scope *S, Decl *D) {
diff --git a/test/Parser/pragma-attribute.cpp b/test/Parser/pragma-attribute.cpp
index c4ae2056fb..4e860b6d58 100644
--- a/test/Parser/pragma-attribute.cpp
+++ b/test/Parser/pragma-attribute.cpp
@@ -102,7 +102,7 @@ void function();
 
 #pragma clang attribute // expected-error {{expected 'push', 'pop', or '(' after '#pragma clang attribute'}}
 #pragma clang attribute 42 // expected-error {{expected 'push', 'pop', or '(' after '#pragma clang attribute'}}
-#pragma clang attribute pushpop // expected-error {{unexpected argument 'pushpop' to '#pragma clang attribute'; expected 'push' or 'pop'}}
+#pragma clang attribute pushpop // expected-error {{expected '.' after pragma attribute namespace 'pushpop'}}
 
 #pragma clang attribute push
 #pragma clang attribute pop
diff --git a/test/Sema/pragma-attribute-namespace.c b/test/Sema/pragma-attribute-namespace.c
new file mode 100644
index 0000000000..35b6419f7d
--- /dev/null
+++ b/test/Sema/pragma-attribute-namespace.c
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+#pragma clang attribute MyNamespace.push (__attribute__((annotate)), apply_to=function) // expected-error 2 {{'annotate' attribute}}
+
+int some_func(); // expected-note{{when applied to this declaration}}
+
+#pragma clang attribute pop // expected-error{{'#pragma clang attribute pop' with no matching '#pragma clang attribute push'}}
+#pragma clang attribute NotMyNamespace.pop // expected-error{{'#pragma clang attribute NotMyNamespace.pop' with no matching '#pragma clang attribute NotMyNamespace.push'}}
+
+#pragma clang attribute MyOtherNamespace.push (__attribute__((annotate)), apply_to=function) // expected-error 2 {{'annotate' attribute}}
+
+int some_other_func(); // expected-note 2 {{when applied to this declaration}}
+
+// Out of order!
+#pragma clang attribute MyNamespace.pop
+
+int some_other_other_func(); // expected-note 1 {{when applied to this declaration}}
+
+#pragma clang attribute MyOtherNamespace.pop
+
+#pragma clang attribute Misc. () // expected-error{{namespace can only apply to 'push' or 'pop' directives}} expected-note {{omit the namespace to add attributes to the most-recently pushed attribute group}}
+
+#pragma clang attribute Misc push // expected-error{{expected '.' after pragma attribute namespace 'Misc'}}
+
+// Test how pushes with namespaces interact with pushes without namespaces.
+
+#pragma clang attribute Merp.push (__attribute__((annotate)), apply_to=function) // expected-error{{'annotate' attribute}}
+#pragma clang attribute push (__attribute__((annotate)), apply_to=function) // expected-warning {{unused attribute}}
+#pragma clang attribute pop // expected-note{{ends here}}
+int test(); // expected-note{{when applied to this declaration}}
+#pragma clang attribute Merp.pop
+
+#pragma clang attribute push (__attribute__((annotate)), apply_to=function) // expected-warning {{unused attribute}}
+#pragma clang attribute Merp.push (__attribute__((annotate)), apply_to=function) // expected-error{{'annotate' attribute}}
+#pragma clang attribute pop // expected-note{{ends here}}
+int test2(); // expected-note{{when applied to this declaration}}
+#pragma clang attribute Merp.pop
-- 
cgit v1.2.3


From 6cbefbb5310964eb830eaf35ed1b993bb685f9ec Mon Sep 17 00:00:00 2001
From: Volodymyr Sapsai 
Date: Thu, 20 Dec 2018 22:43:26 +0000
Subject: [CodeGen] Fix assertion on emitting cleanup for object with inlined
 inherited constructor and non-trivial destructor.

Fixes assertion
> Assertion failed: (isa(Val) && "cast() argument of incompatible type!"), function cast, file llvm/Support/Casting.h, line 255.

It was triggered by trying to cast `FunctionDecl` to `CXXMethodDecl` as
`CGF.CurCodeDecl` in `CallBaseDtor::Emit`. It was happening because
cleanups were emitted in `ScalarExprEmitter::VisitExprWithCleanups`
after destroying `InlinedInheritingConstructorScope`, so
`CodeGenFunction.CurCodeDecl` didn't correspond to expected cleanup decl.

Fix the assertion by emitting cleanups before leaving
`InlinedInheritingConstructorScope` and changing `CurCodeDecl`.

Test cases based on a patch by Shoaib Meenai.

Fixes PR36748.

rdar://problem/45805151

Reviewers: rsmith, rjmccall

Reviewed By: rjmccall

Subscribers: jkorous, dexonsmith, cfe-commits, smeenai, compnerd

Differential Revision: https://reviews.llvm.org/D55543



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349848 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/CodeGen/CGClass.cpp                            |  1 +
 test/CodeGenCXX/inheriting-constructor-cleanup.cpp | 52 ++++++++++++++++++++++
 .../inheriting-constructor-cleanup.mm              | 43 ++++++++++++++++++
 3 files changed, 96 insertions(+)
 create mode 100644 test/CodeGenCXX/inheriting-constructor-cleanup.cpp
 create mode 100644 test/CodeGenObjCXX/inheriting-constructor-cleanup.mm

diff --git a/lib/CodeGen/CGClass.cpp b/lib/CodeGen/CGClass.cpp
index cfc912cc9a..f91f6ede49 100644
--- a/lib/CodeGen/CGClass.cpp
+++ b/lib/CodeGen/CGClass.cpp
@@ -2208,6 +2208,7 @@ void CodeGenFunction::EmitInlinedInheritingCXXConstructorCall(
   GlobalDecl GD(Ctor, CtorType);
   InlinedInheritingConstructorScope Scope(*this, GD);
   ApplyInlineDebugLocation DebugScope(*this, GD);
+  RunCleanupsScope RunCleanups(*this);
 
   // Save the arguments to be passed to the inherited constructor.
   CXXInheritedCtorInitExprArgs = Args;
diff --git a/test/CodeGenCXX/inheriting-constructor-cleanup.cpp b/test/CodeGenCXX/inheriting-constructor-cleanup.cpp
new file mode 100644
index 0000000000..3aac9ac9f7
--- /dev/null
+++ b/test/CodeGenCXX/inheriting-constructor-cleanup.cpp
@@ -0,0 +1,52 @@
+// RUN: %clang_cc1 -triple x86_64-darwin -std=c++11 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-darwin -std=c++11 -fcxx-exceptions -fexceptions -emit-llvm -o - %s | FileCheck %s --check-prefix=EXCEPTIONS
+
+// PR36748
+// rdar://problem/45805151
+
+// Classes to verify order of destroying function parameters.
+struct S1 {
+  ~S1();
+};
+struct S2 {
+  ~S2();
+};
+
+struct Base {
+  // Use variadic args to cause inlining the inherited constructor.
+  Base(const S1&, const S2&, const char *fmt, ...) {}
+};
+
+struct NonTrivialDtor {
+  ~NonTrivialDtor() {}
+};
+struct Inheritor : public NonTrivialDtor, public Base {
+  using Base::Base;
+};
+
+void f() {
+  Inheritor(S1(), S2(), "foo");
+  // CHECK-LABEL: define void @_Z1fv
+  // CHECK: %[[TMP1:.*]] = alloca %struct.S1
+  // CHECK: %[[TMP2:.*]] = alloca %struct.S2
+  // CHECK: call void (%struct.Base*, %struct.S1*, %struct.S2*, i8*, ...) @_ZN4BaseC2ERK2S1RK2S2PKcz(%struct.Base* {{.*}}, %struct.S1* dereferenceable(1) %[[TMP1]], %struct.S2* dereferenceable(1) %[[TMP2]], i8* {{.*}})
+  // CHECK-NEXT: call void @_ZN9InheritorD1Ev(%struct.Inheritor* {{.*}})
+  // CHECK-NEXT: call void @_ZN2S2D1Ev(%struct.S2* %[[TMP2]])
+  // CHECK-NEXT: call void @_ZN2S1D1Ev(%struct.S1* %[[TMP1]])
+
+  // EXCEPTIONS-LABEL: define void @_Z1fv
+  // EXCEPTIONS: %[[TMP1:.*]] = alloca %struct.S1
+  // EXCEPTIONS: %[[TMP2:.*]] = alloca %struct.S2
+  // EXCEPTIONS: invoke void (%struct.Base*, %struct.S1*, %struct.S2*, i8*, ...) @_ZN4BaseC2ERK2S1RK2S2PKcz(%struct.Base* {{.*}}, %struct.S1* dereferenceable(1) %[[TMP1]], %struct.S2* dereferenceable(1) %[[TMP2]], i8* {{.*}})
+  // EXCEPTIONS-NEXT: to label %[[CONT:.*]] unwind label %[[LPAD:.*]]
+
+  // EXCEPTIONS: [[CONT]]:
+  // EXCEPTIONS-NEXT: call void @_ZN9InheritorD1Ev(%struct.Inheritor* {{.*}})
+  // EXCEPTIONS-NEXT: call void @_ZN2S2D1Ev(%struct.S2* %[[TMP2]])
+  // EXCEPTIONS-NEXT: call void @_ZN2S1D1Ev(%struct.S1* %[[TMP1]])
+
+  // EXCEPTIONS: [[LPAD]]:
+  // EXCEPTIONS: call void @_ZN14NonTrivialDtorD2Ev(%struct.NonTrivialDtor* {{.*}})
+  // EXCEPTIONS-NEXT: call void @_ZN2S2D1Ev(%struct.S2* %[[TMP2]])
+  // EXCEPTIONS-NEXT: call void @_ZN2S1D1Ev(%struct.S1* %[[TMP1]])
+}
diff --git a/test/CodeGenObjCXX/inheriting-constructor-cleanup.mm b/test/CodeGenObjCXX/inheriting-constructor-cleanup.mm
new file mode 100644
index 0000000000..075fa9dba0
--- /dev/null
+++ b/test/CodeGenObjCXX/inheriting-constructor-cleanup.mm
@@ -0,0 +1,43 @@
+// RUN: %clang_cc1 -triple x86_64-darwin -std=c++11 -fobjc-arc -emit-llvm -o - %s | FileCheck %s --implicit-check-not "call\ "
+// rdar://problem/45805151
+
+struct Strong {
+  __strong id x;
+};
+
+struct Base {
+  // Use variadic args to cause inlining the inherited constructor.
+  Base(Strong s, ...) {}
+};
+
+struct NonTrivialDtor {
+  ~NonTrivialDtor() {}
+};
+struct Inheritor : public NonTrivialDtor, public Base {
+  using Base::Base;
+};
+
+id g(void);
+void f() {
+  Inheritor({g()});
+}
+// CHECK-LABEL: define void @_Z1fv
+// CHECK:       %[[TMP:.*]] = call i8* @_Z1gv()
+// CHECK:       {{.*}} = call i8* @objc_retainAutoreleasedReturnValue(i8* %[[TMP]])
+// CHECK:       call void (%struct.Base*, i8*, ...) @_ZN4BaseC2E6Strongz(%struct.Base* {{.*}}, i8* {{.*}})
+// CHECK-NEXT:  call void @_ZN9InheritorD1Ev(%struct.Inheritor* {{.*}})
+
+// CHECK-LABEL: define linkonce_odr void @_ZN4BaseC2E6Strongz(%struct.Base* {{.*}}, i8* {{.*}}, ...)
+// CHECK:       call void @_ZN6StrongD1Ev(%struct.Strong* {{.*}})
+
+// CHECK-LABEL: define linkonce_odr void @_ZN9InheritorD1Ev(%struct.Inheritor* {{.*}})
+// CHECK:       call void @_ZN9InheritorD2Ev(%struct.Inheritor* {{.*}})
+
+// CHECK-LABEL: define linkonce_odr void @_ZN6StrongD1Ev(%struct.Strong* {{.*}})
+// CHECK:       call void @_ZN6StrongD2Ev(%struct.Strong* {{.*}})
+
+// CHECK-LABEL: define linkonce_odr void @_ZN6StrongD2Ev(%struct.Strong* {{.*}})
+// CHECK:       call void @objc_storeStrong(i8** {{.*}}, i8* null)
+
+// CHECK-LABEL: define linkonce_odr void @_ZN9InheritorD2Ev(%struct.Inheritor* {{.*}})
+// CHECK:       call void @_ZN14NonTrivialDtorD2Ev(%struct.NonTrivialDtor* {{.*}})
-- 
cgit v1.2.3


From c1b91af3c35279aeb9d8f6a05556fe1cb57c362c Mon Sep 17 00:00:00 2001
From: Volodymyr Sapsai 
Date: Thu, 20 Dec 2018 23:26:29 +0000
Subject: [CodeGen] Fix a test from r349848 by replacing `objc_` with
 `llvm.objc.`

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349853 91177308-0d34-0410-b5e6-96231b3b80d8
---
 test/CodeGenObjCXX/inheriting-constructor-cleanup.mm | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/test/CodeGenObjCXX/inheriting-constructor-cleanup.mm b/test/CodeGenObjCXX/inheriting-constructor-cleanup.mm
index 075fa9dba0..229e84a0f5 100644
--- a/test/CodeGenObjCXX/inheriting-constructor-cleanup.mm
+++ b/test/CodeGenObjCXX/inheriting-constructor-cleanup.mm
@@ -23,7 +23,7 @@ void f() {
 }
 // CHECK-LABEL: define void @_Z1fv
 // CHECK:       %[[TMP:.*]] = call i8* @_Z1gv()
-// CHECK:       {{.*}} = call i8* @objc_retainAutoreleasedReturnValue(i8* %[[TMP]])
+// CHECK:       {{.*}} = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* %[[TMP]])
 // CHECK:       call void (%struct.Base*, i8*, ...) @_ZN4BaseC2E6Strongz(%struct.Base* {{.*}}, i8* {{.*}})
 // CHECK-NEXT:  call void @_ZN9InheritorD1Ev(%struct.Inheritor* {{.*}})
 
@@ -37,7 +37,7 @@ void f() {
 // CHECK:       call void @_ZN6StrongD2Ev(%struct.Strong* {{.*}})
 
 // CHECK-LABEL: define linkonce_odr void @_ZN6StrongD2Ev(%struct.Strong* {{.*}})
-// CHECK:       call void @objc_storeStrong(i8** {{.*}}, i8* null)
+// CHECK:       call void @llvm.objc.storeStrong(i8** {{.*}}, i8* null)
 
 // CHECK-LABEL: define linkonce_odr void @_ZN9InheritorD2Ev(%struct.Inheritor* {{.*}})
 // CHECK:       call void @_ZN14NonTrivialDtorD2Ev(%struct.NonTrivialDtor* {{.*}})
-- 
cgit v1.2.3


From 72c12de609ade2aeeddc4a6aba05e71eda79792c Mon Sep 17 00:00:00 2001
From: Artem Dergachev 
Date: Fri, 21 Dec 2018 00:18:58 +0000
Subject: [analyzer] RetainCount: Suppress retain detection heuristic on some
 CM methods.

If it ends with "Retain" like CFRetain and returns a CFTypeRef like CFRetain,
then it is not necessarily a CFRetain. But it is indeed true that these two
return something retained.

Differential Revision: https://reviews.llvm.org/D55907

rdar://problem/39390714


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349862 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/StaticAnalyzer/Core/RetainSummaryManager.cpp | 11 +++++++++
 test/Analysis/retain-release.m                   | 30 ++++++++++++++++++++++--
 2 files changed, 39 insertions(+), 2 deletions(-)

diff --git a/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp b/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
index 3bbb4c7f9a..0187ebaf3a 100644
--- a/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
+++ b/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
@@ -204,6 +204,11 @@ const RetainSummary *RetainSummaryManager::getSummaryForObjCOrCFObject(
     AllowAnnotations = false;
     return RetTy->isObjCIdType() ? getUnarySummary(FT, cfmakecollectable)
                                  : getPersistentStopSummary();
+  } else if (FName == "CMBufferQueueDequeueAndRetain" ||
+             FName == "CMBufferQueueDequeueIfDataReadyAndRetain") {
+    // Part of: .
+    return getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF), DoNothing,
+                                DoNothing);
   } else if (FName == "CFPlugInInstanceCreate") {
     return getPersistentSummary(RetEffect::MakeNoRet());
   } else if (FName == "IORegistryEntrySearchCFProperty" ||
@@ -591,6 +596,12 @@ RetainSummaryManager::canEval(const CallExpr *CE, const FunctionDecl *FD,
     // Handle: (CF|CG|CV)Retain
     //         CFAutorelease
     // It's okay to be a little sloppy here.
+    if (FName == "CMBufferQueueDequeueAndRetain" ||
+        FName == "CMBufferQueueDequeueIfDataReadyAndRetain") {
+      // Part of: .
+      // These are not retain. They just return something and retain it.
+      return None;
+    }
     if (cocoa::isRefType(ResultTy, "CF", FName) ||
         cocoa::isRefType(ResultTy, "CG", FName) ||
         cocoa::isRefType(ResultTy, "CV", FName))
diff --git a/test/Analysis/retain-release.m b/test/Analysis/retain-release.m
index 4694d6ca61..4a3695d42a 100644
--- a/test/Analysis/retain-release.m
+++ b/test/Analysis/retain-release.m
@@ -1,9 +1,20 @@
 // RUN: rm -f %t.objc.plist %t.objcpp.plist
-// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -analyzer-store=region -fblocks -verify -Wno-objc-root-class %s -analyzer-output=plist -o %t.objc.plist
-// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -analyzer-store=region -fblocks -verify -x objective-c++ -std=gnu++98 -Wno-objc-root-class %s -analyzer-output=plist -o %t.objcpp.plist
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10\
+// RUN:     -analyzer-checker=core,osx.coreFoundation.CFRetainRelease\
+// RUN:     -analyzer-checker=osx.cocoa.ClassRelease,osx.cocoa.RetainCount\
+// RUN:     -analyzer-checker=debug.ExprInspection -fblocks -verify %s\
+// RUN:     -Wno-objc-root-class -analyzer-output=plist -o %t.objcpp.plist
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10\
+// RUN:     -analyzer-checker=core,osx.coreFoundation.CFRetainRelease\
+// RUN:     -analyzer-checker=osx.cocoa.ClassRelease,osx.cocoa.RetainCount\
+// RUN:     -analyzer-checker=debug.ExprInspection -fblocks -verify %s\
+// RUN:     -Wno-objc-root-class -analyzer-output=plist -o %t.objcpp.plist\
+// RUN:     -x objective-c++ -std=gnu++98
 // FIXLATER: cat %t.objc.plist ; FileCheck --input-file=%t.objc.plist %s
 // FIXLATER: cat %t.objcpp.plist ; FileCheck --input-file=%t.objcpp.plist %s
 
+void clang_analyzer_eval(int);
+
 #if __has_feature(attribute_ns_returns_retained)
 #define NS_RETURNS_RETAINED __attribute__((ns_returns_retained))
 #endif
@@ -495,6 +506,21 @@ void testLeakWithReturnsRetainedOutParameter() {
   // status is returned.
 }
 
+typedef CFTypeRef CMBufferRef;
+
+typedef CFTypeRef *CMBufferQueueRef;
+
+CMBufferRef CMBufferQueueDequeueAndRetain(CMBufferQueueRef);
+
+void testCMBufferQueueDequeueAndRetain(CMBufferQueueRef queue) {
+  CMBufferRef buffer = CMBufferQueueDequeueAndRetain(queue); // expected-warning{{Potential leak of an object stored into 'buffer'}}
+  // There's a state split due to the eagerly-assume behavior.
+  // The point here is that we don't treat CMBufferQueueDequeueAndRetain
+  // as some sort of CFRetain() that returns its argument.
+  clang_analyzer_eval((CMFooRef)buffer == (CMFooRef)queue); // expected-warning{{TRUE}}
+                                                            // expected-warning@-1{{FALSE}}
+}
+
 // Test retain/release checker with CFString and CFMutableArray.
 void f11() {
   // Create the array.
-- 
cgit v1.2.3


From b1b14d809d8eccb80b5e6afecd53decd79c0d388 Mon Sep 17 00:00:00 2001
From: George Karpenkov 
Date: Fri, 21 Dec 2018 00:26:19 +0000
Subject: Revert "Revert "[driver] [analyzer] Fix a backward compatibility
 issue after r348038.""

This reverts commit 144927939587b790c0536f4ff08245043fc8d733.

Fixes the bug in the original commit.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349863 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/Driver/ToolChains/Clang.cpp                   | 10 ++-
 test/Analysis/invalid-a-na-ly-zer-con-fig-value.c | 80 +++++++++++++++++++++++
 test/Analysis/invalid-analyzer-config-value.c     |  5 ++
 3 files changed, 92 insertions(+), 3 deletions(-)
 create mode 100644 test/Analysis/invalid-a-na-ly-zer-con-fig-value.c

diff --git a/lib/Driver/ToolChains/Clang.cpp b/lib/Driver/ToolChains/Clang.cpp
index d377b3c032..87f9e818cc 100644
--- a/lib/Driver/ToolChains/Clang.cpp
+++ b/lib/Driver/ToolChains/Clang.cpp
@@ -2360,9 +2360,6 @@ static void RenderAnalyzerOptions(const ArgList &Args, ArgStringList &CmdArgs,
   // Treat blocks as analysis entry points.
   CmdArgs.push_back("-analyzer-opt-analyze-nested-blocks");
 
-  // Enable compatilibily mode to avoid analyzer-config related errors.
-  CmdArgs.push_back("-analyzer-config-compatibility-mode=true");
-
   // Add default argument set.
   if (!Args.hasArg(options::OPT__analyzer_no_default_checks)) {
     CmdArgs.push_back("-analyzer-checker=core");
@@ -3738,6 +3735,13 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
   if (isa(JA))
     RenderAnalyzerOptions(Args, CmdArgs, Triple, Input);
 
+  // Enable compatilibily mode to avoid analyzer-config related errors.
+  // Since we can't access frontend flags through hasArg, let's manually iterate
+  // through them.
+  for (auto Arg : Args.filtered(options::OPT_Xclang))
+    if (StringRef(Arg->getValue()) == "-analyzer-config")
+      CmdArgs.push_back("-analyzer-config-compatibility-mode=true");
+
   CheckCodeGenerationOptions(D, Args);
 
   unsigned FunctionAlignment = ParseFunctionAlignment(TC, Args);
diff --git a/test/Analysis/invalid-a-na-ly-zer-con-fig-value.c b/test/Analysis/invalid-a-na-ly-zer-con-fig-value.c
new file mode 100644
index 0000000000..1b6c97ad1e
--- /dev/null
+++ b/test/Analysis/invalid-a-na-ly-zer-con-fig-value.c
@@ -0,0 +1,80 @@
+// Same as invalid-analyzer-config-value.c but without -analyzer-config
+// in the file name, so that argument string pattern matching
+// didn't accidentally match it.
+
+// RUN: not %clang_analyze_cc1 -verify %s \
+// RUN:   -analyzer-checker=core \
+// RUN:   -analyzer-config notes-as-events=yesplease \
+// RUN:   2>&1 | FileCheck %s -check-prefix=CHECK-BOOL-INPUT
+
+// CHECK-BOOL-INPUT: (frontend): invalid input for analyzer-config option
+// CHECK-BOOL-INPUT-SAME:        'notes-as-events', that expects a boolean value
+
+// RUN: %clang_analyze_cc1 -verify %s \
+// RUN:   -analyzer-checker=core \
+// RUN:   -analyzer-config-compatibility-mode=true \
+// RUN:   -analyzer-config notes-as-events=yesplease
+
+
+// RUN: not %clang_analyze_cc1 -verify %s \
+// RUN:   -analyzer-checker=core \
+// RUN:   -analyzer-config max-inlinable-size=400km/h \
+// RUN:   2>&1 | FileCheck %s -check-prefix=CHECK-UINT-INPUT
+
+// CHECK-UINT-INPUT: (frontend): invalid input for analyzer-config option
+// CHECK-UINT-INPUT-SAME:        'max-inlinable-size', that expects an unsigned
+// CHECK-UINT-INPUT-SAME:        value
+
+// RUN: %clang_analyze_cc1 -verify %s \
+// RUN:   -analyzer-checker=core \
+// RUN:   -analyzer-config-compatibility-mode=true \
+// RUN:   -analyzer-config max-inlinable-size=400km/h
+
+
+// RUN: not %clang_analyze_cc1 -verify %s \
+// RUN:   -analyzer-checker=core \
+// RUN:   -analyzer-config ctu-dir=0123012301230123 \
+// RUN:   2>&1 | FileCheck %s -check-prefix=CHECK-FILENAME-INPUT
+
+// CHECK-FILENAME-INPUT: (frontend): invalid input for analyzer-config option
+// CHECK-FILENAME-INPUT-SAME:        'ctu-dir', that expects a filename
+// CHECK-FILENAME-INPUT-SAME:        value
+
+// RUN: %clang_analyze_cc1 -verify %s \
+// RUN:   -analyzer-checker=core \
+// RUN:   -analyzer-config-compatibility-mode=true \
+// RUN:   -analyzer-config ctu-dir=0123012301230123
+
+
+// RUN: not %clang_analyze_cc1 -verify %s \
+// RUN:   -analyzer-checker=core \
+// RUN:   -analyzer-config no-false-positives=true \
+// RUN:   2>&1 | FileCheck %s -check-prefix=CHECK-UNKNOWN-CFG
+
+// CHECK-UNKNOWN-CFG: (frontend): unknown analyzer-config 'no-false-positives'
+
+// RUN: %clang_analyze_cc1 -verify %s \
+// RUN:   -analyzer-checker=core \
+// RUN:   -analyzer-config-compatibility-mode=true \
+// RUN:   -analyzer-config no-false-positives=true
+
+
+// Test the driver properly using "analyzer-config-compatibility-mode=true",
+// no longer causing an error on input error.
+// RUN: %clang --analyze %s
+
+// RUN: not %clang --analyze %s \
+// RUN:   -Xclang -analyzer-config -Xclang no-false-positives=true \
+// RUN:   -Xclang -analyzer-config-compatibility-mode=false \
+// RUN:   2>&1 | FileCheck %s -check-prefix=CHECK-NO-COMPAT
+
+// CHECK-NO-COMPAT: error: unknown analyzer-config 'no-false-positives'
+
+// Test the driver properly using "analyzer-config-compatibility-mode=true",
+// even if -analyze isn't specified.
+// RUN: %clang -fsyntax-only -Xclang -analyzer-config\
+// RUN:                      -Xclang remember=TheVasa %s
+
+// expected-no-diagnostics
+
+int main() {}
diff --git a/test/Analysis/invalid-analyzer-config-value.c b/test/Analysis/invalid-analyzer-config-value.c
index 34a73a7f9d..4ddcfe8207 100644
--- a/test/Analysis/invalid-analyzer-config-value.c
+++ b/test/Analysis/invalid-analyzer-config-value.c
@@ -66,6 +66,11 @@
 
 // CHECK-NO-COMPAT: error: unknown analyzer-config 'no-false-positives'
 
+// Test the driver properly using "analyzer-config-compatibility-mode=true",
+// even if -analyze isn't specified.
+// RUN: %clang -fsyntax-only -Xclang -analyzer-config\
+// RUN:                      -Xclang remember=TheVasa %s
+
 // expected-no-diagnostics
 
 int main() {}
-- 
cgit v1.2.3


From c3be051cae4ecd84e93d0f730b9a588ee93e9654 Mon Sep 17 00:00:00 2001
From: Artem Dergachev 
Date: Fri, 21 Dec 2018 01:11:21 +0000
Subject: [driver] [analyzer] Fix --analyze -Xanalyzer after r349863.

If an -analyzer-config is passed through -Xanalyzer, it is not found while
looking for -Xclang.

Additionally, don't emit -analyzer-config-compatibility-mode for *every*
-analyzer-config flag we encounter; one is enough.

https://reviews.llvm.org/D55823

rdar://problem/46504165


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349866 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/Driver/ToolChains/Clang.cpp                   | 15 +++++++++++++--
 test/Analysis/invalid-a-na-ly-zer-con-fig-value.c |  4 ++++
 test/Analysis/invalid-analyzer-config-value.c     |  4 ++++
 3 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/lib/Driver/ToolChains/Clang.cpp b/lib/Driver/ToolChains/Clang.cpp
index 87f9e818cc..ec4fdd2e6d 100644
--- a/lib/Driver/ToolChains/Clang.cpp
+++ b/lib/Driver/ToolChains/Clang.cpp
@@ -3738,9 +3738,20 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
   // Enable compatilibily mode to avoid analyzer-config related errors.
   // Since we can't access frontend flags through hasArg, let's manually iterate
   // through them.
+  bool FoundAnalyzerConfig = false;
   for (auto Arg : Args.filtered(options::OPT_Xclang))
-    if (StringRef(Arg->getValue()) == "-analyzer-config")
-      CmdArgs.push_back("-analyzer-config-compatibility-mode=true");
+    if (StringRef(Arg->getValue()) == "-analyzer-config") {
+      FoundAnalyzerConfig = true;
+      break;
+    }
+  if (!FoundAnalyzerConfig)
+    for (auto Arg : Args.filtered(options::OPT_Xanalyzer))
+      if (StringRef(Arg->getValue()) == "-analyzer-config") {
+        FoundAnalyzerConfig = true;
+        break;
+      }
+  if (FoundAnalyzerConfig)
+    CmdArgs.push_back("-analyzer-config-compatibility-mode=true");
 
   CheckCodeGenerationOptions(D, Args);
 
diff --git a/test/Analysis/invalid-a-na-ly-zer-con-fig-value.c b/test/Analysis/invalid-a-na-ly-zer-con-fig-value.c
index 1b6c97ad1e..ec967d3c47 100644
--- a/test/Analysis/invalid-a-na-ly-zer-con-fig-value.c
+++ b/test/Analysis/invalid-a-na-ly-zer-con-fig-value.c
@@ -74,6 +74,10 @@
 // even if -analyze isn't specified.
 // RUN: %clang -fsyntax-only -Xclang -analyzer-config\
 // RUN:                      -Xclang remember=TheVasa %s
+// RUN: %clang -fsyntax-only -Xanalyzer -analyzer-config\
+// RUN:                      -Xanalyzer remember=TheVasa %s
+// RUN: %clang --analyze -Xanalyzer -analyzer-config\
+// RUN:                  -Xanalyzer remember=TheVasa %s
 
 // expected-no-diagnostics
 
diff --git a/test/Analysis/invalid-analyzer-config-value.c b/test/Analysis/invalid-analyzer-config-value.c
index 4ddcfe8207..f942dd3e62 100644
--- a/test/Analysis/invalid-analyzer-config-value.c
+++ b/test/Analysis/invalid-analyzer-config-value.c
@@ -70,6 +70,10 @@
 // even if -analyze isn't specified.
 // RUN: %clang -fsyntax-only -Xclang -analyzer-config\
 // RUN:                      -Xclang remember=TheVasa %s
+// RUN: %clang -fsyntax-only -Xanalyzer -analyzer-config\
+// RUN:                      -Xanalyzer remember=TheVasa %s
+// RUN: %clang --analyze -Xanalyzer -analyzer-config\
+// RUN:                  -Xanalyzer remember=TheVasa %s
 
 // expected-no-diagnostics
 
-- 
cgit v1.2.3


From e6d51bc87e8263a5a8b341182840331d4bccead9 Mon Sep 17 00:00:00 2001
From: Reid Kleckner 
Date: Fri, 21 Dec 2018 01:40:29 +0000
Subject: [mingw] Don't mangle thiscall like fastcall etc

GCC does not mangle it when it is not explicit in the source.  The
mangler as currently written cannot differentiate between explicit and
implicit calling conventions, so we can't match GCC. Explicit thiscall
conventions are rare, so mangle as if the convention was implicit to be
as ABI compatible as possible.

Also fixes some tests using %itanium_abi_triple in some configurations
as a side effect.

Fixes PR40107.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349872 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/AST/ItaniumMangle.cpp          | 10 ++++++++--
 test/CodeGenCXX/mangle-win-ccs.cpp | 17 +++++++++++++----
 2 files changed, 21 insertions(+), 6 deletions(-)

diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp
index 8231ebe88b..98c843db31 100644
--- a/lib/AST/ItaniumMangle.cpp
+++ b/lib/AST/ItaniumMangle.cpp
@@ -2662,12 +2662,18 @@ StringRef CXXNameMangler::getCallingConvQualifierName(CallingConv CC) {
     // FIXME: we should be mangling all of the above.
     return "";
 
+  case CC_X86ThisCall:
+    // FIXME: To match mingw GCC, thiscall should only be mangled in when it is
+    // used explicitly. At this point, we don't have that much information in
+    // the AST, since clang tends to bake the convention into the canonical
+    // function type. thiscall only rarely used explicitly, so don't mangle it
+    // for now.
+    return "";
+
   case CC_X86StdCall:
     return "stdcall";
   case CC_X86FastCall:
     return "fastcall";
-  case CC_X86ThisCall:
-    return "thiscall";
   case CC_X86_64SysV:
     return "sysv_abi";
   case CC_Win64:
diff --git a/test/CodeGenCXX/mangle-win-ccs.cpp b/test/CodeGenCXX/mangle-win-ccs.cpp
index 5336d1d726..f5ddf974cf 100644
--- a/test/CodeGenCXX/mangle-win-ccs.cpp
+++ b/test/CodeGenCXX/mangle-win-ccs.cpp
@@ -17,7 +17,6 @@ void __attribute__((thiscall)) f_thiscall(int, int);
 int as_cdecl() { return func_as_ptr(f_cdecl); }
 int as_stdcall() { return func_as_ptr(f_stdcall); }
 int as_fastcall() { return func_as_ptr(f_fastcall); }
-int as_thiscall() { return func_as_ptr(f_thiscall); }
 
 // CHECK: define dso_local i32 @_Z8as_cdeclv()
 // CHECK:   call i32 @_ZL11func_as_ptrIPFviiEEiT_(void (i32, i32)* @_Z7f_cdeclii)
@@ -28,16 +27,26 @@ int as_thiscall() { return func_as_ptr(f_thiscall); }
 // CHECK: define dso_local i32 @_Z11as_fastcallv()
 // CHECK:   call i32 @_ZL11func_as_ptrIPU8fastcallFviiEEiT_(void (i32, i32)* @"\01@_Z10f_fastcallii@8")
 
-// CHECK: define dso_local i32 @_Z11as_thiscallv()
-// CHECK:   call i32 @_ZL11func_as_ptrIPU8thiscallFviiEEiT_(void (i32, i32)* @_Z10f_thiscallii)
+// PR40107: We should mangle thiscall here but we don't because we can't
+// disambiguate it from the member pointer case below where it shouldn't be
+// mangled.
+//int as_thiscall() { return func_as_ptr(f_thiscall); }
+// CHECKX: define dso_local i32 @_Z11as_thiscallv()
+// CHECKX:   call i32 @_ZL11func_as_ptrIPU8thiscallFviiEEiT_(void (i32, i32)* @_Z10f_thiscallii)
 
 // CHECK: define dso_local void @_Z11funcRefTypeRU8fastcallFviiE(void (i32, i32)* %fr)
 void funcRefType(void(__attribute__((fastcall)) & fr)(int, int)) {
   fr(1, 2);
 }
 
-// CHECK: define dso_local void @_Z12memptrCCTypeR3FooMS_U8fastcallFviiE(%struct.Foo* {{.*}}, { i32, i32 }* byval{{.*}})
 struct Foo { void bar(int, int); };
+
+// PR40107: In this case, the member function pointer uses the thiscall
+// convention, but GCC doesn't mangle it, so we don't either.
+// CHECK: define dso_local void @_Z15memptr_thiscallP3FooMS_FvvE(%struct.Foo* {{.*}})
+void memptr_thiscall(Foo *o, void (Foo::*mp)()) { (o->*mp)(); }
+
+// CHECK: define dso_local void @_Z12memptrCCTypeR3FooMS_U8fastcallFviiE(%struct.Foo* {{.*}}, { i32, i32 }* byval{{.*}})
 void memptrCCType(Foo &o, void (__attribute__((fastcall)) Foo::*mp)(int, int)) {
   (o.*mp)(1, 2);
 }
-- 
cgit v1.2.3


From dcd44990a807cc0770633a5ae634d7f7ac45c8e9 Mon Sep 17 00:00:00 2001
From: George Karpenkov 
Date: Fri, 21 Dec 2018 02:16:23 +0000
Subject: [analyzer] Fix a bug in RetainCountDiagnostics while printing a note
 on mismatched summary in inlined functions

Previously, we were not printing a note at all if at least one of the parameters was not annotated.

rdar://46888422

Differential Revision: https://reviews.llvm.org/D55972

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349875 91177308-0d34-0410-b5e6-96231b3b80d8
---
 .../RetainCountChecker/RetainCountDiagnostics.cpp        |  5 ++---
 test/Analysis/osobject-retain-release.cpp                | 16 ++++++++++++++++
 2 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
index 9dff0be138..8fdd105f18 100644
--- a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
+++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
@@ -268,7 +268,7 @@ annotateConsumedSummaryMismatch(const ExplodedNode *N,
     const ParmVarDecl *PVD = Parameters[I];
 
     if (!PVD->hasAttr())
-      return nullptr;
+      continue;
 
     if (SymbolRef SR = Call->getArgSVal(I).getAsLocSymbol()) {
       const RefVal *CountBeforeCall = getRefBinding(CN->getState(), SR);
@@ -311,10 +311,9 @@ CFRefReportVisitor::VisitNode(const ExplodedNode *N,
                               BugReporterContext &BRC, BugReport &BR) {
   const SourceManager &SM = BRC.getSourceManager();
   CallEventManager &CEMgr = BRC.getStateManager().getCallEventManager();
-  if (auto CE = N->getLocationAs()) {
+  if (auto CE = N->getLocationAs())
     if (auto PD = annotateConsumedSummaryMismatch(N, *CE, SM, CEMgr))
       return PD;
-  }
 
   // FIXME: We will eventually need to handle non-statement-based events
   // (__attribute__((cleanup))).
diff --git a/test/Analysis/osobject-retain-release.cpp b/test/Analysis/osobject-retain-release.cpp
index c8bc4aeaa0..2efd20709b 100644
--- a/test/Analysis/osobject-retain-release.cpp
+++ b/test/Analysis/osobject-retain-release.cpp
@@ -93,6 +93,15 @@ struct OSMetaClassBase {
 void escape(void *);
 bool coin();
 
+bool os_consume_violation_two_args(OS_CONSUME OSObject *obj, bool extra) {
+  if (coin()) { // expected-note{{Assuming the condition is false}}
+                // expected-note@-1{{Taking false branch}}
+    escape(obj);
+    return true;
+  }
+  return false; // expected-note{{Parameter 'obj' is marked as consuming, but the function does not consume the reference}}
+}
+
 bool os_consume_violation(OS_CONSUME OSObject *obj) {
   if (coin()) { // expected-note{{Assuming the condition is false}}
                 // expected-note@-1{{Taking false branch}}
@@ -113,6 +122,13 @@ void use_os_consume_violation() {
 } // expected-note{{Object leaked: object allocated and stored into 'obj' is not referenced later in this execution path and has a retain count of +1}}
   // expected-warning@-1{{Potential leak of an object stored into 'obj'}}
 
+void use_os_consume_violation_two_args() {
+  OSObject *obj = new OSObject; // expected-note{{Operator 'new' returns an OSObject of type OSObject with a +1 retain count}}
+  os_consume_violation_two_args(obj, coin()); // expected-note{{Calling 'os_consume_violation_two_args'}}
+                             // expected-note@-1{{Returning from 'os_consume_violation_two_args'}}
+} // expected-note{{Object leaked: object allocated and stored into 'obj' is not referenced later in this execution path and has a retain count of +1}}
+  // expected-warning@-1{{Potential leak of an object stored into 'obj'}}
+
 void use_os_consume_ok() {
   OSObject *obj = new OSObject;
   os_consume_ok(obj);
-- 
cgit v1.2.3


From 4e2a388a999e41a12743314deb9e0f060252a621 Mon Sep 17 00:00:00 2001
From: George Karpenkov 
Date: Fri, 21 Dec 2018 02:16:36 +0000
Subject: [analyzer] Perform escaping in RetainCountChecker on type mismatch
 even for inlined functions

The fix done in D55465 did not previously apply when the function was inlined.

rdar://46889541

Differential Revision: https://reviews.llvm.org/D55976

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349876 91177308-0d34-0410-b5e6-96231b3b80d8
---
 .../RetainCountChecker/RetainCountChecker.cpp      | 51 ++++++++++++----------
 test/Analysis/osobject-retain-release.cpp          | 10 +++++
 2 files changed, 38 insertions(+), 23 deletions(-)

diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
index 488cf6d3eb..87c1ad9edb 100644
--- a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
@@ -502,6 +502,25 @@ static Optional refValFromRetEffect(RetEffect RE,
   return None;
 }
 
+static bool isPointerToObject(QualType QT) {
+  QualType PT = QT->getPointeeType();
+  if (!PT.isNull())
+    if (PT->getAsCXXRecordDecl())
+      return true;
+  return false;
+}
+
+/// Whether the tracked value should be escaped on a given call.
+/// OSObjects are escaped when passed to void * / etc.
+static bool shouldEscapeArgumentOnCall(const CallEvent &CE, unsigned ArgIdx,
+                                       const RefVal *TrackedValue) {
+  if (TrackedValue->getObjKind() != RetEffect::OS)
+    return false;
+  if (ArgIdx >= CE.parameters().size())
+    return false;
+  return !isPointerToObject(CE.parameters()[ArgIdx]->getType());
+}
+
 // We don't always get the exact modeling of the function with regards to the
 // retain count checker even when the function is inlined. For example, we need
 // to stop tracking the symbols which were marked with StopTrackingHard.
@@ -512,11 +531,16 @@ void RetainCountChecker::processSummaryOfInlined(const RetainSummary &Summ,
 
   // Evaluate the effect of the arguments.
   for (unsigned idx = 0, e = CallOrMsg.getNumArgs(); idx != e; ++idx) {
-    if (Summ.getArg(idx) == StopTrackingHard) {
-      SVal V = CallOrMsg.getArgSVal(idx);
-      if (SymbolRef Sym = V.getAsLocSymbol()) {
+    SVal V = CallOrMsg.getArgSVal(idx);
+
+    if (SymbolRef Sym = V.getAsLocSymbol()) {
+      bool ShouldRemoveBinding = Summ.getArg(idx) == StopTrackingHard;
+      if (const RefVal *T = getRefBinding(state, Sym))
+        if (shouldEscapeArgumentOnCall(CallOrMsg, idx, T))
+          ShouldRemoveBinding = true;
+
+      if (ShouldRemoveBinding)
         state = removeRefBinding(state, Sym);
-      }
     }
   }
 
@@ -574,25 +598,6 @@ static ProgramStateRef updateOutParameter(ProgramStateRef State,
   return State;
 }
 
-static bool isPointerToObject(QualType QT) {
-  QualType PT = QT->getPointeeType();
-  if (!PT.isNull())
-    if (PT->getAsCXXRecordDecl())
-      return true;
-  return false;
-}
-
-/// Whether the tracked value should be escaped on a given call.
-/// OSObjects are escaped when passed to void * / etc.
-static bool shouldEscapeArgumentOnCall(const CallEvent &CE, unsigned ArgIdx,
-                                       const RefVal *TrackedValue) {
-  if (TrackedValue->getObjKind() != RetEffect::OS)
-    return false;
-  if (ArgIdx >= CE.parameters().size())
-    return false;
-  return !isPointerToObject(CE.parameters()[ArgIdx]->getType());
-}
-
 void RetainCountChecker::checkSummary(const RetainSummary &Summ,
                                       const CallEvent &CallOrMsg,
                                       CheckerContext &C) const {
diff --git a/test/Analysis/osobject-retain-release.cpp b/test/Analysis/osobject-retain-release.cpp
index 2efd20709b..0cd9deff0e 100644
--- a/test/Analysis/osobject-retain-release.cpp
+++ b/test/Analysis/osobject-retain-release.cpp
@@ -90,7 +90,10 @@ struct OSMetaClassBase {
   static OSObject *safeMetaCast(const OSObject *inst, const OSMetaClass *meta);
 };
 
+typedef unsigned long MYTYPE;
+
 void escape(void *);
+void escape_with_source(MYTYPE p) {}
 bool coin();
 
 bool os_consume_violation_two_args(OS_CONSUME OSObject *obj, bool extra) {
@@ -139,6 +142,13 @@ void test_escaping_into_voidstar() {
   escape(obj);
 }
 
+void test_escape_has_source() {
+  OSObject *obj = new OSObject;
+  if (obj)
+    escape_with_source((MYTYPE)obj);
+  return;
+}
+
 void test_no_infinite_check_recursion(MyArray *arr) {
   OSObject *input = new OSObject;
   OSObject *o = arr->generateObject(input);
-- 
cgit v1.2.3


From 24b719c0fc2b1251a37741a2339ffcfe9cdcd475 Mon Sep 17 00:00:00 2001
From: Akira Hatanaka 
Date: Fri, 21 Dec 2018 07:05:36 +0000
Subject: [Sema] Produce diagnostics when C++17 aligned allocation/deallocation
 functions that are unavailable on Darwin are explicitly called or called from
 deleting destructors.

rdar://problem/40736230

Differential Revision: https://reviews.llvm.org/D47757

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349890 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/Sema/Sema.h                       |  9 ++++
 lib/Sema/SemaDeclCXX.cpp                        |  1 +
 lib/Sema/SemaExpr.cpp                           |  8 +++
 lib/Sema/SemaExprCXX.cpp                        | 45 +++++++++--------
 test/CXX/drs/dr2xx.cpp                          |  4 +-
 test/SemaCXX/unavailable_aligned_allocation.cpp | 67 +++++++++++++++++++++++++
 6 files changed, 112 insertions(+), 22 deletions(-)

diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index 2396b505cb..6d002b3710 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -5202,6 +5202,15 @@ public:
                          SourceRange DirectInitRange,
                          Expr *Initializer);
 
+  /// Determine whether \p FD is an aligned allocation or deallocation
+  /// function that is unavailable.
+  bool isUnavailableAlignedAllocationFunction(const FunctionDecl &FD) const;
+
+  /// Produce diagnostics if \p FD is an aligned allocation or deallocation
+  /// function that is unavailable.
+  void diagnoseUnavailableAlignedAllocation(const FunctionDecl &FD,
+                                            SourceLocation Loc);
+
   bool CheckAllocatedType(QualType AllocType, SourceLocation Loc,
                           SourceRange R);
 
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index d46aa23c27..8973d63255 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -8288,6 +8288,7 @@ bool Sema::CheckDestructor(CXXDestructorDecl *Destructor) {
         }
       }
 
+      DiagnoseUseOfDecl(OperatorDelete, Loc);
       MarkFunctionReferenced(Loc, OperatorDelete);
       Destructor->setOperatorDelete(OperatorDelete, ThisArg);
     }
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 4ba0fb12e7..5178b03cfd 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -66,6 +66,12 @@ bool Sema::CanUseDecl(NamedDecl *D, bool TreatUnavailableAsInvalid) {
     if (getLangOpts().CPlusPlus14 && FD->getReturnType()->isUndeducedType() &&
         DeduceReturnType(FD, SourceLocation(), /*Diagnose*/ false))
       return false;
+
+    // See if this is an aligned allocation/deallocation function that is
+    // unavailable.
+    if (TreatUnavailableAsInvalid &&
+        isUnavailableAlignedAllocationFunction(*FD))
+      return false;
   }
 
   // See if this function is unavailable.
@@ -228,6 +234,8 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, ArrayRef Locs,
     //   The function 'main' shall not be used within a program.
     if (cast(D)->isMain())
       Diag(Loc, diag::ext_main_used);
+
+    diagnoseUnavailableAlignedAllocation(*cast(D), Loc);
   }
 
   // See if this is an auto-typed variable whose initializer we are parsing.
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index 2b054c4b0f..18d0e78a4f 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -1744,28 +1744,33 @@ static bool isLegalArrayNewInitializer(CXXNewExpr::InitializationStyle Style,
   return false;
 }
 
-// Emit a diagnostic if an aligned allocation/deallocation function that is not
-// implemented in the standard library is selected.
-static void diagnoseUnavailableAlignedAllocation(const FunctionDecl &FD,
-                                                 SourceLocation Loc, bool IsDelete,
-                                                 Sema &S) {
-  if (!S.getLangOpts().AlignedAllocationUnavailable)
-    return;
-
-  // Return if there is a definition.
+bool
+Sema::isUnavailableAlignedAllocationFunction(const FunctionDecl &FD) const {
+  if (!getLangOpts().AlignedAllocationUnavailable)
+    return false;
   if (FD.isDefined())
-    return;
-
+    return false;
   bool IsAligned = false;
-  if (FD.isReplaceableGlobalAllocationFunction(&IsAligned) && IsAligned) {
-    const llvm::Triple &T = S.getASTContext().getTargetInfo().getTriple();
+  if (FD.isReplaceableGlobalAllocationFunction(&IsAligned) && IsAligned)
+    return true;
+  return false;
+}
+
+// Emit a diagnostic if an aligned allocation/deallocation function that is not
+// implemented in the standard library is selected.
+void Sema::diagnoseUnavailableAlignedAllocation(const FunctionDecl &FD,
+                                                SourceLocation Loc) {
+  if (isUnavailableAlignedAllocationFunction(FD)) {
+    const llvm::Triple &T = getASTContext().getTargetInfo().getTriple();
     StringRef OSName = AvailabilityAttr::getPlatformNameSourceSpelling(
-        S.getASTContext().getTargetInfo().getPlatformName());
+        getASTContext().getTargetInfo().getPlatformName());
 
-    S.Diag(Loc, diag::err_aligned_allocation_unavailable)
+    OverloadedOperatorKind Kind = FD.getDeclName().getCXXOverloadedOperator();
+    bool IsDelete = Kind == OO_Delete || Kind == OO_Array_Delete;
+    Diag(Loc, diag::err_aligned_allocation_unavailable)
         << IsDelete << FD.getType().getAsString() << OSName
         << alignedAllocMinVersion(T.getOS()).getAsString();
-    S.Diag(Loc, diag::note_silence_aligned_allocation_unavailable);
+    Diag(Loc, diag::note_silence_aligned_allocation_unavailable);
   }
 }
 
@@ -2149,13 +2154,11 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,
     if (DiagnoseUseOfDecl(OperatorNew, StartLoc))
       return ExprError();
     MarkFunctionReferenced(StartLoc, OperatorNew);
-    diagnoseUnavailableAlignedAllocation(*OperatorNew, StartLoc, false, *this);
   }
   if (OperatorDelete) {
     if (DiagnoseUseOfDecl(OperatorDelete, StartLoc))
       return ExprError();
     MarkFunctionReferenced(StartLoc, OperatorDelete);
-    diagnoseUnavailableAlignedAllocation(*OperatorDelete, StartLoc, true, *this);
   }
 
   // C++0x [expr.new]p17:
@@ -3405,8 +3408,7 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal,
       }
     }
 
-    diagnoseUnavailableAlignedAllocation(*OperatorDelete, StartLoc, true,
-                                         *this);
+    DiagnoseUseOfDecl(OperatorDelete, StartLoc);
 
     // Convert the operand to the type of the first parameter of operator
     // delete. This is only necessary if we selected a destroying operator
@@ -3539,6 +3541,9 @@ Sema::SemaBuiltinOperatorNewDeleteOverloaded(ExprResult TheCallResult,
     return ExprError();
   assert(OperatorNewOrDelete && "should be found");
 
+  DiagnoseUseOfDecl(OperatorNewOrDelete, TheCall->getExprLoc());
+  MarkFunctionReferenced(TheCall->getExprLoc(), OperatorNewOrDelete);
+
   TheCall->setType(OperatorNewOrDelete->getReturnType());
   for (unsigned i = 0; i != TheCall->getNumArgs(); ++i) {
     QualType ParamTy = OperatorNewOrDelete->getParamDecl(i)->getType();
diff --git a/test/CXX/drs/dr2xx.cpp b/test/CXX/drs/dr2xx.cpp
index 4e745ef2f4..b69c014b58 100644
--- a/test/CXX/drs/dr2xx.cpp
+++ b/test/CXX/drs/dr2xx.cpp
@@ -718,7 +718,7 @@ namespace dr261 { // dr261: no
     A() {}
   };
 
-  // FIXME: These are ill-formed, with a required diagnostic, for the same
+  // FIXME: This is ill-formed, with a required diagnostic, for the same
   // reason.
   struct B {
     inline void operator delete(void*) __attribute__((unused));
@@ -726,7 +726,7 @@ namespace dr261 { // dr261: no
   };
   struct C {
     inline void operator delete(void*) __attribute__((unused));
-    virtual ~C() {}
+    virtual ~C() {} // expected-warning {{'operator delete' was marked unused but was used}}
   };
 
   struct D {
diff --git a/test/SemaCXX/unavailable_aligned_allocation.cpp b/test/SemaCXX/unavailable_aligned_allocation.cpp
index 2000e0b6a3..3c746c38c6 100644
--- a/test/SemaCXX/unavailable_aligned_allocation.cpp
+++ b/test/SemaCXX/unavailable_aligned_allocation.cpp
@@ -124,6 +124,73 @@ void testOveralignedCheckOS() {
 // expected-note@-20 2 {{if you supply your own aligned allocation functions}}
 #endif
 
+// Test that diagnostics are produced when an unavailable aligned deallocation
+// function is called from a deleting destructor.
+struct alignas(256) OveralignedS2 {
+  int a[4];
+  virtual ~OveralignedS2();
+};
+
+OveralignedS2::~OveralignedS2() {}
+
+#ifdef NO_ERRORS
+// expected-no-diagnostics
+#else
+#if defined(IOS)
+// expected-error@-6 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on iOS 11 or newer}}}
+// expected-note@-7 {{if you supply your own aligned allocation functions}}
+#elif defined(TVOS)
+// expected-error@-9 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on tvOS 11 or newer}}}
+// expected-note@-10 {{if you supply your own aligned allocation functions}}
+#elif defined(WATCHOS)
+// expected-error@-12 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on watchOS 4 or newer}}}
+// expected-note@-13 {{if you supply your own aligned allocation functions}}
+#else
+// expected-error@-15 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on macOS 10.13 or newer}}}
+// expected-note@-16 {{if you supply your own aligned allocation functions}}
+#endif
+#endif
+
+void testExplicitOperatorNewDelete() {
+  void *p = operator new(128);
+  operator delete(p);
+  p = operator new[](128);
+  operator delete[](p);
+  p = __builtin_operator_new(128);
+  __builtin_operator_delete(p);
+}
+
+void testExplicitOperatorNewDeleteOveraligned() {
+  void *p = operator new(128, (std::align_val_t)64);
+  operator delete(p, (std::align_val_t)64);
+  p = operator new[](128, (std::align_val_t)64);
+  operator delete[](p, (std::align_val_t)64);
+  p = __builtin_operator_new(128, (std::align_val_t)64);
+  __builtin_operator_delete(p, (std::align_val_t)64);
+}
+
+#ifdef NO_ERRORS
+// expected-no-diagnostics
+#else
+// expected-error@-11 {{aligned allocation function of type 'void *(unsigned long, enum std::align_val_t)' is only available on}}
+// expected-note@-12 {{if you supply your own aligned allocation functions}}
+
+// expected-error@-13 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on}}
+// expected-note@-14 {{if you supply your own aligned allocation functions}}
+
+// expected-error@-15 {{aligned allocation function of type 'void *(unsigned long, enum std::align_val_t)' is only available on}}
+// expected-note@-16 {{if you supply your own aligned allocation functions}}
+
+// expected-error@-17 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on}}
+// expected-note@-18 {{if you supply your own aligned allocation functions}}
+
+// expected-error@-19 {{aligned allocation function of type 'void *(unsigned long, enum std::align_val_t)' is only available on}}
+// expected-note@-20 {{if you supply your own aligned allocation functions}}
+
+// expected-error@-21 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on}}
+// expected-note@-22 {{if you supply your own aligned allocation functions}}
+#endif
+
 // No errors if user-defined aligned allocation functions are available.
 void *operator new(std::size_t __sz, std::align_val_t) {
   static char array[256];
-- 
cgit v1.2.3


From 5497b2946151d2c29d5d55cf556c42e83b51ea22 Mon Sep 17 00:00:00 2001
From: Simon Pilgrim 
Date: Fri, 21 Dec 2018 10:11:23 +0000
Subject: Revert rL349876 from cfe/trunk: [analyzer] Perform escaping in
 RetainCountChecker on type mismatch even for inlined functions

The fix done in D55465 did not previously apply when the function was inlined.

rdar://46889541

Differential Revision: https://reviews.llvm.org/D55976
........
Fixes broken buildbot: http://lab.llvm.org:8011/builders/llvm-clang-x86_64-expensive-checks-win/builds/14764

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349894 91177308-0d34-0410-b5e6-96231b3b80d8
---
 .../RetainCountChecker/RetainCountChecker.cpp      | 51 ++++++++++------------
 test/Analysis/osobject-retain-release.cpp          | 10 -----
 2 files changed, 23 insertions(+), 38 deletions(-)

diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
index 87c1ad9edb..488cf6d3eb 100644
--- a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
@@ -502,25 +502,6 @@ static Optional refValFromRetEffect(RetEffect RE,
   return None;
 }
 
-static bool isPointerToObject(QualType QT) {
-  QualType PT = QT->getPointeeType();
-  if (!PT.isNull())
-    if (PT->getAsCXXRecordDecl())
-      return true;
-  return false;
-}
-
-/// Whether the tracked value should be escaped on a given call.
-/// OSObjects are escaped when passed to void * / etc.
-static bool shouldEscapeArgumentOnCall(const CallEvent &CE, unsigned ArgIdx,
-                                       const RefVal *TrackedValue) {
-  if (TrackedValue->getObjKind() != RetEffect::OS)
-    return false;
-  if (ArgIdx >= CE.parameters().size())
-    return false;
-  return !isPointerToObject(CE.parameters()[ArgIdx]->getType());
-}
-
 // We don't always get the exact modeling of the function with regards to the
 // retain count checker even when the function is inlined. For example, we need
 // to stop tracking the symbols which were marked with StopTrackingHard.
@@ -531,16 +512,11 @@ void RetainCountChecker::processSummaryOfInlined(const RetainSummary &Summ,
 
   // Evaluate the effect of the arguments.
   for (unsigned idx = 0, e = CallOrMsg.getNumArgs(); idx != e; ++idx) {
-    SVal V = CallOrMsg.getArgSVal(idx);
-
-    if (SymbolRef Sym = V.getAsLocSymbol()) {
-      bool ShouldRemoveBinding = Summ.getArg(idx) == StopTrackingHard;
-      if (const RefVal *T = getRefBinding(state, Sym))
-        if (shouldEscapeArgumentOnCall(CallOrMsg, idx, T))
-          ShouldRemoveBinding = true;
-
-      if (ShouldRemoveBinding)
+    if (Summ.getArg(idx) == StopTrackingHard) {
+      SVal V = CallOrMsg.getArgSVal(idx);
+      if (SymbolRef Sym = V.getAsLocSymbol()) {
         state = removeRefBinding(state, Sym);
+      }
     }
   }
 
@@ -598,6 +574,25 @@ static ProgramStateRef updateOutParameter(ProgramStateRef State,
   return State;
 }
 
+static bool isPointerToObject(QualType QT) {
+  QualType PT = QT->getPointeeType();
+  if (!PT.isNull())
+    if (PT->getAsCXXRecordDecl())
+      return true;
+  return false;
+}
+
+/// Whether the tracked value should be escaped on a given call.
+/// OSObjects are escaped when passed to void * / etc.
+static bool shouldEscapeArgumentOnCall(const CallEvent &CE, unsigned ArgIdx,
+                                       const RefVal *TrackedValue) {
+  if (TrackedValue->getObjKind() != RetEffect::OS)
+    return false;
+  if (ArgIdx >= CE.parameters().size())
+    return false;
+  return !isPointerToObject(CE.parameters()[ArgIdx]->getType());
+}
+
 void RetainCountChecker::checkSummary(const RetainSummary &Summ,
                                       const CallEvent &CallOrMsg,
                                       CheckerContext &C) const {
diff --git a/test/Analysis/osobject-retain-release.cpp b/test/Analysis/osobject-retain-release.cpp
index 0cd9deff0e..2efd20709b 100644
--- a/test/Analysis/osobject-retain-release.cpp
+++ b/test/Analysis/osobject-retain-release.cpp
@@ -90,10 +90,7 @@ struct OSMetaClassBase {
   static OSObject *safeMetaCast(const OSObject *inst, const OSMetaClass *meta);
 };
 
-typedef unsigned long MYTYPE;
-
 void escape(void *);
-void escape_with_source(MYTYPE p) {}
 bool coin();
 
 bool os_consume_violation_two_args(OS_CONSUME OSObject *obj, bool extra) {
@@ -142,13 +139,6 @@ void test_escaping_into_voidstar() {
   escape(obj);
 }
 
-void test_escape_has_source() {
-  OSObject *obj = new OSObject;
-  if (obj)
-    escape_with_source((MYTYPE)obj);
-  return;
-}
-
 void test_no_infinite_check_recursion(MyArray *arr) {
   OSObject *input = new OSObject;
   OSObject *o = arr->generateObject(input);
-- 
cgit v1.2.3


From 7d10f0803fe5d45a0dc9230049d5f3be46fbdf14 Mon Sep 17 00:00:00 2001
From: Bruno Ricci 
Date: Fri, 21 Dec 2018 14:10:18 +0000
Subject: [AST][NFC] Pass the AST context to one of the ctor of DeclRefExpr.

All of the other constructors already take a reference to the AST context.
This avoids calling Decl::getASTContext in most cases. Additionally move
the definition of the constructor from Expr.h to Expr.cpp since it is calling
DeclRefExpr::computeDependence. NFC.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349901 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/AST/Expr.h                   |  16 +---
 lib/AST/ASTContext.cpp                     |   2 +-
 lib/AST/Expr.cpp                           |  27 +++++--
 lib/Analysis/ThreadSafety.cpp              |   8 +-
 lib/Analysis/ThreadSafetyCommon.cpp        |   3 +-
 lib/CodeGen/CGBlocks.cpp                   |   4 +-
 lib/CodeGen/CGDecl.cpp                     |   4 +-
 lib/CodeGen/CGObjC.cpp                     |  40 +++++-----
 lib/CodeGen/CGOpenMPRuntime.cpp            |   2 +-
 lib/CodeGen/CGStmtOpenMP.cpp               |  39 +++++-----
 lib/Frontend/Rewrite/RewriteModernObjC.cpp | 120 ++++++++++++++---------------
 lib/Frontend/Rewrite/RewriteObjC.cpp       |  91 +++++++++++-----------
 lib/Sema/Sema.cpp                          |   3 +-
 lib/Sema/SemaCUDA.cpp                      |   2 +-
 lib/Sema/SemaExpr.cpp                      |   9 +--
 lib/Sema/SemaObjCProperty.cpp              |  16 ++--
 lib/Sema/SemaOverload.cpp                  |   8 +-
 lib/Sema/TreeTransform.h                   |   6 +-
 18 files changed, 200 insertions(+), 200 deletions(-)

diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index d57c45eec0..ee4e0d57b4 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -1086,20 +1086,10 @@ class DeclRefExpr final
   void computeDependence(const ASTContext &Ctx);
 
 public:
-  DeclRefExpr(ValueDecl *D, bool RefersToEnclosingVariableOrCapture, QualType T,
+  DeclRefExpr(const ASTContext &Ctx, ValueDecl *D,
+              bool RefersToEnclosingVariableOrCapture, QualType T,
               ExprValueKind VK, SourceLocation L,
-              const DeclarationNameLoc &LocInfo = DeclarationNameLoc())
-      : Expr(DeclRefExprClass, T, VK, OK_Ordinary, false, false, false, false),
-        D(D), DNLoc(LocInfo) {
-    DeclRefExprBits.HasQualifier = false;
-    DeclRefExprBits.HasTemplateKWAndArgsInfo = false;
-    DeclRefExprBits.HasFoundDecl = false;
-    DeclRefExprBits.HadMultipleCandidates = false;
-    DeclRefExprBits.RefersToEnclosingVariableOrCapture =
-        RefersToEnclosingVariableOrCapture;
-    DeclRefExprBits.Loc = L;
-    computeDependence(D->getASTContext());
-  }
+              const DeclarationNameLoc &LocInfo = DeclarationNameLoc());
 
   static DeclRefExpr *
   Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc,
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index fae1cf863c..21b6f36e9a 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -4320,7 +4320,7 @@ TemplateArgument ASTContext::getInjectedTemplateArg(NamedDecl *Param) {
     Arg = TemplateArgument(ArgType);
   } else if (auto *NTTP = dyn_cast(Param)) {
     Expr *E = new (*this) DeclRefExpr(
-        NTTP, /*enclosing*/false,
+        *this, NTTP, /*enclosing*/ false,
         NTTP->getType().getNonLValueExprType(*this),
         Expr::getValueKindForType(NTTP->getType()), NTTP->getLocation());
 
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 5a80016850..4f3c5b3344 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -341,16 +341,31 @@ void DeclRefExpr::computeDependence(const ASTContext &Ctx) {
     ExprBits.ContainsUnexpandedParameterPack = true;
 }
 
+DeclRefExpr::DeclRefExpr(const ASTContext &Ctx, ValueDecl *D,
+                         bool RefersToEnclosingVariableOrCapture, QualType T,
+                         ExprValueKind VK, SourceLocation L,
+                         const DeclarationNameLoc &LocInfo)
+    : Expr(DeclRefExprClass, T, VK, OK_Ordinary, false, false, false, false),
+      D(D), DNLoc(LocInfo) {
+  DeclRefExprBits.HasQualifier = false;
+  DeclRefExprBits.HasTemplateKWAndArgsInfo = false;
+  DeclRefExprBits.HasFoundDecl = false;
+  DeclRefExprBits.HadMultipleCandidates = false;
+  DeclRefExprBits.RefersToEnclosingVariableOrCapture =
+      RefersToEnclosingVariableOrCapture;
+  DeclRefExprBits.Loc = L;
+  computeDependence(Ctx);
+}
+
 DeclRefExpr::DeclRefExpr(const ASTContext &Ctx,
                          NestedNameSpecifierLoc QualifierLoc,
-                         SourceLocation TemplateKWLoc,
-                         ValueDecl *D, bool RefersToEnclosingVariableOrCapture,
-                         const DeclarationNameInfo &NameInfo,
-                         NamedDecl *FoundD,
+                         SourceLocation TemplateKWLoc, ValueDecl *D,
+                         bool RefersToEnclosingVariableOrCapture,
+                         const DeclarationNameInfo &NameInfo, NamedDecl *FoundD,
                          const TemplateArgumentListInfo *TemplateArgs,
                          QualType T, ExprValueKind VK)
-  : Expr(DeclRefExprClass, T, VK, OK_Ordinary, false, false, false, false),
-    D(D), DNLoc(NameInfo.getInfo()) {
+    : Expr(DeclRefExprClass, T, VK, OK_Ordinary, false, false, false, false),
+      D(D), DNLoc(NameInfo.getInfo()) {
   DeclRefExprBits.Loc = NameInfo.getLoc();
   DeclRefExprBits.HasQualifier = QualifierLoc ? 1 : 0;
   if (QualifierLoc) {
diff --git a/lib/Analysis/ThreadSafety.cpp b/lib/Analysis/ThreadSafety.cpp
index fe6d3a23a8..78e1b056e1 100644
--- a/lib/Analysis/ThreadSafety.cpp
+++ b/lib/Analysis/ThreadSafety.cpp
@@ -1939,7 +1939,8 @@ void BuildLockset::handleCall(const Expr *Exp, const NamedDecl *D,
   if (isScopedVar) {
     // Add the managing object as a dummy mutex, mapped to the underlying mutex.
     SourceLocation MLoc = VD->getLocation();
-    DeclRefExpr DRE(VD, false, VD->getType(), VK_LValue, VD->getLocation());
+    DeclRefExpr DRE(VD->getASTContext(), VD, false, VD->getType(), VK_LValue,
+                    VD->getLocation());
     // FIXME: does this store a pointer to DRE?
     CapabilityExpr Scp = Analyzer->SxBuilder.translateAttrExpr(&DRE, nullptr);
 
@@ -2475,8 +2476,9 @@ void ThreadSafetyAnalyzer::runAnalysis(AnalysisDeclContext &AC) {
 
           // Create a dummy expression,
           auto *VD = const_cast(AD.getVarDecl());
-          DeclRefExpr DRE(VD, false, VD->getType().getNonReferenceType(),
-                          VK_LValue, AD.getTriggerStmt()->getEndLoc());
+          DeclRefExpr DRE(VD->getASTContext(), VD, false,
+                          VD->getType().getNonReferenceType(), VK_LValue,
+                          AD.getTriggerStmt()->getEndLoc());
           LocksetBuilder.handleCall(&DRE, DD);
           break;
         }
diff --git a/lib/Analysis/ThreadSafetyCommon.cpp b/lib/Analysis/ThreadSafetyCommon.cpp
index 0c09974cf4..14d1d9c7a8 100644
--- a/lib/Analysis/ThreadSafetyCommon.cpp
+++ b/lib/Analysis/ThreadSafetyCommon.cpp
@@ -128,7 +128,8 @@ CapabilityExpr SExprBuilder::translateAttrExpr(const Expr *AttrExp,
   // Hack to handle constructors, where self cannot be recovered from
   // the expression.
   if (SelfDecl && !Ctx.SelfArg) {
-    DeclRefExpr SelfDRE(SelfDecl, false, SelfDecl->getType(), VK_LValue,
+    DeclRefExpr SelfDRE(SelfDecl->getASTContext(), SelfDecl, false,
+                        SelfDecl->getType(), VK_LValue,
                         SelfDecl->getLocation());
     Ctx.SelfArg = &SelfDRE;
 
diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp
index 6631bfb0df..06b794fc8d 100644
--- a/lib/CodeGen/CGBlocks.cpp
+++ b/lib/CodeGen/CGBlocks.cpp
@@ -1075,7 +1075,7 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) {
         src = I->second;
       }
     } else {
-      DeclRefExpr declRef(const_cast(variable),
+      DeclRefExpr declRef(getContext(), const_cast(variable),
                           /*RefersToEnclosingVariableOrCapture*/ CI.isNested(),
                           type.getNonReferenceType(), VK_LValue,
                           SourceLocation());
@@ -1149,7 +1149,7 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) {
 
       // We use one of these or the other depending on whether the
       // reference is nested.
-      DeclRefExpr declRef(const_cast(variable),
+      DeclRefExpr declRef(getContext(), const_cast(variable),
                           /*RefersToEnclosingVariableOrCapture*/ CI.isNested(),
                           type, VK_LValue, SourceLocation());
 
diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp
index 2b3696a4f2..2262c998af 100644
--- a/lib/CodeGen/CGDecl.cpp
+++ b/lib/CodeGen/CGDecl.cpp
@@ -547,7 +547,7 @@ namespace {
     void Emit(CodeGenFunction &CGF, Flags flags) override {
       // Compute the address of the local variable, in case it's a
       // byref or something.
-      DeclRefExpr DRE(const_cast(&Var), false,
+      DeclRefExpr DRE(CGF.getContext(), const_cast(&Var), false,
                       Var.getType(), VK_LValue, SourceLocation());
       llvm::Value *value = CGF.EmitLoadOfScalar(CGF.EmitDeclRefLValue(&DRE),
                                                 SourceLocation());
@@ -565,7 +565,7 @@ namespace {
       : CleanupFn(CleanupFn), FnInfo(*Info), Var(*Var) {}
 
     void Emit(CodeGenFunction &CGF, Flags flags) override {
-      DeclRefExpr DRE(const_cast(&Var), false,
+      DeclRefExpr DRE(CGF.getContext(), const_cast(&Var), false,
                       Var.getType(), VK_LValue, SourceLocation());
       // Compute the address of the local variable, in case it's a byref
       // or something.
diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp
index bfb31337b2..d497179a53 100644
--- a/lib/CodeGen/CGObjC.cpp
+++ b/lib/CodeGen/CGObjC.cpp
@@ -1125,8 +1125,9 @@ static void emitStructSetterCall(CodeGenFunction &CGF, ObjCMethodDecl *OMD,
 
   // The second argument is the address of the parameter variable.
   ParmVarDecl *argVar = *OMD->param_begin();
-  DeclRefExpr argRef(argVar, false, argVar->getType().getNonReferenceType(),
-                     VK_LValue, SourceLocation());
+  DeclRefExpr argRef(CGF.getContext(), argVar, false,
+                     argVar->getType().getNonReferenceType(), VK_LValue,
+                     SourceLocation());
   llvm::Value *argAddr = CGF.EmitLValue(&argRef).getPointer();
   argAddr = CGF.Builder.CreateBitCast(argAddr, CGF.Int8PtrTy);
   args.add(RValue::get(argAddr), CGF.getContext().VoidPtrTy);
@@ -1170,8 +1171,9 @@ static void emitCPPObjectAtomicSetterCall(CodeGenFunction &CGF,
 
   // The second argument is the address of the parameter variable.
   ParmVarDecl *argVar = *OMD->param_begin();
-  DeclRefExpr argRef(argVar, false, argVar->getType().getNonReferenceType(),
-                     VK_LValue, SourceLocation());
+  DeclRefExpr argRef(CGF.getContext(), argVar, false,
+                     argVar->getType().getNonReferenceType(), VK_LValue,
+                     SourceLocation());
   llvm::Value *argAddr = CGF.EmitLValue(&argRef).getPointer();
   argAddr = CGF.Builder.CreateBitCast(argAddr, CGF.Int8PtrTy);
   args.add(RValue::get(argAddr), CGF.getContext().VoidPtrTy);
@@ -1343,7 +1345,7 @@ CodeGenFunction::generateObjCSetterBody(const ObjCImplementationDecl *classImpl,
 
   // Otherwise, fake up some ASTs and emit a normal assignment.
   ValueDecl *selfDecl = setterMethod->getSelfDecl();
-  DeclRefExpr self(selfDecl, false, selfDecl->getType(),
+  DeclRefExpr self(getContext(), selfDecl, false, selfDecl->getType(),
                    VK_LValue, SourceLocation());
   ImplicitCastExpr selfLoad(ImplicitCastExpr::OnStack,
                             selfDecl->getType(), CK_LValueToRValue, &self,
@@ -1354,7 +1356,8 @@ CodeGenFunction::generateObjCSetterBody(const ObjCImplementationDecl *classImpl,
 
   ParmVarDecl *argDecl = *setterMethod->param_begin();
   QualType argType = argDecl->getType().getNonReferenceType();
-  DeclRefExpr arg(argDecl, false, argType, VK_LValue, SourceLocation());
+  DeclRefExpr arg(getContext(), argDecl, false, argType, VK_LValue,
+                  SourceLocation());
   ImplicitCastExpr argLoad(ImplicitCastExpr::OnStack,
                            argType.getUnqualifiedType(), CK_LValueToRValue,
                            &arg, VK_RValue);
@@ -1516,7 +1519,8 @@ void CodeGenFunction::GenerateObjCCtorDtorMethod(ObjCImplementationDecl *IMP,
 
 llvm::Value *CodeGenFunction::LoadObjCSelf() {
   VarDecl *Self = cast(CurFuncDecl)->getSelfDecl();
-  DeclRefExpr DRE(Self, /*is enclosing local*/ (CurFuncDecl != CurCodeDecl),
+  DeclRefExpr DRE(getContext(), Self,
+                  /*is enclosing local*/ (CurFuncDecl != CurCodeDecl),
                   Self->getType(), VK_LValue, SourceLocation());
   return EmitLoadOfScalar(EmitDeclRefLValue(&DRE), SourceLocation());
 }
@@ -1702,9 +1706,9 @@ void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S){
     // Initialize the variable, in case it's a __block variable or something.
     EmitAutoVarInit(variable);
 
-    const VarDecl* D = cast(SD->getSingleDecl());
-    DeclRefExpr tempDRE(const_cast(D), false, D->getType(),
-                        VK_LValue, SourceLocation());
+    const VarDecl *D = cast(SD->getSingleDecl());
+    DeclRefExpr tempDRE(getContext(), const_cast(D), false,
+                        D->getType(), VK_LValue, SourceLocation());
     elementLValue = EmitLValue(&tempDRE);
     elementType = D->getType();
     elementIsVariable = true;
@@ -3374,13 +3378,13 @@ CodeGenFunction::GenerateObjCAtomicSetterCopyHelperFunction(
 
   StartFunction(FD, ReturnTy, Fn, FI, args);
 
-  DeclRefExpr DstExpr(&DstDecl, false, DestTy,
-                      VK_RValue, SourceLocation());
+  DeclRefExpr DstExpr(getContext(), &DstDecl, false, DestTy, VK_RValue,
+                      SourceLocation());
   UnaryOperator DST(&DstExpr, UO_Deref, DestTy->getPointeeType(),
                     VK_LValue, OK_Ordinary, SourceLocation(), false);
 
-  DeclRefExpr SrcExpr(&SrcDecl, false, SrcTy,
-                      VK_RValue, SourceLocation());
+  DeclRefExpr SrcExpr(getContext(), &SrcDecl, false, SrcTy, VK_RValue,
+                      SourceLocation());
   UnaryOperator SRC(&SrcExpr, UO_Deref, SrcTy->getPointeeType(),
                     VK_LValue, OK_Ordinary, SourceLocation(), false);
 
@@ -3457,8 +3461,8 @@ CodeGenFunction::GenerateObjCAtomicGetterCopyHelperFunction(
 
   StartFunction(FD, ReturnTy, Fn, FI, args);
 
-  DeclRefExpr SrcExpr(&SrcDecl, false, SrcTy,
-                      VK_RValue, SourceLocation());
+  DeclRefExpr SrcExpr(getContext(), &SrcDecl, false, SrcTy, VK_RValue,
+                      SourceLocation());
 
   UnaryOperator SRC(&SrcExpr, UO_Deref, SrcTy->getPointeeType(),
                     VK_LValue, OK_Ordinary, SourceLocation(), false);
@@ -3483,8 +3487,8 @@ CodeGenFunction::GenerateObjCAtomicGetterCopyHelperFunction(
                              CXXConstExpr->getConstructionKind(),
                              SourceRange());
 
-  DeclRefExpr DstExpr(&DstDecl, false, DestTy,
-                      VK_RValue, SourceLocation());
+  DeclRefExpr DstExpr(getContext(), &DstDecl, false, DestTy, VK_RValue,
+                      SourceLocation());
 
   RValue DV = EmitAnyExpr(&DstExpr);
   CharUnits Alignment
diff --git a/lib/CodeGen/CGOpenMPRuntime.cpp b/lib/CodeGen/CGOpenMPRuntime.cpp
index d7a0a72de1..746d3d3e64 100644
--- a/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -353,7 +353,7 @@ public:
       if (VD->isLocalVarDeclOrParm())
         continue;
 
-      DeclRefExpr DRE(const_cast(VD),
+      DeclRefExpr DRE(CGF.getContext(), const_cast(VD),
                       /*RefersToEnclosingVariableOrCapture=*/false,
                       VD->getType().getNonReferenceType(), VK_LValue,
                       C.getLocation());
diff --git a/lib/CodeGen/CGStmtOpenMP.cpp b/lib/CodeGen/CGStmtOpenMP.cpp
index 4f635efe71..ee38593084 100644
--- a/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/lib/CodeGen/CGStmtOpenMP.cpp
@@ -73,7 +73,7 @@ public:
         assert(VD == VD->getCanonicalDecl() &&
                "Canonical decl must be captured.");
         DeclRefExpr DRE(
-            const_cast(VD),
+            CGF.getContext(), const_cast(VD),
             isCapturedVar(CGF, VD) || (CGF.CapturedStmtInfo &&
                                        InlinedShareds.isGlobalVarCaptured(VD)),
             VD->getType().getNonReferenceType(), VK_LValue, C.getLocation());
@@ -191,7 +191,7 @@ public:
           auto *VD = C.getCapturedVar();
           assert(VD == VD->getCanonicalDecl() &&
                  "Canonical decl must be captured.");
-          DeclRefExpr DRE(const_cast(VD),
+          DeclRefExpr DRE(CGF.getContext(), const_cast(VD),
                           isCapturedVar(CGF, VD) ||
                               (CGF.CapturedStmtInfo &&
                                InlinedShareds.isGlobalVarCaptured(VD)),
@@ -222,7 +222,7 @@ LValue CodeGenFunction::EmitOMPSharedLValue(const Expr *E) {
           LambdaCaptureFields.lookup(OrigVD) ||
           (CapturedStmtInfo && CapturedStmtInfo->lookup(OrigVD)) ||
           (CurCodeDecl && isa(CurCodeDecl));
-      DeclRefExpr DRE(const_cast(OrigVD), IsCaptured,
+      DeclRefExpr DRE(getContext(), const_cast(OrigVD), IsCaptured,
                       OrigDRE->getType(), VK_LValue, OrigDRE->getExprLoc());
       return EmitLValue(&DRE);
     }
@@ -763,7 +763,7 @@ bool CodeGenFunction::EmitOMPFirstprivateClause(const OMPExecutableDirective &D,
         const auto *VDInit =
             cast(cast(*InitsRef)->getDecl());
         bool IsRegistered;
-        DeclRefExpr DRE(const_cast(OrigVD),
+        DeclRefExpr DRE(getContext(), const_cast(OrigVD),
                         /*RefersToEnclosingVariableOrCapture=*/FD != nullptr,
                         (*IRef)->getType(), VK_LValue, (*IRef)->getExprLoc());
         LValue OriginalLVal = EmitLValue(&DRE);
@@ -878,8 +878,8 @@ bool CodeGenFunction::EmitOMPCopyinClause(const OMPExecutableDirective &D) {
             getContext().getTargetInfo().isTLSSupported()) {
           assert(CapturedStmtInfo->lookup(VD) &&
                  "Copyin threadprivates should have been captured!");
-          DeclRefExpr DRE(const_cast(VD), true, (*IRef)->getType(),
-                          VK_LValue, (*IRef)->getExprLoc());
+          DeclRefExpr DRE(getContext(), const_cast(VD), true,
+                          (*IRef)->getType(), VK_LValue, (*IRef)->getExprLoc());
           MasterAddr = EmitLValue(&DRE).getAddress();
           LocalDeclMap.erase(VD);
         } else {
@@ -953,11 +953,10 @@ bool CodeGenFunction::EmitOMPLastprivateClauseInit(
         const auto *DestVD =
             cast(cast(*IDestRef)->getDecl());
         PrivateScope.addPrivate(DestVD, [this, OrigVD, IRef]() {
-          DeclRefExpr DRE(
-              const_cast(OrigVD),
-              /*RefersToEnclosingVariableOrCapture=*/CapturedStmtInfo->lookup(
-                  OrigVD) != nullptr,
-              (*IRef)->getType(), VK_LValue, (*IRef)->getExprLoc());
+          DeclRefExpr DRE(getContext(), const_cast(OrigVD),
+                          /*RefersToEnclosingVariableOrCapture=*/
+                              CapturedStmtInfo->lookup(OrigVD) != nullptr,
+                          (*IRef)->getType(), VK_LValue, (*IRef)->getExprLoc());
           return EmitLValue(&DRE).getAddress();
         });
         // Check if the variable is also a firstprivate: in this case IInit is
@@ -1384,7 +1383,7 @@ bool CodeGenFunction::EmitOMPLinearClauseInit(const OMPLoopDirective &D) {
               dyn_cast(VD->getInit()->IgnoreImpCasts())) {
         AutoVarEmission Emission = EmitAutoVarAlloca(*VD);
         const auto *OrigVD = cast(Ref->getDecl());
-        DeclRefExpr DRE(const_cast(OrigVD),
+        DeclRefExpr DRE(getContext(), const_cast(OrigVD),
                         CapturedStmtInfo->lookup(OrigVD) != nullptr,
                         VD->getInit()->getType(), VK_LValue,
                         VD->getInit()->getExprLoc());
@@ -1429,7 +1428,7 @@ void CodeGenFunction::EmitOMPLinearClauseFinal(
         }
       }
       const auto *OrigVD = cast(cast(*IC)->getDecl());
-      DeclRefExpr DRE(const_cast(OrigVD),
+      DeclRefExpr DRE(getContext(), const_cast(OrigVD),
                       CapturedStmtInfo->lookup(OrigVD) != nullptr,
                       (*IC)->getType(), VK_LValue, (*IC)->getExprLoc());
       Address OrigAddr = EmitLValue(&DRE).getAddress();
@@ -1497,7 +1496,7 @@ void CodeGenFunction::EmitOMPPrivateLoopCounters(
     if (LocalDeclMap.count(VD) || CapturedStmtInfo->lookup(VD) ||
         VD->hasGlobalStorage()) {
       (void)LoopScope.addPrivate(PrivateVD, [this, VD, E]() {
-        DeclRefExpr DRE(const_cast(VD),
+        DeclRefExpr DRE(getContext(), const_cast(VD),
                         LocalDeclMap.count(VD) || CapturedStmtInfo->lookup(VD),
                         E->getType(), VK_LValue, E->getExprLoc());
         return EmitLValue(&DRE).getAddress();
@@ -1644,7 +1643,7 @@ void CodeGenFunction::EmitOMPSimdFinal(
       if (CED) {
         OrigAddr = EmitLValue(CED->getInit()->IgnoreImpCasts()).getAddress();
       } else {
-        DeclRefExpr DRE(const_cast(PrivateVD),
+        DeclRefExpr DRE(getContext(), const_cast(PrivateVD),
                         /*RefersToEnclosingVariableOrCapture=*/false,
                         (*IPC)->getType(), VK_LValue, (*IPC)->getExprLoc());
         OrigAddr = EmitLValue(&DRE).getAddress();
@@ -2929,11 +2928,11 @@ void CodeGenFunction::EmitOMPTaskBasedDirective(
                                                           CopyFn, CallArgs);
       for (const auto &Pair : LastprivateDstsOrigs) {
         const auto *OrigVD = cast(Pair.second->getDecl());
-        DeclRefExpr DRE(
-            const_cast(OrigVD),
-            /*RefersToEnclosingVariableOrCapture=*/CGF.CapturedStmtInfo->lookup(
-                OrigVD) != nullptr,
-            Pair.second->getType(), VK_LValue, Pair.second->getExprLoc());
+        DeclRefExpr DRE(CGF.getContext(), const_cast(OrigVD),
+                        /*RefersToEnclosingVariableOrCapture=*/
+                            CGF.CapturedStmtInfo->lookup(OrigVD) != nullptr,
+                        Pair.second->getType(), VK_LValue,
+                        Pair.second->getExprLoc());
         Scope.addPrivate(Pair.first, [&CGF, &DRE]() {
           return CGF.EmitLValue(&DRE).getAddress();
         });
diff --git a/lib/Frontend/Rewrite/RewriteModernObjC.cpp b/lib/Frontend/Rewrite/RewriteModernObjC.cpp
index 8c2d4994bf..9ed8b1568b 100644
--- a/lib/Frontend/Rewrite/RewriteModernObjC.cpp
+++ b/lib/Frontend/Rewrite/RewriteModernObjC.cpp
@@ -2096,8 +2096,8 @@ RewriteModernObjC::SynthesizeCallToFunctionDecl(FunctionDecl *FD,
   QualType msgSendType = FD->getType();
 
   // Create a reference to the objc_msgSend() declaration.
-  DeclRefExpr *DRE =
-    new (Context) DeclRefExpr(FD, false, msgSendType, VK_LValue, SourceLocation());
+  DeclRefExpr *DRE = new (Context) DeclRefExpr(*Context, FD, false, msgSendType,
+                                               VK_LValue, SourceLocation());
 
   // Now, we cast the reference to a pointer to the objc_msgSend type.
   QualType pToFunc = Context->getPointerType(msgSendType);
@@ -2584,12 +2584,11 @@ Stmt *RewriteModernObjC::RewriteObjCStringLiteral(ObjCStringLiteral *Exp) {
   VarDecl *NewVD = VarDecl::Create(*Context, TUDecl, SourceLocation(),
                                    SourceLocation(), &Context->Idents.get(S),
                                    strType, nullptr, SC_Static);
-  DeclRefExpr *DRE = new (Context) DeclRefExpr(NewVD, false, strType, VK_LValue,
-                                               SourceLocation());
-  Expr *Unop = new (Context) UnaryOperator(DRE, UO_AddrOf,
-                                 Context->getPointerType(DRE->getType()),
-                                           VK_RValue, OK_Ordinary,
-                                           SourceLocation(), false);
+  DeclRefExpr *DRE = new (Context)
+      DeclRefExpr(*Context, NewVD, false, strType, VK_LValue, SourceLocation());
+  Expr *Unop = new (Context)
+      UnaryOperator(DRE, UO_AddrOf, Context->getPointerType(DRE->getType()),
+                    VK_RValue, OK_Ordinary, SourceLocation(), false);
   // cast to NSConstantString *
   CastExpr *cast = NoTypeInfoCStyleCastExpr(Context, Exp->getType(),
                                             CK_CPointerToObjCPointerCast, Unop);
@@ -2673,12 +2672,11 @@ Stmt *RewriteModernObjC::RewriteObjCBoxedExpr(ObjCBoxedExpr *Exp) {
   QualType msgSendType = MsgSendFlavor->getType();
 
   // Create a reference to the objc_msgSend() declaration.
-  DeclRefExpr *DRE = new (Context) DeclRefExpr(MsgSendFlavor, false, msgSendType,
-                                               VK_LValue, SourceLocation());
+  DeclRefExpr *DRE = new (Context) DeclRefExpr(
+      *Context, MsgSendFlavor, false, msgSendType, VK_LValue, SourceLocation());
 
-  CastExpr *cast = NoTypeInfoCStyleCastExpr(Context,
-                                            Context->getPointerType(Context->VoidTy),
-                                            CK_BitCast, DRE);
+  CastExpr *cast = NoTypeInfoCStyleCastExpr(
+      Context, Context->getPointerType(Context->VoidTy), CK_BitCast, DRE);
 
   // Now do the "normal" pointer to function cast.
   QualType castType =
@@ -2717,9 +2715,8 @@ Stmt *RewriteModernObjC::RewriteObjCArrayLiteralExpr(ObjCArrayLiteral *Exp) {
     getSimpleFunctionType(Context->VoidTy, IntQT, true);
   std::string NSArrayFName("__NSContainer_literal");
   FunctionDecl *NSArrayFD = SynthBlockInitFunctionDecl(NSArrayFName);
-  DeclRefExpr *NSArrayDRE =
-    new (Context) DeclRefExpr(NSArrayFD, false, NSArrayFType, VK_RValue,
-                              SourceLocation());
+  DeclRefExpr *NSArrayDRE = new (Context) DeclRefExpr(
+      *Context, NSArrayFD, false, NSArrayFType, VK_RValue, SourceLocation());
 
   SmallVector InitExprs;
   unsigned NumElements = Exp->getNumElements();
@@ -2796,12 +2793,11 @@ Stmt *RewriteModernObjC::RewriteObjCArrayLiteralExpr(ObjCArrayLiteral *Exp) {
   QualType msgSendType = MsgSendFlavor->getType();
 
   // Create a reference to the objc_msgSend() declaration.
-  DeclRefExpr *DRE = new (Context) DeclRefExpr(MsgSendFlavor, false, msgSendType,
-                                               VK_LValue, SourceLocation());
+  DeclRefExpr *DRE = new (Context) DeclRefExpr(
+      *Context, MsgSendFlavor, false, msgSendType, VK_LValue, SourceLocation());
 
-  CastExpr *cast = NoTypeInfoCStyleCastExpr(Context,
-                                            Context->getPointerType(Context->VoidTy),
-                                            CK_BitCast, DRE);
+  CastExpr *cast = NoTypeInfoCStyleCastExpr(
+      Context, Context->getPointerType(Context->VoidTy), CK_BitCast, DRE);
 
   // Now do the "normal" pointer to function cast.
   QualType castType =
@@ -2840,9 +2836,8 @@ Stmt *RewriteModernObjC::RewriteObjCDictionaryLiteralExpr(ObjCDictionaryLiteral
     getSimpleFunctionType(Context->VoidTy, IntQT, true);
   std::string NSDictFName("__NSContainer_literal");
   FunctionDecl *NSDictFD = SynthBlockInitFunctionDecl(NSDictFName);
-  DeclRefExpr *NSDictDRE =
-    new (Context) DeclRefExpr(NSDictFD, false, NSDictFType, VK_RValue,
-                              SourceLocation());
+  DeclRefExpr *NSDictDRE = new (Context) DeclRefExpr(
+      *Context, NSDictFD, false, NSDictFType, VK_RValue, SourceLocation());
 
   SmallVector KeyExprs;
   SmallVector ValueExprs;
@@ -2950,12 +2945,11 @@ Stmt *RewriteModernObjC::RewriteObjCDictionaryLiteralExpr(ObjCDictionaryLiteral
   QualType msgSendType = MsgSendFlavor->getType();
 
   // Create a reference to the objc_msgSend() declaration.
-  DeclRefExpr *DRE = new (Context) DeclRefExpr(MsgSendFlavor, false, msgSendType,
-                                               VK_LValue, SourceLocation());
+  DeclRefExpr *DRE = new (Context) DeclRefExpr(
+      *Context, MsgSendFlavor, false, msgSendType, VK_LValue, SourceLocation());
 
-  CastExpr *cast = NoTypeInfoCStyleCastExpr(Context,
-                                            Context->getPointerType(Context->VoidTy),
-                                            CK_BitCast, DRE);
+  CastExpr *cast = NoTypeInfoCStyleCastExpr(
+      Context, Context->getPointerType(Context->VoidTy), CK_BitCast, DRE);
 
   // Now do the "normal" pointer to function cast.
   QualType castType =
@@ -3178,8 +3172,8 @@ Expr *RewriteModernObjC::SynthMsgSendStretCallExpr(FunctionDecl *MsgSendStretFla
   FunctionDecl *FD =
       FunctionDecl::Create(*Context, TUDecl, SourceLocation(), SourceLocation(),
                            ID, FuncType, nullptr, SC_Extern, false, false);
-  DeclRefExpr *DRE = new (Context) DeclRefExpr(FD, false, castType, VK_RValue,
-                                               SourceLocation());
+  DeclRefExpr *DRE = new (Context) DeclRefExpr(*Context, FD, false, castType,
+                                               VK_RValue, SourceLocation());
   CallExpr *STCE = new (Context) CallExpr(*Context, DRE, MsgExprs,
                                           castType, VK_LValue, SourceLocation());
 
@@ -3247,7 +3241,8 @@ Stmt *RewriteModernObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
     InitExprs.push_back(
       NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
                                CK_BitCast,
-                   new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(),
+                   new (Context) DeclRefExpr(*Context,
+                                             CurMethodDef->getSelfDecl(),
                                              false,
                                              Context->getObjCIdType(),
                                              VK_RValue,
@@ -3278,9 +3273,9 @@ Stmt *RewriteModernObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
     if (LangOpts.MicrosoftExt) {
       SynthSuperConstructorFunctionDecl();
       // Simulate a constructor call...
-      DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperConstructorFunctionDecl,
-                                                   false, superType, VK_LValue,
-                                                   SourceLocation());
+      DeclRefExpr *DRE = new (Context)
+          DeclRefExpr(*Context, SuperConstructorFunctionDecl, false, superType,
+                      VK_LValue, SourceLocation());
       SuperRep = new (Context) CallExpr(*Context, DRE, InitExprs,
                                         superType, VK_LValue,
                                         SourceLocation());
@@ -3343,7 +3338,8 @@ Stmt *RewriteModernObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
     InitExprs.push_back(
       NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
                                CK_BitCast,
-                   new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(),
+                   new (Context) DeclRefExpr(*Context,
+                                             CurMethodDef->getSelfDecl(),
                                              false,
                                              Context->getObjCIdType(),
                                              VK_RValue, SourceLocation()))
@@ -3373,7 +3369,8 @@ Stmt *RewriteModernObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
     if (LangOpts.MicrosoftExt) {
       SynthSuperConstructorFunctionDecl();
       // Simulate a constructor call...
-      DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperConstructorFunctionDecl,
+      DeclRefExpr *DRE = new (Context) DeclRefExpr(*Context,
+                                                   SuperConstructorFunctionDecl,
                                                    false, superType, VK_LValue,
                                                    SourceLocation());
       SuperRep = new (Context) CallExpr(*Context, DRE, InitExprs,
@@ -3517,8 +3514,8 @@ Stmt *RewriteModernObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
   QualType msgSendType = MsgSendFlavor->getType();
 
   // Create a reference to the objc_msgSend() declaration.
-  DeclRefExpr *DRE = new (Context) DeclRefExpr(MsgSendFlavor, false, msgSendType,
-                                               VK_LValue, SourceLocation());
+  DeclRefExpr *DRE = new (Context) DeclRefExpr(
+      *Context, MsgSendFlavor, false, msgSendType, VK_LValue, SourceLocation());
 
   // Need to cast objc_msgSend to "void *" (to workaround a GCC bandaid).
   // If we don't do this cast, we get the following bizarre warning/note:
@@ -3595,10 +3592,9 @@ Stmt *RewriteModernObjC::RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp) {
   VarDecl *VD = VarDecl::Create(*Context, TUDecl, SourceLocation(),
                                 SourceLocation(), ID, getProtocolType(),
                                 nullptr, SC_Extern);
-  DeclRefExpr *DRE = new (Context) DeclRefExpr(VD, false, getProtocolType(),
-                                               VK_LValue, SourceLocation());
-  CastExpr *castExpr =
-    NoTypeInfoCStyleCastExpr(
+  DeclRefExpr *DRE = new (Context) DeclRefExpr(
+      *Context, VD, false, getProtocolType(), VK_LValue, SourceLocation());
+  CastExpr *castExpr = NoTypeInfoCStyleCastExpr(
       Context, Context->getPointerType(DRE->getType()), CK_BitCast, DRE);
   ReplaceStmt(Exp, castExpr);
   ProtocolExprDecls.insert(Exp->getProtocol()->getCanonicalDecl());
@@ -5285,15 +5281,15 @@ Stmt *RewriteModernObjC::SynthBlockInitExpr(BlockExpr *Exp,
   Tag += FuncName + "_block_impl_" + BlockNumber;
 
   FD = SynthBlockInitFunctionDecl(Tag);
-  DeclRefExpr *DRE = new (Context) DeclRefExpr(FD, false, FType, VK_RValue,
-                                               SourceLocation());
+  DeclRefExpr *DRE = new (Context)
+      DeclRefExpr(*Context, FD, false, FType, VK_RValue, SourceLocation());
 
   SmallVector InitExprs;
 
   // Initialize the block function.
   FD = SynthBlockInitFunctionDecl(Func);
-  DeclRefExpr *Arg = new (Context) DeclRefExpr(FD, false, FD->getType(),
-                                               VK_LValue, SourceLocation());
+  DeclRefExpr *Arg = new (Context) DeclRefExpr(
+      *Context, FD, false, FD->getType(), VK_LValue, SourceLocation());
   CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, Context->VoidPtrTy,
                                                 CK_BitCast, Arg);
   InitExprs.push_back(castExpr);
@@ -5304,15 +5300,11 @@ Stmt *RewriteModernObjC::SynthBlockInitExpr(BlockExpr *Exp,
   VarDecl *NewVD = VarDecl::Create(
       *Context, TUDecl, SourceLocation(), SourceLocation(),
       &Context->Idents.get(DescData), Context->VoidPtrTy, nullptr, SC_Static);
-  UnaryOperator *DescRefExpr =
-    new (Context) UnaryOperator(new (Context) DeclRefExpr(NewVD, false,
-                                                          Context->VoidPtrTy,
-                                                          VK_LValue,
-                                                          SourceLocation()),
-                                UO_AddrOf,
-                                Context->getPointerType(Context->VoidPtrTy),
-                                VK_RValue, OK_Ordinary,
-                                SourceLocation(), false);
+  UnaryOperator *DescRefExpr = new (Context) UnaryOperator(
+      new (Context) DeclRefExpr(*Context, NewVD, false, Context->VoidPtrTy,
+                                VK_LValue, SourceLocation()),
+      UO_AddrOf, Context->getPointerType(Context->VoidPtrTy), VK_RValue,
+      OK_Ordinary, SourceLocation(), false);
   InitExprs.push_back(DescRefExpr);
 
   // Add initializers for any closure decl refs.
@@ -5324,7 +5316,7 @@ Stmt *RewriteModernObjC::SynthBlockInitExpr(BlockExpr *Exp,
       if (isObjCType((*I)->getType())) {
         // FIXME: Conform to ABI ([[obj retain] autorelease]).
         FD = SynthBlockInitFunctionDecl((*I)->getName());
-        Exp = new (Context) DeclRefExpr(FD, false, FD->getType(),
+        Exp = new (Context) DeclRefExpr(*Context, FD, false, FD->getType(),
                                         VK_LValue, SourceLocation());
         if (HasLocalVariableExternalStorage(*I)) {
           QualType QT = (*I)->getType();
@@ -5335,13 +5327,13 @@ Stmt *RewriteModernObjC::SynthBlockInitExpr(BlockExpr *Exp,
         }
       } else if (isTopLevelBlockPointerType((*I)->getType())) {
         FD = SynthBlockInitFunctionDecl((*I)->getName());
-        Arg = new (Context) DeclRefExpr(FD, false, FD->getType(),
+        Arg = new (Context) DeclRefExpr(*Context, FD, false, FD->getType(),
                                         VK_LValue, SourceLocation());
         Exp = NoTypeInfoCStyleCastExpr(Context, Context->VoidPtrTy,
                                        CK_BitCast, Arg);
       } else {
         FD = SynthBlockInitFunctionDecl((*I)->getName());
-        Exp = new (Context) DeclRefExpr(FD, false, FD->getType(),
+        Exp = new (Context) DeclRefExpr(*Context, FD, false, FD->getType(),
                                         VK_LValue, SourceLocation());
         if (HasLocalVariableExternalStorage(*I)) {
           QualType QT = (*I)->getType();
@@ -5370,8 +5362,8 @@ Stmt *RewriteModernObjC::SynthBlockInitExpr(BlockExpr *Exp,
       QualType castT = Context->getPointerType(Context->getTagDeclType(RD));
 
       FD = SynthBlockInitFunctionDecl((*I)->getName());
-      Exp = new (Context) DeclRefExpr(FD, false, FD->getType(), VK_LValue,
-                                      SourceLocation());
+      Exp = new (Context) DeclRefExpr(*Context, FD, false, FD->getType(),
+                                      VK_LValue, SourceLocation());
       bool isNestedCapturedVar = false;
       if (block)
         for (const auto &CI : block->captures()) {
@@ -7497,9 +7489,9 @@ Stmt *RewriteModernObjC::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) {
                                        SourceLocation(), &Context->Idents.get(IvarOffsetName),
                                        Context->UnsignedLongTy, nullptr,
                                        SC_Extern);
-      DeclRefExpr *DRE = new (Context) DeclRefExpr(NewVD, false,
-                                                   Context->UnsignedLongTy, VK_LValue,
-                                                   SourceLocation());
+      DeclRefExpr *DRE = new (Context)
+          DeclRefExpr(*Context, NewVD, false, Context->UnsignedLongTy,
+                      VK_LValue, SourceLocation());
       BinaryOperator *addExpr =
         new (Context) BinaryOperator(castExpr, DRE, BO_Add,
                                      Context->getPointerType(Context->CharTy),
diff --git a/lib/Frontend/Rewrite/RewriteObjC.cpp b/lib/Frontend/Rewrite/RewriteObjC.cpp
index 5a5c81b061..0bbf4266fd 100644
--- a/lib/Frontend/Rewrite/RewriteObjC.cpp
+++ b/lib/Frontend/Rewrite/RewriteObjC.cpp
@@ -2009,7 +2009,7 @@ RewriteObjC::SynthesizeCallToFunctionDecl(FunctionDecl *FD,
   QualType msgSendType = FD->getType();
 
   // Create a reference to the objc_msgSend() declaration.
-  DeclRefExpr *DRE = new (Context) DeclRefExpr(FD, false, msgSendType,
+  DeclRefExpr *DRE = new (Context) DeclRefExpr(*Context, FD, false, msgSendType,
                                                VK_LValue, SourceLocation());
 
   // Now, we cast the reference to a pointer to the objc_msgSend type.
@@ -2506,12 +2506,11 @@ Stmt *RewriteObjC::RewriteObjCStringLiteral(ObjCStringLiteral *Exp) {
   VarDecl *NewVD = VarDecl::Create(*Context, TUDecl, SourceLocation(),
                                    SourceLocation(), &Context->Idents.get(S),
                                    strType, nullptr, SC_Static);
-  DeclRefExpr *DRE = new (Context) DeclRefExpr(NewVD, false, strType, VK_LValue,
-                                               SourceLocation());
-  Expr *Unop = new (Context) UnaryOperator(DRE, UO_AddrOf,
-                                 Context->getPointerType(DRE->getType()),
-                                           VK_RValue, OK_Ordinary,
-                                           SourceLocation(), false);
+  DeclRefExpr *DRE = new (Context)
+      DeclRefExpr(*Context, NewVD, false, strType, VK_LValue, SourceLocation());
+  Expr *Unop = new (Context)
+      UnaryOperator(DRE, UO_AddrOf, Context->getPointerType(DRE->getType()),
+                    VK_RValue, OK_Ordinary, SourceLocation(), false);
   // cast to NSConstantString *
   CastExpr *cast = NoTypeInfoCStyleCastExpr(Context, Exp->getType(),
                                             CK_CPointerToObjCPointerCast, Unop);
@@ -2589,9 +2588,9 @@ CallExpr *RewriteObjC::SynthMsgSendStretCallExpr(FunctionDecl *MsgSendStretFlavo
                                                 SmallVectorImpl &MsgExprs,
                                                 ObjCMethodDecl *Method) {
   // Create a reference to the objc_msgSend_stret() declaration.
-  DeclRefExpr *STDRE = new (Context) DeclRefExpr(MsgSendStretFlavor,
-                                                 false, msgSendType,
-                                                 VK_LValue, SourceLocation());
+  DeclRefExpr *STDRE =
+      new (Context) DeclRefExpr(*Context, MsgSendStretFlavor, false,
+                                msgSendType, VK_LValue, SourceLocation());
   // Need to cast objc_msgSend_stret to "void *" (see above comment).
   CastExpr *cast = NoTypeInfoCStyleCastExpr(Context,
                                   Context->getPointerType(Context->VoidTy),
@@ -2664,7 +2663,8 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
     InitExprs.push_back(
       NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
                                CK_BitCast,
-                   new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(),
+                   new (Context) DeclRefExpr(*Context,
+                                             CurMethodDef->getSelfDecl(),
                                              false,
                                              Context->getObjCIdType(),
                                              VK_RValue,
@@ -2697,9 +2697,9 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
     if (LangOpts.MicrosoftExt) {
       SynthSuperConstructorFunctionDecl();
       // Simulate a constructor call...
-      DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperConstructorFunctionDecl,
-                                                   false, superType, VK_LValue,
-                                                   SourceLocation());
+      DeclRefExpr *DRE = new (Context)
+          DeclRefExpr(*Context, SuperConstructorFunctionDecl, false, superType,
+                      VK_LValue, SourceLocation());
       SuperRep = new (Context) CallExpr(*Context, DRE, InitExprs,
                                         superType, VK_LValue,
                                         SourceLocation());
@@ -2759,7 +2759,8 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
     InitExprs.push_back(
       NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
                                CK_BitCast,
-                   new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(),
+                   new (Context) DeclRefExpr(*Context,
+                                             CurMethodDef->getSelfDecl(),
                                              false,
                                              Context->getObjCIdType(),
                                              VK_RValue, SourceLocation()))
@@ -2792,9 +2793,9 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
     if (LangOpts.MicrosoftExt) {
       SynthSuperConstructorFunctionDecl();
       // Simulate a constructor call...
-      DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperConstructorFunctionDecl,
-                                                   false, superType, VK_LValue,
-                                                   SourceLocation());
+      DeclRefExpr *DRE = new (Context)
+          DeclRefExpr(*Context, SuperConstructorFunctionDecl, false, superType,
+                      VK_LValue, SourceLocation());
       SuperRep = new (Context) CallExpr(*Context, DRE, InitExprs,
                                         superType, VK_LValue, SourceLocation());
       // The code for super is a little tricky to prevent collision with
@@ -2936,8 +2937,8 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
   QualType msgSendType = MsgSendFlavor->getType();
 
   // Create a reference to the objc_msgSend() declaration.
-  DeclRefExpr *DRE = new (Context) DeclRefExpr(MsgSendFlavor, false, msgSendType,
-                                               VK_LValue, SourceLocation());
+  DeclRefExpr *DRE = new (Context) DeclRefExpr(
+      *Context, MsgSendFlavor, false, msgSendType, VK_LValue, SourceLocation());
 
   // Need to cast objc_msgSend to "void *" (to workaround a GCC bandaid).
   // If we don't do this cast, we get the following bizarre warning/note:
@@ -3041,8 +3042,8 @@ Stmt *RewriteObjC::RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp) {
   VarDecl *VD = VarDecl::Create(*Context, TUDecl, SourceLocation(),
                                 SourceLocation(), ID, getProtocolType(),
                                 nullptr, SC_Extern);
-  DeclRefExpr *DRE = new (Context) DeclRefExpr(VD, false, getProtocolType(),
-                                               VK_LValue, SourceLocation());
+  DeclRefExpr *DRE = new (Context) DeclRefExpr(
+      *Context, VD, false, getProtocolType(), VK_LValue, SourceLocation());
   Expr *DerefExpr = new (Context) UnaryOperator(DRE, UO_AddrOf,
                              Context->getPointerType(DRE->getType()),
                              VK_RValue, OK_Ordinary, SourceLocation(), false);
@@ -4411,17 +4412,17 @@ Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp,
 
   // Simulate a constructor call...
   FD = SynthBlockInitFunctionDecl(Tag);
-  DeclRefExpr *DRE = new (Context) DeclRefExpr(FD, false, FType, VK_RValue,
-                                               SourceLocation());
+  DeclRefExpr *DRE = new (Context)
+      DeclRefExpr(*Context, FD, false, FType, VK_RValue, SourceLocation());
 
   SmallVector InitExprs;
 
   // Initialize the block function.
   FD = SynthBlockInitFunctionDecl(Func);
-  DeclRefExpr *Arg = new (Context) DeclRefExpr(FD, false, FD->getType(),
-                                               VK_LValue, SourceLocation());
-  CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, Context->VoidPtrTy,
-                                                CK_BitCast, Arg);
+  DeclRefExpr *Arg = new (Context) DeclRefExpr(
+      *Context, FD, false, FD->getType(), VK_LValue, SourceLocation());
+  CastExpr *castExpr =
+      NoTypeInfoCStyleCastExpr(Context, Context->VoidPtrTy, CK_BitCast, Arg);
   InitExprs.push_back(castExpr);
 
   // Initialize the block descriptor.
@@ -4430,15 +4431,11 @@ Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp,
   VarDecl *NewVD = VarDecl::Create(
       *Context, TUDecl, SourceLocation(), SourceLocation(),
       &Context->Idents.get(DescData), Context->VoidPtrTy, nullptr, SC_Static);
-  UnaryOperator *DescRefExpr =
-    new (Context) UnaryOperator(new (Context) DeclRefExpr(NewVD, false,
-                                                          Context->VoidPtrTy,
-                                                          VK_LValue,
-                                                          SourceLocation()),
-                                UO_AddrOf,
-                                Context->getPointerType(Context->VoidPtrTy),
-                                VK_RValue, OK_Ordinary,
-                                SourceLocation(), false);
+  UnaryOperator *DescRefExpr = new (Context) UnaryOperator(
+      new (Context) DeclRefExpr(*Context, NewVD, false, Context->VoidPtrTy,
+                                VK_LValue, SourceLocation()),
+      UO_AddrOf, Context->getPointerType(Context->VoidPtrTy), VK_RValue,
+      OK_Ordinary, SourceLocation(), false);
   InitExprs.push_back(DescRefExpr);
 
   // Add initializers for any closure decl refs.
@@ -4450,8 +4447,8 @@ Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp,
       if (isObjCType((*I)->getType())) {
         // FIXME: Conform to ABI ([[obj retain] autorelease]).
         FD = SynthBlockInitFunctionDecl((*I)->getName());
-        Exp = new (Context) DeclRefExpr(FD, false, FD->getType(), VK_LValue,
-                                        SourceLocation());
+        Exp = new (Context) DeclRefExpr(*Context, FD, false, FD->getType(),
+                                        VK_LValue, SourceLocation());
         if (HasLocalVariableExternalStorage(*I)) {
           QualType QT = (*I)->getType();
           QT = Context->getPointerType(QT);
@@ -4461,14 +4458,14 @@ Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp,
         }
       } else if (isTopLevelBlockPointerType((*I)->getType())) {
         FD = SynthBlockInitFunctionDecl((*I)->getName());
-        Arg = new (Context) DeclRefExpr(FD, false, FD->getType(), VK_LValue,
-                                        SourceLocation());
-        Exp = NoTypeInfoCStyleCastExpr(Context, Context->VoidPtrTy,
-                                       CK_BitCast, Arg);
+        Arg = new (Context) DeclRefExpr(*Context, FD, false, FD->getType(),
+                                        VK_LValue, SourceLocation());
+        Exp = NoTypeInfoCStyleCastExpr(Context, Context->VoidPtrTy, CK_BitCast,
+                                       Arg);
       } else {
         FD = SynthBlockInitFunctionDecl((*I)->getName());
-        Exp = new (Context) DeclRefExpr(FD, false, FD->getType(), VK_LValue,
-                                        SourceLocation());
+        Exp = new (Context) DeclRefExpr(*Context, FD, false, FD->getType(),
+                                        VK_LValue, SourceLocation());
         if (HasLocalVariableExternalStorage(*I)) {
           QualType QT = (*I)->getType();
           QT = Context->getPointerType(QT);
@@ -4495,8 +4492,8 @@ Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp,
       QualType castT = Context->getPointerType(Context->getTagDeclType(RD));
 
       FD = SynthBlockInitFunctionDecl((*I)->getName());
-      Exp = new (Context) DeclRefExpr(FD, false, FD->getType(), VK_LValue,
-                                      SourceLocation());
+      Exp = new (Context) DeclRefExpr(*Context, FD, false, FD->getType(),
+                                      VK_LValue, SourceLocation());
       bool isNestedCapturedVar = false;
       if (block)
         for (const auto &CI : block->captures()) {
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp
index a8e3b85fe0..9fa3996862 100644
--- a/lib/Sema/Sema.cpp
+++ b/lib/Sema/Sema.cpp
@@ -1415,7 +1415,8 @@ static void checkEscapingByref(VarDecl *VD, Sema &S) {
   EnterExpressionEvaluationContext scope(
       S, Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
   SourceLocation Loc = VD->getLocation();
-  Expr *VarRef = new (S.Context) DeclRefExpr(VD, false, T, VK_LValue, Loc);
+  Expr *VarRef =
+      new (S.Context) DeclRefExpr(S.Context, VD, false, T, VK_LValue, Loc);
   ExprResult Result = S.PerformMoveOrCopyInitialization(
       InitializedEntity::InitializeBlock(Loc, T, false), VD, VD->getType(),
       VarRef, /*AllowNRVO=*/true);
diff --git a/lib/Sema/SemaCUDA.cpp b/lib/Sema/SemaCUDA.cpp
index 13dd8d936f..ffc7288985 100644
--- a/lib/Sema/SemaCUDA.cpp
+++ b/lib/Sema/SemaCUDA.cpp
@@ -48,7 +48,7 @@ ExprResult Sema::ActOnCUDAExecConfigExpr(Scope *S, SourceLocation LLLLoc,
   QualType ConfigQTy = ConfigDecl->getType();
 
   DeclRefExpr *ConfigDR = new (Context)
-      DeclRefExpr(ConfigDecl, false, ConfigQTy, VK_LValue, LLLLoc);
+      DeclRefExpr(Context, ConfigDecl, false, ConfigQTy, VK_LValue, LLLLoc);
   MarkFunctionReferenced(LLLLoc, ConfigDecl);
 
   return ActOnCallExpr(S, ConfigDR, LLLLoc, ExecConfig, GGGLoc, nullptr,
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 5178b03cfd..041ecc9105 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -15044,9 +15044,8 @@ static bool captureInBlock(BlockScopeInfo *BSI, VarDecl *Var,
         // According to the blocks spec, the capture of a variable from
         // the stack requires a const copy constructor.  This is not true
         // of the copy/move done to move a __block variable to the heap.
-        Expr *DeclRef = new (S.Context) DeclRefExpr(Var, Nested,
-                                                  DeclRefType.withConst(),
-                                                  VK_LValue, Loc);
+        Expr *DeclRef = new (S.Context) DeclRefExpr(
+            S.Context, Var, Nested, DeclRefType.withConst(), VK_LValue, Loc);
 
         ExprResult Result
           = S.PerformCopyInitialization(
@@ -15122,8 +15121,8 @@ static bool captureInCapturedRegion(CapturedRegionScopeInfo *RSI,
     if (S.getLangOpts().OpenMP && RSI->CapRegionKind == CR_OpenMP)
       S.setOpenMPCaptureKind(Field, Var, RSI->OpenMPLevel);
 
-    CopyExpr = new (S.Context) DeclRefExpr(Var, RefersToCapturedVariable,
-                                            DeclRefType, VK_LValue, Loc);
+    CopyExpr = new (S.Context) DeclRefExpr(
+        S.Context, Var, RefersToCapturedVariable, DeclRefType, VK_LValue, Loc);
     Var->setReferenced(true);
     Var->markUsed(S.Context);
   }
diff --git a/lib/Sema/SemaObjCProperty.cpp b/lib/Sema/SemaObjCProperty.cpp
index d000027972..9412d01600 100644
--- a/lib/Sema/SemaObjCProperty.cpp
+++ b/lib/Sema/SemaObjCProperty.cpp
@@ -1412,9 +1412,9 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S,
       // FIXME. Eventually we want to do this for Objective-C as well.
       SynthesizedFunctionScope Scope(*this, getterMethod);
       ImplicitParamDecl *SelfDecl = getterMethod->getSelfDecl();
-      DeclRefExpr *SelfExpr =
-        new (Context) DeclRefExpr(SelfDecl, false, SelfDecl->getType(),
-                                  VK_LValue, PropertyDiagLoc);
+      DeclRefExpr *SelfExpr = new (Context)
+          DeclRefExpr(Context, SelfDecl, false, SelfDecl->getType(), VK_LValue,
+                      PropertyDiagLoc);
       MarkDeclRefReferenced(SelfExpr);
       Expr *LoadSelfExpr =
         ImplicitCastExpr::Create(Context, SelfDecl->getType(),
@@ -1464,9 +1464,9 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S,
       // FIXME. Eventually we want to do this for Objective-C as well.
       SynthesizedFunctionScope Scope(*this, setterMethod);
       ImplicitParamDecl *SelfDecl = setterMethod->getSelfDecl();
-      DeclRefExpr *SelfExpr =
-        new (Context) DeclRefExpr(SelfDecl, false, SelfDecl->getType(),
-                                  VK_LValue, PropertyDiagLoc);
+      DeclRefExpr *SelfExpr = new (Context)
+          DeclRefExpr(Context, SelfDecl, false, SelfDecl->getType(), VK_LValue,
+                      PropertyDiagLoc);
       MarkDeclRefReferenced(SelfExpr);
       Expr *LoadSelfExpr =
         ImplicitCastExpr::Create(Context, SelfDecl->getType(),
@@ -1481,8 +1481,8 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S,
       ObjCMethodDecl::param_iterator P = setterMethod->param_begin();
       ParmVarDecl *Param = (*P);
       QualType T = Param->getType().getNonReferenceType();
-      DeclRefExpr *rhs = new (Context) DeclRefExpr(Param, false, T,
-                                                   VK_LValue, PropertyDiagLoc);
+      DeclRefExpr *rhs = new (Context)
+          DeclRefExpr(Context, Param, false, T, VK_LValue, PropertyDiagLoc);
       MarkDeclRefReferenced(rhs);
       ExprResult Res = BuildBinOp(S, PropertyDiagLoc,
                                   BO_Assign, lhs, rhs);
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 4c7d61d79e..d829194364 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -63,8 +63,8 @@ CreateFunctionRefExpr(Sema &S, FunctionDecl *Fn, NamedDecl *FoundDecl,
     return ExprError();
   if (auto *FPT = Fn->getType()->getAs())
     S.ResolveExceptionSpec(Loc, FPT);
-  DeclRefExpr *DRE = new (S.Context) DeclRefExpr(Fn, false, Fn->getType(),
-                                                 VK_LValue, Loc, LocInfo);
+  DeclRefExpr *DRE = new (S.Context)
+      DeclRefExpr(S.Context, Fn, false, Fn->getType(), VK_LValue, Loc, LocInfo);
   if (HadMultipleCandidates)
     DRE->setHadMultipleCandidates(true);
 
@@ -6983,8 +6983,8 @@ Sema::AddConversionCandidate(CXXConversionDecl *Conversion,
   // lvalues/rvalues and the type. Fortunately, we can allocate this
   // call on the stack and we don't need its arguments to be
   // well-formed.
-  DeclRefExpr ConversionRef(Conversion, false, Conversion->getType(), VK_LValue,
-                            From->getBeginLoc());
+  DeclRefExpr ConversionRef(Context, Conversion, false, Conversion->getType(),
+                            VK_LValue, From->getBeginLoc());
   ImplicitCastExpr ConversionFn(ImplicitCastExpr::OnStack,
                                 Context.getPointerType(Conversion->getType()),
                                 CK_FunctionToPointerDecay,
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index 50ecd6d81f..cffc22e1b4 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -3130,9 +3130,9 @@ public:
 
     // Build a reference to the __builtin_shufflevector builtin
     FunctionDecl *Builtin = cast(Lookup.front());
-    Expr *Callee = new (SemaRef.Context) DeclRefExpr(Builtin, false,
-                                                  SemaRef.Context.BuiltinFnTy,
-                                                  VK_RValue, BuiltinLoc);
+    Expr *Callee = new (SemaRef.Context)
+        DeclRefExpr(SemaRef.Context, Builtin, false,
+                    SemaRef.Context.BuiltinFnTy, VK_RValue, BuiltinLoc);
     QualType CalleePtrTy = SemaRef.Context.getPointerType(Builtin->getType());
     Callee = SemaRef.ImpCastExprToType(Callee, CalleePtrTy,
                                        CK_BuiltinFnToFnPtr).get();
-- 
cgit v1.2.3


From 169415427ed21cb092dbccbdef07a358156ca53f Mon Sep 17 00:00:00 2001
From: Bruno Ricci 
Date: Fri, 21 Dec 2018 14:35:24 +0000
Subject: [Sema][NFC] Remove some unnecessary calls to getASTContext.

The AST context is already easily available. NFC.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349904 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/Sema/SemaChecking.cpp |  2 --
 lib/Sema/SemaDecl.cpp     |  8 ++++----
 lib/Sema/SemaExpr.cpp     |  2 +-
 lib/Sema/SemaTemplate.cpp | 13 +++++++------
 4 files changed, 12 insertions(+), 13 deletions(-)

diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index 9fe65c1dce..b9284a5b46 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -5148,8 +5148,6 @@ Sema::SemaBuiltinAtomicOverloaded(ExprResult TheCallResult) {
     TheCall->setArg(i+1, Arg.get());
   }
 
-  ASTContext& Context = this->getASTContext();
-
   // Create a new DeclRefExpr to refer to the new decl.
   DeclRefExpr* NewDRE = DeclRefExpr::Create(
       Context,
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 6dab332f4f..80cafbedf5 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -5875,10 +5875,10 @@ isOutOfScopePreviousDeclaration(NamedDecl *PrevDecl, DeclContext *DC,
   return true;
 }
 
-static void SetNestedNameSpecifier(DeclaratorDecl *DD, Declarator &D) {
+static void SetNestedNameSpecifier(Sema &S, DeclaratorDecl *DD, Declarator &D) {
   CXXScopeSpec &SS = D.getCXXScopeSpec();
   if (!SS.isSet()) return;
-  DD->setQualifierInfo(SS.getWithLocInContext(DD->getASTContext()));
+  DD->setQualifierInfo(SS.getWithLocInContext(S.Context));
 }
 
 bool Sema::inferObjCARCLifetime(ValueDecl *decl) {
@@ -6583,7 +6583,7 @@ NamedDecl *Sema::ActOnVariableDeclarator(
         NewTemplate->setInvalidDecl();
     }
 
-    SetNestedNameSpecifier(NewVD, D);
+    SetNestedNameSpecifier(*this, NewVD, D);
 
     // If we have any template parameter lists that don't directly belong to
     // the variable (matching the scope specifier), store them.
@@ -8384,7 +8384,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
         Diag(D.getDeclSpec().getVirtualSpecLoc(), diag::err_virtual_in_union);
     }
 
-    SetNestedNameSpecifier(NewFD, D);
+    SetNestedNameSpecifier(*this, NewFD, D);
     isMemberSpecialization = false;
     isFunctionTemplateSpecialization = false;
     if (D.isInvalidType())
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 041ecc9105..78dbf4365c 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -16547,7 +16547,7 @@ ExprResult RebuildUnknownAnyExpr::resolveDecl(Expr *E, ValueDecl *VD) {
       DeclRefExpr *DRE = dyn_cast(E);
       if (DRE && Proto && Proto->getParamTypes().empty() && Proto->isVariadic()) {
         SourceLocation Loc = FD->getLocation();
-        FunctionDecl *NewFD = FunctionDecl::Create(FD->getASTContext(),
+        FunctionDecl *NewFD = FunctionDecl::Create(S.Context,
                                       FD->getDeclContext(),
                                       Loc, Loc, FD->getNameInfo().getName(),
                                       DestType, FD->getTypeSourceInfo(),
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index e0f4d2e495..2d2d08f23e 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -1255,9 +1255,10 @@ Sema::ActOnTemplateParameterList(unsigned Depth,
       RAngleLoc, RequiresClause);
 }
 
-static void SetNestedNameSpecifier(TagDecl *T, const CXXScopeSpec &SS) {
+static void SetNestedNameSpecifier(Sema &S, TagDecl *T,
+                                   const CXXScopeSpec &SS) {
   if (SS.isSet())
-    T->setQualifierInfo(SS.getWithLocInContext(T->getASTContext()));
+    T->setQualifierInfo(SS.getWithLocInContext(S.Context));
 }
 
 DeclResult Sema::CheckClassTemplate(
@@ -1554,7 +1555,7 @@ DeclResult Sema::CheckClassTemplate(
                           PrevClassTemplate && ShouldAddRedecl ?
                             PrevClassTemplate->getTemplatedDecl() : nullptr,
                           /*DelayTypeCreation=*/true);
-  SetNestedNameSpecifier(NewClass, SS);
+  SetNestedNameSpecifier(*this, NewClass, SS);
   if (NumOuterTemplateParamLists > 0)
     NewClass->setTemplateParameterListsInfo(
         Context, llvm::makeArrayRef(OuterTemplateParamLists,
@@ -7650,7 +7651,7 @@ DeclResult Sema::ActOnClassTemplateSpecialization(
                                                        TemplateArgs,
                                                        CanonType,
                                                        PrevPartial);
-    SetNestedNameSpecifier(Partial, SS);
+    SetNestedNameSpecifier(*this, Partial, SS);
     if (TemplateParameterLists.size() > 1 && SS.isSet()) {
       Partial->setTemplateParameterListsInfo(
           Context, TemplateParameterLists.drop_back(1));
@@ -7676,7 +7677,7 @@ DeclResult Sema::ActOnClassTemplateSpecialization(
                                                 ClassTemplate,
                                                 Converted,
                                                 PrevDecl);
-    SetNestedNameSpecifier(Specialization, SS);
+    SetNestedNameSpecifier(*this, Specialization, SS);
     if (TemplateParameterLists.size() > 0) {
       Specialization->setTemplateParameterListsInfo(Context,
                                                     TemplateParameterLists);
@@ -8775,7 +8776,7 @@ DeclResult Sema::ActOnExplicitInstantiation(
                                                 ClassTemplate,
                                                 Converted,
                                                 PrevDecl);
-    SetNestedNameSpecifier(Specialization, SS);
+    SetNestedNameSpecifier(*this, Specialization, SS);
 
     if (!HasNoEffect && !PrevDecl) {
       // Insert the new specialization.
-- 
cgit v1.2.3


From 9f569d45e0e42bcf60fe8f43b847a133a1a38c12 Mon Sep 17 00:00:00 2001
From: Bruno Ricci 
Date: Fri, 21 Dec 2018 15:20:32 +0000
Subject: [AST] Store the callee and argument expressions of CallExpr in a
 trailing array.

Since CallExpr::setNumArgs has been removed, it is now possible to store the
callee expression and the argument expressions of CallExpr in a trailing array.
This saves one pointer per CallExpr, CXXOperatorCallExpr, CXXMemberCallExpr,
CUDAKernelCallExpr and UserDefinedLiteral.

Given that CallExpr is used as a base of the above classes we cannot use
llvm::TrailingObjects. Instead we store the offset in bytes from the this pointer
to the start of the trailing objects and manually do the casts + arithmetic.

Some notes:

1.) I did not try to fit the number of arguments in the bit-fields of Stmt.
    This leaves some space for future additions and avoid the discussion about
    whether x bits are sufficient to hold the number of arguments.

2.) It would be perfectly possible to recompute the offset to the trailing
    objects before accessing the trailing objects. However the trailing objects
    are frequently accessed and benchmarks show that it is slightly faster to
    just load the offset from the bit-fields. Additionally, because of 1),
    we have plenty of space in the bit-fields of Stmt.

Differential Revision: https://reviews.llvm.org/D55771

Reviewed By: rjmccall



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349910 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/AST/Expr.h                   | 208 +++++++++++++++++++----------
 include/clang/AST/ExprCXX.h                | 123 ++++++++++-------
 include/clang/AST/Stmt.h                   |   9 ++
 lib/AST/ASTImporter.cpp                    |  13 +-
 lib/AST/Expr.cpp                           | 130 +++++++++++-------
 lib/AST/ExprCXX.cpp                        | 145 ++++++++++++++++++++
 lib/Analysis/BodyFarm.cpp                  |  22 +--
 lib/CodeGen/CGObjC.cpp                     |   8 +-
 lib/Frontend/Rewrite/RewriteModernObjC.cpp |  67 +++++-----
 lib/Frontend/Rewrite/RewriteObjC.cpp       |  37 +++--
 lib/Sema/SemaExpr.cpp                      |  31 ++---
 lib/Sema/SemaExprCXX.cpp                   |   4 +-
 lib/Sema/SemaOpenMP.cpp                    |   4 +-
 lib/Sema/SemaOverload.cpp                  | 114 ++++++++--------
 lib/Sema/TreeTransform.h                   |   2 +-
 lib/Serialization/ASTReaderStmt.cpp        |  19 ++-
 16 files changed, 598 insertions(+), 338 deletions(-)

diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index ee4e0d57b4..156782b330 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -2395,59 +2395,126 @@ public:
 /// a subclass for overloaded operator calls that use operator syntax, e.g.,
 /// "str1 + str2" to resolve to a function call.
 class CallExpr : public Expr {
-  enum { FN=0, PREARGS_START=1 };
-  Stmt **SubExprs;
+  enum { FN = 0, PREARGS_START = 1 };
+
+  /// The number of arguments in the call expression.
   unsigned NumArgs;
+
+  /// The location of the right parenthese. This has a different meaning for
+  /// the derived classes of CallExpr.
   SourceLocation RParenLoc;
 
   void updateDependenciesFromArg(Expr *Arg);
 
+  // CallExpr store some data in trailing objects. However since CallExpr
+  // is used a base of other expression classes we cannot use
+  // llvm::TrailingObjects. Instead we manually perform the pointer arithmetic
+  // and casts.
+  //
+  // The trailing objects are in order:
+  //
+  // * A single "Stmt *" for the callee expression.
+  //
+  // * An array of getNumPreArgs() "Stmt *" for the pre-argument expressions.
+  //
+  // * An array of getNumArgs() "Stmt *" for the argument expressions.
+  //
+  // Note that we store the offset in bytes from the this pointer to the start
+  // of the trailing objects. It would be perfectly possible to compute it
+  // based on the dynamic kind of the CallExpr. However 1.) we have plenty of
+  // space in the bit-fields of Stmt. 2.) It was benchmarked to be faster to
+  // compute this once and then load the offset from the bit-fields of Stmt,
+  // instead of re-computing the offset each time the trailing objects are
+  // accessed.
+
+  /// Return a pointer to the start of the trailing array of "Stmt *".
+  Stmt **getTrailingStmts() {
+    return reinterpret_cast(reinterpret_cast(this) +
+                                     CallExprBits.OffsetToTrailingObjects);
+  }
+  Stmt *const *getTrailingStmts() const {
+    return const_cast(this)->getTrailingStmts();
+  }
+
+  /// Map a statement class to the appropriate offset in bytes from the
+  /// this pointer to the trailing objects.
+  static unsigned offsetToTrailingObjects(StmtClass SC);
+
 public:
   enum class ADLCallKind : bool { NotADL, UsesADL };
   static constexpr ADLCallKind NotADL = ADLCallKind::NotADL;
   static constexpr ADLCallKind UsesADL = ADLCallKind::UsesADL;
 
 protected:
-  // These versions of the constructor are for derived classes.
-  CallExpr(const ASTContext &C, StmtClass SC, Expr *fn,
-           ArrayRef preargs, ArrayRef args, QualType t,
-           ExprValueKind VK, SourceLocation rparenloc, unsigned MinNumArgs = 0,
-           ADLCallKind UsesADL = NotADL);
-  CallExpr(const ASTContext &C, StmtClass SC, Expr *fn, ArrayRef args,
-           QualType t, ExprValueKind VK, SourceLocation rparenloc,
-           unsigned MinNumArgs = 0, ADLCallKind UsesADL = NotADL);
-  CallExpr(const ASTContext &C, StmtClass SC, unsigned NumPreArgs,
-           unsigned NumArgs, EmptyShell Empty);
-
-  Stmt *getPreArg(unsigned i) {
-    assert(i < getNumPreArgs() && "Prearg access out of range!");
-    return SubExprs[PREARGS_START+i];
-  }
-  const Stmt *getPreArg(unsigned i) const {
-    assert(i < getNumPreArgs() && "Prearg access out of range!");
-    return SubExprs[PREARGS_START+i];
-  }
-  void setPreArg(unsigned i, Stmt *PreArg) {
-    assert(i < getNumPreArgs() && "Prearg access out of range!");
-    SubExprs[PREARGS_START+i] = PreArg;
+  /// Build a call expression, assuming that appropriate storage has been
+  /// allocated for the trailing objects.
+  CallExpr(StmtClass SC, Expr *Fn, ArrayRef PreArgs,
+           ArrayRef Args, QualType Ty, ExprValueKind VK,
+           SourceLocation RParenLoc, unsigned MinNumArgs, ADLCallKind UsesADL);
+
+  /// Build an empty call expression, for deserialization.
+  CallExpr(StmtClass SC, unsigned NumPreArgs, unsigned NumArgs,
+           EmptyShell Empty);
+
+  /// Return the size in bytes needed for the trailing objects.
+  /// Used by the derived classes to allocate the right amount of storage.
+  static unsigned sizeOfTrailingObjects(unsigned NumPreArgs, unsigned NumArgs) {
+    return (1 + NumPreArgs + NumArgs) * sizeof(Stmt *);
+  }
+
+  Stmt *getPreArg(unsigned I) {
+    assert(I < getNumPreArgs() && "Prearg access out of range!");
+    return getTrailingStmts()[PREARGS_START + I];
+  }
+  const Stmt *getPreArg(unsigned I) const {
+    assert(I < getNumPreArgs() && "Prearg access out of range!");
+    return getTrailingStmts()[PREARGS_START + I];
+  }
+  void setPreArg(unsigned I, Stmt *PreArg) {
+    assert(I < getNumPreArgs() && "Prearg access out of range!");
+    getTrailingStmts()[PREARGS_START + I] = PreArg;
   }
 
   unsigned getNumPreArgs() const { return CallExprBits.NumPreArgs; }
 
 public:
-  /// Build a call expression. MinNumArgs specifies the minimum number of
-  /// arguments. The actual number of arguments will be the greater of
-  /// args.size() and MinNumArgs.
-  CallExpr(const ASTContext &C, Expr *fn, ArrayRef args, QualType t,
-           ExprValueKind VK, SourceLocation rparenloc, unsigned MinNumArgs = 0,
-           ADLCallKind UsesADL = NotADL);
+  /// Create a call expression. Fn is the callee expression, Args is the
+  /// argument array, Ty is the type of the call expression (which is *not*
+  /// the return type in general), VK is the value kind of the call expression
+  /// (lvalue, rvalue, ...), and RParenLoc is the location of the right
+  /// parenthese in the call expression. MinNumArgs specifies the minimum
+  /// number of arguments. The actual number of arguments will be the greater
+  /// of Args.size() and MinNumArgs. This is used in a few places to allocate
+  /// enough storage for the default arguments. UsesADL specifies whether the
+  /// callee was found through argument-dependent lookup.
+  ///
+  /// Note that you can use CreateTemporary if you need a temporary call
+  /// expression on the stack.
+  static CallExpr *Create(const ASTContext &Ctx, Expr *Fn,
+                          ArrayRef Args, QualType Ty, ExprValueKind VK,
+                          SourceLocation RParenLoc, unsigned MinNumArgs = 0,
+                          ADLCallKind UsesADL = NotADL);
+
+  /// Create a temporary call expression with no arguments in the memory
+  /// pointed to by Mem. Mem must points to at least sizeof(CallExpr)
+  /// + sizeof(Stmt *) bytes of storage, aligned to alignof(CallExpr):
+  ///
+  /// \code{.cpp}
+  ///   llvm::AlignedCharArray Buffer;
+  ///   CallExpr *TheCall = CallExpr::CreateTemporary(Buffer.buffer, etc);
+  /// \endcode
+  static CallExpr *CreateTemporary(void *Mem, Expr *Fn, QualType Ty,
+                                   ExprValueKind VK, SourceLocation RParenLoc,
+                                   ADLCallKind UsesADL = NotADL);
 
-  /// Build an empty call expression.
-  CallExpr(const ASTContext &C, unsigned NumArgs, EmptyShell Empty);
+  /// Create an empty call expression, for deserialization.
+  static CallExpr *CreateEmpty(const ASTContext &Ctx, unsigned NumArgs,
+                               EmptyShell Empty);
 
-  const Expr *getCallee() const { return cast(SubExprs[FN]); }
-  Expr *getCallee() { return cast(SubExprs[FN]); }
-  void setCallee(Expr *F) { SubExprs[FN] = F; }
+  Expr *getCallee() { return cast(getTrailingStmts()[FN]); }
+  const Expr *getCallee() const { return cast(getTrailingStmts()[FN]); }
+  void setCallee(Expr *F) { getTrailingStmts()[FN] = F; }
 
   ADLCallKind getADLCallKind() const {
     return static_cast(CallExprBits.UsesADL);
@@ -2457,55 +2524,56 @@ public:
   }
   bool usesADL() const { return getADLCallKind() == UsesADL; }
 
-  Decl *getCalleeDecl();
+  Decl *getCalleeDecl() { return getCallee()->getReferencedDeclOfCallee(); }
   const Decl *getCalleeDecl() const {
-    return const_cast(this)->getCalleeDecl();
+    return getCallee()->getReferencedDeclOfCallee();
   }
 
-  /// If the callee is a FunctionDecl, return it. Otherwise return 0.
-  FunctionDecl *getDirectCallee();
+  /// If the callee is a FunctionDecl, return it. Otherwise return null.
+  FunctionDecl *getDirectCallee() {
+    return dyn_cast_or_null(getCalleeDecl());
+  }
   const FunctionDecl *getDirectCallee() const {
-    return const_cast(this)->getDirectCallee();
+    return dyn_cast_or_null(getCalleeDecl());
   }
 
   /// getNumArgs - Return the number of actual arguments to this call.
-  ///
   unsigned getNumArgs() const { return NumArgs; }
 
   /// Retrieve the call arguments.
   Expr **getArgs() {
-    return reinterpret_cast(SubExprs+getNumPreArgs()+PREARGS_START);
+    return reinterpret_cast(getTrailingStmts() + PREARGS_START +
+                                     getNumPreArgs());
   }
   const Expr *const *getArgs() const {
-    return reinterpret_cast(SubExprs + getNumPreArgs() +
-                                     PREARGS_START);
+    return reinterpret_cast(
+        getTrailingStmts() + PREARGS_START + getNumPreArgs());
   }
 
   /// getArg - Return the specified argument.
   Expr *getArg(unsigned Arg) {
-    assert(Arg < NumArgs && "Arg access out of range!");
-    return cast_or_null(SubExprs[Arg + getNumPreArgs() + PREARGS_START]);
+    assert(Arg < getNumArgs() && "Arg access out of range!");
+    return getArgs()[Arg];
   }
   const Expr *getArg(unsigned Arg) const {
-    assert(Arg < NumArgs && "Arg access out of range!");
-    return cast_or_null(SubExprs[Arg + getNumPreArgs() + PREARGS_START]);
+    assert(Arg < getNumArgs() && "Arg access out of range!");
+    return getArgs()[Arg];
   }
 
   /// setArg - Set the specified argument.
   void setArg(unsigned Arg, Expr *ArgExpr) {
-    assert(Arg < NumArgs && "Arg access out of range!");
-    SubExprs[Arg+getNumPreArgs()+PREARGS_START] = ArgExpr;
+    assert(Arg < getNumArgs() && "Arg access out of range!");
+    getArgs()[Arg] = ArgExpr;
   }
 
   /// Reduce the number of arguments in this call expression. This is used for
   /// example during error recovery to drop extra arguments. There is no way
   /// to perform the opposite because: 1.) We don't track how much storage
   /// we have for the argument array 2.) This would potentially require growing
-  /// the argument array, something we cannot support since the arguments will
-  /// be stored in a trailing array in the future.
-  /// (TODO: update this comment when this is done).
+  /// the argument array, something we cannot support since the arguments are
+  /// stored in a trailing array.
   void shrinkNumArgs(unsigned NewNumArgs) {
-    assert((NewNumArgs <= NumArgs) &&
+    assert((NewNumArgs <= getNumArgs()) &&
            "shrinkNumArgs cannot increase the number of arguments!");
     NumArgs = NewNumArgs;
   }
@@ -2520,29 +2588,28 @@ public:
     return const_arg_range(arg_begin(), arg_end());
   }
 
-  arg_iterator arg_begin() { return SubExprs+PREARGS_START+getNumPreArgs(); }
-  arg_iterator arg_end() {
-    return SubExprs+PREARGS_START+getNumPreArgs()+getNumArgs();
+  arg_iterator arg_begin() {
+    return getTrailingStmts() + PREARGS_START + getNumPreArgs();
   }
+  arg_iterator arg_end() { return arg_begin() + getNumArgs(); }
+
   const_arg_iterator arg_begin() const {
-    return SubExprs+PREARGS_START+getNumPreArgs();
-  }
-  const_arg_iterator arg_end() const {
-    return SubExprs+PREARGS_START+getNumPreArgs()+getNumArgs();
+    return getTrailingStmts() + PREARGS_START + getNumPreArgs();
   }
+  const_arg_iterator arg_end() const { return arg_begin() + getNumArgs(); }
 
   /// This method provides fast access to all the subexpressions of
   /// a CallExpr without going through the slower virtual child_iterator
   /// interface.  This provides efficient reverse iteration of the
   /// subexpressions.  This is currently used for CFG construction.
-  ArrayRef getRawSubExprs() {
-    return llvm::makeArrayRef(SubExprs,
-                              getNumPreArgs() + PREARGS_START + getNumArgs());
+  ArrayRef getRawSubExprs() {
+    return llvm::makeArrayRef(getTrailingStmts(),
+                              PREARGS_START + getNumPreArgs() + getNumArgs());
   }
 
   /// getNumCommas - Return the number of commas that must have been present in
   /// this function call.
-  unsigned getNumCommas() const { return NumArgs ? NumArgs - 1 : 0; }
+  unsigned getNumCommas() const { return getNumArgs() ? getNumArgs() - 1 : 0; }
 
   /// getBuiltinCallee - If this is a call to a builtin, return the builtin ID
   /// of the callee. If not, return 0.
@@ -2568,7 +2635,7 @@ public:
   bool isBuiltinAssumeFalse(const ASTContext &Ctx) const;
 
   bool isCallToStdMove() const {
-    const FunctionDecl* FD = getDirectCallee();
+    const FunctionDecl *FD = getDirectCallee();
     return getNumArgs() == 1 && FD && FD->isInStdNamespace() &&
            FD->getIdentifier() && FD->getIdentifier()->isStr("move");
   }
@@ -2580,13 +2647,14 @@ public:
 
   // Iterators
   child_range children() {
-    return child_range(&SubExprs[0],
-                       &SubExprs[0]+NumArgs+getNumPreArgs()+PREARGS_START);
+    return child_range(getTrailingStmts(), getTrailingStmts() + PREARGS_START +
+                                               getNumPreArgs() + getNumArgs());
   }
 
   const_child_range children() const {
-    return const_child_range(&SubExprs[0], &SubExprs[0] + NumArgs +
-                                               getNumPreArgs() + PREARGS_START);
+    return const_child_range(getTrailingStmts(),
+                             getTrailingStmts() + PREARGS_START +
+                                 getNumPreArgs() + getNumArgs());
   }
 };
 
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index f39bddb040..21692c82b4 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -75,7 +75,10 @@ class TemplateParameterList;
 /// function itself will be a (possibly empty) set of functions and
 /// function templates that were found by name lookup at template
 /// definition time.
-class CXXOperatorCallExpr : public CallExpr {
+class CXXOperatorCallExpr final : public CallExpr {
+  friend class ASTStmtReader;
+  friend class ASTStmtWriter;
+
   /// The overloaded operator.
   OverloadedOperatorKind Operator;
 
@@ -84,29 +87,29 @@ class CXXOperatorCallExpr : public CallExpr {
   // Only meaningful for floating point types.
   FPOptions FPFeatures;
 
+  // CXXOperatorCallExpr has some trailing objects belonging
+  // to CallExpr. See CallExpr for the details.
+
   SourceRange getSourceRangeImpl() const LLVM_READONLY;
 
-public:
-  friend class ASTStmtReader;
-  friend class ASTStmtWriter;
+  CXXOperatorCallExpr(OverloadedOperatorKind OpKind, Expr *Fn,
+                      ArrayRef Args, QualType Ty, ExprValueKind VK,
+                      SourceLocation OperatorLoc, FPOptions FPFeatures,
+                      ADLCallKind UsesADL);
 
-  CXXOperatorCallExpr(ASTContext &C, OverloadedOperatorKind Op, Expr *fn,
-                      ArrayRef args, QualType t, ExprValueKind VK,
-                      SourceLocation operatorloc, FPOptions FPFeatures,
-                      ADLCallKind UsesADL = NotADL)
-      : CallExpr(C, CXXOperatorCallExprClass, fn, args, t, VK, operatorloc,
-                 /*MinNumArgs=*/0, UsesADL),
-        Operator(Op), FPFeatures(FPFeatures) {
-    Range = getSourceRangeImpl();
-  }
+  CXXOperatorCallExpr(unsigned NumArgs, EmptyShell Empty);
+
+public:
+  static CXXOperatorCallExpr *
+  Create(const ASTContext &Ctx, OverloadedOperatorKind OpKind, Expr *Fn,
+         ArrayRef Args, QualType Ty, ExprValueKind VK,
+         SourceLocation OperatorLoc, FPOptions FPFeatures,
+         ADLCallKind UsesADL = NotADL);
 
-  explicit CXXOperatorCallExpr(ASTContext &C, unsigned NumArgs,
-                               EmptyShell Empty)
-      : CallExpr(C, CXXOperatorCallExprClass, /*NumPreArgs=*/0, NumArgs,
-                 Empty) {}
+  static CXXOperatorCallExpr *CreateEmpty(const ASTContext &Ctx,
+                                          unsigned NumArgs, EmptyShell Empty);
 
-  /// Returns the kind of overloaded operator that this
-  /// expression refers to.
+  /// Returns the kind of overloaded operator that this expression refers to.
   OverloadedOperatorKind getOperator() const { return Operator; }
 
   static bool isAssignmentOp(OverloadedOperatorKind Opc) {
@@ -165,16 +168,23 @@ public:
 /// both the object argument and the member function, while the
 /// arguments are the arguments within the parentheses (not including
 /// the object argument).
-class CXXMemberCallExpr : public CallExpr {
+class CXXMemberCallExpr final : public CallExpr {
+  // CXXMemberCallExpr has some trailing objects belonging
+  // to CallExpr. See CallExpr for the details.
+
+  CXXMemberCallExpr(Expr *Fn, ArrayRef Args, QualType Ty,
+                    ExprValueKind VK, SourceLocation RP, unsigned MinNumArgs);
+
+  CXXMemberCallExpr(unsigned NumArgs, EmptyShell Empty);
+
 public:
-  CXXMemberCallExpr(ASTContext &C, Expr *fn, ArrayRef args, QualType t,
-                    ExprValueKind VK, SourceLocation RP,
-                    unsigned MinNumArgs = 0)
-      : CallExpr(C, CXXMemberCallExprClass, fn, args, t, VK, RP, MinNumArgs,
-                 NotADL) {}
+  static CXXMemberCallExpr *Create(const ASTContext &Ctx, Expr *Fn,
+                                   ArrayRef Args, QualType Ty,
+                                   ExprValueKind VK, SourceLocation RP,
+                                   unsigned MinNumArgs = 0);
 
-  CXXMemberCallExpr(ASTContext &C, unsigned NumArgs, EmptyShell Empty)
-      : CallExpr(C, CXXMemberCallExprClass, /*NumPreArgs=*/0, NumArgs, Empty) {}
+  static CXXMemberCallExpr *CreateEmpty(const ASTContext &Ctx, unsigned NumArgs,
+                                        EmptyShell Empty);
 
   /// Retrieves the implicit object argument for the member call.
   ///
@@ -206,20 +216,26 @@ public:
 };
 
 /// Represents a call to a CUDA kernel function.
-class CUDAKernelCallExpr : public CallExpr {
-private:
+class CUDAKernelCallExpr final : public CallExpr {
   enum { CONFIG, END_PREARG };
 
+  // CUDAKernelCallExpr has some trailing objects belonging
+  // to CallExpr. See CallExpr for the details.
+
+  CUDAKernelCallExpr(Expr *Fn, CallExpr *Config, ArrayRef Args,
+                     QualType Ty, ExprValueKind VK, SourceLocation RP,
+                     unsigned MinNumArgs);
+
+  CUDAKernelCallExpr(unsigned NumArgs, EmptyShell Empty);
+
 public:
-  CUDAKernelCallExpr(ASTContext &C, Expr *fn, CallExpr *Config,
-                     ArrayRef args, QualType t, ExprValueKind VK,
-                     SourceLocation RP, unsigned MinNumArgs = 0)
-      : CallExpr(C, CUDAKernelCallExprClass, fn, Config, args, t, VK, RP,
-                 MinNumArgs, NotADL) {}
+  static CUDAKernelCallExpr *Create(const ASTContext &Ctx, Expr *Fn,
+                                    CallExpr *Config, ArrayRef Args,
+                                    QualType Ty, ExprValueKind VK,
+                                    SourceLocation RP, unsigned MinNumArgs = 0);
 
-  CUDAKernelCallExpr(ASTContext &C, unsigned NumArgs, EmptyShell Empty)
-      : CallExpr(C, CUDAKernelCallExprClass, /*NumPreArgs=*/END_PREARG, NumArgs,
-                 Empty) {}
+  static CUDAKernelCallExpr *CreateEmpty(const ASTContext &Ctx,
+                                         unsigned NumArgs, EmptyShell Empty);
 
   const CallExpr *getConfig() const {
     return cast_or_null(getPreArg(CONFIG));
@@ -482,25 +498,30 @@ public:
 ///
 /// Since literal operators are never found by ADL and can only be declared at
 /// namespace scope, a user-defined literal is never dependent.
-class UserDefinedLiteral : public CallExpr {
+class UserDefinedLiteral final : public CallExpr {
+  friend class ASTStmtReader;
+  friend class ASTStmtWriter;
+
   /// The location of a ud-suffix within the literal.
   SourceLocation UDSuffixLoc;
 
-public:
-  friend class ASTStmtReader;
-  friend class ASTStmtWriter;
+  // UserDefinedLiteral has some trailing objects belonging
+  // to CallExpr. See CallExpr for the details.
 
-  UserDefinedLiteral(const ASTContext &C, Expr *Fn, ArrayRef Args,
-                     QualType T, ExprValueKind VK, SourceLocation LitEndLoc,
-                     SourceLocation SuffixLoc)
-      : CallExpr(C, UserDefinedLiteralClass, Fn, Args, T, VK, LitEndLoc,
-                 /*MinNumArgs=*/0, NotADL),
-        UDSuffixLoc(SuffixLoc) {}
+  UserDefinedLiteral(Expr *Fn, ArrayRef Args, QualType Ty,
+                     ExprValueKind VK, SourceLocation LitEndLoc,
+                     SourceLocation SuffixLoc);
 
-  explicit UserDefinedLiteral(const ASTContext &C, unsigned NumArgs,
-                              EmptyShell Empty)
-      : CallExpr(C, UserDefinedLiteralClass, /*NumPreArgs=*/0, NumArgs, Empty) {
-  }
+  UserDefinedLiteral(unsigned NumArgs, EmptyShell Empty);
+
+public:
+  static UserDefinedLiteral *Create(const ASTContext &Ctx, Expr *Fn,
+                                    ArrayRef Args, QualType Ty,
+                                    ExprValueKind VK, SourceLocation LitEndLoc,
+                                    SourceLocation SuffixLoc);
+
+  static UserDefinedLiteral *CreateEmpty(const ASTContext &Ctx,
+                                         unsigned NumArgs, EmptyShell Empty);
 
   /// The kind of literal operator which is invoked.
   enum LiteralOperatorKind {
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index 23ac5af7ae..66872464e0 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -433,7 +433,16 @@ protected:
 
     /// True if the callee of the call expression was found using ADL.
     unsigned UsesADL : 1;
+
+    /// Padding used to align OffsetToTrailingObjects to a byte multiple.
+    unsigned : 24 - 2 - NumExprBits;
+
+    /// The offset in bytes from the this pointer to the start of the
+    /// trailing objects belonging to CallExpr. Intentionally byte sized
+    /// for faster access.
+    unsigned OffsetToTrailingObjects : 8;
   };
+  enum { NumCallExprBits = 32 };
 
   class MemberExprBitfields {
     friend class MemberExpr;
diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp
index 6a893c5035..a6169ff652 100644
--- a/lib/AST/ASTImporter.cpp
+++ b/lib/AST/ASTImporter.cpp
@@ -6990,9 +6990,8 @@ ExpectedStmt ASTNodeImporter::VisitCXXMemberCallExpr(CXXMemberCallExpr *E) {
   if (Error Err = ImportContainerChecked(E->arguments(), ToArgs))
     return std::move(Err);
 
-  return new (Importer.getToContext()) CXXMemberCallExpr(
-      Importer.getToContext(), ToCallee, ToArgs, ToType, E->getValueKind(),
-      ToRParenLoc);
+  return CXXMemberCallExpr::Create(Importer.getToContext(), ToCallee, ToArgs,
+                                   ToType, E->getValueKind(), ToRParenLoc);
 }
 
 ExpectedStmt ASTNodeImporter::VisitCXXThisExpr(CXXThisExpr *E) {
@@ -7317,15 +7316,15 @@ ExpectedStmt ASTNodeImporter::VisitCallExpr(CallExpr *E) {
      return std::move(Err);
 
   if (const auto *OCE = dyn_cast(E)) {
-    return new (Importer.getToContext()) CXXOperatorCallExpr(
+    return CXXOperatorCallExpr::Create(
         Importer.getToContext(), OCE->getOperator(), ToCallee, ToArgs, ToType,
         OCE->getValueKind(), ToRParenLoc, OCE->getFPFeatures(),
         OCE->getADLCallKind());
   }
 
-  return new (Importer.getToContext()) CallExpr(
-      Importer.getToContext(), ToCallee, ToArgs, ToType, E->getValueKind(),
-      ToRParenLoc, /*MinNumArgs=*/0, E->getADLCallKind());
+  return CallExpr::Create(Importer.getToContext(), ToCallee, ToArgs, ToType,
+                          E->getValueKind(), ToRParenLoc, /*MinNumArgs=*/0,
+                          E->getADLCallKind());
 }
 
 ExpectedStmt ASTNodeImporter::VisitLambdaExpr(LambdaExpr *E) {
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 4f3c5b3344..11191c4682 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -1234,57 +1234,99 @@ OverloadedOperatorKind UnaryOperator::getOverloadedOperator(Opcode Opc) {
 // Postfix Operators.
 //===----------------------------------------------------------------------===//
 
-CallExpr::CallExpr(const ASTContext &C, StmtClass SC, Expr *fn,
-                   ArrayRef preargs, ArrayRef args, QualType t,
-                   ExprValueKind VK, SourceLocation rparenloc,
-                   unsigned MinNumArgs, ADLCallKind UsesADL)
-    : Expr(SC, t, VK, OK_Ordinary, fn->isTypeDependent(),
-           fn->isValueDependent(), fn->isInstantiationDependent(),
-           fn->containsUnexpandedParameterPack()),
-      RParenLoc(rparenloc) {
-  CallExprBits.UsesADL = static_cast(UsesADL);
-
-  NumArgs = std::max(args.size(), MinNumArgs);
-  unsigned NumPreArgs = preargs.size();
+CallExpr::CallExpr(StmtClass SC, Expr *Fn, ArrayRef PreArgs,
+                   ArrayRef Args, QualType Ty, ExprValueKind VK,
+                   SourceLocation RParenLoc, unsigned MinNumArgs,
+                   ADLCallKind UsesADL)
+    : Expr(SC, Ty, VK, OK_Ordinary, Fn->isTypeDependent(),
+           Fn->isValueDependent(), Fn->isInstantiationDependent(),
+           Fn->containsUnexpandedParameterPack()),
+      RParenLoc(RParenLoc) {
+  NumArgs = std::max(Args.size(), MinNumArgs);
+  unsigned NumPreArgs = PreArgs.size();
   CallExprBits.NumPreArgs = NumPreArgs;
+  assert((NumPreArgs == getNumPreArgs()) && "NumPreArgs overflow!");
+
+  unsigned OffsetToTrailingObjects = offsetToTrailingObjects(SC);
+  CallExprBits.OffsetToTrailingObjects = OffsetToTrailingObjects;
+  assert((CallExprBits.OffsetToTrailingObjects == OffsetToTrailingObjects) &&
+         "OffsetToTrailingObjects overflow!");
 
-  SubExprs = new (C) Stmt *[NumArgs + PREARGS_START + NumPreArgs];
-  SubExprs[FN] = fn;
-  for (unsigned i = 0; i != NumPreArgs; ++i) {
-    updateDependenciesFromArg(preargs[i]);
-    SubExprs[i+PREARGS_START] = preargs[i];
+  CallExprBits.UsesADL = static_cast(UsesADL);
+
+  setCallee(Fn);
+  for (unsigned I = 0; I != NumPreArgs; ++I) {
+    updateDependenciesFromArg(PreArgs[I]);
+    setPreArg(I, PreArgs[I]);
   }
-  for (unsigned i = 0; i != args.size(); ++i) {
-    updateDependenciesFromArg(args[i]);
-    SubExprs[i+PREARGS_START+NumPreArgs] = args[i];
+  for (unsigned I = 0; I != Args.size(); ++I) {
+    updateDependenciesFromArg(Args[I]);
+    setArg(I, Args[I]);
   }
-  for (unsigned i = args.size(); i != NumArgs; ++i) {
-    SubExprs[i + PREARGS_START + NumPreArgs] = nullptr;
+  for (unsigned I = Args.size(); I != NumArgs; ++I) {
+    setArg(I, nullptr);
   }
 }
 
-CallExpr::CallExpr(const ASTContext &C, StmtClass SC, Expr *fn,
-                   ArrayRef args, QualType t, ExprValueKind VK,
-                   SourceLocation rparenloc, unsigned MinNumArgs,
-                   ADLCallKind UsesADL)
-    : CallExpr(C, SC, fn, ArrayRef(), args, t, VK, rparenloc,
-               MinNumArgs, UsesADL) {}
-
-CallExpr::CallExpr(const ASTContext &C, Expr *fn, ArrayRef args,
-                   QualType t, ExprValueKind VK, SourceLocation rparenloc,
-                   unsigned MinNumArgs, ADLCallKind UsesADL)
-    : CallExpr(C, CallExprClass, fn, ArrayRef(), args, t, VK, rparenloc,
-               MinNumArgs, UsesADL) {}
-
-CallExpr::CallExpr(const ASTContext &C, StmtClass SC, unsigned NumPreArgs,
-                   unsigned NumArgs, EmptyShell Empty)
+CallExpr::CallExpr(StmtClass SC, unsigned NumPreArgs, unsigned NumArgs,
+                   EmptyShell Empty)
     : Expr(SC, Empty), NumArgs(NumArgs) {
   CallExprBits.NumPreArgs = NumPreArgs;
-  SubExprs = new (C) Stmt *[NumArgs + PREARGS_START + NumPreArgs];
+  assert((NumPreArgs == getNumPreArgs()) && "NumPreArgs overflow!");
+
+  unsigned OffsetToTrailingObjects = offsetToTrailingObjects(SC);
+  CallExprBits.OffsetToTrailingObjects = OffsetToTrailingObjects;
+  assert((CallExprBits.OffsetToTrailingObjects == OffsetToTrailingObjects) &&
+         "OffsetToTrailingObjects overflow!");
 }
 
-CallExpr::CallExpr(const ASTContext &C, unsigned NumArgs, EmptyShell Empty)
-    : CallExpr(C, CallExprClass, /*NumPreArgs=*/0, NumArgs, Empty) {}
+CallExpr *CallExpr::Create(const ASTContext &Ctx, Expr *Fn,
+                           ArrayRef Args, QualType Ty, ExprValueKind VK,
+                           SourceLocation RParenLoc, unsigned MinNumArgs,
+                           ADLCallKind UsesADL) {
+  unsigned NumArgs = std::max(Args.size(), MinNumArgs);
+  unsigned SizeOfTrailingObjects =
+      CallExpr::sizeOfTrailingObjects(/*NumPreArgs=*/0, NumArgs);
+  void *Mem =
+      Ctx.Allocate(sizeof(CallExpr) + SizeOfTrailingObjects, alignof(CallExpr));
+  return new (Mem) CallExpr(CallExprClass, Fn, /*PreArgs=*/{}, Args, Ty, VK,
+                            RParenLoc, MinNumArgs, UsesADL);
+}
+
+CallExpr *CallExpr::CreateTemporary(void *Mem, Expr *Fn, QualType Ty,
+                                    ExprValueKind VK, SourceLocation RParenLoc,
+                                    ADLCallKind UsesADL) {
+  assert(!(reinterpret_cast(Mem) % alignof(CallExpr)) &&
+         "Misaligned memory in CallExpr::CreateTemporary!");
+  return new (Mem) CallExpr(CallExprClass, Fn, /*PreArgs=*/{}, /*Args=*/{}, Ty,
+                            VK, RParenLoc, /*MinNumArgs=*/0, UsesADL);
+}
+
+CallExpr *CallExpr::CreateEmpty(const ASTContext &Ctx, unsigned NumArgs,
+                                EmptyShell Empty) {
+  unsigned SizeOfTrailingObjects =
+      CallExpr::sizeOfTrailingObjects(/*NumPreArgs=*/0, NumArgs);
+  void *Mem =
+      Ctx.Allocate(sizeof(CallExpr) + SizeOfTrailingObjects, alignof(CallExpr));
+  return new (Mem) CallExpr(CallExprClass, /*NumPreArgs=*/0, NumArgs, Empty);
+}
+
+unsigned CallExpr::offsetToTrailingObjects(StmtClass SC) {
+  switch (SC) {
+  case CallExprClass:
+    return sizeof(CallExpr);
+  case CXXOperatorCallExprClass:
+    return sizeof(CXXOperatorCallExpr);
+  case CXXMemberCallExprClass:
+    return sizeof(CXXMemberCallExpr);
+  case UserDefinedLiteralClass:
+    return sizeof(UserDefinedLiteral);
+  case CUDAKernelCallExprClass:
+    return sizeof(CUDAKernelCallExpr);
+  default:
+    llvm_unreachable("unexpected class deriving from CallExpr!");
+  }
+}
 
 void CallExpr::updateDependenciesFromArg(Expr *Arg) {
   if (Arg->isTypeDependent())
@@ -1297,14 +1339,6 @@ void CallExpr::updateDependenciesFromArg(Expr *Arg) {
     ExprBits.ContainsUnexpandedParameterPack = true;
 }
 
-FunctionDecl *CallExpr::getDirectCallee() {
-  return dyn_cast_or_null(getCalleeDecl());
-}
-
-Decl *CallExpr::getCalleeDecl() {
-  return getCallee()->getReferencedDeclOfCallee();
-}
-
 Decl *Expr::getReferencedDeclOfCallee() {
   Expr *CEE = IgnoreParenImpCasts();
 
diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp
index 5ed4ea2ab7..3ddfbf1d19 100644
--- a/lib/AST/ExprCXX.cpp
+++ b/lib/AST/ExprCXX.cpp
@@ -478,6 +478,46 @@ SourceLocation CXXConstructExpr::getEndLoc() const {
   return End;
 }
 
+CXXOperatorCallExpr::CXXOperatorCallExpr(OverloadedOperatorKind OpKind,
+                                         Expr *Fn, ArrayRef Args,
+                                         QualType Ty, ExprValueKind VK,
+                                         SourceLocation OperatorLoc,
+                                         FPOptions FPFeatures,
+                                         ADLCallKind UsesADL)
+    : CallExpr(CXXOperatorCallExprClass, Fn, /*PreArgs=*/{}, Args, Ty, VK,
+               OperatorLoc, /*MinNumArgs=*/0, UsesADL),
+      Operator(OpKind), FPFeatures(FPFeatures) {
+  Range = getSourceRangeImpl();
+}
+
+CXXOperatorCallExpr::CXXOperatorCallExpr(unsigned NumArgs, EmptyShell Empty)
+    : CallExpr(CXXOperatorCallExprClass, /*NumPreArgs=*/0, NumArgs, Empty) {}
+
+CXXOperatorCallExpr *CXXOperatorCallExpr::Create(
+    const ASTContext &Ctx, OverloadedOperatorKind OpKind, Expr *Fn,
+    ArrayRef Args, QualType Ty, ExprValueKind VK,
+    SourceLocation OperatorLoc, FPOptions FPFeatures, ADLCallKind UsesADL) {
+  // Allocate storage for the trailing objects of CallExpr.
+  unsigned NumArgs = Args.size();
+  unsigned SizeOfTrailingObjects =
+      CallExpr::sizeOfTrailingObjects(/*NumPreArgs=*/0, NumArgs);
+  void *Mem = Ctx.Allocate(sizeof(CXXOperatorCallExpr) + SizeOfTrailingObjects,
+                           alignof(CXXOperatorCallExpr));
+  return new (Mem) CXXOperatorCallExpr(OpKind, Fn, Args, Ty, VK, OperatorLoc,
+                                       FPFeatures, UsesADL);
+}
+
+CXXOperatorCallExpr *CXXOperatorCallExpr::CreateEmpty(const ASTContext &Ctx,
+                                                      unsigned NumArgs,
+                                                      EmptyShell Empty) {
+  // Allocate storage for the trailing objects of CallExpr.
+  unsigned SizeOfTrailingObjects =
+      CallExpr::sizeOfTrailingObjects(/*NumPreArgs=*/0, NumArgs);
+  void *Mem = Ctx.Allocate(sizeof(CXXOperatorCallExpr) + SizeOfTrailingObjects,
+                           alignof(CXXOperatorCallExpr));
+  return new (Mem) CXXOperatorCallExpr(NumArgs, Empty);
+}
+
 SourceRange CXXOperatorCallExpr::getSourceRangeImpl() const {
   OverloadedOperatorKind Kind = getOperator();
   if (Kind == OO_PlusPlus || Kind == OO_MinusMinus) {
@@ -502,6 +542,40 @@ SourceRange CXXOperatorCallExpr::getSourceRangeImpl() const {
   }
 }
 
+CXXMemberCallExpr::CXXMemberCallExpr(Expr *Fn, ArrayRef Args,
+                                     QualType Ty, ExprValueKind VK,
+                                     SourceLocation RP, unsigned MinNumArgs)
+    : CallExpr(CXXMemberCallExprClass, Fn, /*PreArgs=*/{}, Args, Ty, VK, RP,
+               MinNumArgs, NotADL) {}
+
+CXXMemberCallExpr::CXXMemberCallExpr(unsigned NumArgs, EmptyShell Empty)
+    : CallExpr(CXXMemberCallExprClass, /*NumPreArgs=*/0, NumArgs, Empty) {}
+
+CXXMemberCallExpr *CXXMemberCallExpr::Create(const ASTContext &Ctx, Expr *Fn,
+                                             ArrayRef Args, QualType Ty,
+                                             ExprValueKind VK,
+                                             SourceLocation RP,
+                                             unsigned MinNumArgs) {
+  // Allocate storage for the trailing objects of CallExpr.
+  unsigned NumArgs = std::max(Args.size(), MinNumArgs);
+  unsigned SizeOfTrailingObjects =
+      CallExpr::sizeOfTrailingObjects(/*NumPreArgs=*/0, NumArgs);
+  void *Mem = Ctx.Allocate(sizeof(CXXMemberCallExpr) + SizeOfTrailingObjects,
+                           alignof(CXXMemberCallExpr));
+  return new (Mem) CXXMemberCallExpr(Fn, Args, Ty, VK, RP, MinNumArgs);
+}
+
+CXXMemberCallExpr *CXXMemberCallExpr::CreateEmpty(const ASTContext &Ctx,
+                                                  unsigned NumArgs,
+                                                  EmptyShell Empty) {
+  // Allocate storage for the trailing objects of CallExpr.
+  unsigned SizeOfTrailingObjects =
+      CallExpr::sizeOfTrailingObjects(/*NumPreArgs=*/0, NumArgs);
+  void *Mem = Ctx.Allocate(sizeof(CXXMemberCallExpr) + SizeOfTrailingObjects,
+                           alignof(CXXMemberCallExpr));
+  return new (Mem) CXXMemberCallExpr(NumArgs, Empty);
+}
+
 Expr *CXXMemberCallExpr::getImplicitObjectArgument() const {
   const Expr *Callee = getCallee()->IgnoreParens();
   if (const auto *MemExpr = dyn_cast(Callee))
@@ -715,6 +789,42 @@ SourceLocation CXXFunctionalCastExpr::getEndLoc() const {
   return RParenLoc.isValid() ? RParenLoc : getSubExpr()->getEndLoc();
 }
 
+UserDefinedLiteral::UserDefinedLiteral(Expr *Fn, ArrayRef Args,
+                                       QualType Ty, ExprValueKind VK,
+                                       SourceLocation LitEndLoc,
+                                       SourceLocation SuffixLoc)
+    : CallExpr(UserDefinedLiteralClass, Fn, /*PreArgs=*/{}, Args, Ty, VK,
+               LitEndLoc, /*MinNumArgs=*/0, NotADL),
+      UDSuffixLoc(SuffixLoc) {}
+
+UserDefinedLiteral::UserDefinedLiteral(unsigned NumArgs, EmptyShell Empty)
+    : CallExpr(UserDefinedLiteralClass, /*NumPreArgs=*/0, NumArgs, Empty) {}
+
+UserDefinedLiteral *UserDefinedLiteral::Create(const ASTContext &Ctx, Expr *Fn,
+                                               ArrayRef Args,
+                                               QualType Ty, ExprValueKind VK,
+                                               SourceLocation LitEndLoc,
+                                               SourceLocation SuffixLoc) {
+  // Allocate storage for the trailing objects of CallExpr.
+  unsigned NumArgs = Args.size();
+  unsigned SizeOfTrailingObjects =
+      CallExpr::sizeOfTrailingObjects(/*NumPreArgs=*/0, NumArgs);
+  void *Mem = Ctx.Allocate(sizeof(UserDefinedLiteral) + SizeOfTrailingObjects,
+                           alignof(UserDefinedLiteral));
+  return new (Mem) UserDefinedLiteral(Fn, Args, Ty, VK, LitEndLoc, SuffixLoc);
+}
+
+UserDefinedLiteral *UserDefinedLiteral::CreateEmpty(const ASTContext &Ctx,
+                                                    unsigned NumArgs,
+                                                    EmptyShell Empty) {
+  // Allocate storage for the trailing objects of CallExpr.
+  unsigned SizeOfTrailingObjects =
+      CallExpr::sizeOfTrailingObjects(/*NumPreArgs=*/0, NumArgs);
+  void *Mem = Ctx.Allocate(sizeof(UserDefinedLiteral) + SizeOfTrailingObjects,
+                           alignof(UserDefinedLiteral));
+  return new (Mem) UserDefinedLiteral(NumArgs, Empty);
+}
+
 UserDefinedLiteral::LiteralOperatorKind
 UserDefinedLiteral::getLiteralOperatorKind() const {
   if (getNumArgs() == 0)
@@ -1443,3 +1553,38 @@ TypeTraitExpr *TypeTraitExpr::CreateDeserialized(const ASTContext &C,
   void *Mem = C.Allocate(totalSizeToAlloc(NumArgs));
   return new (Mem) TypeTraitExpr(EmptyShell());
 }
+
+CUDAKernelCallExpr::CUDAKernelCallExpr(Expr *Fn, CallExpr *Config,
+                                       ArrayRef Args, QualType Ty,
+                                       ExprValueKind VK, SourceLocation RP,
+                                       unsigned MinNumArgs)
+    : CallExpr(CUDAKernelCallExprClass, Fn, /*PreArgs=*/Config, Args, Ty, VK,
+               RP, MinNumArgs, NotADL) {}
+
+CUDAKernelCallExpr::CUDAKernelCallExpr(unsigned NumArgs, EmptyShell Empty)
+    : CallExpr(CUDAKernelCallExprClass, /*NumPreArgs=*/END_PREARG, NumArgs,
+               Empty) {}
+
+CUDAKernelCallExpr *
+CUDAKernelCallExpr::Create(const ASTContext &Ctx, Expr *Fn, CallExpr *Config,
+                           ArrayRef Args, QualType Ty, ExprValueKind VK,
+                           SourceLocation RP, unsigned MinNumArgs) {
+  // Allocate storage for the trailing objects of CallExpr.
+  unsigned NumArgs = std::max(Args.size(), MinNumArgs);
+  unsigned SizeOfTrailingObjects =
+      CallExpr::sizeOfTrailingObjects(/*NumPreArgs=*/END_PREARG, NumArgs);
+  void *Mem = Ctx.Allocate(sizeof(CUDAKernelCallExpr) + SizeOfTrailingObjects,
+                           alignof(CUDAKernelCallExpr));
+  return new (Mem) CUDAKernelCallExpr(Fn, Config, Args, Ty, VK, RP, MinNumArgs);
+}
+
+CUDAKernelCallExpr *CUDAKernelCallExpr::CreateEmpty(const ASTContext &Ctx,
+                                                    unsigned NumArgs,
+                                                    EmptyShell Empty) {
+  // Allocate storage for the trailing objects of CallExpr.
+  unsigned SizeOfTrailingObjects =
+      CallExpr::sizeOfTrailingObjects(/*NumPreArgs=*/END_PREARG, NumArgs);
+  void *Mem = Ctx.Allocate(sizeof(CUDAKernelCallExpr) + SizeOfTrailingObjects,
+                           alignof(CUDAKernelCallExpr));
+  return new (Mem) CUDAKernelCallExpr(NumArgs, Empty);
+}
diff --git a/lib/Analysis/BodyFarm.cpp b/lib/Analysis/BodyFarm.cpp
index 9c1d529a68..35f0464067 100644
--- a/lib/Analysis/BodyFarm.cpp
+++ b/lib/Analysis/BodyFarm.cpp
@@ -269,8 +269,8 @@ static CallExpr *create_call_once_funcptr_call(ASTContext &C, ASTMaker M,
     llvm_unreachable("Unexpected state");
   }
 
-  return new (C)
-      CallExpr(C, SubExpr, CallArgs, C.VoidTy, VK_RValue, SourceLocation());
+  return CallExpr::Create(C, SubExpr, CallArgs, C.VoidTy, VK_RValue,
+                          SourceLocation());
 }
 
 static CallExpr *create_call_once_lambda_call(ASTContext &C, ASTMaker M,
@@ -292,12 +292,12 @@ static CallExpr *create_call_once_lambda_call(ASTContext &C, ASTMaker M,
                           /* T =*/ callOperatorDecl->getType(),
                           /* VK =*/ VK_LValue);
 
-  return new (C)
-      CXXOperatorCallExpr(/*AstContext=*/C, OO_Call, callOperatorDeclRef,
-                          /*args=*/CallArgs,
-                          /*QualType=*/C.VoidTy,
-                          /*ExprValueType=*/VK_RValue,
-                          /*SourceLocation=*/SourceLocation(), FPOptions());
+  return CXXOperatorCallExpr::Create(
+      /*AstContext=*/C, OO_Call, callOperatorDeclRef,
+      /*args=*/CallArgs,
+      /*QualType=*/C.VoidTy,
+      /*ExprValueType=*/VK_RValue,
+      /*SourceLocation=*/SourceLocation(), FPOptions());
 }
 
 /// Create a fake body for std::call_once.
@@ -509,7 +509,7 @@ static Stmt *create_dispatch_once(ASTContext &C, const FunctionDecl *D) {
   ASTMaker M(C);
 
   // (1) Create the call.
-  CallExpr *CE = new (C) CallExpr(
+  CallExpr *CE = CallExpr::Create(
       /*ASTContext=*/C,
       /*StmtClass=*/M.makeLvalueToRvalue(/*Expr=*/Block),
       /*args=*/None,
@@ -579,8 +579,8 @@ static Stmt *create_dispatch_sync(ASTContext &C, const FunctionDecl *D) {
   ASTMaker M(C);
   DeclRefExpr *DR = M.makeDeclRefExpr(PV);
   ImplicitCastExpr *ICE = M.makeLvalueToRvalue(DR, Ty);
-  CallExpr *CE = new (C) CallExpr(C, ICE, None, C.VoidTy, VK_RValue,
-                                  SourceLocation());
+  CallExpr *CE =
+      CallExpr::Create(C, ICE, None, C.VoidTy, VK_RValue, SourceLocation());
   return CE;
 }
 
diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp
index d497179a53..4cc86ad094 100644
--- a/lib/CodeGen/CGObjC.cpp
+++ b/lib/CodeGen/CGObjC.cpp
@@ -3390,11 +3390,11 @@ CodeGenFunction::GenerateObjCAtomicSetterCopyHelperFunction(
 
   Expr *Args[2] = { &DST, &SRC };
   CallExpr *CalleeExp = cast(PID->getSetterCXXAssignment());
-  CXXOperatorCallExpr TheCall(C, OO_Equal, CalleeExp->getCallee(),
-                              Args, DestTy->getPointeeType(),
-                              VK_LValue, SourceLocation(), FPOptions());
+  CXXOperatorCallExpr *TheCall = CXXOperatorCallExpr::Create(
+      C, OO_Equal, CalleeExp->getCallee(), Args, DestTy->getPointeeType(),
+      VK_LValue, SourceLocation(), FPOptions());
 
-  EmitStmt(&TheCall);
+  EmitStmt(TheCall);
 
   FinishFunction();
   HelperFn = llvm::ConstantExpr::getBitCast(Fn, VoidPtrTy);
diff --git a/lib/Frontend/Rewrite/RewriteModernObjC.cpp b/lib/Frontend/Rewrite/RewriteModernObjC.cpp
index 9ed8b1568b..10ca9a7856 100644
--- a/lib/Frontend/Rewrite/RewriteModernObjC.cpp
+++ b/lib/Frontend/Rewrite/RewriteModernObjC.cpp
@@ -2107,9 +2107,8 @@ RewriteModernObjC::SynthesizeCallToFunctionDecl(FunctionDecl *FD,
 
   const FunctionType *FT = msgSendType->getAs();
 
-  CallExpr *Exp =  new (Context) CallExpr(*Context, ICE, Args,
-                                          FT->getCallResultType(*Context),
-                                          VK_RValue, EndLoc);
+  CallExpr *Exp = CallExpr::Create(
+      *Context, ICE, Args, FT->getCallResultType(*Context), VK_RValue, EndLoc);
   return Exp;
 }
 
@@ -2689,8 +2688,8 @@ Stmt *RewriteModernObjC::RewriteObjCBoxedExpr(ObjCBoxedExpr *Exp) {
   ParenExpr *PE = new (Context) ParenExpr(StartLoc, EndLoc, cast);
 
   const FunctionType *FT = msgSendType->getAs();
-  CallExpr *CE = new (Context)
-      CallExpr(*Context, PE, MsgExprs, FT->getReturnType(), VK_RValue, EndLoc);
+  CallExpr *CE = CallExpr::Create(*Context, PE, MsgExprs, FT->getReturnType(),
+                                  VK_RValue, EndLoc);
   ReplaceStmt(Exp, CE);
   return CE;
 }
@@ -2729,8 +2728,8 @@ Stmt *RewriteModernObjC::RewriteObjCArrayLiteralExpr(ObjCArrayLiteral *Exp) {
   for (unsigned i = 0; i < NumElements; i++)
     InitExprs.push_back(Exp->getElement(i));
   Expr *NSArrayCallExpr =
-    new (Context) CallExpr(*Context, NSArrayDRE, InitExprs,
-                           NSArrayFType, VK_LValue, SourceLocation());
+      CallExpr::Create(*Context, NSArrayDRE, InitExprs, NSArrayFType, VK_LValue,
+                       SourceLocation());
 
   FieldDecl *ARRFD = FieldDecl::Create(*Context, nullptr, SourceLocation(),
                                     SourceLocation(),
@@ -2810,8 +2809,8 @@ Stmt *RewriteModernObjC::RewriteObjCArrayLiteralExpr(ObjCArrayLiteral *Exp) {
   ParenExpr *PE = new (Context) ParenExpr(StartLoc, EndLoc, cast);
 
   const FunctionType *FT = msgSendType->getAs();
-  CallExpr *CE = new (Context)
-      CallExpr(*Context, PE, MsgExprs, FT->getReturnType(), VK_RValue, EndLoc);
+  CallExpr *CE = CallExpr::Create(*Context, PE, MsgExprs, FT->getReturnType(),
+                                  VK_RValue, EndLoc);
   ReplaceStmt(Exp, CE);
   return CE;
 }
@@ -2858,8 +2857,8 @@ Stmt *RewriteModernObjC::RewriteObjCDictionaryLiteralExpr(ObjCDictionaryLiteral
 
   // (const id [])objects
   Expr *NSValueCallExpr =
-    new (Context) CallExpr(*Context, NSDictDRE, ValueExprs,
-                           NSDictFType, VK_LValue, SourceLocation());
+      CallExpr::Create(*Context, NSDictDRE, ValueExprs, NSDictFType, VK_LValue,
+                       SourceLocation());
 
   FieldDecl *ARRFD = FieldDecl::Create(*Context, nullptr, SourceLocation(),
                                        SourceLocation(),
@@ -2877,9 +2876,8 @@ Stmt *RewriteModernObjC::RewriteObjCDictionaryLiteralExpr(ObjCDictionaryLiteral
                              CK_BitCast,
                              DictLiteralValueME);
   // (const id  [])keys
-  Expr *NSKeyCallExpr =
-    new (Context) CallExpr(*Context, NSDictDRE, KeyExprs,
-                           NSDictFType, VK_LValue, SourceLocation());
+  Expr *NSKeyCallExpr = CallExpr::Create(
+      *Context, NSDictDRE, KeyExprs, NSDictFType, VK_LValue, SourceLocation());
 
   MemberExpr *DictLiteralKeyME = new (Context)
       MemberExpr(NSKeyCallExpr, false, SourceLocation(), ARRFD,
@@ -2962,8 +2960,8 @@ Stmt *RewriteModernObjC::RewriteObjCDictionaryLiteralExpr(ObjCDictionaryLiteral
   ParenExpr *PE = new (Context) ParenExpr(StartLoc, EndLoc, cast);
 
   const FunctionType *FT = msgSendType->getAs();
-  CallExpr *CE = new (Context)
-      CallExpr(*Context, PE, MsgExprs, FT->getReturnType(), VK_RValue, EndLoc);
+  CallExpr *CE = CallExpr::Create(*Context, PE, MsgExprs, FT->getReturnType(),
+                                  VK_RValue, EndLoc);
   ReplaceStmt(Exp, CE);
   return CE;
 }
@@ -3172,10 +3170,10 @@ Expr *RewriteModernObjC::SynthMsgSendStretCallExpr(FunctionDecl *MsgSendStretFla
   FunctionDecl *FD =
       FunctionDecl::Create(*Context, TUDecl, SourceLocation(), SourceLocation(),
                            ID, FuncType, nullptr, SC_Extern, false, false);
-  DeclRefExpr *DRE = new (Context) DeclRefExpr(*Context, FD, false, castType,
-                                               VK_RValue, SourceLocation());
-  CallExpr *STCE = new (Context) CallExpr(*Context, DRE, MsgExprs,
-                                          castType, VK_LValue, SourceLocation());
+  DeclRefExpr *DRE = new (Context)
+      DeclRefExpr(*Context, FD, false, castType, VK_RValue, SourceLocation());
+  CallExpr *STCE = CallExpr::Create(*Context, DRE, MsgExprs, castType,
+                                    VK_LValue, SourceLocation());
 
   FieldDecl *FieldD = FieldDecl::Create(*Context, nullptr, SourceLocation(),
                                     SourceLocation(),
@@ -3276,9 +3274,8 @@ Stmt *RewriteModernObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
       DeclRefExpr *DRE = new (Context)
           DeclRefExpr(*Context, SuperConstructorFunctionDecl, false, superType,
                       VK_LValue, SourceLocation());
-      SuperRep = new (Context) CallExpr(*Context, DRE, InitExprs,
-                                        superType, VK_LValue,
-                                        SourceLocation());
+      SuperRep = CallExpr::Create(*Context, DRE, InitExprs, superType,
+                                  VK_LValue, SourceLocation());
       // The code for super is a little tricky to prevent collision with
       // the structure definition in the header. The rewriter has it's own
       // internal definition (__rw_objc_super) that is uses. This is why
@@ -3369,12 +3366,11 @@ Stmt *RewriteModernObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
     if (LangOpts.MicrosoftExt) {
       SynthSuperConstructorFunctionDecl();
       // Simulate a constructor call...
-      DeclRefExpr *DRE = new (Context) DeclRefExpr(*Context,
-                                                   SuperConstructorFunctionDecl,
-                                                   false, superType, VK_LValue,
-                                                   SourceLocation());
-      SuperRep = new (Context) CallExpr(*Context, DRE, InitExprs,
-                                        superType, VK_LValue, SourceLocation());
+      DeclRefExpr *DRE = new (Context)
+          DeclRefExpr(*Context, SuperConstructorFunctionDecl, false, superType,
+                      VK_LValue, SourceLocation());
+      SuperRep = CallExpr::Create(*Context, DRE, InitExprs, superType,
+                                  VK_LValue, SourceLocation());
       // The code for super is a little tricky to prevent collision with
       // the structure definition in the header. The rewriter has it's own
       // internal definition (__rw_objc_super) that is uses. This is why
@@ -3538,8 +3534,8 @@ Stmt *RewriteModernObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
   ParenExpr *PE = new (Context) ParenExpr(StartLoc, EndLoc, cast);
 
   const FunctionType *FT = msgSendType->getAs();
-  CallExpr *CE = new (Context)
-      CallExpr(*Context, PE, MsgExprs, FT->getReturnType(), VK_RValue, EndLoc);
+  CallExpr *CE = CallExpr::Create(*Context, PE, MsgExprs, FT->getReturnType(),
+                                  VK_RValue, EndLoc);
   Stmt *ReplacingStmt = CE;
   if (MsgSendStretFlavor) {
     // We have the method which returns a struct/union. Must also generate
@@ -4650,9 +4646,8 @@ Stmt *RewriteModernObjC::SynthesizeBlockCall(CallExpr *Exp, const Expr *BlockExp
        E = Exp->arg_end(); I != E; ++I) {
     BlkExprs.push_back(*I);
   }
-  CallExpr *CE = new (Context) CallExpr(*Context, PE, BlkExprs,
-                                        Exp->getType(), VK_RValue,
-                                        SourceLocation());
+  CallExpr *CE = CallExpr::Create(*Context, PE, BlkExprs, Exp->getType(),
+                                  VK_RValue, SourceLocation());
   return CE;
 }
 
@@ -5395,8 +5390,8 @@ Stmt *RewriteModernObjC::SynthBlockInitExpr(BlockExpr *Exp,
                                            Context->IntTy, SourceLocation());
     InitExprs.push_back(FlagExp);
   }
-  NewRep = new (Context) CallExpr(*Context, DRE, InitExprs,
-                                  FType, VK_LValue, SourceLocation());
+  NewRep = CallExpr::Create(*Context, DRE, InitExprs, FType, VK_LValue,
+                            SourceLocation());
 
   if (GlobalBlockExpr) {
     assert (!GlobalConstructionExp &&
diff --git a/lib/Frontend/Rewrite/RewriteObjC.cpp b/lib/Frontend/Rewrite/RewriteObjC.cpp
index 0bbf4266fd..3e018800b9 100644
--- a/lib/Frontend/Rewrite/RewriteObjC.cpp
+++ b/lib/Frontend/Rewrite/RewriteObjC.cpp
@@ -2020,9 +2020,8 @@ RewriteObjC::SynthesizeCallToFunctionDecl(FunctionDecl *FD,
 
   const FunctionType *FT = msgSendType->getAs();
 
-  CallExpr *Exp = new (Context) CallExpr(*Context, ICE, Args,
-                                         FT->getCallResultType(*Context),
-                                         VK_RValue, EndLoc);
+  CallExpr *Exp = CallExpr::Create(
+      *Context, ICE, Args, FT->getCallResultType(*Context), VK_RValue, EndLoc);
   return Exp;
 }
 
@@ -2607,8 +2606,8 @@ CallExpr *RewriteObjC::SynthMsgSendStretCallExpr(FunctionDecl *MsgSendStretFlavo
   ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), cast);
 
   const FunctionType *FT = msgSendType->getAs();
-  CallExpr *STCE = new (Context) CallExpr(
-      *Context, PE, MsgExprs, FT->getReturnType(), VK_RValue, SourceLocation());
+  CallExpr *STCE = CallExpr::Create(*Context, PE, MsgExprs, FT->getReturnType(),
+                                    VK_RValue, SourceLocation());
   return STCE;
 }
 
@@ -2700,9 +2699,8 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
       DeclRefExpr *DRE = new (Context)
           DeclRefExpr(*Context, SuperConstructorFunctionDecl, false, superType,
                       VK_LValue, SourceLocation());
-      SuperRep = new (Context) CallExpr(*Context, DRE, InitExprs,
-                                        superType, VK_LValue,
-                                        SourceLocation());
+      SuperRep = CallExpr::Create(*Context, DRE, InitExprs, superType,
+                                  VK_LValue, SourceLocation());
       // The code for super is a little tricky to prevent collision with
       // the structure definition in the header. The rewriter has it's own
       // internal definition (__rw_objc_super) that is uses. This is why
@@ -2796,8 +2794,8 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
       DeclRefExpr *DRE = new (Context)
           DeclRefExpr(*Context, SuperConstructorFunctionDecl, false, superType,
                       VK_LValue, SourceLocation());
-      SuperRep = new (Context) CallExpr(*Context, DRE, InitExprs,
-                                        superType, VK_LValue, SourceLocation());
+      SuperRep = CallExpr::Create(*Context, DRE, InitExprs, superType,
+                                  VK_LValue, SourceLocation());
       // The code for super is a little tricky to prevent collision with
       // the structure definition in the header. The rewriter has it's own
       // internal definition (__rw_objc_super) that is uses. This is why
@@ -2961,8 +2959,8 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
   ParenExpr *PE = new (Context) ParenExpr(StartLoc, EndLoc, cast);
 
   const FunctionType *FT = msgSendType->getAs();
-  CallExpr *CE = new (Context)
-      CallExpr(*Context, PE, MsgExprs, FT->getReturnType(), VK_RValue, EndLoc);
+  CallExpr *CE = CallExpr::Create(*Context, PE, MsgExprs, FT->getReturnType(),
+                                  VK_RValue, EndLoc);
   Stmt *ReplacingStmt = CE;
   if (MsgSendStretFlavor) {
     // We have the method which returns a struct/union. Must also generate
@@ -3812,9 +3810,8 @@ Stmt *RewriteObjC::SynthesizeBlockCall(CallExpr *Exp, const Expr *BlockExp) {
        E = Exp->arg_end(); I != E; ++I) {
     BlkExprs.push_back(*I);
   }
-  CallExpr *CE = new (Context) CallExpr(*Context, PE, BlkExprs,
-                                        Exp->getType(), VK_RValue,
-                                        SourceLocation());
+  CallExpr *CE = CallExpr::Create(*Context, PE, BlkExprs, Exp->getType(),
+                                  VK_RValue, SourceLocation());
   return CE;
 }
 
@@ -4524,11 +4521,11 @@ Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp,
                                            Context->IntTy, SourceLocation());
     InitExprs.push_back(FlagExp);
   }
-  NewRep = new (Context) CallExpr(*Context, DRE, InitExprs,
-                                  FType, VK_LValue, SourceLocation());
-  NewRep = new (Context) UnaryOperator(NewRep, UO_AddrOf,
-                             Context->getPointerType(NewRep->getType()),
-                             VK_RValue, OK_Ordinary, SourceLocation(), false);
+  NewRep = CallExpr::Create(*Context, DRE, InitExprs, FType, VK_LValue,
+                            SourceLocation());
+  NewRep = new (Context) UnaryOperator(
+      NewRep, UO_AddrOf, Context->getPointerType(NewRep->getType()), VK_RValue,
+      OK_Ordinary, SourceLocation(), false);
   NewRep = NoTypeInfoCStyleCastExpr(Context, FType, CK_BitCast,
                                     NewRep);
   BlockDeclRefs.clear();
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 78dbf4365c..d38ae0fdc8 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -5439,8 +5439,8 @@ ExprResult Sema::ActOnCallExpr(Scope *Scope, Expr *Fn, SourceLocation LParenLoc,
                                ArgExprs.back()->getEndLoc()));
       }
 
-      return new (Context)
-          CallExpr(Context, Fn, None, Context.VoidTy, VK_RValue, RParenLoc);
+      return CallExpr::Create(Context, Fn, /*Args=*/{}, Context.VoidTy,
+                              VK_RValue, RParenLoc);
     }
     if (Fn->getType() == Context.PseudoObjectTy) {
       ExprResult result = CheckPlaceholderExpr(Fn);
@@ -5452,7 +5452,7 @@ ExprResult Sema::ActOnCallExpr(Scope *Scope, Expr *Fn, SourceLocation LParenLoc,
     // in which case we won't do any semantic analysis now.
     if (Fn->isTypeDependent() || Expr::hasAnyTypeDependentArguments(ArgExprs)) {
       if (ExecConfig) {
-        return new (Context) CUDAKernelCallExpr(
+        return CUDAKernelCallExpr::Create(
             Context, Fn, cast(ExecConfig), ArgExprs,
             Context.DependentTy, VK_RValue, RParenLoc);
       } else {
@@ -5461,8 +5461,8 @@ ExprResult Sema::ActOnCallExpr(Scope *Scope, Expr *Fn, SourceLocation LParenLoc,
             *this, dyn_cast(Fn->IgnoreParens()),
             Fn->getBeginLoc());
 
-        return new (Context) CallExpr(
-            Context, Fn, ArgExprs, Context.DependentTy, VK_RValue, RParenLoc);
+        return CallExpr::Create(Context, Fn, ArgExprs, Context.DependentTy,
+                                VK_RValue, RParenLoc);
       }
     }
 
@@ -5490,8 +5490,8 @@ ExprResult Sema::ActOnCallExpr(Scope *Scope, Expr *Fn, SourceLocation LParenLoc,
     // We aren't supposed to apply this logic if there's an '&' involved.
     if (!find.HasFormOfMemberPointer) {
       if (Expr::hasAnyTypeDependentArguments(ArgExprs))
-        return new (Context) CallExpr(
-            Context, Fn, ArgExprs, Context.DependentTy, VK_RValue, RParenLoc);
+        return CallExpr::Create(Context, Fn, ArgExprs, Context.DependentTy,
+                                VK_RValue, RParenLoc);
       OverloadExpr *ovl = find.Expression;
       if (UnresolvedLookupExpr *ULE = dyn_cast(ovl))
         return BuildOverloadedCallExpr(
@@ -5680,12 +5680,12 @@ ExprResult Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl,
   if (Config) {
     assert(UsesADL == ADLCallKind::NotADL &&
            "CUDAKernelCallExpr should not use ADL");
-    TheCall = new (Context)
-        CUDAKernelCallExpr(Context, Fn, cast(Config), Args, ResultTy,
-                           VK_RValue, RParenLoc, NumParams);
+    TheCall =
+        CUDAKernelCallExpr::Create(Context, Fn, cast(Config), Args,
+                                   ResultTy, VK_RValue, RParenLoc, NumParams);
   } else {
-    TheCall = new (Context) CallExpr(Context, Fn, Args, ResultTy, VK_RValue,
-                                     RParenLoc, NumParams, UsesADL);
+    TheCall = CallExpr::Create(Context, Fn, Args, ResultTy, VK_RValue,
+                               RParenLoc, NumParams, UsesADL);
   }
 
   if (!getLangOpts().CPlusPlus) {
@@ -16775,9 +16775,10 @@ ExprResult Sema::CheckPlaceholderExpr(Expr *E) {
       auto *FD = cast(DRE->getDecl());
       if (FD->getBuiltinID() == Builtin::BI__noop) {
         E = ImpCastExprToType(E, Context.getPointerType(FD->getType()),
-                              CK_BuiltinFnToFnPtr).get();
-        return new (Context) CallExpr(Context, E, None, Context.IntTy,
-                                      VK_RValue, SourceLocation());
+                              CK_BuiltinFnToFnPtr)
+                .get();
+        return CallExpr::Create(Context, E, /*Args=*/{}, Context.IntTy,
+                                VK_RValue, SourceLocation());
       }
     }
 
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index 18d0e78a4f..730c426076 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -7189,8 +7189,8 @@ ExprResult Sema::BuildCXXMemberCallExpr(Expr *E, NamedDecl *FoundDecl,
   ExprValueKind VK = Expr::getValueKindForType(ResultType);
   ResultType = ResultType.getNonLValueExprType(Context);
 
-  CXXMemberCallExpr *CE = new (Context) CXXMemberCallExpr(
-      Context, ME, None, ResultType, VK, Exp.get()->getEndLoc());
+  CXXMemberCallExpr *CE = CXXMemberCallExpr::Create(
+      Context, ME, /*Args=*/{}, ResultType, VK, Exp.get()->getEndLoc());
 
   if (CheckFunctionCall(Method, CE,
                         Method->getType()->castAs()))
diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp
index 4fe8d3dd59..24e9ef4aaa 100644
--- a/lib/Sema/SemaOpenMP.cpp
+++ b/lib/Sema/SemaOpenMP.cpp
@@ -11231,8 +11231,8 @@ static bool actOnOMPReductionKindClause(
           ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary,
           S.DefaultLvalueConversion(DeclareReductionRef.get()).get());
       Expr *Args[] = {LHS.get(), RHS.get()};
-      ReductionOp = new (Context)
-          CallExpr(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc);
+      ReductionOp =
+          CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc);
     } else {
       ReductionOp = S.BuildBinOp(
           Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE);
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index d829194364..94f7979f66 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -7003,13 +7003,17 @@ Sema::AddConversionCandidate(CXXConversionDecl *Conversion,
   // there are 0 arguments (i.e., nothing is allocated using ASTContext's
   // allocator).
   QualType CallResultType = ConversionType.getNonLValueExprType(Context);
-  CallExpr Call(Context, &ConversionFn, None, CallResultType, VK,
-                From->getBeginLoc());
+
+  llvm::AlignedCharArray
+      Buffer;
+  CallExpr *TheTemporaryCall = CallExpr::CreateTemporary(
+      Buffer.buffer, &ConversionFn, CallResultType, VK, From->getBeginLoc());
+
   ImplicitConversionSequence ICS =
-    TryCopyInitialization(*this, &Call, ToType,
-                          /*SuppressUserConversions=*/true,
-                          /*InOverloadResolution=*/false,
-                          /*AllowObjCWritebackConversion=*/false);
+      TryCopyInitialization(*this, TheTemporaryCall, ToType,
+                            /*SuppressUserConversions=*/true,
+                            /*InOverloadResolution=*/false,
+                            /*AllowObjCWritebackConversion=*/false);
 
   switch (ICS.getKind()) {
   case ImplicitConversionSequence::StandardConversion:
@@ -11988,12 +11992,12 @@ bool Sema::buildOverloadedCallSet(Scope *S, Expr *Fn,
     if (CandidateSet->empty() ||
         CandidateSet->BestViableFunction(*this, Fn->getBeginLoc(), Best) ==
             OR_No_Viable_Function) {
-      // In Microsoft mode, if we are inside a template class member function then
-      // create a type dependent CallExpr. The goal is to postpone name lookup
-      // to instantiation time to be able to search into type dependent base
-      // classes.
-      CallExpr *CE = new (Context) CallExpr(
-          Context, Fn, Args, Context.DependentTy, VK_RValue, RParenLoc);
+      // In Microsoft mode, if we are inside a template class member function
+      // then create a type dependent CallExpr. The goal is to postpone name
+      // lookup to instantiation time to be able to search into type dependent
+      // base classes.
+      CallExpr *CE = CallExpr::Create(Context, Fn, Args, Context.DependentTy,
+                                      VK_RValue, RParenLoc);
       CE->setTypeDependent(true);
       CE->setValueDependent(true);
       CE->setInstantiationDependent(true);
@@ -12199,14 +12203,12 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc,
                                          VK_RValue, OK_Ordinary, OpLoc, false);
 
     CXXRecordDecl *NamingClass = nullptr; // lookup ignores member operators
-    UnresolvedLookupExpr *Fn
-      = UnresolvedLookupExpr::Create(Context, NamingClass,
-                                     NestedNameSpecifierLoc(), OpNameInfo,
-                                     /*ADL*/ true, IsOverloaded(Fns),
-                                     Fns.begin(), Fns.end());
-    return new (Context)
-        CXXOperatorCallExpr(Context, Op, Fn, ArgsArray, Context.DependentTy,
-                            VK_RValue, OpLoc, FPOptions());
+    UnresolvedLookupExpr *Fn = UnresolvedLookupExpr::Create(
+        Context, NamingClass, NestedNameSpecifierLoc(), OpNameInfo,
+        /*ADL*/ true, IsOverloaded(Fns), Fns.begin(), Fns.end());
+    return CXXOperatorCallExpr::Create(Context, Op, Fn, ArgsArray,
+                                       Context.DependentTy, VK_RValue, OpLoc,
+                                       FPOptions());
   }
 
   // Build an empty overload set.
@@ -12278,9 +12280,9 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc,
       ResultTy = ResultTy.getNonLValueExprType(Context);
 
       Args[0] = Input;
-      CallExpr *TheCall = new (Context)
-          CXXOperatorCallExpr(Context, Op, FnExpr.get(), ArgsArray, ResultTy,
-                              VK, OpLoc, FPOptions(), Best->IsADLCandidate);
+      CallExpr *TheCall = CXXOperatorCallExpr::Create(
+          Context, Op, FnExpr.get(), ArgsArray, ResultTy, VK, OpLoc,
+          FPOptions(), Best->IsADLCandidate);
 
       if (CheckCallReturnType(FnDecl->getReturnType(), OpLoc, TheCall, FnDecl))
         return ExprError();
@@ -12390,14 +12392,12 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
     CXXRecordDecl *NamingClass = nullptr; // lookup ignores member operators
     // TODO: provide better source location info in DNLoc component.
     DeclarationNameInfo OpNameInfo(OpName, OpLoc);
-    UnresolvedLookupExpr *Fn
-      = UnresolvedLookupExpr::Create(Context, NamingClass,
-                                     NestedNameSpecifierLoc(), OpNameInfo,
-                                     /*ADL*/PerformADL, IsOverloaded(Fns),
-                                     Fns.begin(), Fns.end());
-    return new (Context)
-        CXXOperatorCallExpr(Context, Op, Fn, Args, Context.DependentTy,
-                            VK_RValue, OpLoc, FPFeatures);
+    UnresolvedLookupExpr *Fn = UnresolvedLookupExpr::Create(
+        Context, NamingClass, NestedNameSpecifierLoc(), OpNameInfo,
+        /*ADL*/ PerformADL, IsOverloaded(Fns), Fns.begin(), Fns.end());
+    return CXXOperatorCallExpr::Create(Context, Op, Fn, Args,
+                                       Context.DependentTy, VK_RValue, OpLoc,
+                                       FPFeatures);
   }
 
   // Always do placeholder-like conversions on the RHS.
@@ -12510,9 +12510,9 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
         ExprValueKind VK = Expr::getValueKindForType(ResultTy);
         ResultTy = ResultTy.getNonLValueExprType(Context);
 
-        CXXOperatorCallExpr *TheCall = new (Context)
-            CXXOperatorCallExpr(Context, Op, FnExpr.get(), Args, ResultTy, VK,
-                                OpLoc, FPFeatures, Best->IsADLCandidate);
+        CXXOperatorCallExpr *TheCall = CXXOperatorCallExpr::Create(
+            Context, Op, FnExpr.get(), Args, ResultTy, VK, OpLoc, FPFeatures,
+            Best->IsADLCandidate);
 
         if (CheckCallReturnType(FnDecl->getReturnType(), OpLoc, TheCall,
                                 FnDecl))
@@ -12658,9 +12658,9 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc,
                                      UnresolvedSetIterator());
     // Can't add any actual overloads yet
 
-    return new (Context)
-        CXXOperatorCallExpr(Context, OO_Subscript, Fn, Args,
-                            Context.DependentTy, VK_RValue, RLoc, FPOptions());
+    return CXXOperatorCallExpr::Create(Context, OO_Subscript, Fn, Args,
+                                       Context.DependentTy, VK_RValue, RLoc,
+                                       FPOptions());
   }
 
   // Handle placeholders on both operands.
@@ -12734,10 +12734,8 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc,
         ResultTy = ResultTy.getNonLValueExprType(Context);
 
         CXXOperatorCallExpr *TheCall =
-          new (Context) CXXOperatorCallExpr(Context, OO_Subscript,
-                                            FnExpr.get(), Args,
-                                            ResultTy, VK, RLoc,
-                                            FPOptions());
+            CXXOperatorCallExpr::Create(Context, OO_Subscript, FnExpr.get(),
+                                        Args, ResultTy, VK, RLoc, FPOptions());
 
         if (CheckCallReturnType(FnDecl->getReturnType(), LLoc, TheCall, FnDecl))
           return ExprError();
@@ -12857,10 +12855,9 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
         << (qualsString.find(' ') == std::string::npos ? 1 : 2);
     }
 
-    CXXMemberCallExpr *call
-      = new (Context) CXXMemberCallExpr(Context, MemExprE, Args,
-                                        resultType, valueKind, RParenLoc,
-                                        proto->getNumParams());
+    CXXMemberCallExpr *call =
+        CXXMemberCallExpr::Create(Context, MemExprE, Args, resultType,
+                                  valueKind, RParenLoc, proto->getNumParams());
 
     if (CheckCallReturnType(proto->getReturnType(), op->getRHS()->getBeginLoc(),
                             call, nullptr))
@@ -12876,8 +12873,8 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
   }
 
   if (isa(NakedMemExpr))
-    return new (Context)
-        CallExpr(Context, MemExprE, Args, Context.VoidTy, VK_RValue, RParenLoc);
+    return CallExpr::Create(Context, MemExprE, Args, Context.VoidTy, VK_RValue,
+                            RParenLoc);
 
   UnbridgedCastsSet UnbridgedCasts;
   if (checkArgPlaceholdersForOverload(*this, Args, UnbridgedCasts))
@@ -13012,9 +13009,8 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
   assert(Method && "Member call to something that isn't a method?");
   const auto *Proto = Method->getType()->getAs();
   CXXMemberCallExpr *TheCall =
-    new (Context) CXXMemberCallExpr(Context, MemExprE, Args,
-                                    ResultType, VK, RParenLoc,
-                                    Proto->getNumParams());
+      CXXMemberCallExpr::Create(Context, MemExprE, Args, ResultType, VK,
+                                RParenLoc, Proto->getNumParams());
 
   // Check for a valid return type.
   if (CheckCallReturnType(Method->getReturnType(), MemExpr->getMemberLoc(),
@@ -13353,9 +13349,9 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj,
   ExprValueKind VK = Expr::getValueKindForType(ResultTy);
   ResultTy = ResultTy.getNonLValueExprType(Context);
 
-  CXXOperatorCallExpr *TheCall = new (Context)
-      CXXOperatorCallExpr(Context, OO_Call, NewFn.get(), MethodArgs, ResultTy,
-                          VK, RParenLoc, FPOptions());
+  CXXOperatorCallExpr *TheCall =
+      CXXOperatorCallExpr::Create(Context, OO_Call, NewFn.get(), MethodArgs,
+                                  ResultTy, VK, RParenLoc, FPOptions());
 
   if (CheckCallReturnType(Method->getReturnType(), LParenLoc, TheCall, Method))
     return true;
@@ -13471,9 +13467,8 @@ Sema::BuildOverloadedArrowExpr(Scope *S, Expr *Base, SourceLocation OpLoc,
   QualType ResultTy = Method->getReturnType();
   ExprValueKind VK = Expr::getValueKindForType(ResultTy);
   ResultTy = ResultTy.getNonLValueExprType(Context);
-  CXXOperatorCallExpr *TheCall =
-    new (Context) CXXOperatorCallExpr(Context, OO_Arrow, FnExpr.get(),
-                                      Base, ResultTy, VK, OpLoc, FPOptions());
+  CXXOperatorCallExpr *TheCall = CXXOperatorCallExpr::Create(
+      Context, OO_Arrow, FnExpr.get(), Base, ResultTy, VK, OpLoc, FPOptions());
 
   if (CheckCallReturnType(Method->getReturnType(), OpLoc, TheCall, Method))
     return ExprError();
@@ -13545,10 +13540,9 @@ ExprResult Sema::BuildLiteralOperatorCall(LookupResult &R,
   ExprValueKind VK = Expr::getValueKindForType(ResultTy);
   ResultTy = ResultTy.getNonLValueExprType(Context);
 
-  UserDefinedLiteral *UDL =
-    new (Context) UserDefinedLiteral(Context, Fn.get(),
-                                     llvm::makeArrayRef(ConvArgs, Args.size()),
-                                     ResultTy, VK, LitEndLoc, UDSuffixLoc);
+  UserDefinedLiteral *UDL = UserDefinedLiteral::Create(
+      Context, Fn.get(), llvm::makeArrayRef(ConvArgs, Args.size()), ResultTy,
+      VK, LitEndLoc, UDSuffixLoc);
 
   if (CheckCallReturnType(FD->getReturnType(), UDSuffixLoc, UDL, FD))
     return ExprError();
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index cffc22e1b4..9de4e8d654 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -3138,7 +3138,7 @@ public:
                                        CK_BuiltinFnToFnPtr).get();
 
     // Build the CallExpr
-    ExprResult TheCall = new (SemaRef.Context) CallExpr(
+    ExprResult TheCall = CallExpr::Create(
         SemaRef.Context, Callee, SubExprs, Builtin->getCallResultType(),
         Expr::getValueKindForType(Builtin->getReturnType()), RParenLoc);
 
diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp
index 88e7bb6471..1b7389e71c 100644
--- a/lib/Serialization/ASTReaderStmt.cpp
+++ b/lib/Serialization/ASTReaderStmt.cpp
@@ -2481,9 +2481,8 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
       break;
 
     case EXPR_CALL:
-      S = new (Context) CallExpr(
-          Context, /* NumArgs=*/Record[ASTStmtReader::NumExprFields],
-          Empty);
+      S = CallExpr::CreateEmpty(
+          Context, /*NumArgs=*/Record[ASTStmtReader::NumExprFields], Empty);
       break;
 
     case EXPR_MEMBER: {
@@ -3073,15 +3072,13 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
     }
 
     case EXPR_CXX_OPERATOR_CALL:
-      S = new (Context) CXXOperatorCallExpr(
-          Context, /*NumArgs=*/Record[ASTStmtReader::NumExprFields],
-          Empty);
+      S = CXXOperatorCallExpr::CreateEmpty(
+          Context, /*NumArgs=*/Record[ASTStmtReader::NumExprFields], Empty);
       break;
 
     case EXPR_CXX_MEMBER_CALL:
-      S = new (Context) CXXMemberCallExpr(
-          Context, /*NumArgs=*/Record[ASTStmtReader::NumExprFields],
-          Empty);
+      S = CXXMemberCallExpr::CreateEmpty(
+          Context, /*NumArgs=*/Record[ASTStmtReader::NumExprFields], Empty);
       break;
 
     case EXPR_CXX_CONSTRUCT:
@@ -3121,7 +3118,7 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
       break;
 
     case EXPR_USER_DEFINED_LITERAL:
-      S = new (Context) UserDefinedLiteral(
+      S = UserDefinedLiteral::CreateEmpty(
           Context, /*NumArgs=*/Record[ASTStmtReader::NumExprFields], Empty);
       break;
 
@@ -3292,7 +3289,7 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
       break;
 
     case EXPR_CUDA_KERNEL_CALL:
-      S = new (Context) CUDAKernelCallExpr(
+      S = CUDAKernelCallExpr::CreateEmpty(
           Context, /*NumArgs=*/Record[ASTStmtReader::NumExprFields], Empty);
       break;
 
-- 
cgit v1.2.3


From 440b5e7cd6258f17cc2ab386e885ad3ec42c9807 Mon Sep 17 00:00:00 2001
From: Bruno Ricci 
Date: Fri, 21 Dec 2018 16:51:57 +0000
Subject: [AST][NFC] Pack CXXOperatorCallExpr

Use the space available in the bit-fields of Stmt.
This saves 8 bytes per CXXOperatorCallExpr. NFC.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349924 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/AST/ExprCXX.h         | 38 ++++++++++++++++++-------------------
 include/clang/AST/Stmt.h            | 15 +++++++++++++++
 lib/AST/ExprCXX.cpp                 |  9 +++++++--
 lib/Serialization/ASTReaderStmt.cpp |  4 ++--
 lib/Serialization/ASTWriterStmt.cpp |  2 +-
 5 files changed, 44 insertions(+), 24 deletions(-)

diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index 21692c82b4..ea24ef8de4 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -79,14 +79,8 @@ class CXXOperatorCallExpr final : public CallExpr {
   friend class ASTStmtReader;
   friend class ASTStmtWriter;
 
-  /// The overloaded operator.
-  OverloadedOperatorKind Operator;
-
   SourceRange Range;
 
-  // Only meaningful for floating point types.
-  FPOptions FPFeatures;
-
   // CXXOperatorCallExpr has some trailing objects belonging
   // to CallExpr. See CallExpr for the details.
 
@@ -110,15 +104,17 @@ public:
                                           unsigned NumArgs, EmptyShell Empty);
 
   /// Returns the kind of overloaded operator that this expression refers to.
-  OverloadedOperatorKind getOperator() const { return Operator; }
+  OverloadedOperatorKind getOperator() const {
+    return static_cast(
+        CXXOperatorCallExprBits.OperatorKind);
+  }
 
   static bool isAssignmentOp(OverloadedOperatorKind Opc) {
-    return Opc == OO_Equal || Opc == OO_StarEqual ||
-           Opc == OO_SlashEqual || Opc == OO_PercentEqual ||
-           Opc == OO_PlusEqual || Opc == OO_MinusEqual ||
-           Opc == OO_LessLessEqual || Opc == OO_GreaterGreaterEqual ||
-           Opc == OO_AmpEqual || Opc == OO_CaretEqual ||
-           Opc == OO_PipeEqual;
+    return Opc == OO_Equal || Opc == OO_StarEqual || Opc == OO_SlashEqual ||
+           Opc == OO_PercentEqual || Opc == OO_PlusEqual ||
+           Opc == OO_MinusEqual || Opc == OO_LessLessEqual ||
+           Opc == OO_GreaterGreaterEqual || Opc == OO_AmpEqual ||
+           Opc == OO_CaretEqual || Opc == OO_PipeEqual;
   }
   bool isAssignmentOp() const { return isAssignmentOp(getOperator()); }
 
@@ -133,14 +129,15 @@ public:
   SourceLocation getOperatorLoc() const { return getRParenLoc(); }
 
   SourceLocation getExprLoc() const LLVM_READONLY {
+    OverloadedOperatorKind Operator = getOperator();
     return (Operator < OO_Plus || Operator >= OO_Arrow ||
             Operator == OO_PlusPlus || Operator == OO_MinusMinus)
                ? getBeginLoc()
                : getOperatorLoc();
   }
 
-  SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); }
-  SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); }
+  SourceLocation getBeginLoc() const { return Range.getBegin(); }
+  SourceLocation getEndLoc() const { return Range.getEnd(); }
   SourceRange getSourceRange() const { return Range; }
 
   static bool classof(const Stmt *T) {
@@ -149,14 +146,17 @@ public:
 
   // Set the FP contractability status of this operator. Only meaningful for
   // operations on floating point types.
-  void setFPFeatures(FPOptions F) { FPFeatures = F; }
-
-  FPOptions getFPFeatures() const { return FPFeatures; }
+  void setFPFeatures(FPOptions F) {
+    CXXOperatorCallExprBits.FPFeatures = F.getInt();
+  }
+  FPOptions getFPFeatures() const {
+    return FPOptions(CXXOperatorCallExprBits.FPFeatures);
+  }
 
   // Get the FP contractability status of this operator. Only meaningful for
   // operations on floating point types.
   bool isFPContractableWithinStatement() const {
-    return FPFeatures.allowFPContractWithinStatement();
+    return getFPFeatures().allowFPContractWithinStatement();
   }
 };
 
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index 66872464e0..ff9be8dbb7 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -532,6 +532,20 @@ protected:
 
   //===--- C++ Expression bitfields classes ---===//
 
+  class CXXOperatorCallExprBitfields {
+    friend class ASTStmtReader;
+    friend class CXXOperatorCallExpr;
+
+    unsigned : NumCallExprBits;
+
+    /// The kind of this overloaded operator. One of the enumerator
+    /// value of OverloadedOperatorKind.
+    unsigned OperatorKind : 6;
+
+    // Only meaningful for floating point types.
+    unsigned FPFeatures : 3;
+  };
+
   class CXXBoolLiteralExprBitfields {
     friend class CXXBoolLiteralExpr;
 
@@ -723,6 +737,7 @@ protected:
     PseudoObjectExprBitfields PseudoObjectExprBits;
 
     // C++ Expressions
+    CXXOperatorCallExprBitfields CXXOperatorCallExprBits;
     CXXBoolLiteralExprBitfields CXXBoolLiteralExprBits;
     CXXNullPtrLiteralExprBitfields CXXNullPtrLiteralExprBits;
     CXXThisExprBitfields CXXThisExprBits;
diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp
index 3ddfbf1d19..a9fdb6377e 100644
--- a/lib/AST/ExprCXX.cpp
+++ b/lib/AST/ExprCXX.cpp
@@ -485,8 +485,13 @@ CXXOperatorCallExpr::CXXOperatorCallExpr(OverloadedOperatorKind OpKind,
                                          FPOptions FPFeatures,
                                          ADLCallKind UsesADL)
     : CallExpr(CXXOperatorCallExprClass, Fn, /*PreArgs=*/{}, Args, Ty, VK,
-               OperatorLoc, /*MinNumArgs=*/0, UsesADL),
-      Operator(OpKind), FPFeatures(FPFeatures) {
+               OperatorLoc, /*MinNumArgs=*/0, UsesADL) {
+  CXXOperatorCallExprBits.OperatorKind = OpKind;
+  CXXOperatorCallExprBits.FPFeatures = FPFeatures.getInt();
+  assert((CXXOperatorCallExprBits.OperatorKind == OpKind) &&
+         "OperatorKind overflow!");
+  assert((CXXOperatorCallExprBits.FPFeatures == FPFeatures.getInt()) &&
+         "FPFeatures overflow!");
   Range = getSourceRangeImpl();
 }
 
diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp
index 1b7389e71c..3b5ff78698 100644
--- a/lib/Serialization/ASTReaderStmt.cpp
+++ b/lib/Serialization/ASTReaderStmt.cpp
@@ -1346,9 +1346,9 @@ void ASTStmtReader::VisitMSDependentExistsStmt(MSDependentExistsStmt *S) {
 
 void ASTStmtReader::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
   VisitCallExpr(E);
-  E->Operator = (OverloadedOperatorKind)Record.readInt();
+  E->CXXOperatorCallExprBits.OperatorKind = Record.readInt();
+  E->CXXOperatorCallExprBits.FPFeatures = Record.readInt();
   E->Range = Record.readSourceRange();
-  E->setFPFeatures(FPOptions(Record.readInt()));
 }
 
 void ASTStmtReader::VisitCXXConstructExpr(CXXConstructExpr *E) {
diff --git a/lib/Serialization/ASTWriterStmt.cpp b/lib/Serialization/ASTWriterStmt.cpp
index 3a14c39fa1..c7527aa38b 100644
--- a/lib/Serialization/ASTWriterStmt.cpp
+++ b/lib/Serialization/ASTWriterStmt.cpp
@@ -1303,8 +1303,8 @@ void ASTStmtWriter::VisitMSDependentExistsStmt(MSDependentExistsStmt *S) {
 void ASTStmtWriter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
   VisitCallExpr(E);
   Record.push_back(E->getOperator());
-  Record.AddSourceRange(E->Range);
   Record.push_back(E->getFPFeatures().getInt());
+  Record.AddSourceRange(E->Range);
   Code = serialization::EXPR_CXX_OPERATOR_CALL;
 }
 
-- 
cgit v1.2.3


From 600227629f8cfa321d37f42d56d2c67e42bf1ea4 Mon Sep 17 00:00:00 2001
From: Bruno Ricci 
Date: Fri, 21 Dec 2018 17:52:13 +0000
Subject: [Sema][NFC] Fix Wimplicit-fallthrough warning in getCursorKindForDecl

All cases are covered so add an llvm_unreachable. NFC.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349933 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/Sema/SemaCodeComplete.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp
index f8d4e4bb0e..d9f007a46d 100644
--- a/lib/Sema/SemaCodeComplete.cpp
+++ b/lib/Sema/SemaCodeComplete.cpp
@@ -3447,6 +3447,7 @@ CXCursorKind clang::getCursorKindForDecl(const Decl *D) {
     case ObjCPropertyImplDecl::Synthesize:
       return CXCursor_ObjCSynthesizeDecl;
     }
+    llvm_unreachable("Unexpected Kind!");
 
   case Decl::Import:
     return CXCursor_ModuleImportDecl;
-- 
cgit v1.2.3


From 4dfa0aabd804638c6e01df789f8f10273f6b330c Mon Sep 17 00:00:00 2001
From: Bruno Ricci 
Date: Fri, 21 Dec 2018 17:54:51 +0000
Subject: [AST][NFC] Fix Wsign-compare warning introduced in
 CXXOperatorCallExpr

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349934 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/AST/ExprCXX.cpp | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp
index a9fdb6377e..03bffbedcf 100644
--- a/lib/AST/ExprCXX.cpp
+++ b/lib/AST/ExprCXX.cpp
@@ -488,8 +488,9 @@ CXXOperatorCallExpr::CXXOperatorCallExpr(OverloadedOperatorKind OpKind,
                OperatorLoc, /*MinNumArgs=*/0, UsesADL) {
   CXXOperatorCallExprBits.OperatorKind = OpKind;
   CXXOperatorCallExprBits.FPFeatures = FPFeatures.getInt();
-  assert((CXXOperatorCallExprBits.OperatorKind == OpKind) &&
-         "OperatorKind overflow!");
+  assert(
+      (CXXOperatorCallExprBits.OperatorKind == static_cast(OpKind)) &&
+      "OperatorKind overflow!");
   assert((CXXOperatorCallExprBits.FPFeatures == FPFeatures.getInt()) &&
          "FPFeatures overflow!");
   Range = getSourceRangeImpl();
-- 
cgit v1.2.3


From af36987d2a76530d428adf7c191ae1c8d8080a5a Mon Sep 17 00:00:00 2001
From: George Karpenkov 
Date: Fri, 21 Dec 2018 19:13:28 +0000
Subject: [analyzer] Correct the summary violation diagnostics for the retain
 count checker

It should be in the past tense.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349938 91177308-0d34-0410-b5e6-96231b3b80d8
---
 .../Checkers/RetainCountChecker/RetainCountDiagnostics.cpp            | 2 +-
 test/Analysis/osobject-retain-release.cpp                             | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
index 8fdd105f18..74dd1e149e 100644
--- a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
+++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
@@ -285,7 +285,7 @@ annotateConsumedSummaryMismatch(const ExplodedNode *N,
         os << "Parameter '";
         PVD->getNameForDiagnostic(os, PVD->getASTContext().getPrintingPolicy(),
                                   /*Qualified=*/false);
-        os << "' is marked as consuming, but the function does not consume "
+        os << "' is marked as consuming, but the function did not consume "
            << "the reference\n";
       }
     }
diff --git a/test/Analysis/osobject-retain-release.cpp b/test/Analysis/osobject-retain-release.cpp
index 2efd20709b..4c23cdc6e0 100644
--- a/test/Analysis/osobject-retain-release.cpp
+++ b/test/Analysis/osobject-retain-release.cpp
@@ -99,7 +99,7 @@ bool os_consume_violation_two_args(OS_CONSUME OSObject *obj, bool extra) {
     escape(obj);
     return true;
   }
-  return false; // expected-note{{Parameter 'obj' is marked as consuming, but the function does not consume the reference}}
+  return false; // expected-note{{Parameter 'obj' is marked as consuming, but the function did not consume the reference}}
 }
 
 bool os_consume_violation(OS_CONSUME OSObject *obj) {
@@ -108,7 +108,7 @@ bool os_consume_violation(OS_CONSUME OSObject *obj) {
     escape(obj);
     return true;
   }
-  return false; // expected-note{{Parameter 'obj' is marked as consuming, but the function does not consume the reference}}
+  return false; // expected-note{{Parameter 'obj' is marked as consuming, but the function did not consume the reference}}
 }
 
 void os_consume_ok(OS_CONSUME OSObject *obj) {
-- 
cgit v1.2.3


From 07a54a8080be7ade8ca0613da0d95f980bd6c3f7 Mon Sep 17 00:00:00 2001
From: George Karpenkov 
Date: Fri, 21 Dec 2018 19:13:40 +0000
Subject: Revert "Revert rL349876 from cfe/trunk: [analyzer] Perform escaping
 in RetainCountChecker on type mismatch even for inlined functions"

This reverts commit b44b33f6e020a2c369da2b0c1d53cd52975f2526.

Revert the revert with the fix.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349939 91177308-0d34-0410-b5e6-96231b3b80d8
---
 .../RetainCountChecker/RetainCountChecker.cpp      | 51 ++++++++++++----------
 test/Analysis/osobject-retain-release.cpp          |  8 ++++
 2 files changed, 36 insertions(+), 23 deletions(-)

diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
index 488cf6d3eb..87c1ad9edb 100644
--- a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
@@ -502,6 +502,25 @@ static Optional refValFromRetEffect(RetEffect RE,
   return None;
 }
 
+static bool isPointerToObject(QualType QT) {
+  QualType PT = QT->getPointeeType();
+  if (!PT.isNull())
+    if (PT->getAsCXXRecordDecl())
+      return true;
+  return false;
+}
+
+/// Whether the tracked value should be escaped on a given call.
+/// OSObjects are escaped when passed to void * / etc.
+static bool shouldEscapeArgumentOnCall(const CallEvent &CE, unsigned ArgIdx,
+                                       const RefVal *TrackedValue) {
+  if (TrackedValue->getObjKind() != RetEffect::OS)
+    return false;
+  if (ArgIdx >= CE.parameters().size())
+    return false;
+  return !isPointerToObject(CE.parameters()[ArgIdx]->getType());
+}
+
 // We don't always get the exact modeling of the function with regards to the
 // retain count checker even when the function is inlined. For example, we need
 // to stop tracking the symbols which were marked with StopTrackingHard.
@@ -512,11 +531,16 @@ void RetainCountChecker::processSummaryOfInlined(const RetainSummary &Summ,
 
   // Evaluate the effect of the arguments.
   for (unsigned idx = 0, e = CallOrMsg.getNumArgs(); idx != e; ++idx) {
-    if (Summ.getArg(idx) == StopTrackingHard) {
-      SVal V = CallOrMsg.getArgSVal(idx);
-      if (SymbolRef Sym = V.getAsLocSymbol()) {
+    SVal V = CallOrMsg.getArgSVal(idx);
+
+    if (SymbolRef Sym = V.getAsLocSymbol()) {
+      bool ShouldRemoveBinding = Summ.getArg(idx) == StopTrackingHard;
+      if (const RefVal *T = getRefBinding(state, Sym))
+        if (shouldEscapeArgumentOnCall(CallOrMsg, idx, T))
+          ShouldRemoveBinding = true;
+
+      if (ShouldRemoveBinding)
         state = removeRefBinding(state, Sym);
-      }
     }
   }
 
@@ -574,25 +598,6 @@ static ProgramStateRef updateOutParameter(ProgramStateRef State,
   return State;
 }
 
-static bool isPointerToObject(QualType QT) {
-  QualType PT = QT->getPointeeType();
-  if (!PT.isNull())
-    if (PT->getAsCXXRecordDecl())
-      return true;
-  return false;
-}
-
-/// Whether the tracked value should be escaped on a given call.
-/// OSObjects are escaped when passed to void * / etc.
-static bool shouldEscapeArgumentOnCall(const CallEvent &CE, unsigned ArgIdx,
-                                       const RefVal *TrackedValue) {
-  if (TrackedValue->getObjKind() != RetEffect::OS)
-    return false;
-  if (ArgIdx >= CE.parameters().size())
-    return false;
-  return !isPointerToObject(CE.parameters()[ArgIdx]->getType());
-}
-
 void RetainCountChecker::checkSummary(const RetainSummary &Summ,
                                       const CallEvent &CallOrMsg,
                                       CheckerContext &C) const {
diff --git a/test/Analysis/osobject-retain-release.cpp b/test/Analysis/osobject-retain-release.cpp
index 4c23cdc6e0..0e8e49dd83 100644
--- a/test/Analysis/osobject-retain-release.cpp
+++ b/test/Analysis/osobject-retain-release.cpp
@@ -91,6 +91,7 @@ struct OSMetaClassBase {
 };
 
 void escape(void *);
+void escape_with_source(void *p) {}
 bool coin();
 
 bool os_consume_violation_two_args(OS_CONSUME OSObject *obj, bool extra) {
@@ -139,6 +140,13 @@ void test_escaping_into_voidstar() {
   escape(obj);
 }
 
+void test_escape_has_source() {
+  OSObject *obj = new OSObject;
+  if (obj)
+    escape_with_source((MYTYPE)obj);
+  return;
+}
+
 void test_no_infinite_check_recursion(MyArray *arr) {
   OSObject *input = new OSObject;
   OSObject *o = arr->generateObject(input);
-- 
cgit v1.2.3


From 4b4e8fad244aca3a7c049ee438ae8120490216a5 Mon Sep 17 00:00:00 2001
From: Aaron Ballman 
Date: Fri, 21 Dec 2018 19:16:38 +0000
Subject: Switch from cast<> to dyn_cast<>.

This avoids a potential failed assertion that is happening on someone's out-of-tree build.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349940 91177308-0d34-0410-b5e6-96231b3b80d8
---
 utils/TableGen/ClangSACheckersEmitter.cpp | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/utils/TableGen/ClangSACheckersEmitter.cpp b/utils/TableGen/ClangSACheckersEmitter.cpp
index 4f20274334..453dfe564b 100644
--- a/utils/TableGen/ClangSACheckersEmitter.cpp
+++ b/utils/TableGen/ClangSACheckersEmitter.cpp
@@ -63,8 +63,11 @@ static inline uint64_t getValueFromBitsInit(const BitsInit *B) {
 
   uint64_t Value = 0;
   for (unsigned i = 0, e = B->getNumBits(); i != e; ++i) {
-    const auto *Bit = cast(B->getBit(i));
-    Value |= uint64_t(Bit->getValue()) << i;
+    const auto *Bit = dyn_cast(B->getBit(i));
+    if (Bit)
+      Value |= uint64_t(Bit->getValue()) << i;
+    else
+      PrintFatalError("Invalid bits");
   }
   return Value;
 }
-- 
cgit v1.2.3


From 5d78f362c90e69336722e8997adb28be3664835b Mon Sep 17 00:00:00 2001
From: Alex Lorenz 
Date: Fri, 21 Dec 2018 19:33:09 +0000
Subject: Remove stat cache chaining as it's no longer needed after PTH support
 has been removed

Stat cache chaining was implemented for a StatListener in the PTH writer so that
it could write out the stat information to PTH. r348266 removed support for PTH,
and it doesn't seem like there are other uses of stat cache chaining. We can
remove the chaining support.

Differential Revision: https://reviews.llvm.org/D55455


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349942 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/Basic/FileManager.h         | 14 +++---------
 include/clang/Basic/FileSystemStatCache.h | 30 ------------------------
 lib/Basic/FileManager.cpp                 | 38 +++----------------------------
 lib/Basic/FileSystemStatCache.cpp         | 17 +++++++-------
 lib/Tooling/Tooling.cpp                   |  2 +-
 unittests/Basic/FileManagerTest.cpp       | 29 ++++++++---------------
 6 files changed, 25 insertions(+), 105 deletions(-)

diff --git a/include/clang/Basic/FileManager.h b/include/clang/Basic/FileManager.h
index 8e021f41c1..e7891baf53 100644
--- a/include/clang/Basic/FileManager.h
+++ b/include/clang/Basic/FileManager.h
@@ -192,18 +192,10 @@ public:
   ///
   /// \param statCache the new stat cache to install. Ownership of this
   /// object is transferred to the FileManager.
-  ///
-  /// \param AtBeginning whether this new stat cache must be installed at the
-  /// beginning of the chain of stat caches. Otherwise, it will be added to
-  /// the end of the chain.
-  void addStatCache(std::unique_ptr statCache,
-                    bool AtBeginning = false);
-
-  /// Removes the specified FileSystemStatCache object from the manager.
-  void removeStatCache(FileSystemStatCache *statCache);
+  void setStatCache(std::unique_ptr statCache);
 
-  /// Removes all FileSystemStatCache objects from the manager.
-  void clearStatCaches();
+  /// Removes the FileSystemStatCache object from the manager.
+  void clearStatCache();
 
   /// Lookup, cache, and verify the specified directory (real or
   /// virtual).
diff --git a/include/clang/Basic/FileSystemStatCache.h b/include/clang/Basic/FileSystemStatCache.h
index a0277009d7..f93170c754 100644
--- a/include/clang/Basic/FileSystemStatCache.h
+++ b/include/clang/Basic/FileSystemStatCache.h
@@ -60,9 +60,6 @@ struct FileData {
 class FileSystemStatCache {
   virtual void anchor();
 
-protected:
-  std::unique_ptr NextStatCache;
-
 public:
   virtual ~FileSystemStatCache() = default;
 
@@ -88,22 +85,6 @@ public:
                   std::unique_ptr *F,
                   FileSystemStatCache *Cache, llvm::vfs::FileSystem &FS);
 
-  /// Sets the next stat call cache in the chain of stat caches.
-  /// Takes ownership of the given stat cache.
-  void setNextStatCache(std::unique_ptr Cache) {
-    NextStatCache = std::move(Cache);
-  }
-
-  /// Retrieve the next stat call cache in the chain.
-  FileSystemStatCache *getNextStatCache() { return NextStatCache.get(); }
-
-  /// Retrieve the next stat call cache in the chain, transferring
-  /// ownership of this cache (and, transitively, all of the remaining caches)
-  /// to the caller.
-  std::unique_ptr takeNextStatCache() {
-    return std::move(NextStatCache);
-  }
-
 protected:
   // FIXME: The pointer here is a non-owning/optional reference to the
   // unique_ptr. Optional&> might be nicer, but
@@ -111,17 +92,6 @@ protected:
   virtual LookupResult getStat(StringRef Path, FileData &Data, bool isFile,
                                std::unique_ptr *F,
                                llvm::vfs::FileSystem &FS) = 0;
-
-  LookupResult statChained(StringRef Path, FileData &Data, bool isFile,
-                           std::unique_ptr *F,
-                           llvm::vfs::FileSystem &FS) {
-    if (FileSystemStatCache *Next = getNextStatCache())
-      return Next->getStat(Path, Data, isFile, F, FS);
-
-    // If we hit the end of the list of stat caches to try, just compute and
-    // return it without a cache.
-    return get(Path, Data, isFile, F, nullptr, FS) ? CacheMissing : CacheExists;
-  }
 };
 
 /// A stat "cache" that can be used by FileManager to keep
diff --git a/lib/Basic/FileManager.cpp b/lib/Basic/FileManager.cpp
index 455d25c100..f5a2d4894c 100644
--- a/lib/Basic/FileManager.cpp
+++ b/lib/Basic/FileManager.cpp
@@ -63,44 +63,12 @@ FileManager::FileManager(const FileSystemOptions &FSO,
 
 FileManager::~FileManager() = default;
 
-void FileManager::addStatCache(std::unique_ptr statCache,
-                               bool AtBeginning) {
+void FileManager::setStatCache(std::unique_ptr statCache) {
   assert(statCache && "No stat cache provided?");
-  if (AtBeginning || !StatCache.get()) {
-    statCache->setNextStatCache(std::move(StatCache));
-    StatCache = std::move(statCache);
-    return;
-  }
-
-  FileSystemStatCache *LastCache = StatCache.get();
-  while (LastCache->getNextStatCache())
-    LastCache = LastCache->getNextStatCache();
-
-  LastCache->setNextStatCache(std::move(statCache));
+  StatCache = std::move(statCache);
 }
 
-void FileManager::removeStatCache(FileSystemStatCache *statCache) {
-  if (!statCache)
-    return;
-
-  if (StatCache.get() == statCache) {
-    // This is the first stat cache.
-    StatCache = StatCache->takeNextStatCache();
-    return;
-  }
-
-  // Find the stat cache in the list.
-  FileSystemStatCache *PrevCache = StatCache.get();
-  while (PrevCache && PrevCache->getNextStatCache() != statCache)
-    PrevCache = PrevCache->getNextStatCache();
-
-  assert(PrevCache && "Stat cache not found for removal");
-  PrevCache->setNextStatCache(statCache->takeNextStatCache());
-}
-
-void FileManager::clearStatCaches() {
-  StatCache.reset();
-}
+void FileManager::clearStatCache() { StatCache.reset(); }
 
 /// Retrieve the directory that the given file name resides in.
 /// Filename can point to either a real file or a virtual file.
diff --git a/lib/Basic/FileSystemStatCache.cpp b/lib/Basic/FileSystemStatCache.cpp
index 9a515e89e2..6f2eef4e20 100644
--- a/lib/Basic/FileSystemStatCache.cpp
+++ b/lib/Basic/FileSystemStatCache.cpp
@@ -114,18 +114,17 @@ MemorizeStatCalls::LookupResult
 MemorizeStatCalls::getStat(StringRef Path, FileData &Data, bool isFile,
                            std::unique_ptr *F,
                            llvm::vfs::FileSystem &FS) {
-  LookupResult Result = statChained(Path, Data, isFile, F, FS);
-
-  // Do not cache failed stats, it is easy to construct common inconsistent
-  // situations if we do, and they are not important for PCH performance (which
-  // currently only needs the stats to construct the initial FileManager
-  // entries).
-  if (Result == CacheMissing)
-    return Result;
+  if (get(Path, Data, isFile, F, nullptr, FS)) {
+    // Do not cache failed stats, it is easy to construct common inconsistent
+    // situations if we do, and they are not important for PCH performance
+    // (which currently only needs the stats to construct the initial
+    // FileManager entries).
+    return CacheMissing;
+  }
 
   // Cache file 'stat' results and directories with absolutely paths.
   if (!Data.IsDirectory || llvm::sys::path::is_absolute(Path))
     StatCalls[Path] = Data;
 
-  return Result;
+  return CacheExists;
 }
diff --git a/lib/Tooling/Tooling.cpp b/lib/Tooling/Tooling.cpp
index cfdb32f0ae..84a4ac648c 100644
--- a/lib/Tooling/Tooling.cpp
+++ b/lib/Tooling/Tooling.cpp
@@ -369,7 +369,7 @@ bool FrontendActionFactory::runInvocation(
 
   const bool Success = Compiler.ExecuteAction(*ScopedToolAction);
 
-  Files->clearStatCaches();
+  Files->clearStatCache();
   return Success;
 }
 
diff --git a/unittests/Basic/FileManagerTest.cpp b/unittests/Basic/FileManagerTest.cpp
index c0efaf4fc4..746d9ad5e8 100644
--- a/unittests/Basic/FileManagerTest.cpp
+++ b/unittests/Basic/FileManagerTest.cpp
@@ -111,7 +111,7 @@ TEST_F(FileManagerTest, NoVirtualDirectoryExistsBeforeAVirtualFileIsAdded) {
   // FileManager to report "file/directory doesn't exist".  This
   // avoids the possibility of the result of this test being affected
   // by what's in the real file system.
-  manager.addStatCache(llvm::make_unique());
+  manager.setStatCache(llvm::make_unique());
 
   EXPECT_EQ(nullptr, manager.getDirectory("virtual/dir/foo"));
   EXPECT_EQ(nullptr, manager.getDirectory("virtual/dir"));
@@ -121,7 +121,7 @@ TEST_F(FileManagerTest, NoVirtualDirectoryExistsBeforeAVirtualFileIsAdded) {
 // When a virtual file is added, all of its ancestors should be created.
 TEST_F(FileManagerTest, getVirtualFileCreatesDirectoryEntriesForAncestors) {
   // Fake an empty real file system.
-  manager.addStatCache(llvm::make_unique());
+  manager.setStatCache(llvm::make_unique());
 
   manager.getVirtualFile("virtual/dir/bar.h", 100, 0);
   EXPECT_EQ(nullptr, manager.getDirectory("virtual/dir/foo"));
@@ -149,7 +149,7 @@ TEST_F(FileManagerTest, getFileReturnsValidFileEntryForExistingRealFile) {
   statCache->InjectFile(FileName, 45);
 #endif
 
-  manager.addStatCache(std::move(statCache));
+  manager.setStatCache(std::move(statCache));
 
   const FileEntry *file = manager.getFile("/tmp/test");
   ASSERT_TRUE(file != nullptr);
@@ -173,7 +173,7 @@ TEST_F(FileManagerTest, getFileReturnsValidFileEntryForExistingRealFile) {
 // getFile() returns non-NULL if a virtual file exists at the given path.
 TEST_F(FileManagerTest, getFileReturnsValidFileEntryForExistingVirtualFile) {
   // Fake an empty real file system.
-  manager.addStatCache(llvm::make_unique());
+  manager.setStatCache(llvm::make_unique());
 
   manager.getVirtualFile("virtual/dir/bar.h", 100, 0);
   const FileEntry *file = manager.getFile("virtual/dir/bar.h");
@@ -195,7 +195,7 @@ TEST_F(FileManagerTest, getFileReturnsDifferentFileEntriesForDifferentFiles) {
   statCache->InjectDirectory(".", 41);
   statCache->InjectFile("foo.cpp", 42);
   statCache->InjectFile("bar.cpp", 43);
-  manager.addStatCache(std::move(statCache));
+  manager.setStatCache(std::move(statCache));
 
   const FileEntry *fileFoo = manager.getFile("foo.cpp");
   const FileEntry *fileBar = manager.getFile("bar.cpp");
@@ -213,7 +213,7 @@ TEST_F(FileManagerTest, getFileReturnsNULLForNonexistentFile) {
   auto statCache = llvm::make_unique();
   statCache->InjectDirectory(".", 41);
   statCache->InjectFile("foo.cpp", 42);
-  manager.addStatCache(std::move(statCache));
+  manager.setStatCache(std::move(statCache));
 
   // Create a virtual bar.cpp file.
   manager.getVirtualFile("bar.cpp", 200, 0);
@@ -260,7 +260,7 @@ TEST_F(FileManagerTest, getFileReturnsSameFileEntryForAliasedRealFiles) {
   statCache->InjectDirectory("abc", 41);
   statCache->InjectFile("abc/foo.cpp", 42);
   statCache->InjectFile("abc/bar.cpp", 42);
-  manager.addStatCache(std::move(statCache));
+  manager.setStatCache(std::move(statCache));
 
   EXPECT_EQ(manager.getFile("abc/foo.cpp"), manager.getFile("abc/bar.cpp"));
 }
@@ -273,7 +273,7 @@ TEST_F(FileManagerTest, getFileReturnsSameFileEntryForAliasedVirtualFiles) {
   statCache->InjectDirectory("abc", 41);
   statCache->InjectFile("abc/foo.cpp", 42);
   statCache->InjectFile("abc/bar.cpp", 42);
-  manager.addStatCache(std::move(statCache));
+  manager.setStatCache(std::move(statCache));
 
   ASSERT_TRUE(manager.getVirtualFile("abc/foo.cpp", 100, 0)->isValid());
   ASSERT_TRUE(manager.getVirtualFile("abc/bar.cpp", 200, 0)->isValid());
@@ -281,15 +281,6 @@ TEST_F(FileManagerTest, getFileReturnsSameFileEntryForAliasedVirtualFiles) {
   EXPECT_EQ(manager.getFile("abc/foo.cpp"), manager.getFile("abc/bar.cpp"));
 }
 
-TEST_F(FileManagerTest, addRemoveStatCache) {
-  manager.addStatCache(llvm::make_unique());
-  auto statCacheOwner = llvm::make_unique();
-  auto *statCache = statCacheOwner.get();
-  manager.addStatCache(std::move(statCacheOwner));
-  manager.addStatCache(llvm::make_unique());
-  manager.removeStatCache(statCache);
-}
-
 // getFile() Should return the same entry as getVirtualFile if the file actually
 // is a virtual file, even if the name is not exactly the same (but is after
 // normalisation done by the file system, like on Windows). This can be checked
@@ -300,7 +291,7 @@ TEST_F(FileManagerTest, getVirtualFileWithDifferentName) {
   statCache->InjectDirectory("c:\\tmp", 42);
   statCache->InjectFile("c:\\tmp\\test", 43);
 
-  manager.addStatCache(std::move(statCache));
+  manager.setStatCache(std::move(statCache));
 
   // Inject the virtual file:
   const FileEntry *file1 = manager.getVirtualFile("c:\\tmp\\test", 123, 1);
@@ -371,7 +362,7 @@ TEST_F(FileManagerTest, getVirtualFileFillsRealPathName) {
   statCache->InjectDirectory("/tmp", 42);
   statCache->InjectFile("/tmp/test", 43);
 
-  Manager.addStatCache(std::move(statCache));
+  Manager.setStatCache(std::move(statCache));
 
   // Check for real path.
   const FileEntry *file = Manager.getVirtualFile("/tmp/test", 123, 1);
-- 
cgit v1.2.3


From 519ff3868cf77841205bdab72fcd574504d9eff7 Mon Sep 17 00:00:00 2001
From: George Karpenkov 
Date: Fri, 21 Dec 2018 19:40:44 +0000
Subject: [analyzer] Tests quickfix.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349943 91177308-0d34-0410-b5e6-96231b3b80d8
---
 test/Analysis/osobject-retain-release.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/test/Analysis/osobject-retain-release.cpp b/test/Analysis/osobject-retain-release.cpp
index 0e8e49dd83..1fc5e31aa5 100644
--- a/test/Analysis/osobject-retain-release.cpp
+++ b/test/Analysis/osobject-retain-release.cpp
@@ -143,7 +143,7 @@ void test_escaping_into_voidstar() {
 void test_escape_has_source() {
   OSObject *obj = new OSObject;
   if (obj)
-    escape_with_source((MYTYPE)obj);
+    escape_with_source(obj);
   return;
 }
 
-- 
cgit v1.2.3


From 85b7fd6c9a2e3fb8eb9ace53f438a2a41f92c03b Mon Sep 17 00:00:00 2001
From: Bruno Ricci 
Date: Fri, 21 Dec 2018 20:23:07 +0000
Subject: [AST][NFC] Remove stale comment in
 CXXRecordDecl::is(Virtually)DerivedFrom.

The "this" capture was removed in r291939.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349948 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/AST/CXXInheritance.cpp | 2 --
 1 file changed, 2 deletions(-)

diff --git a/lib/AST/CXXInheritance.cpp b/lib/AST/CXXInheritance.cpp
index a0b22b6a85..ddb350e72b 100644
--- a/lib/AST/CXXInheritance.cpp
+++ b/lib/AST/CXXInheritance.cpp
@@ -103,7 +103,6 @@ bool CXXRecordDecl::isDerivedFrom(const CXXRecordDecl *Base,
   Paths.setOrigin(const_cast(this));
 
   const CXXRecordDecl *BaseDecl = Base->getCanonicalDecl();
-  // FIXME: Capturing 'this' is a workaround for name lookup bugs in GCC 4.7.
   return lookupInBases(
       [BaseDecl](const CXXBaseSpecifier *Specifier, CXXBasePath &Path) {
         return FindBaseClass(Specifier, Path, BaseDecl);
@@ -124,7 +123,6 @@ bool CXXRecordDecl::isVirtuallyDerivedFrom(const CXXRecordDecl *Base) const {
   Paths.setOrigin(const_cast(this));
 
   const CXXRecordDecl *BaseDecl = Base->getCanonicalDecl();
-  // FIXME: Capturing 'this' is a workaround for name lookup bugs in GCC 4.7.
   return lookupInBases(
       [BaseDecl](const CXXBaseSpecifier *Specifier, CXXBasePath &Path) {
         return FindVirtualBaseClass(Specifier, Path, BaseDecl);
-- 
cgit v1.2.3


From 0a9d6b3eca7b8695cf8162aa3c4e70a206a53786 Mon Sep 17 00:00:00 2001
From: Bruno Ricci 
Date: Fri, 21 Dec 2018 20:38:06 +0000
Subject: [Sema][NFC] Fix a Wimplicit-fallthrough warning in
 CheckSpecializationInstantiationRedecl

All cases are covered so add an llvm_unreachable. NFC.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349949 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/Sema/SemaTemplate.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index 2d2d08f23e..8485ecd3a3 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -7966,6 +7966,7 @@ Sema::CheckSpecializationInstantiationRedecl(SourceLocation NewLoc,
       HasNoEffect = true;
       return false;
     }
+    llvm_unreachable("Unexpected TemplateSpecializationKind!");
 
   case TSK_ExplicitInstantiationDefinition:
     switch (PrevTSK) {
-- 
cgit v1.2.3


From 4eb2cac7f8a6760bc77c844fadba159ac2f22fcc Mon Sep 17 00:00:00 2001
From: Pete Cooper 
Date: Fri, 21 Dec 2018 21:00:32 +0000
Subject: Convert some ObjC retain/release msgSends to runtime calls.

It is faster to directly call the ObjC runtime for methods such as retain/release instead of sending a message to those functions.

Differential Revision: https://reviews.llvm.org/D55869

Reviewed By: rjmccall

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349952 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/Basic/ObjCRuntime.h                  | 37 +++++++++++
 lib/CodeGen/CGObjC.cpp                             | 77 ++++++++++++++++++++++
 lib/CodeGen/CodeGenFunction.h                      |  5 ++
 lib/CodeGen/CodeGenModule.h                        | 12 ++++
 .../convert-messages-to-runtime-calls.m            | 69 +++++++++++++++++++
 5 files changed, 200 insertions(+)

diff --git a/include/clang/Basic/ObjCRuntime.h b/include/clang/Basic/ObjCRuntime.h
index f8b4826d3d..fcfbe56b49 100644
--- a/include/clang/Basic/ObjCRuntime.h
+++ b/include/clang/Basic/ObjCRuntime.h
@@ -173,6 +173,43 @@ public:
     llvm_unreachable("bad kind");
   }
 
+  /// Does this runtime provide ARC entrypoints that are likely to be faster
+  /// than an ordinary message send of the appropriate selector?
+  ///
+  /// The ARC entrypoints are guaranteed to be equivalent to just sending the
+  /// corresponding message.  If the entrypoint is implemented naively as just a
+  /// message send, using it is a trade-off: it sacrifices a few cycles of
+  /// overhead to save a small amount of code.  However, it's possible for
+  /// runtimes to detect and special-case classes that use "standard"
+  /// retain/release behavior; if that's dynamically a large proportion of all
+  /// retained objects, using the entrypoint will also be faster than using a
+  /// message send.
+  ///
+  /// When this method returns true, Clang will turn non-super message sends of
+  /// certain selectors into calls to the correspond entrypoint:
+  ///   retain => objc_retain
+  ///   release => objc_release
+  ///   autorelease => objc_autorelease
+  bool shouldUseARCFunctionsForRetainRelease() const {
+    switch (getKind()) {
+    case FragileMacOSX:
+      return false;
+    case MacOSX:
+      return getVersion() >= VersionTuple(10, 10);
+    case iOS:
+      return getVersion() >= VersionTuple(8);
+    case WatchOS:
+      return true;
+    case GCC:
+      return false;
+    case GNUstep:
+      return false;
+    case ObjFW:
+      return false;
+    }
+    llvm_unreachable("bad kind");
+  }
+
   /// Does this runtime provide entrypoints that are likely to be faster
   /// than an ordinary message send of the "alloc" selector?
   ///
diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp
index 4cc86ad094..8d24b15f76 100644
--- a/lib/CodeGen/CGObjC.cpp
+++ b/lib/CodeGen/CGObjC.cpp
@@ -396,6 +396,29 @@ tryGenerateSpecializedMessageSend(CodeGenFunction &CGF, QualType ResultType,
     }
     break;
 
+  case OMF_autorelease:
+    if (ResultType->isObjCObjectPointerType() &&
+        CGM.getLangOpts().getGC() == LangOptions::NonGC &&
+        Runtime.shouldUseARCFunctionsForRetainRelease())
+      return CGF.EmitObjCAutorelease(Receiver, CGF.ConvertType(ResultType));
+    break;
+
+  case OMF_retain:
+    if (ResultType->isObjCObjectPointerType() &&
+        CGM.getLangOpts().getGC() == LangOptions::NonGC &&
+        Runtime.shouldUseARCFunctionsForRetainRelease())
+      return CGF.EmitObjCRetainNonBlock(Receiver, CGF.ConvertType(ResultType));
+    break;
+
+  case OMF_release:
+    if (ResultType->isVoidType() &&
+        CGM.getLangOpts().getGC() == LangOptions::NonGC &&
+        Runtime.shouldUseARCFunctionsForRetainRelease()) {
+      CGF.EmitObjCRelease(Receiver, ARCPreciseLifetime);
+      return nullptr;
+    }
+    break;
+
   default:
     break;
   }
@@ -2006,6 +2029,11 @@ static llvm::Value *emitObjCValueOperation(CodeGenFunction &CGF,
     llvm::FunctionType *fnType =
       llvm::FunctionType::get(CGF.Int8PtrTy, CGF.Int8PtrTy, false);
     fn = CGF.CGM.CreateRuntimeFunction(fnType, fnName);
+
+    // We have Native ARC, so set nonlazybind attribute for performance
+    if (llvm::Function *f = dyn_cast(fn))
+      if (fnName == "objc_retain")
+        f->addFnAttr(llvm::Attribute::NonLazyBind);
   }
 
   // Cast the argument to 'id'.
@@ -2510,6 +2538,55 @@ void CodeGenFunction::emitARCIntrinsicUse(CodeGenFunction &CGF, Address addr,
   CGF.EmitARCIntrinsicUse(value);
 }
 
+/// Autorelease the given object.
+///   call i8* \@objc_autorelease(i8* %value)
+llvm::Value *CodeGenFunction::EmitObjCAutorelease(llvm::Value *value,
+                                                  llvm::Type *returnType) {
+  return emitObjCValueOperation(*this, value, returnType,
+                      CGM.getObjCEntrypoints().objc_autoreleaseRuntimeFunction,
+                                "objc_autorelease");
+}
+
+/// Retain the given object, with normal retain semantics.
+///   call i8* \@objc_retain(i8* %value)
+llvm::Value *CodeGenFunction::EmitObjCRetainNonBlock(llvm::Value *value,
+                                                     llvm::Type *returnType) {
+  return emitObjCValueOperation(*this, value, returnType,
+                          CGM.getObjCEntrypoints().objc_retainRuntimeFunction,
+                                "objc_retain");
+}
+
+/// Release the given object.
+///   call void \@objc_release(i8* %value)
+void CodeGenFunction::EmitObjCRelease(llvm::Value *value,
+                                      ARCPreciseLifetime_t precise) {
+  if (isa(value)) return;
+
+  llvm::Constant *&fn = CGM.getObjCEntrypoints().objc_release;
+  if (!fn) {
+    if (!fn) {
+      llvm::FunctionType *fnType =
+        llvm::FunctionType::get(Builder.getVoidTy(), Int8PtrTy, false);
+      fn = CGM.CreateRuntimeFunction(fnType, "objc_release");
+      setARCRuntimeFunctionLinkage(CGM, fn);
+      // We have Native ARC, so set nonlazybind attribute for performance
+      if (llvm::Function *f = dyn_cast(fn))
+        f->addFnAttr(llvm::Attribute::NonLazyBind);
+    }
+  }
+
+  // Cast the argument to 'id'.
+  value = Builder.CreateBitCast(value, Int8PtrTy);
+
+  // Call objc_release.
+  llvm::CallInst *call = EmitNounwindRuntimeCall(fn, value);
+
+  if (precise == ARCImpreciseLifetime) {
+    call->setMetadata("clang.imprecise_release",
+                      llvm::MDNode::get(Builder.getContext(), None));
+  }
+}
+
 namespace {
   struct CallObjCAutoreleasePoolObject final : EHScopeStack::Cleanup {
     llvm::Value *Token;
diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h
index 8971accdcd..c8b300236f 100644
--- a/lib/CodeGen/CodeGenFunction.h
+++ b/lib/CodeGen/CodeGenFunction.h
@@ -3798,6 +3798,11 @@ public:
   llvm::Value *EmitARCRetainAutoreleasedReturnValue(llvm::Value *value);
   llvm::Value *EmitARCUnsafeClaimAutoreleasedReturnValue(llvm::Value *value);
 
+  llvm::Value *EmitObjCAutorelease(llvm::Value *value, llvm::Type *returnType);
+  llvm::Value *EmitObjCRetainNonBlock(llvm::Value *value,
+                                      llvm::Type *returnType);
+  void EmitObjCRelease(llvm::Value *value, ARCPreciseLifetime_t precise);
+
   std::pair
   EmitARCStoreAutoreleasing(const BinaryOperator *e);
   std::pair
diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h
index f0d72af3ad..75679d11c1 100644
--- a/lib/CodeGen/CodeGenModule.h
+++ b/lib/CodeGen/CodeGenModule.h
@@ -138,6 +138,10 @@ struct ObjCEntrypoints {
   /// id objc_autorelease(id);
   llvm::Constant *objc_autorelease;
 
+  /// id objc_autorelease(id);
+  /// Note this is the runtime method not the intrinsic.
+  llvm::Constant *objc_autoreleaseRuntimeFunction;
+
   /// id objc_autoreleaseReturnValue(id);
   llvm::Constant *objc_autoreleaseReturnValue;
 
@@ -162,6 +166,10 @@ struct ObjCEntrypoints {
   /// id objc_retain(id);
   llvm::Constant *objc_retain;
 
+  /// id objc_retain(id);
+  /// Note this is the runtime method not the intrinsic.
+  llvm::Constant *objc_retainRuntimeFunction;
+
   /// id objc_retainAutorelease(id);
   llvm::Constant *objc_retainAutorelease;
 
@@ -177,6 +185,10 @@ struct ObjCEntrypoints {
   /// void objc_release(id);
   llvm::Constant *objc_release;
 
+  /// void objc_release(id);
+  /// Note this is the runtime method not the intrinsic.
+  llvm::Constant *objc_releaseRuntimeFunction;
+
   /// void objc_storeStrong(id*, id);
   llvm::Constant *objc_storeStrong;
 
diff --git a/test/CodeGenObjC/convert-messages-to-runtime-calls.m b/test/CodeGenObjC/convert-messages-to-runtime-calls.m
index 0a018204f3..adbbd4b173 100644
--- a/test/CodeGenObjC/convert-messages-to-runtime-calls.m
+++ b/test/CodeGenObjC/convert-messages-to-runtime-calls.m
@@ -14,16 +14,28 @@
 + (id)alloc;
 + (id)allocWithZone:(void*)zone;
 + (id)alloc2;
+- (id)retain;
+- (void)release;
+- (id)autorelease;
 @end
 
 // CHECK-LABEL: define {{.*}}void @test1
 void test1(id x) {
+  // MSGS: {{call.*@objc_msgSend}}
+  // MSGS: {{call.*@objc_msgSend}}
+  // MSGS: {{call.*@objc_msgSend}}
   // MSGS: {{call.*@objc_msgSend}}
   // MSGS: {{call.*@objc_msgSend}}
   // CALLS: {{call.*@objc_alloc}}
   // CALLS: {{call.*@objc_allocWithZone}}
+  // CALLS: {{call.*@objc_retain}}
+  // CALLS: {{call.*@objc_release}}
+  // CALLS: {{call.*@objc_autorelease}}
   [NSObject alloc];
   [NSObject allocWithZone:nil];
+  [x retain];
+  [x release];
+  [x autorelease];
 }
 
 // CHECK-LABEL: define {{.*}}void @test2
@@ -43,6 +55,8 @@ void test2(void* x) {
 @interface B
 + (A*) alloc;
 + (A*)allocWithZone:(void*)zone;
+- (A*) retain;
+- (A*) autorelease;
 @end
 
 // Make sure we get a bitcast on the return type as the
@@ -65,9 +79,30 @@ A* test_allocWithZone_class_ptr() {
   return [B allocWithZone:nil];
 }
 
+// Make sure we get a bitcast on the return type as the
+// call will return i8* which we have to cast to A*
+// CHECK-LABEL: define {{.*}}void @test_retain_class_ptr
+A* test_retain_class_ptr(B *b) {
+  // CALLS: {{call.*@objc_retain}}
+  // CALLS-NEXT: bitcast i8*
+  // CALLS-NEXT: ret
+  return [b retain];
+}
+
+// Make sure we get a bitcast on the return type as the
+// call will return i8* which we have to cast to A*
+// CHECK-LABEL: define {{.*}}void @test_autorelease_class_ptr
+A* test_autorelease_class_ptr(B *b) {
+  // CALLS: {{call.*@objc_autorelease}}
+  // CALLS-NEXT: bitcast i8*
+  // CALLS-NEXT: ret
+  return [b autorelease];
+}
+
 
 @interface C
 + (id)allocWithZone:(int)intArg;
+- (float) retain;
 @end
 
 // Make sure we only accept pointer types
@@ -78,3 +113,37 @@ C* test_allocWithZone_int() {
   return [C allocWithZone:3];
 }
 
+// Make sure we use a message and not a call as the return type is
+// not a pointer type.
+// CHECK-LABEL: define {{.*}}void @test_cannot_message_return_float
+float test_cannot_message_return_float(C *c) {
+  // MSGS: {{call.*@objc_msgSend}}
+  // CALLS: {{call.*@objc_msgSend}}
+  return [c retain];
+}
+
+@interface NSString : NSObject
++ (void)retain_self;
+- (void)retain_super;
+@end
+
+@implementation NSString
+
+// Make sure we can convert a message to a dynamic receiver to a call
+// CHECK-LABEL: define {{.*}}void @retain_self
++ (void)retain_self {
+  // MSGS: {{call.*@objc_msgSend}}
+  // CALLS: {{call.*@objc_retain}}
+  [self retain];
+}
+
+// Make sure we never convert a message to super to a call
+// CHECK-LABEL: define {{.*}}void @retain_super
+- (void)retain_super {
+  // MSGS: {{call.*@objc_msgSend}}
+  // CALLS: {{call.*@objc_msgSend}}
+  [super retain];
+}
+
+@end
+
-- 
cgit v1.2.3


From bd282df269cc1b61ea433838d2d3d5b4316c0ace Mon Sep 17 00:00:00 2001
From: Aaron Ballman 
Date: Fri, 21 Dec 2018 21:11:36 +0000
Subject: Switch from static_cast<> to cast<>, update identifier for coding
 conventions; NFC.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349955 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/Sema/SemaStmt.cpp | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index cc3c25cfb5..47130cf480 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -469,11 +469,9 @@ Sema::ActOnCaseStmt(SourceLocation CaseLoc, ExprResult LHSVal,
 }
 
 /// ActOnCaseStmtBody - This installs a statement as the body of a case.
-void Sema::ActOnCaseStmtBody(Stmt *caseStmt, Stmt *SubStmt) {
+void Sema::ActOnCaseStmtBody(Stmt *S, Stmt *SubStmt) {
   DiagnoseUnusedExprResult(SubStmt);
-
-  auto *CS = static_cast(caseStmt);
-  CS->setSubStmt(SubStmt);
+  cast(S)->setSubStmt(SubStmt);
 }
 
 StmtResult
-- 
cgit v1.2.3


From 5ce73e9a7953d8b153974c3c5a1ed1330558a73f Mon Sep 17 00:00:00 2001
From: Artem Belevich 
Date: Sat, 22 Dec 2018 01:11:09 +0000
Subject: [CUDA] Treat extern global variable shadows same as regular extern
 vars.

This fixes compiler crash when we attempted to compile this code:

extern __device__ int data;
__device__ int data = 1;

Differential Revision: https://reviews.llvm.org/D56033

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349981 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/CodeGen/CodeGenModule.cpp   | 15 +++++----------
 test/CodeGenCUDA/device-stub.cu | 19 +++++++++++++------
 2 files changed, 18 insertions(+), 16 deletions(-)

diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index df814d6386..b398f98024 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -2188,15 +2188,7 @@ void CodeGenModule::EmitGlobal(GlobalDecl GD) {
   } else {
     const auto *VD = cast(Global);
     assert(VD->isFileVarDecl() && "Cannot emit local var decl as global.");
-    // We need to emit device-side global CUDA variables even if a
-    // variable does not have a definition -- we still need to define
-    // host-side shadow for it.
-    bool MustEmitForCuda = LangOpts.CUDA && !LangOpts.CUDAIsDevice &&
-                           !VD->hasDefinition() &&
-                           (VD->hasAttr() ||
-                            VD->hasAttr());
-    if (!MustEmitForCuda &&
-        VD->isThisDeclarationADefinition() != VarDecl::Definition &&
+    if (VD->isThisDeclarationADefinition() != VarDecl::Definition &&
         !Context.isMSStaticDataMemberInlineDefinition(VD)) {
       if (LangOpts.OpenMP) {
         // Emit declaration of the must-be-emitted declare target variable.
@@ -3616,7 +3608,10 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D,
           Flags |= CGCUDARuntime::ExternDeviceVar;
         if (D->hasAttr())
           Flags |= CGCUDARuntime::ConstantDeviceVar;
-        getCUDARuntime().registerDeviceVar(*GV, Flags);
+        // Extern global variables will be registered in the TU where they are
+        // defined.
+        if (!D->hasExternalStorage())
+          getCUDARuntime().registerDeviceVar(*GV, Flags);
       } else if (D->hasAttr())
         // __shared__ variables are odd. Shadows do get created, but
         // they are not registered with the CUDA runtime, so they
diff --git a/test/CodeGenCUDA/device-stub.cu b/test/CodeGenCUDA/device-stub.cu
index 7abb7ae3a0..ea45c391d2 100644
--- a/test/CodeGenCUDA/device-stub.cu
+++ b/test/CodeGenCUDA/device-stub.cu
@@ -42,13 +42,20 @@ int host_var;
 // ALL-DAG: @ext_host_var = external global i32
 extern int ext_host_var;
 
-// Shadows for external device-side variables are *definitions* of
-// those variables.
-// ALL-DAG: @ext_device_var = internal global i32
+// external device-side variables -> extern references to their shadows.
+// ALL-DAG: @ext_device_var = external global i32
 extern __device__ int ext_device_var;
-// ALL-DAG: @ext_device_var = internal global i32
+// ALL-DAG: @ext_device_var = external global i32
 extern __constant__ int ext_constant_var;
 
+// external device-side variables with definitions should generate
+// definitions for the shadows.
+// ALL-DAG: @ext_device_var_def = internal global i32 undef,
+extern __device__ int ext_device_var_def;
+__device__ int ext_device_var_def = 1;
+// ALL-DAG: @ext_device_var_def = internal global i32 undef,
+__constant__ int ext_constant_var_def = 2;
+
 void use_pointers() {
   int *p;
   p = &device_var;
@@ -114,8 +121,8 @@ void hostfunc(void) { kernelfunc<<<1, 1>>>(1, 1, 1); }
 // ALL: call{{.*}}[[PREFIX]]RegisterFunction(i8** %0, {{.*}}kernelfunc
 // ALL-DAG: call{{.*}}[[PREFIX]]RegisterVar(i8** %0, {{.*}}device_var{{.*}}i32 0, i32 4, i32 0, i32 0
 // ALL-DAG: call{{.*}}[[PREFIX]]RegisterVar(i8** %0, {{.*}}constant_var{{.*}}i32 0, i32 4, i32 1, i32 0
-// ALL-DAG: call{{.*}}[[PREFIX]]RegisterVar(i8** %0, {{.*}}ext_device_var{{.*}}i32 1, i32 4, i32 0, i32 0
-// ALL-DAG: call{{.*}}[[PREFIX]]RegisterVar(i8** %0, {{.*}}ext_constant_var{{.*}}i32 1, i32 4, i32 1, i32 0
+// ALL-DAG: call{{.*}}[[PREFIX]]RegisterVar(i8** %0, {{.*}}ext_device_var_def{{.*}}i32 0, i32 4, i32 0, i32 0
+// ALL-DAG: call{{.*}}[[PREFIX]]RegisterVar(i8** %0, {{.*}}ext_constant_var_def{{.*}}i32 0, i32 4, i32 1, i32 0
 // ALL: ret void
 
 // Test that we've built a constructor.
-- 
cgit v1.2.3


From 71ba9f34f8103934f0aa68e04ba3f9b6bbca0a5f Mon Sep 17 00:00:00 2001
From: Artem Dergachev 
Date: Sat, 22 Dec 2018 02:06:51 +0000
Subject: [analyzer] pr38668: Do not attempt to cast loaded integers to floats.

This patch is a different approach to landing the reverted r349701.

It is expected to have the same object (memory region) treated as if it has
different types in different program points. The correct behavior for
RegionStore when an object is stored as an object of type T1 but loaded as
an object of type T2 is to store the object as if it has type T1 but cast it
to T2 during load.

Note that the cast here is some sort of a "reinterpret_cast" (even in C). For
instance, if you store an integer and load a float, you won't get your integer
represented as a float; instead, you will get garbage.

Admit that we cannot perform the cast and return an unknown value.

Differential Revision: https://reviews.llvm.org/D55875

rdar://problem/45062567


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349984 91177308-0d34-0410-b5e6-96231b3b80d8
---
 .../Checkers/ExprInspectionChecker.cpp             | 29 ++++++++++++++------
 lib/StaticAnalyzer/Core/Store.cpp                  | 11 ++++++++
 test/Analysis/casts.c                              | 32 ++++++++++++++++++++++
 test/Analysis/casts.cpp                            | 12 ++++++++
 test/Analysis/expr-inspection.cpp                  |  4 +--
 test/Analysis/svalbuilder-float-cast.c             | 20 ++++++++++++++
 6 files changed, 97 insertions(+), 11 deletions(-)
 create mode 100644 test/Analysis/svalbuilder-float-cast.c

diff --git a/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp b/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp
index 742266bfe6..2553f54bbc 100644
--- a/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp
@@ -321,11 +321,6 @@ void ExprInspectionChecker::analyzerDenote(const CallExpr *CE,
     return;
   }
 
-  if (!isa(Sym)) {
-    reportBug("Not an atomic symbol", C);
-    return;
-  }
-
   const auto *E = dyn_cast(CE->getArg(1)->IgnoreParenCasts());
   if (!E) {
     reportBug("Not a string literal", C);
@@ -345,7 +340,7 @@ class SymbolExpressor
 public:
   SymbolExpressor(ProgramStateRef State) : State(State) {}
 
-  Optional VisitSymExpr(const SymExpr *S) {
+  Optional lookup(const SymExpr *S) {
     if (const StringLiteral *const *SLPtr = State->get(S)) {
       const StringLiteral *SL = *SLPtr;
       return std::string(SL->getBytes());
@@ -353,8 +348,14 @@ public:
     return None;
   }
 
+  Optional VisitSymExpr(const SymExpr *S) {
+    return lookup(S);
+  }
+
   Optional VisitSymIntExpr(const SymIntExpr *S) {
-    if (auto Str = Visit(S->getLHS()))
+    if (Optional Str = lookup(S))
+      return Str;
+    if (Optional Str = Visit(S->getLHS()))
       return (*Str + " " + BinaryOperator::getOpcodeStr(S->getOpcode()) + " " +
               std::to_string(S->getRHS().getLimitedValue()) +
               (S->getRHS().isUnsigned() ? "U" : ""))
@@ -363,12 +364,22 @@ public:
   }
 
   Optional VisitSymSymExpr(const SymSymExpr *S) {
-    if (auto Str1 = Visit(S->getLHS()))
-      if (auto Str2 = Visit(S->getRHS()))
+    if (Optional Str = lookup(S))
+      return Str;
+    if (Optional Str1 = Visit(S->getLHS()))
+      if (Optional Str2 = Visit(S->getRHS()))
         return (*Str1 + " " + BinaryOperator::getOpcodeStr(S->getOpcode()) +
                 " " + *Str2).str();
     return None;
   }
+
+  Optional VisitSymbolCast(const SymbolCast *S) {
+    if (Optional Str = lookup(S))
+      return Str;
+    if (Optional Str = Visit(S->getOperand()))
+      return (Twine("(") + S->getType().getAsString() + ")" + *Str).str();
+    return None;
+  }
 };
 } // namespace
 
diff --git a/lib/StaticAnalyzer/Core/Store.cpp b/lib/StaticAnalyzer/Core/Store.cpp
index 794fd84364..4fa937d965 100644
--- a/lib/StaticAnalyzer/Core/Store.cpp
+++ b/lib/StaticAnalyzer/Core/Store.cpp
@@ -402,6 +402,17 @@ SVal StoreManager::CastRetrievedVal(SVal V, const TypedValueRegion *R,
   if (castTy.isNull() || V.isUnknownOrUndef())
     return V;
 
+  // The dispatchCast() call below would convert the int into a float.
+  // What we want, however, is a bit-by-bit reinterpretation of the int
+  // as a float, which usually yields nothing garbage. For now skip casts
+  // from ints to floats.
+  // TODO: What other combinations of types are affected?
+  if (castTy->isFloatingType()) {
+    SymbolRef Sym = V.getAsSymbol();
+    if (Sym && !Sym->getType()->isFloatingType())
+      return UnknownVal();
+  }
+
   // When retrieving symbolic pointer and expecting a non-void pointer,
   // wrap them into element regions of the expected type if necessary.
   // SValBuilder::dispatchCast() doesn't do that, but it is necessary to
diff --git a/test/Analysis/casts.c b/test/Analysis/casts.c
index 45ce1940df..2d96aa3571 100644
--- a/test/Analysis/casts.c
+++ b/test/Analysis/casts.c
@@ -213,3 +213,35 @@ void no_crash_on_symsym_cast_to_long() {
 }
 
 #endif
+
+char no_crash_SymbolCast_of_float_type_aux(int *p) {
+  *p += 1;
+  return *p;
+}
+
+void no_crash_SymbolCast_of_float_type() {
+  extern float x;
+  char (*f)() = no_crash_SymbolCast_of_float_type_aux;
+  f(&x);
+}
+
+double no_crash_reinterpret_double_as_int(double a) {
+  *(int *)&a = 1;
+  return a * a;
+}
+
+double no_crash_reinterpret_double_as_ptr(double a) {
+  *(void **)&a = 0;
+  return a * a;
+}
+
+double no_crash_reinterpret_double_as_sym_int(double a, int b) {
+  *(int *)&a = b;
+  return a * a;
+}
+
+double no_crash_reinterpret_double_as_sym_ptr(double a, void * b) {
+  *(void **)&a = b;
+  return a * a;
+}
+
diff --git a/test/Analysis/casts.cpp b/test/Analysis/casts.cpp
index e920bd96da..aa2bd9c1fa 100644
--- a/test/Analysis/casts.cpp
+++ b/test/Analysis/casts.cpp
@@ -102,3 +102,15 @@ void foo(VeryOpaqueRef ORef) {
   castToDerived(reinterpret_cast(ORef))->getNotInt();
 }
 } // namespace base_to_derived_opaque_class
+
+namespace bool_to_nullptr {
+struct S {
+  int *a[1];
+  bool b;
+};
+void foo(S s) {
+  s.b = true;
+  for (int i = 0; i < 2; ++i)
+    (void)(s.a[i] != nullptr); // no-crash
+}
+} // namespace bool_to_nullptr
diff --git a/test/Analysis/expr-inspection.cpp b/test/Analysis/expr-inspection.cpp
index 28f35b3eac..609b44ca6d 100644
--- a/test/Analysis/expr-inspection.cpp
+++ b/test/Analysis/expr-inspection.cpp
@@ -24,7 +24,7 @@ void foo(int x, unsigned y) {
   clang_analyzer_denote(1, "$z");     // expected-warning{{Not a symbol}}
   clang_analyzer_express(1);     // expected-warning{{Not a symbol}}
 
-  clang_analyzer_denote(x + 1, "$w"); // expected-warning{{Not an atomic symbol}}
-  clang_analyzer_express(x + 1); // expected-warning{{$x + 1}}
+  clang_analyzer_denote(x + 1, "$w");
+  clang_analyzer_express(x + 1); // expected-warning{{$w}}
   clang_analyzer_express(y + 1); // expected-warning{{$y + 1U}}
 }
diff --git a/test/Analysis/svalbuilder-float-cast.c b/test/Analysis/svalbuilder-float-cast.c
new file mode 100644
index 0000000000..0f5760cbfc
--- /dev/null
+++ b/test/Analysis/svalbuilder-float-cast.c
@@ -0,0 +1,20 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker debug.ExprInspection -verify %s
+void clang_analyzer_denote(int, const char *);
+void clang_analyzer_express(int);
+
+void SymbolCast_of_float_type_aux(int *p) {
+  *p += 0;
+  // FIXME: Ideally, all unknown values should be symbolicated.
+  clang_analyzer_denote(*p, "$x"); // expected-warning{{Not a symbol}}
+
+  *p += 1;
+  // This should NOT be (float)$x + 1. Symbol $x was never casted to float.
+  // FIXME: Ideally, this should be $x + 1.
+  clang_analyzer_express(*p); // expected-warning{{Not a symbol}}
+}
+
+void SymbolCast_of_float_type() {
+  extern float x;
+  void (*f)() = SymbolCast_of_float_type_aux;
+  f(&x);
+}
-- 
cgit v1.2.3


From c98f5f226b27512367700c50c6fb477d663e5c95 Mon Sep 17 00:00:00 2001
From: Bruno Ricci 
Date: Sat, 22 Dec 2018 14:39:30 +0000
Subject: [AST] Store the arguments of CXXConstructExpr in a trailing array

Store the arguments of CXXConstructExpr in a trailing array. This is very
similar to the CallExpr case in D55771, with the exception that there is
only one derived class (CXXTemporaryObjectExpr) and that we compute the
offset to the trailing array instead of storing it.

This saves one pointer per CXXConstructExpr and CXXTemporaryObjectExpr.

Reviewed By: rjmccall

Differential Revision: https://reviews.llvm.org/D56022



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350003 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/AST/ExprCXX.h         | 211 ++++++++++++++++++++++--------------
 include/clang/AST/Stmt.h            |  17 +++
 lib/AST/ASTImporter.cpp             |   2 +-
 lib/AST/ExprCXX.cpp                 | 172 ++++++++++++++++-------------
 lib/Sema/SemaInit.cpp               |   2 +-
 lib/Serialization/ASTReaderStmt.cpp |  38 ++++---
 lib/Serialization/ASTWriterStmt.cpp |  11 +-
 7 files changed, 274 insertions(+), 179 deletions(-)

diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index ea24ef8de4..3f22d8e9c5 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -1280,6 +1280,8 @@ public:
 
 /// Represents a call to a C++ constructor.
 class CXXConstructExpr : public Expr {
+  friend class ASTStmtReader;
+
 public:
   enum ConstructionKind {
     CK_Complete,
@@ -1289,98 +1291,119 @@ public:
   };
 
 private:
-  CXXConstructorDecl *Constructor = nullptr;
-  SourceLocation Loc;
+  /// A pointer to the constructor which will be ultimately called.
+  CXXConstructorDecl *Constructor;
+
   SourceRange ParenOrBraceRange;
-  unsigned NumArgs : 16;
-  unsigned Elidable : 1;
-  unsigned HadMultipleCandidates : 1;
-  unsigned ListInitialization : 1;
-  unsigned StdInitListInitialization : 1;
-  unsigned ZeroInitialization : 1;
-  unsigned ConstructKind : 2;
-  Stmt **Args = nullptr;
 
-  void setConstructor(CXXConstructorDecl *C) { Constructor = C; }
+  /// The number of arguments.
+  unsigned NumArgs;
+
+  // We would like to stash the arguments of the constructor call after
+  // CXXConstructExpr. However CXXConstructExpr is used as a base class of
+  // CXXTemporaryObjectExpr which makes the use of llvm::TrailingObjects
+  // impossible.
+  //
+  // Instead we manually stash the trailing object after the full object
+  // containing CXXConstructExpr (that is either CXXConstructExpr or
+  // CXXTemporaryObjectExpr).
+  //
+  // The trailing objects are:
+  //
+  // * An array of getNumArgs() "Stmt *" for the arguments of the
+  //   constructor call.
+
+  /// Return a pointer to the start of the trailing arguments.
+  /// Defined just after CXXTemporaryObjectExpr.
+  inline Stmt **getTrailingArgs();
+  const Stmt *const *getTrailingArgs() const {
+    return const_cast(this)->getTrailingArgs();
+  }
 
 protected:
-  CXXConstructExpr(const ASTContext &C, StmtClass SC, QualType T,
-                   SourceLocation Loc,
-                   CXXConstructorDecl *Ctor,
-                   bool Elidable,
-                   ArrayRef Args,
-                   bool HadMultipleCandidates,
-                   bool ListInitialization,
-                   bool StdInitListInitialization,
-                   bool ZeroInitialization,
-                   ConstructionKind ConstructKind,
+  /// Build a C++ construction expression.
+  CXXConstructExpr(StmtClass SC, QualType Ty, SourceLocation Loc,
+                   CXXConstructorDecl *Ctor, bool Elidable,
+                   ArrayRef Args, bool HadMultipleCandidates,
+                   bool ListInitialization, bool StdInitListInitialization,
+                   bool ZeroInitialization, ConstructionKind ConstructKind,
                    SourceRange ParenOrBraceRange);
 
-  /// Construct an empty C++ construction expression.
-  CXXConstructExpr(StmtClass SC, EmptyShell Empty)
-      : Expr(SC, Empty), NumArgs(0), Elidable(false),
-        HadMultipleCandidates(false), ListInitialization(false),
-        ZeroInitialization(false), ConstructKind(0) {}
+  /// Build an empty C++ construction expression.
+  CXXConstructExpr(StmtClass SC, EmptyShell Empty, unsigned NumArgs);
+
+  /// Return the size in bytes of the trailing objects. Used by
+  /// CXXTemporaryObjectExpr to allocate the right amount of storage.
+  static unsigned sizeOfTrailingObjects(unsigned NumArgs) {
+    return NumArgs * sizeof(Stmt *);
+  }
 
 public:
-  friend class ASTStmtReader;
+  /// Create a C++ construction expression.
+  static CXXConstructExpr *
+  Create(const ASTContext &Ctx, QualType Ty, SourceLocation Loc,
+         CXXConstructorDecl *Ctor, bool Elidable, ArrayRef Args,
+         bool HadMultipleCandidates, bool ListInitialization,
+         bool StdInitListInitialization, bool ZeroInitialization,
+         ConstructionKind ConstructKind, SourceRange ParenOrBraceRange);
 
-  /// Construct an empty C++ construction expression.
-  explicit CXXConstructExpr(EmptyShell Empty)
-      : CXXConstructExpr(CXXConstructExprClass, Empty) {}
-
-  static CXXConstructExpr *Create(const ASTContext &C, QualType T,
-                                  SourceLocation Loc,
-                                  CXXConstructorDecl *Ctor,
-                                  bool Elidable,
-                                  ArrayRef Args,
-                                  bool HadMultipleCandidates,
-                                  bool ListInitialization,
-                                  bool StdInitListInitialization,
-                                  bool ZeroInitialization,
-                                  ConstructionKind ConstructKind,
-                                  SourceRange ParenOrBraceRange);
+  /// Create an empty C++ construction expression.
+  static CXXConstructExpr *CreateEmpty(const ASTContext &Ctx, unsigned NumArgs);
 
   /// Get the constructor that this expression will (ultimately) call.
   CXXConstructorDecl *getConstructor() const { return Constructor; }
 
-  SourceLocation getLocation() const { return Loc; }
-  void setLocation(SourceLocation Loc) { this->Loc = Loc; }
+  SourceLocation getLocation() const { return CXXConstructExprBits.Loc; }
+  void setLocation(SourceLocation Loc) { CXXConstructExprBits.Loc = Loc; }
 
   /// Whether this construction is elidable.
-  bool isElidable() const { return Elidable; }
-  void setElidable(bool E) { Elidable = E; }
+  bool isElidable() const { return CXXConstructExprBits.Elidable; }
+  void setElidable(bool E) { CXXConstructExprBits.Elidable = E; }
 
   /// Whether the referred constructor was resolved from
   /// an overloaded set having size greater than 1.
-  bool hadMultipleCandidates() const { return HadMultipleCandidates; }
-  void setHadMultipleCandidates(bool V) { HadMultipleCandidates = V; }
+  bool hadMultipleCandidates() const {
+    return CXXConstructExprBits.HadMultipleCandidates;
+  }
+  void setHadMultipleCandidates(bool V) {
+    CXXConstructExprBits.HadMultipleCandidates = V;
+  }
 
   /// Whether this constructor call was written as list-initialization.
-  bool isListInitialization() const { return ListInitialization; }
-  void setListInitialization(bool V) { ListInitialization = V; }
+  bool isListInitialization() const {
+    return CXXConstructExprBits.ListInitialization;
+  }
+  void setListInitialization(bool V) {
+    CXXConstructExprBits.ListInitialization = V;
+  }
 
   /// Whether this constructor call was written as list-initialization,
   /// but was interpreted as forming a std::initializer_list from the list
   /// and passing that as a single constructor argument.
   /// See C++11 [over.match.list]p1 bullet 1.
-  bool isStdInitListInitialization() const { return StdInitListInitialization; }
-  void setStdInitListInitialization(bool V) { StdInitListInitialization = V; }
+  bool isStdInitListInitialization() const {
+    return CXXConstructExprBits.StdInitListInitialization;
+  }
+  void setStdInitListInitialization(bool V) {
+    CXXConstructExprBits.StdInitListInitialization = V;
+  }
 
   /// Whether this construction first requires
   /// zero-initialization before the initializer is called.
-  bool requiresZeroInitialization() const { return ZeroInitialization; }
+  bool requiresZeroInitialization() const {
+    return CXXConstructExprBits.ZeroInitialization;
+  }
   void setRequiresZeroInitialization(bool ZeroInit) {
-    ZeroInitialization = ZeroInit;
+    CXXConstructExprBits.ZeroInitialization = ZeroInit;
   }
 
   /// Determine whether this constructor is actually constructing
   /// a base class (rather than a complete object).
   ConstructionKind getConstructionKind() const {
-    return (ConstructionKind)ConstructKind;
+    return static_cast(CXXConstructExprBits.ConstructionKind);
   }
   void setConstructionKind(ConstructionKind CK) {
-    ConstructKind = CK;
+    CXXConstructExprBits.ConstructionKind = CK;
   }
 
   using arg_iterator = ExprIterator;
@@ -1393,31 +1416,33 @@ public:
     return const_arg_range(arg_begin(), arg_end());
   }
 
-  arg_iterator arg_begin() { return Args; }
-  arg_iterator arg_end() { return Args + NumArgs; }
-  const_arg_iterator arg_begin() const { return Args; }
-  const_arg_iterator arg_end() const { return Args + NumArgs; }
+  arg_iterator arg_begin() { return getTrailingArgs(); }
+  arg_iterator arg_end() { return arg_begin() + getNumArgs(); }
+  const_arg_iterator arg_begin() const { return getTrailingArgs(); }
+  const_arg_iterator arg_end() const { return arg_begin() + getNumArgs(); }
 
-  Expr **getArgs() { return reinterpret_cast(Args); }
+  Expr **getArgs() { return reinterpret_cast(getTrailingArgs()); }
   const Expr *const *getArgs() const {
-    return const_cast(this)->getArgs();
+    return reinterpret_cast(getTrailingArgs());
   }
+
+  /// Return the number of arguments to the constructor call.
   unsigned getNumArgs() const { return NumArgs; }
 
   /// Return the specified argument.
   Expr *getArg(unsigned Arg) {
-    assert(Arg < NumArgs && "Arg access out of range!");
-    return cast(Args[Arg]);
+    assert(Arg < getNumArgs() && "Arg access out of range!");
+    return getArgs()[Arg];
   }
   const Expr *getArg(unsigned Arg) const {
-    assert(Arg < NumArgs && "Arg access out of range!");
-    return cast(Args[Arg]);
+    assert(Arg < getNumArgs() && "Arg access out of range!");
+    return getArgs()[Arg];
   }
 
   /// Set the specified argument.
   void setArg(unsigned Arg, Expr *ArgExpr) {
-    assert(Arg < NumArgs && "Arg access out of range!");
-    Args[Arg] = ArgExpr;
+    assert(Arg < getNumArgs() && "Arg access out of range!");
+    getArgs()[Arg] = ArgExpr;
   }
 
   SourceLocation getBeginLoc() const LLVM_READONLY;
@@ -1427,12 +1452,12 @@ public:
 
   static bool classof(const Stmt *T) {
     return T->getStmtClass() == CXXConstructExprClass ||
-      T->getStmtClass() == CXXTemporaryObjectExprClass;
+           T->getStmtClass() == CXXTemporaryObjectExprClass;
   }
 
   // Iterators
   child_range children() {
-    return child_range(&Args[0], &Args[0]+NumArgs);
+    return child_range(getTrailingArgs(), getTrailingArgs() + getNumArgs());
   }
 };
 
@@ -1578,26 +1603,36 @@ public:
 ///   return X(1, 3.14f); // creates a CXXTemporaryObjectExpr
 /// };
 /// \endcode
-class CXXTemporaryObjectExpr : public CXXConstructExpr {
-  TypeSourceInfo *Type = nullptr;
-
-public:
+class CXXTemporaryObjectExpr final : public CXXConstructExpr {
   friend class ASTStmtReader;
 
-  CXXTemporaryObjectExpr(const ASTContext &C,
-                         CXXConstructorDecl *Cons,
-                         QualType Type,
-                         TypeSourceInfo *TSI,
-                         ArrayRef Args,
+  // CXXTemporaryObjectExpr has some trailing objects belonging
+  // to CXXConstructExpr. See the comment inside CXXConstructExpr
+  // for more details.
+
+  TypeSourceInfo *TSI;
+
+  CXXTemporaryObjectExpr(CXXConstructorDecl *Cons, QualType Ty,
+                         TypeSourceInfo *TSI, ArrayRef Args,
                          SourceRange ParenOrBraceRange,
-                         bool HadMultipleCandidates,
-                         bool ListInitialization,
+                         bool HadMultipleCandidates, bool ListInitialization,
                          bool StdInitListInitialization,
                          bool ZeroInitialization);
-  explicit CXXTemporaryObjectExpr(EmptyShell Empty)
-      : CXXConstructExpr(CXXTemporaryObjectExprClass, Empty) {}
 
-  TypeSourceInfo *getTypeSourceInfo() const { return Type; }
+  CXXTemporaryObjectExpr(EmptyShell Empty, unsigned NumArgs);
+
+public:
+  static CXXTemporaryObjectExpr *
+  Create(const ASTContext &Ctx, CXXConstructorDecl *Cons, QualType Ty,
+         TypeSourceInfo *TSI, ArrayRef Args,
+         SourceRange ParenOrBraceRange, bool HadMultipleCandidates,
+         bool ListInitialization, bool StdInitListInitialization,
+         bool ZeroInitialization);
+
+  static CXXTemporaryObjectExpr *CreateEmpty(const ASTContext &Ctx,
+                                             unsigned NumArgs);
+
+  TypeSourceInfo *getTypeSourceInfo() const { return TSI; }
 
   SourceLocation getBeginLoc() const LLVM_READONLY;
   SourceLocation getEndLoc() const LLVM_READONLY;
@@ -1607,6 +1642,14 @@ public:
   }
 };
 
+Stmt **CXXConstructExpr::getTrailingArgs() {
+  if (auto *E = dyn_cast(this))
+    return reinterpret_cast(E + 1);
+  assert((getStmtClass() == CXXConstructExprClass) &&
+         "Unexpected class deriving from CXXConstructExpr!");
+  return reinterpret_cast(this + 1);
+}
+
 /// A C++ lambda expression, which produces a function object
 /// (of unspecified type) that can be invoked later.
 ///
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index ff9be8dbb7..9d8a297487 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -655,6 +655,22 @@ protected:
     unsigned NumArgs : 32 - 8 - 1 - NumExprBits;
   };
 
+  class CXXConstructExprBitfields {
+    friend class ASTStmtReader;
+    friend class CXXConstructExpr;
+
+    unsigned : NumExprBits;
+
+    unsigned Elidable : 1;
+    unsigned HadMultipleCandidates : 1;
+    unsigned ListInitialization : 1;
+    unsigned StdInitListInitialization : 1;
+    unsigned ZeroInitialization : 1;
+    unsigned ConstructionKind : 3;
+
+    SourceLocation Loc;
+  };
+
   class ExprWithCleanupsBitfields {
     friend class ASTStmtReader; // deserialization
     friend class ExprWithCleanups;
@@ -746,6 +762,7 @@ protected:
     CXXDefaultInitExprBitfields CXXDefaultInitExprBits;
     CXXDeleteExprBitfields CXXDeleteExprBits;
     TypeTraitExprBitfields TypeTraitExprBits;
+    CXXConstructExprBitfields CXXConstructExprBits;
     ExprWithCleanupsBitfields ExprWithCleanupsBits;
 
     // C++ Coroutines TS expressions
diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp
index a6169ff652..251d078635 100644
--- a/lib/AST/ASTImporter.cpp
+++ b/lib/AST/ASTImporter.cpp
@@ -6816,7 +6816,7 @@ ASTNodeImporter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) {
   if (Error Err = ImportContainerChecked(E->arguments(), ToArgs))
     return std::move(Err);
 
-  return new (Importer.getToContext()) CXXTemporaryObjectExpr(
+  return CXXTemporaryObjectExpr::Create(
       Importer.getToContext(), ToConstructor, ToType, ToTypeSourceInfo, ToArgs,
       ToParenOrBraceRange, E->hadMultipleCandidates(),
       E->isListInitialization(), E->isStdInitListInitialization(),
diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp
index 03bffbedcf..83af29a638 100644
--- a/lib/AST/ExprCXX.cpp
+++ b/lib/AST/ExprCXX.cpp
@@ -453,7 +453,7 @@ DependentScopeDeclRefExpr::CreateEmpty(const ASTContext &C,
 SourceLocation CXXConstructExpr::getBeginLoc() const {
   if (isa(this))
     return cast(this)->getBeginLoc();
-  return Loc;
+  return getLocation();
 }
 
 SourceLocation CXXConstructExpr::getEndLoc() const {
@@ -463,7 +463,7 @@ SourceLocation CXXConstructExpr::getEndLoc() const {
   if (ParenOrBraceRange.isValid())
     return ParenOrBraceRange.getEnd();
 
-  SourceLocation End = Loc;
+  SourceLocation End = getLocation();
   for (unsigned I = getNumArgs(); I > 0; --I) {
     const Expr *Arg = getArg(I-1);
     if (!Arg->isDefaultArgument()) {
@@ -892,25 +892,47 @@ CXXBindTemporaryExpr *CXXBindTemporaryExpr::Create(const ASTContext &C,
   return new (C) CXXBindTemporaryExpr(Temp, SubExpr);
 }
 
-CXXTemporaryObjectExpr::CXXTemporaryObjectExpr(const ASTContext &C,
-                                               CXXConstructorDecl *Cons,
-                                               QualType Type,
-                                               TypeSourceInfo *TSI,
-                                               ArrayRef Args,
-                                               SourceRange ParenOrBraceRange,
-                                               bool HadMultipleCandidates,
-                                               bool ListInitialization,
-                                               bool StdInitListInitialization,
-                                               bool ZeroInitialization)
-    : CXXConstructExpr(C, CXXTemporaryObjectExprClass, Type,
-                       TSI->getTypeLoc().getBeginLoc(), Cons, false, Args,
-                       HadMultipleCandidates, ListInitialization,
-                       StdInitListInitialization,  ZeroInitialization,
-                       CXXConstructExpr::CK_Complete, ParenOrBraceRange),
-      Type(TSI) {}
+CXXTemporaryObjectExpr::CXXTemporaryObjectExpr(
+    CXXConstructorDecl *Cons, QualType Ty, TypeSourceInfo *TSI,
+    ArrayRef Args, SourceRange ParenOrBraceRange,
+    bool HadMultipleCandidates, bool ListInitialization,
+    bool StdInitListInitialization, bool ZeroInitialization)
+    : CXXConstructExpr(
+          CXXTemporaryObjectExprClass, Ty, TSI->getTypeLoc().getBeginLoc(),
+          Cons, /* Elidable=*/false, Args, HadMultipleCandidates,
+          ListInitialization, StdInitListInitialization, ZeroInitialization,
+          CXXConstructExpr::CK_Complete, ParenOrBraceRange),
+      TSI(TSI) {}
+
+CXXTemporaryObjectExpr::CXXTemporaryObjectExpr(EmptyShell Empty,
+                                               unsigned NumArgs)
+    : CXXConstructExpr(CXXTemporaryObjectExprClass, Empty, NumArgs) {}
+
+CXXTemporaryObjectExpr *CXXTemporaryObjectExpr::Create(
+    const ASTContext &Ctx, CXXConstructorDecl *Cons, QualType Ty,
+    TypeSourceInfo *TSI, ArrayRef Args, SourceRange ParenOrBraceRange,
+    bool HadMultipleCandidates, bool ListInitialization,
+    bool StdInitListInitialization, bool ZeroInitialization) {
+  unsigned SizeOfTrailingObjects = sizeOfTrailingObjects(Args.size());
+  void *Mem =
+      Ctx.Allocate(sizeof(CXXTemporaryObjectExpr) + SizeOfTrailingObjects,
+                   alignof(CXXTemporaryObjectExpr));
+  return new (Mem) CXXTemporaryObjectExpr(
+      Cons, Ty, TSI, Args, ParenOrBraceRange, HadMultipleCandidates,
+      ListInitialization, StdInitListInitialization, ZeroInitialization);
+}
+
+CXXTemporaryObjectExpr *
+CXXTemporaryObjectExpr::CreateEmpty(const ASTContext &Ctx, unsigned NumArgs) {
+  unsigned SizeOfTrailingObjects = sizeOfTrailingObjects(NumArgs);
+  void *Mem =
+      Ctx.Allocate(sizeof(CXXTemporaryObjectExpr) + SizeOfTrailingObjects,
+                   alignof(CXXTemporaryObjectExpr));
+  return new (Mem) CXXTemporaryObjectExpr(EmptyShell(), NumArgs);
+}
 
 SourceLocation CXXTemporaryObjectExpr::getBeginLoc() const {
-  return Type->getTypeLoc().getBeginLoc();
+  return getTypeSourceInfo()->getTypeLoc().getBeginLoc();
 }
 
 SourceLocation CXXTemporaryObjectExpr::getEndLoc() const {
@@ -920,64 +942,68 @@ SourceLocation CXXTemporaryObjectExpr::getEndLoc() const {
   return Loc;
 }
 
-CXXConstructExpr *CXXConstructExpr::Create(const ASTContext &C, QualType T,
-                                           SourceLocation Loc,
-                                           CXXConstructorDecl *Ctor,
-                                           bool Elidable,
-                                           ArrayRef Args,
-                                           bool HadMultipleCandidates,
-                                           bool ListInitialization,
-                                           bool StdInitListInitialization,
-                                           bool ZeroInitialization,
-                                           ConstructionKind ConstructKind,
-                                           SourceRange ParenOrBraceRange) {
-  return new (C) CXXConstructExpr(C, CXXConstructExprClass, T, Loc,
-                                  Ctor, Elidable, Args,
-                                  HadMultipleCandidates, ListInitialization,
-                                  StdInitListInitialization,
-                                  ZeroInitialization, ConstructKind,
-                                  ParenOrBraceRange);
-}
-
-CXXConstructExpr::CXXConstructExpr(const ASTContext &C, StmtClass SC,
-                                   QualType T, SourceLocation Loc,
-                                   CXXConstructorDecl *Ctor,
-                                   bool Elidable,
-                                   ArrayRef Args,
-                                   bool HadMultipleCandidates,
-                                   bool ListInitialization,
-                                   bool StdInitListInitialization,
-                                   bool ZeroInitialization,
-                                   ConstructionKind ConstructKind,
-                                   SourceRange ParenOrBraceRange)
-    : Expr(SC, T, VK_RValue, OK_Ordinary,
-           T->isDependentType(), T->isDependentType(),
-           T->isInstantiationDependentType(),
-           T->containsUnexpandedParameterPack()),
-      Constructor(Ctor), Loc(Loc), ParenOrBraceRange(ParenOrBraceRange),
-      NumArgs(Args.size()), Elidable(Elidable),
-      HadMultipleCandidates(HadMultipleCandidates),
-      ListInitialization(ListInitialization),
-      StdInitListInitialization(StdInitListInitialization),
-      ZeroInitialization(ZeroInitialization), ConstructKind(ConstructKind) {
-  if (NumArgs) {
-    this->Args = new (C) Stmt*[Args.size()];
-
-    for (unsigned i = 0; i != Args.size(); ++i) {
-      assert(Args[i] && "NULL argument in CXXConstructExpr");
-
-      if (Args[i]->isValueDependent())
-        ExprBits.ValueDependent = true;
-      if (Args[i]->isInstantiationDependent())
-        ExprBits.InstantiationDependent = true;
-      if (Args[i]->containsUnexpandedParameterPack())
-        ExprBits.ContainsUnexpandedParameterPack = true;
+CXXConstructExpr *CXXConstructExpr::Create(
+    const ASTContext &Ctx, QualType Ty, SourceLocation Loc,
+    CXXConstructorDecl *Ctor, bool Elidable, ArrayRef Args,
+    bool HadMultipleCandidates, bool ListInitialization,
+    bool StdInitListInitialization, bool ZeroInitialization,
+    ConstructionKind ConstructKind, SourceRange ParenOrBraceRange) {
+  unsigned SizeOfTrailingObjects = sizeOfTrailingObjects(Args.size());
+  void *Mem = Ctx.Allocate(sizeof(CXXConstructExpr) + SizeOfTrailingObjects,
+                           alignof(CXXConstructExpr));
+  return new (Mem) CXXConstructExpr(
+      CXXConstructExprClass, Ty, Loc, Ctor, Elidable, Args,
+      HadMultipleCandidates, ListInitialization, StdInitListInitialization,
+      ZeroInitialization, ConstructKind, ParenOrBraceRange);
+}
+
+CXXConstructExpr *CXXConstructExpr::CreateEmpty(const ASTContext &Ctx,
+                                                unsigned NumArgs) {
+  unsigned SizeOfTrailingObjects = sizeOfTrailingObjects(NumArgs);
+  void *Mem = Ctx.Allocate(sizeof(CXXConstructExpr) + SizeOfTrailingObjects,
+                           alignof(CXXConstructExpr));
+  return new (Mem)
+      CXXConstructExpr(CXXConstructExprClass, EmptyShell(), NumArgs);
+}
+
+CXXConstructExpr::CXXConstructExpr(
+    StmtClass SC, QualType Ty, SourceLocation Loc, CXXConstructorDecl *Ctor,
+    bool Elidable, ArrayRef Args, bool HadMultipleCandidates,
+    bool ListInitialization, bool StdInitListInitialization,
+    bool ZeroInitialization, ConstructionKind ConstructKind,
+    SourceRange ParenOrBraceRange)
+    : Expr(SC, Ty, VK_RValue, OK_Ordinary, Ty->isDependentType(),
+           Ty->isDependentType(), Ty->isInstantiationDependentType(),
+           Ty->containsUnexpandedParameterPack()),
+      Constructor(Ctor), ParenOrBraceRange(ParenOrBraceRange),
+      NumArgs(Args.size()) {
+  CXXConstructExprBits.Elidable = Elidable;
+  CXXConstructExprBits.HadMultipleCandidates = HadMultipleCandidates;
+  CXXConstructExprBits.ListInitialization = ListInitialization;
+  CXXConstructExprBits.StdInitListInitialization = StdInitListInitialization;
+  CXXConstructExprBits.ZeroInitialization = ZeroInitialization;
+  CXXConstructExprBits.ConstructionKind = ConstructKind;
+  CXXConstructExprBits.Loc = Loc;
+
+  Stmt **TrailingArgs = getTrailingArgs();
+  for (unsigned I = 0, N = Args.size(); I != N; ++I) {
+    assert(Args[I] && "NULL argument in CXXConstructExpr!");
 
-      this->Args[i] = Args[i];
-    }
+    if (Args[I]->isValueDependent())
+      ExprBits.ValueDependent = true;
+    if (Args[I]->isInstantiationDependent())
+      ExprBits.InstantiationDependent = true;
+    if (Args[I]->containsUnexpandedParameterPack())
+      ExprBits.ContainsUnexpandedParameterPack = true;
+
+    TrailingArgs[I] = Args[I];
   }
 }
 
+CXXConstructExpr::CXXConstructExpr(StmtClass SC, EmptyShell Empty,
+                                   unsigned NumArgs)
+    : Expr(SC, Empty), NumArgs(NumArgs) {}
+
 LambdaCapture::LambdaCapture(SourceLocation Loc, bool Implicit,
                              LambdaCaptureKind Kind, VarDecl *Var,
                              SourceLocation EllipsisLoc)
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp
index c2f14229d8..80cc4617eb 100644
--- a/lib/Sema/SemaInit.cpp
+++ b/lib/Sema/SemaInit.cpp
@@ -6199,7 +6199,7 @@ PerformConstructorInitialization(Sema &S,
     }
     S.MarkFunctionReferenced(Loc, Constructor);
 
-    CurInit = new (S.Context) CXXTemporaryObjectExpr(
+    CurInit = CXXTemporaryObjectExpr::Create(
         S.Context, Constructor,
         Entity.getType().getNonLValueExprType(S.Context), TSInfo,
         ConstructorArgs, ParenOrBraceRange, HadMultipleCandidates,
diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp
index 3b5ff78698..83b4fcd1d9 100644
--- a/lib/Serialization/ASTReaderStmt.cpp
+++ b/lib/Serialization/ASTReaderStmt.cpp
@@ -1353,20 +1353,22 @@ void ASTStmtReader::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
 
 void ASTStmtReader::VisitCXXConstructExpr(CXXConstructExpr *E) {
   VisitExpr(E);
-  E->NumArgs = Record.readInt();
-  if (E->NumArgs)
-    E->Args = new (Record.getContext()) Stmt*[E->NumArgs];
-  for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
-    E->setArg(I, Record.readSubExpr());
-  E->setConstructor(ReadDeclAs());
-  E->setLocation(ReadSourceLocation());
-  E->setElidable(Record.readInt());
-  E->setHadMultipleCandidates(Record.readInt());
-  E->setListInitialization(Record.readInt());
-  E->setStdInitListInitialization(Record.readInt());
-  E->setRequiresZeroInitialization(Record.readInt());
-  E->setConstructionKind((CXXConstructExpr::ConstructionKind)Record.readInt());
+
+  unsigned NumArgs = Record.readInt();
+  assert((NumArgs == E->getNumArgs()) && "Wrong NumArgs!");
+
+  E->CXXConstructExprBits.Elidable = Record.readInt();
+  E->CXXConstructExprBits.HadMultipleCandidates = Record.readInt();
+  E->CXXConstructExprBits.ListInitialization = Record.readInt();
+  E->CXXConstructExprBits.StdInitListInitialization = Record.readInt();
+  E->CXXConstructExprBits.ZeroInitialization = Record.readInt();
+  E->CXXConstructExprBits.ConstructionKind = Record.readInt();
+  E->CXXConstructExprBits.Loc = ReadSourceLocation();
+  E->Constructor = ReadDeclAs();
   E->ParenOrBraceRange = ReadSourceRange();
+
+  for (unsigned I = 0; I != NumArgs; ++I)
+    E->setArg(I, Record.readSubExpr());
 }
 
 void ASTStmtReader::VisitCXXInheritedCtorInitExpr(CXXInheritedCtorInitExpr *E) {
@@ -1379,7 +1381,7 @@ void ASTStmtReader::VisitCXXInheritedCtorInitExpr(CXXInheritedCtorInitExpr *E) {
 
 void ASTStmtReader::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) {
   VisitCXXConstructExpr(E);
-  E->Type = GetTypeSourceInfo();
+  E->TSI = GetTypeSourceInfo();
 }
 
 void ASTStmtReader::VisitLambdaExpr(LambdaExpr *E) {
@@ -3082,7 +3084,9 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
       break;
 
     case EXPR_CXX_CONSTRUCT:
-      S = new (Context) CXXConstructExpr(Empty);
+      S = CXXConstructExpr::CreateEmpty(
+          Context,
+          /* NumArgs=*/Record[ASTStmtReader::NumExprFields]);
       break;
 
     case EXPR_CXX_INHERITED_CTOR_INIT:
@@ -3090,7 +3094,9 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
       break;
 
     case EXPR_CXX_TEMPORARY_OBJECT:
-      S = new (Context) CXXTemporaryObjectExpr(Empty);
+      S = CXXTemporaryObjectExpr::CreateEmpty(
+          Context,
+          /* NumArgs=*/Record[ASTStmtReader::NumExprFields]);
       break;
 
     case EXPR_CXX_STATIC_CAST:
diff --git a/lib/Serialization/ASTWriterStmt.cpp b/lib/Serialization/ASTWriterStmt.cpp
index c7527aa38b..f0e1e10b5e 100644
--- a/lib/Serialization/ASTWriterStmt.cpp
+++ b/lib/Serialization/ASTWriterStmt.cpp
@@ -1315,18 +1315,21 @@ void ASTStmtWriter::VisitCXXMemberCallExpr(CXXMemberCallExpr *E) {
 
 void ASTStmtWriter::VisitCXXConstructExpr(CXXConstructExpr *E) {
   VisitExpr(E);
+
   Record.push_back(E->getNumArgs());
-  for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
-    Record.AddStmt(E->getArg(I));
-  Record.AddDeclRef(E->getConstructor());
-  Record.AddSourceLocation(E->getLocation());
   Record.push_back(E->isElidable());
   Record.push_back(E->hadMultipleCandidates());
   Record.push_back(E->isListInitialization());
   Record.push_back(E->isStdInitListInitialization());
   Record.push_back(E->requiresZeroInitialization());
   Record.push_back(E->getConstructionKind()); // FIXME: stable encoding
+  Record.AddSourceLocation(E->getLocation());
+  Record.AddDeclRef(E->getConstructor());
   Record.AddSourceRange(E->getParenOrBraceRange());
+
+  for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
+    Record.AddStmt(E->getArg(I));
+
   Code = serialization::EXPR_CXX_CONSTRUCT;
 }
 
-- 
cgit v1.2.3


From a6eb16ed631365f3bbadd0450ab52746c151794d Mon Sep 17 00:00:00 2001
From: Aaron Ballman 
Date: Sat, 22 Dec 2018 15:31:57 +0000
Subject: Improving this fatal diagnostic to help checker developers figure out
 what's actually gone wrong when they hit it.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350004 91177308-0d34-0410-b5e6-96231b3b80d8
---
 utils/TableGen/ClangSACheckersEmitter.cpp | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/utils/TableGen/ClangSACheckersEmitter.cpp b/utils/TableGen/ClangSACheckersEmitter.cpp
index 453dfe564b..57850a4387 100644
--- a/utils/TableGen/ClangSACheckersEmitter.cpp
+++ b/utils/TableGen/ClangSACheckersEmitter.cpp
@@ -58,7 +58,7 @@ static std::string getStringValue(const Record &R, StringRef field) {
 }
 
 // Calculates the integer value representing the BitsInit object
-static inline uint64_t getValueFromBitsInit(const BitsInit *B) {
+static inline uint64_t getValueFromBitsInit(const BitsInit *B, const Record &R) {
   assert(B->getNumBits() <= sizeof(uint64_t) * 8 && "BitInits' too long!");
 
   uint64_t Value = 0;
@@ -67,7 +67,8 @@ static inline uint64_t getValueFromBitsInit(const BitsInit *B) {
     if (Bit)
       Value |= uint64_t(Bit->getValue()) << i;
     else
-      PrintFatalError("Invalid bits");
+      PrintFatalError(R.getLoc(),
+                      "missing Documentation for " + getCheckerFullName(&R));
   }
   return Value;
 }
@@ -75,7 +76,7 @@ static inline uint64_t getValueFromBitsInit(const BitsInit *B) {
 static std::string getCheckerDocs(const Record &R) {
   StringRef LandingPage;
   if (BitsInit *BI = R.getValueAsBitsInit("Documentation")) {
-    uint64_t V = getValueFromBitsInit(BI);
+    uint64_t V = getValueFromBitsInit(BI, R);
     if (V == 1)
       LandingPage = "available_checks.html";
     else if (V == 2)
-- 
cgit v1.2.3


From 40c9a5ffc3ed1bdc20243851b7a0d6eeecf28d5a Mon Sep 17 00:00:00 2001
From: Michal Gorny 
Date: Sun, 23 Dec 2018 15:07:19 +0000
Subject: [Distro] Support detecting Gentoo

Add support for distinguishing plain Gentoo distribution, and a unit
test for it.  This is going to be used to introduce distro-specific
customizations in the driver code; most notably, it is going to be used
to disable -faddrsig.

Differential Revision: https://reviews.llvm.org/D56024

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350027 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/Driver/Distro.h   |  5 +++++
 lib/Driver/Distro.cpp           |  3 +++
 unittests/Driver/DistroTest.cpp | 36 ++++++++++++++++++++++++++++++++++++
 3 files changed, 44 insertions(+)

diff --git a/include/clang/Driver/Distro.h b/include/clang/Driver/Distro.h
index 3cf7048298..5651ebb6d4 100644
--- a/include/clang/Driver/Distro.h
+++ b/include/clang/Driver/Distro.h
@@ -39,6 +39,7 @@ public:
     RHEL6,
     RHEL7,
     Fedora,
+    Gentoo,
     OpenSUSE,
     UbuntuHardy,
     UbuntuIntrepid,
@@ -123,6 +124,10 @@ public:
     return DistroVal == AlpineLinux;
   }
 
+  bool IsGentoo() const {
+    return DistroVal == Gentoo;
+  }
+
   /// @}
 };
 
diff --git a/lib/Driver/Distro.cpp b/lib/Driver/Distro.cpp
index eb537c87e7..396d0bee56 100644
--- a/lib/Driver/Distro.cpp
+++ b/lib/Driver/Distro.cpp
@@ -138,6 +138,9 @@ static Distro::DistroType DetectDistro(llvm::vfs::FileSystem &VFS) {
   if (VFS.exists("/etc/arch-release"))
     return Distro::ArchLinux;
 
+  if (VFS.exists("/etc/gentoo-release"))
+    return Distro::Gentoo;
+
   return Distro::UnknownDistro;
 }
 
diff --git a/unittests/Driver/DistroTest.cpp b/unittests/Driver/DistroTest.cpp
index 5a23392e8c..bc1863c429 100644
--- a/unittests/Driver/DistroTest.cpp
+++ b/unittests/Driver/DistroTest.cpp
@@ -51,6 +51,7 @@ TEST(DistroTest, DetectUbuntu) {
   ASSERT_FALSE(UbuntuTrusty.IsRedhat());
   ASSERT_FALSE(UbuntuTrusty.IsOpenSUSE());
   ASSERT_FALSE(UbuntuTrusty.IsDebian());
+  ASSERT_FALSE(UbuntuTrusty.IsGentoo());
 
   llvm::vfs::InMemoryFileSystem UbuntuYakketyFileSystem;
   UbuntuYakketyFileSystem.addFile("/etc/debian_version", 0,
@@ -80,6 +81,7 @@ TEST(DistroTest, DetectUbuntu) {
   ASSERT_FALSE(UbuntuYakkety.IsRedhat());
   ASSERT_FALSE(UbuntuYakkety.IsOpenSUSE());
   ASSERT_FALSE(UbuntuYakkety.IsDebian());
+  ASSERT_FALSE(UbuntuYakkety.IsGentoo());
 }
 
 TEST(DistroTest, DetectRedhat) {
@@ -114,6 +116,7 @@ TEST(DistroTest, DetectRedhat) {
   ASSERT_TRUE(Fedora25.IsRedhat());
   ASSERT_FALSE(Fedora25.IsOpenSUSE());
   ASSERT_FALSE(Fedora25.IsDebian());
+  ASSERT_FALSE(Fedora25.IsGentoo());
 
   llvm::vfs::InMemoryFileSystem CentOS7FileSystem;
   CentOS7FileSystem.addFile("/etc/system-release-cpe", 0,
@@ -150,6 +153,7 @@ TEST(DistroTest, DetectRedhat) {
   ASSERT_TRUE(CentOS7.IsRedhat());
   ASSERT_FALSE(CentOS7.IsOpenSUSE());
   ASSERT_FALSE(CentOS7.IsDebian());
+  ASSERT_FALSE(CentOS7.IsGentoo());
 }
 
 TEST(DistroTest, DetectOpenSUSE) {
@@ -177,6 +181,7 @@ TEST(DistroTest, DetectOpenSUSE) {
   ASSERT_FALSE(OpenSUSELeap421.IsRedhat());
   ASSERT_TRUE(OpenSUSELeap421.IsOpenSUSE());
   ASSERT_FALSE(OpenSUSELeap421.IsDebian());
+  ASSERT_FALSE(OpenSUSELeap421.IsGentoo());
 
   llvm::vfs::InMemoryFileSystem OpenSUSE132FileSystem;
   OpenSUSE132FileSystem.addFile("/etc/SuSE-release", 0,
@@ -202,6 +207,7 @@ TEST(DistroTest, DetectOpenSUSE) {
   ASSERT_FALSE(OpenSUSE132.IsRedhat());
   ASSERT_TRUE(OpenSUSE132.IsOpenSUSE());
   ASSERT_FALSE(OpenSUSE132.IsDebian());
+  ASSERT_FALSE(OpenSUSE132.IsGentoo());
 
   llvm::vfs::InMemoryFileSystem SLES10FileSystem;
   SLES10FileSystem.addFile("/etc/SuSE-release", 0,
@@ -218,6 +224,7 @@ TEST(DistroTest, DetectOpenSUSE) {
   ASSERT_FALSE(SLES10.IsRedhat());
   ASSERT_FALSE(SLES10.IsOpenSUSE());
   ASSERT_FALSE(SLES10.IsDebian());
+  ASSERT_FALSE(SLES10.IsGentoo());
 }
 
 TEST(DistroTest, DetectDebian) {
@@ -240,6 +247,7 @@ TEST(DistroTest, DetectDebian) {
   ASSERT_FALSE(DebianJessie.IsRedhat());
   ASSERT_FALSE(DebianJessie.IsOpenSUSE());
   ASSERT_TRUE(DebianJessie.IsDebian());
+  ASSERT_FALSE(DebianJessie.IsGentoo());
 
   llvm::vfs::InMemoryFileSystem DebianStretchSidFileSystem;
   DebianStretchSidFileSystem.addFile("/etc/debian_version", 0,
@@ -258,6 +266,7 @@ TEST(DistroTest, DetectDebian) {
   ASSERT_FALSE(DebianStretchSid.IsRedhat());
   ASSERT_FALSE(DebianStretchSid.IsOpenSUSE());
   ASSERT_TRUE(DebianStretchSid.IsDebian());
+  ASSERT_FALSE(DebianStretchSid.IsGentoo());
 }
 
 TEST(DistroTest, DetectExherbo) {
@@ -279,6 +288,7 @@ TEST(DistroTest, DetectExherbo) {
   ASSERT_FALSE(Exherbo.IsRedhat());
   ASSERT_FALSE(Exherbo.IsOpenSUSE());
   ASSERT_FALSE(Exherbo.IsDebian());
+  ASSERT_FALSE(Exherbo.IsGentoo());
 }
 
 TEST(DistroTest, DetectArchLinux) {
@@ -300,6 +310,32 @@ TEST(DistroTest, DetectArchLinux) {
   ASSERT_FALSE(ArchLinux.IsRedhat());
   ASSERT_FALSE(ArchLinux.IsOpenSUSE());
   ASSERT_FALSE(ArchLinux.IsDebian());
+  ASSERT_FALSE(ArchLinux.IsGentoo());
+}
+
+TEST(DistroTest, DetectGentoo) {
+  llvm::vfs::InMemoryFileSystem GentooFileSystem;
+  GentooFileSystem.addFile(
+      "/etc/gentoo-release", 0,
+      llvm::MemoryBuffer::getMemBuffer("Gentoo Base System release 2.6"));
+  GentooFileSystem.addFile(
+      "/etc/os-release", 0,
+      llvm::MemoryBuffer::getMemBuffer(
+          "NAME=Gentoo\n"
+          "ID=gentoo\n"
+          "PRETTY_NAME=\"Gentoo/Linux\"\n"
+          "ANSI_COLOR=\"1;32\"\n"
+          "HOME_URL=\"https://www.gentoo.org/\"\n"
+          "SUPPORT_URL=\"https://www.gentoo.org/support/\"\n"
+          "BUG_REPORT_URL=\"https://bugs.gentoo.org/\"\n"));
+
+  Distro Gentoo{GentooFileSystem};
+  ASSERT_EQ(Distro(Distro::Gentoo), Gentoo);
+  ASSERT_FALSE(Gentoo.IsUbuntu());
+  ASSERT_FALSE(Gentoo.IsRedhat());
+  ASSERT_FALSE(Gentoo.IsOpenSUSE());
+  ASSERT_FALSE(Gentoo.IsDebian());
+  ASSERT_TRUE(Gentoo.IsGentoo());
 }
 
 } // end anonymous namespace
-- 
cgit v1.2.3


From 3ece3f2fc6c8f80be85e34c99a419e791bce076a Mon Sep 17 00:00:00 2001
From: Michal Gorny 
Date: Sun, 23 Dec 2018 15:07:26 +0000
Subject: [Driver] Disable -faddrsig on Gentoo by default

Gentoo supports combining clang toolchain with GNU binutils, and many
users actually do that.  As -faddrsig is not supported by GNU strip,
this results in a lot of warnings.  Disable it by default and let users
enable it explicitly if they want it; with the intent of reevaluating
when the underlying feature becomes standarized.

See also: https://bugs.gentoo.org/667854

Differential Revision: https://reviews.llvm.org/D56047

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350028 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/Driver/ToolChains/Clang.cpp | 2 ++
 test/Driver/addrsig.c           | 3 +++
 test/lit.cfg.py                 | 3 +++
 3 files changed, 8 insertions(+)

diff --git a/lib/Driver/ToolChains/Clang.cpp b/lib/Driver/ToolChains/Clang.cpp
index ec4fdd2e6d..10487a6d45 100644
--- a/lib/Driver/ToolChains/Clang.cpp
+++ b/lib/Driver/ToolChains/Clang.cpp
@@ -25,6 +25,7 @@
 #include "clang/Basic/LangOptions.h"
 #include "clang/Basic/ObjCRuntime.h"
 #include "clang/Basic/Version.h"
+#include "clang/Driver/Distro.h"
 #include "clang/Driver/DriverDiagnostic.h"
 #include "clang/Driver/Options.h"
 #include "clang/Driver/SanitizerArgs.h"
@@ -5290,6 +5291,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
                     TC.getTriple().isOSBinFormatCOFF()) &&
                       !TC.getTriple().isPS4() &&
                       !TC.getTriple().isOSNetBSD() &&
+                      !Distro(D.getVFS()).IsGentoo() &&
                        TC.useIntegratedAs()))
     CmdArgs.push_back("-faddrsig");
 
diff --git a/test/Driver/addrsig.c b/test/Driver/addrsig.c
index 739dcc35ff..556a908e30 100644
--- a/test/Driver/addrsig.c
+++ b/test/Driver/addrsig.c
@@ -1,3 +1,6 @@
+// Gentoo disables -faddrsig by default
+// XFAIL: gentoo
+
 // RUN: %clang -### -target x86_64-unknown-linux -c %s 2>&1 | FileCheck -check-prefix=ADDRSIG %s
 // RUN: %clang -### -target x86_64-pc-win32 -c %s 2>&1 | FileCheck -check-prefix=ADDRSIG %s
 // RUN: %clang -### -target x86_64-unknown-linux -fno-integrated-as -c %s 2>&1 | FileCheck -check-prefix=NO-ADDRSIG %s
diff --git a/test/lit.cfg.py b/test/lit.cfg.py
index d105f8d7e1..e61b4bb104 100644
--- a/test/lit.cfg.py
+++ b/test/lit.cfg.py
@@ -190,3 +190,6 @@ lit.util.usePlatformSdkOnDarwin(config, lit_config)
 macOSSDKVersion = lit.util.findPlatformSdkVersionOnMacOS(config, lit_config)
 if macOSSDKVersion is not None:
     config.available_features.add('macos-sdk-' + macOSSDKVersion)
+
+if os.path.exists('/etc/gentoo-release'):
+    config.available_features.add('gentoo')
-- 
cgit v1.2.3


From a2651c2716eb81e1183bce4a15b91c056b3a17fe Mon Sep 17 00:00:00 2001
From: George Karpenkov 
Date: Mon, 24 Dec 2018 18:45:18 +0000
Subject: [analyzer] [NFC] Clean up the mess of constructing argument effects
 in RetainCountChecker

Previously, argument effects were stored in a method variable, which was
effectively global.
The global state was reset at each (hopefully) entrance point to the
summary construction,
and every function could modify it.

Differential Revision: https://reviews.llvm.org/D56036

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350057 91177308-0d34-0410-b5e6-96231b3b80d8
---
 .../StaticAnalyzer/Core/RetainSummaryManager.h     |  19 ++-
 lib/StaticAnalyzer/Core/RetainSummaryManager.cpp   | 143 ++++++++++++---------
 2 files changed, 91 insertions(+), 71 deletions(-)

diff --git a/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h b/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
index de16a1781a..9540f01c70 100644
--- a/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
+++ b/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
@@ -508,9 +508,6 @@ class RetainSummaryManager {
   /// AF - A factory for ArgEffects objects.
   ArgEffects::Factory AF;
 
-  /// ScratchArgs - A holding buffer for construct ArgEffects.
-  ArgEffects ScratchArgs;
-
   /// ObjCAllocRetE - Default return effect for methods returning Objective-C
   ///  objects.
   RetEffect ObjCAllocRetE;
@@ -523,10 +520,6 @@ class RetainSummaryManager {
   /// effects.
   llvm::FoldingSet SimpleSummaries;
 
-  /// getArgEffects - Returns a persistent ArgEffects object based on the
-  ///  data in ScratchArgs.
-  ArgEffects getArgEffects();
-
   /// Create an OS object at +1.
   const RetainSummary *getOSSummaryCreateRule(const FunctionDecl *FD);
 
@@ -554,25 +547,30 @@ class RetainSummaryManager {
   const RetainSummary *getPersistentSummary(const RetainSummary &OldSumm);
 
   const RetainSummary *getPersistentSummary(RetEffect RetEff,
+                                            ArgEffects ScratchArgs,
                                             ArgEffect ReceiverEff = DoNothing,
                                             ArgEffect DefaultEff = MayEscape,
                                             ArgEffect ThisEff = DoNothing) {
-    RetainSummary Summ(getArgEffects(), RetEff, DefaultEff, ReceiverEff,
+    RetainSummary Summ(ScratchArgs, RetEff, DefaultEff, ReceiverEff,
                        ThisEff);
     return getPersistentSummary(Summ);
   }
 
   const RetainSummary *getDoNothingSummary() {
-    return getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);
+    return getPersistentSummary(RetEffect::MakeNoRet(),
+                                ArgEffects(AF.getEmptyMap()),
+                                DoNothing, DoNothing);
   }
 
   const RetainSummary *getDefaultSummary() {
     return getPersistentSummary(RetEffect::MakeNoRet(),
+                                ArgEffects(AF.getEmptyMap()),
                                 DoNothing, MayEscape);
   }
 
   const RetainSummary *getPersistentStopSummary() {
     return getPersistentSummary(RetEffect::MakeNoRet(),
+                                ArgEffects(AF.getEmptyMap()),
                                 StopTracking, StopTracking);
   }
 
@@ -649,7 +647,6 @@ class RetainSummaryManager {
   bool applyFunctionParamAnnotationEffect(const ParmVarDecl *pd,
                                         unsigned parm_idx,
                                         const FunctionDecl *FD,
-                                        ArgEffects::Factory &AF,
                                         RetainSummaryTemplate &Template);
 
 public:
@@ -661,7 +658,7 @@ public:
      ARCEnabled(usesARC),
      TrackObjCAndCFObjects(trackObjCAndCFObjects),
      TrackOSObjects(trackOSObjects),
-     AF(BPAlloc), ScratchArgs(AF.getEmptyMap()),
+     AF(BPAlloc),
      ObjCAllocRetE(usesARC ? RetEffect::MakeNotOwned(RetEffect::ObjC)
                                : RetEffect::MakeOwned(RetEffect::ObjC)),
      ObjCInitRetE(usesARC ? RetEffect::MakeNotOwned(RetEffect::ObjC)
diff --git a/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp b/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
index 0187ebaf3a..13955b5e50 100644
--- a/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
+++ b/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
@@ -49,12 +49,6 @@ template  bool RetainSummaryManager::isAttrEnabled() {
   llvm_unreachable("Unexpected attribute passed");
 }
 
-ArgEffects RetainSummaryManager::getArgEffects() {
-  ArgEffects AE = ScratchArgs;
-  ScratchArgs = AF.getEmptyMap();
-  return AE;
-}
-
 const RetainSummary *
 RetainSummaryManager::getPersistentSummary(const RetainSummary &OldSumm) {
   // Unique "simple" summaries -- those without ArgEffects.
@@ -190,11 +184,9 @@ const RetainSummary *RetainSummaryManager::getSummaryForObjCOrCFObject(
     const FunctionType *FT,
     bool &AllowAnnotations) {
 
-  std::string RetTyName = RetTy.getAsString();
+  ArgEffects ScratchArgs(AF.getEmptyMap());
 
-  // FIXME: This should all be refactored into a chain of "summary lookup"
-  //  filters.
-  assert(ScratchArgs.isEmpty());
+  std::string RetTyName = RetTy.getAsString();
   if (FName == "pthread_create" || FName == "pthread_setspecific") {
     // Part of:  and .
     // This will be addressed better with IPA.
@@ -207,10 +199,12 @@ const RetainSummary *RetainSummaryManager::getSummaryForObjCOrCFObject(
   } else if (FName == "CMBufferQueueDequeueAndRetain" ||
              FName == "CMBufferQueueDequeueIfDataReadyAndRetain") {
     // Part of: .
-    return getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF), DoNothing,
+    return getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF),
+                                ScratchArgs,
+                                DoNothing,
                                 DoNothing);
   } else if (FName == "CFPlugInInstanceCreate") {
-    return getPersistentSummary(RetEffect::MakeNoRet());
+    return getPersistentSummary(RetEffect::MakeNoRet(), ScratchArgs);
   } else if (FName == "IORegistryEntrySearchCFProperty" ||
              (RetTyName == "CFMutableDictionaryRef" &&
               (FName == "IOBSDNameMatching" || FName == "IOServiceMatching" ||
@@ -219,21 +213,25 @@ const RetainSummary *RetainSummaryManager::getSummaryForObjCOrCFObject(
                FName == "IOOpenFirmwarePathMatching"))) {
     // Part of . (IOKit)
     // This should be addressed using a API table.
-    return getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF), DoNothing,
-                             DoNothing);
+    return getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF),
+                                ScratchArgs, DoNothing, DoNothing);
   } else if (FName == "IOServiceGetMatchingService" ||
              FName == "IOServiceGetMatchingServices") {
     // FIXES: 
     // This should be addressed using a API table.  This strcmp is also
     // a little gross, but there is no need to super optimize here.
     ScratchArgs = AF.add(ScratchArgs, 1, DecRef);
-    return getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);
+    return getPersistentSummary(RetEffect::MakeNoRet(),
+                                ScratchArgs,
+                                DoNothing, DoNothing);
   } else if (FName == "IOServiceAddNotification" ||
              FName == "IOServiceAddMatchingNotification") {
     // Part of . (IOKit)
     // This should be addressed using a API table.
     ScratchArgs = AF.add(ScratchArgs, 2, DecRef);
-    return getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);
+    return getPersistentSummary(RetEffect::MakeNoRet(),
+                                ScratchArgs,
+                                DoNothing, DoNothing);
   } else if (FName == "CVPixelBufferCreateWithBytes") {
     // FIXES: 
     // Eventually this can be improved by recognizing that the pixel
@@ -242,15 +240,17 @@ const RetainSummary *RetainSummaryManager::getSummaryForObjCOrCFObject(
     // FIXME: This function has an out parameter that returns an
     // allocated object.
     ScratchArgs = AF.add(ScratchArgs, 7, StopTracking);
-    return getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);
+    return getPersistentSummary(RetEffect::MakeNoRet(),
+                                ScratchArgs,
+                                DoNothing, DoNothing);
   } else if (FName == "CGBitmapContextCreateWithData") {
     // FIXES: 
     // Eventually this can be improved by recognizing that 'releaseInfo'
     // passed to CGBitmapContextCreateWithData is released via
     // a callback and doing full IPA to make sure this is done correctly.
     ScratchArgs = AF.add(ScratchArgs, 8, StopTracking);
-    return getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF), DoNothing,
-                             DoNothing);
+    return getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF),
+                                ScratchArgs, DoNothing, DoNothing);
   } else if (FName == "CVPixelBufferCreateWithPlanarBytes") {
     // FIXES: 
     // Eventually this can be improved by recognizing that the pixel
@@ -258,7 +258,9 @@ const RetainSummary *RetainSummaryManager::getSummaryForObjCOrCFObject(
     // via a callback and doing full IPA to make sure this is done
     // correctly.
     ScratchArgs = AF.add(ScratchArgs, 12, StopTracking);
-    return getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);
+    return getPersistentSummary(RetEffect::MakeNoRet(),
+                                ScratchArgs,
+                                DoNothing, DoNothing);
   } else if (FName == "VTCompressionSessionEncodeFrame") {
     // The context argument passed to VTCompressionSessionEncodeFrame()
     // is passed to the callback specified when creating the session
@@ -266,7 +268,9 @@ const RetainSummary *RetainSummaryManager::getSummaryForObjCOrCFObject(
     // To account for this possibility, conservatively stop tracking
     // the context.
     ScratchArgs = AF.add(ScratchArgs, 5, StopTracking);
-    return getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);
+    return getPersistentSummary(RetEffect::MakeNoRet(),
+                                ScratchArgs,
+                                DoNothing, DoNothing);
   } else if (FName == "dispatch_set_context" ||
              FName == "xpc_connection_set_context") {
     //  - The analyzer currently doesn't have
@@ -276,7 +280,9 @@ const RetainSummary *RetainSummaryManager::getSummaryForObjCOrCFObject(
     // FIXME: this hack should possibly go away once we can handle
     // libdispatch and XPC finalizers.
     ScratchArgs = AF.add(ScratchArgs, 1, StopTracking);
-    return getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);
+    return getPersistentSummary(RetEffect::MakeNoRet(),
+                                ScratchArgs,
+                                DoNothing, DoNothing);
   } else if (FName.startswith("NSLog")) {
     return getDoNothingSummary();
   } else if (FName.startswith("NS") &&
@@ -285,7 +291,8 @@ const RetainSummary *RetainSummaryManager::getSummaryForObjCOrCFObject(
     // be deallocated by NSMapRemove. (radar://11152419)
     ScratchArgs = AF.add(ScratchArgs, 1, StopTracking);
     ScratchArgs = AF.add(ScratchArgs, 2, StopTracking);
-    return getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);
+    return getPersistentSummary(RetEffect::MakeNoRet(),
+                                ScratchArgs, DoNothing, DoNothing);
   }
 
   if (RetTy->isPointerType()) {
@@ -368,7 +375,8 @@ const RetainSummary *RetainSummaryManager::getSummaryForObjCOrCFObject(
                         ? MayEscape
                         : DoNothing;
 
-      return getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, E);
+      return getPersistentSummary(RetEffect::MakeNoRet(), ScratchArgs,
+                                  DoNothing, E);
     }
   }
 
@@ -405,7 +413,9 @@ RetainSummaryManager::generateSummary(const FunctionDecl *FD,
 
   if (const auto *MD = dyn_cast(FD))
     if (!(TrackOSObjects && isOSObjectRelated(MD)))
-      return getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, StopTracking,
+      return getPersistentSummary(RetEffect::MakeNoRet(),
+                                  ArgEffects(AF.getEmptyMap()),
+                                  DoNothing, StopTracking,
                                   DoNothing);
 
   return getDefaultSummary();
@@ -473,6 +483,7 @@ void RetainSummaryManager::updateSummaryForCall(const RetainSummary *&S,
     ArgEffect DefEffect =
       getStopTrackingHardEquivalent(S->getDefaultArgEffect());
 
+    ArgEffects ScratchArgs(AF.getEmptyMap());
     ArgEffects CustomArgEffects = S->getArgEffects();
     for (ArgEffects::iterator I = CustomArgEffects.begin(),
                               E = CustomArgEffects.end();
@@ -499,7 +510,7 @@ void RetainSummaryManager::updateSummaryForCall(const RetainSummary *&S,
       }
     }
 
-    S = getPersistentSummary(RE, RecEffect, DefEffect);
+    S = getPersistentSummary(RE, ScratchArgs, RecEffect, DefEffect);
   }
 
   // Special case '[super init];' and '[self init];'
@@ -639,14 +650,15 @@ const RetainSummary *
 RetainSummaryManager::getUnarySummary(const FunctionType* FT,
                                       UnaryFuncKind func) {
 
+  // Unary functions have no arg effects by definition.
+  ArgEffects ScratchArgs(AF.getEmptyMap());
+
   // Sanity check that this is *really* a unary function.  This can
   // happen if people do weird things.
   const FunctionProtoType* FTP = dyn_cast(FT);
   if (!FTP || FTP->getNumParams() != 1)
     return getPersistentStopSummary();
 
-  assert (ScratchArgs.isEmpty());
-
   ArgEffect Effect;
   switch (func) {
   case cfretain: Effect = IncRef; break;
@@ -656,12 +668,15 @@ RetainSummaryManager::getUnarySummary(const FunctionType* FT,
   }
 
   ScratchArgs = AF.add(ScratchArgs, 0, Effect);
-  return getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);
+  return getPersistentSummary(RetEffect::MakeNoRet(),
+                              ScratchArgs,
+                              DoNothing, DoNothing);
 }
 
 const RetainSummary *
 RetainSummaryManager::getOSSummaryRetainRule(const FunctionDecl *FD) {
   return getPersistentSummary(RetEffect::MakeNoRet(),
+                              AF.getEmptyMap(),
                               /*ReceiverEff=*/DoNothing,
                               /*DefaultEff=*/DoNothing,
                               /*ThisEff=*/IncRef);
@@ -670,6 +685,7 @@ RetainSummaryManager::getOSSummaryRetainRule(const FunctionDecl *FD) {
 const RetainSummary *
 RetainSummaryManager::getOSSummaryReleaseRule(const FunctionDecl *FD) {
   return getPersistentSummary(RetEffect::MakeNoRet(),
+                              AF.getEmptyMap(),
                               /*ReceiverEff=*/DoNothing,
                               /*DefaultEff=*/DoNothing,
                               /*ThisEff=*/DecRef);
@@ -678,6 +694,7 @@ RetainSummaryManager::getOSSummaryReleaseRule(const FunctionDecl *FD) {
 const RetainSummary *
 RetainSummaryManager::getOSSummaryFreeRule(const FunctionDecl *FD) {
   return getPersistentSummary(RetEffect::MakeNoRet(),
+                              AF.getEmptyMap(),
                               /*ReceiverEff=*/DoNothing,
                               /*DefaultEff=*/DoNothing,
                               /*ThisEff=*/Dealloc);
@@ -685,25 +702,26 @@ RetainSummaryManager::getOSSummaryFreeRule(const FunctionDecl *FD) {
 
 const RetainSummary *
 RetainSummaryManager::getOSSummaryCreateRule(const FunctionDecl *FD) {
-  return getPersistentSummary(RetEffect::MakeOwned(RetEffect::OS));
+  return getPersistentSummary(RetEffect::MakeOwned(RetEffect::OS),
+                              AF.getEmptyMap());
 }
 
 const RetainSummary *
 RetainSummaryManager::getOSSummaryGetRule(const FunctionDecl *FD) {
-  return getPersistentSummary(RetEffect::MakeNotOwned(RetEffect::OS));
+  return getPersistentSummary(RetEffect::MakeNotOwned(RetEffect::OS),
+                              AF.getEmptyMap());
 }
 
 const RetainSummary *
 RetainSummaryManager::getCFSummaryCreateRule(const FunctionDecl *FD) {
-  assert (ScratchArgs.isEmpty());
-
-  return getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF));
+  return getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF),
+                              ArgEffects(AF.getEmptyMap()));
 }
 
 const RetainSummary *
 RetainSummaryManager::getCFSummaryGetRule(const FunctionDecl *FD) {
-  assert (ScratchArgs.isEmpty());
   return getPersistentSummary(RetEffect::MakeNotOwned(RetEffect::CF),
+                              ArgEffects(AF.getEmptyMap()),
                               DoNothing, DoNothing);
 }
 
@@ -753,11 +771,9 @@ RetainSummaryManager::getRetEffectFromAnnotations(QualType RetTy,
   return None;
 }
 
-bool RetainSummaryManager::applyFunctionParamAnnotationEffect(const ParmVarDecl *pd,
-                                        unsigned parm_idx,
-                                        const FunctionDecl *FD,
-                                        ArgEffects::Factory &AF,
-                                        RetainSummaryTemplate &Template) {
+bool RetainSummaryManager::applyFunctionParamAnnotationEffect(
+    const ParmVarDecl *pd, unsigned parm_idx, const FunctionDecl *FD,
+    RetainSummaryTemplate &Template) {
   if (hasEnabledAttr(pd)) {
     Template->addArg(AF, parm_idx, DecRefMsg);
     return true;
@@ -787,7 +803,7 @@ bool RetainSummaryManager::applyFunctionParamAnnotationEffect(const ParmVarDecl
     if (const auto *MD = dyn_cast(FD)) {
       for (const auto *OD : MD->overridden_methods()) {
         const ParmVarDecl *OP = OD->parameters()[parm_idx];
-        if (applyFunctionParamAnnotationEffect(OP, parm_idx, OD, AF, Template))
+        if (applyFunctionParamAnnotationEffect(OP, parm_idx, OD, Template))
           return true;
       }
     }
@@ -810,7 +826,7 @@ RetainSummaryManager::updateSummaryFromAnnotations(const RetainSummary *&Summ,
   for (auto pi = FD->param_begin(),
          pe = FD->param_end(); pi != pe; ++pi, ++parm_idx) {
     const ParmVarDecl *pd = *pi;
-    applyFunctionParamAnnotationEffect(pd, parm_idx, FD, AF, Template);
+    applyFunctionParamAnnotationEffect(pd, parm_idx, FD, Template);
   }
 
   QualType RetTy = FD->getReturnType();
@@ -950,15 +966,17 @@ RetainSummaryManager::getStandardMethodSummary(const ObjCMethodDecl *MD,
     }
   }
 
-  if (ScratchArgs.isEmpty() && ReceiverEff == DoNothing &&
+  if (ReceiverEff == DoNothing &&
       ResultEff.getKind() == RetEffect::NoRet)
     return getDefaultSummary();
 
-  return getPersistentSummary(ResultEff, ReceiverEff, MayEscape);
+  return getPersistentSummary(ResultEff, ArgEffects(AF.getEmptyMap()),
+                              ReceiverEff, MayEscape);
 }
 
 const RetainSummary *RetainSummaryManager::getInstanceMethodSummary(
-    const ObjCMethodCall &Msg, QualType ReceiverType) {
+    const ObjCMethodCall &Msg,
+    QualType ReceiverType) {
   const ObjCInterfaceDecl *ReceiverClass = nullptr;
 
   // We do better tracking of the type of the object than the core ExprEngine.
@@ -985,7 +1003,8 @@ const RetainSummary *RetainSummaryManager::getInstanceMethodSummary(
 }
 
 const RetainSummary *
-RetainSummaryManager::getMethodSummary(Selector S, const ObjCInterfaceDecl *ID,
+RetainSummaryManager::getMethodSummary(Selector S,
+                                       const ObjCInterfaceDecl *ID,
                                        const ObjCMethodDecl *MD, QualType RetTy,
                                        ObjCMethodSummariesTy &CachedSummaries) {
 
@@ -1010,25 +1029,29 @@ RetainSummaryManager::getMethodSummary(Selector S, const ObjCInterfaceDecl *ID,
 }
 
 void RetainSummaryManager::InitializeClassMethodSummaries() {
-  assert(ScratchArgs.isEmpty());
+  ArgEffects ScratchArgs = AF.getEmptyMap();
+
   // Create the [NSAssertionHandler currentHander] summary.
   addClassMethSummary("NSAssertionHandler", "currentHandler",
-                getPersistentSummary(RetEffect::MakeNotOwned(RetEffect::ObjC)));
+                getPersistentSummary(RetEffect::MakeNotOwned(RetEffect::ObjC),
+                                     ScratchArgs));
 
   // Create the [NSAutoreleasePool addObject:] summary.
   ScratchArgs = AF.add(ScratchArgs, 0, Autorelease);
   addClassMethSummary("NSAutoreleasePool", "addObject",
                       getPersistentSummary(RetEffect::MakeNoRet(),
+                                           ScratchArgs,
                                            DoNothing, Autorelease));
 }
 
 void RetainSummaryManager::InitializeMethodSummaries() {
 
-  assert (ScratchArgs.isEmpty());
-
+  ArgEffects ScratchArgs = AF.getEmptyMap();
   // Create the "init" selector.  It just acts as a pass-through for the
   // receiver.
-  const RetainSummary *InitSumm = getPersistentSummary(ObjCInitRetE, DecRefMsg);
+  const RetainSummary *InitSumm = getPersistentSummary(ObjCInitRetE,
+                                                       ScratchArgs,
+                                                       DecRefMsg);
   addNSObjectMethSummary(GetNullarySelector("init", Ctx), InitSumm);
 
   // awakeAfterUsingCoder: behaves basically like an 'init' method.  It
@@ -1037,25 +1060,26 @@ void RetainSummaryManager::InitializeMethodSummaries() {
                          InitSumm);
 
   // The next methods are allocators.
-  const RetainSummary *AllocSumm = getPersistentSummary(ObjCAllocRetE);
+  const RetainSummary *AllocSumm = getPersistentSummary(ObjCAllocRetE,
+                                                        ScratchArgs);
   const RetainSummary *CFAllocSumm =
-    getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF));
+    getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF), ScratchArgs);
 
   // Create the "retain" selector.
   RetEffect NoRet = RetEffect::MakeNoRet();
-  const RetainSummary *Summ = getPersistentSummary(NoRet, IncRefMsg);
+  const RetainSummary *Summ = getPersistentSummary(NoRet, ScratchArgs, IncRefMsg);
   addNSObjectMethSummary(GetNullarySelector("retain", Ctx), Summ);
 
   // Create the "release" selector.
-  Summ = getPersistentSummary(NoRet, DecRefMsg);
+  Summ = getPersistentSummary(NoRet, ScratchArgs, DecRefMsg);
   addNSObjectMethSummary(GetNullarySelector("release", Ctx), Summ);
 
   // Create the -dealloc summary.
-  Summ = getPersistentSummary(NoRet, Dealloc);
+  Summ = getPersistentSummary(NoRet, ScratchArgs, Dealloc);
   addNSObjectMethSummary(GetNullarySelector("dealloc", Ctx), Summ);
 
   // Create the "autorelease" selector.
-  Summ = getPersistentSummary(NoRet, Autorelease);
+  Summ = getPersistentSummary(NoRet, ScratchArgs, Autorelease);
   addNSObjectMethSummary(GetNullarySelector("autorelease", Ctx), Summ);
 
   // For NSWindow, allocated objects are (initially) self-owned.
@@ -1064,9 +1088,8 @@ void RetainSummaryManager::InitializeMethodSummaries() {
   //  Thus, we need to track an NSWindow's display status.
   //  This is tracked in .
   //  See also http://llvm.org/bugs/show_bug.cgi?id=3714.
-  const RetainSummary *NoTrackYet = getPersistentSummary(RetEffect::MakeNoRet(),
-                                                   StopTracking,
-                                                   StopTracking);
+  const RetainSummary *NoTrackYet = getPersistentSummary(
+      RetEffect::MakeNoRet(), ScratchArgs, StopTracking, StopTracking);
 
   addClassMethSummary("NSWindow", "alloc", NoTrackYet);
 
-- 
cgit v1.2.3


From 7e3a9ce433bf3ef170d4cd6ae85828407393c20a Mon Sep 17 00:00:00 2001
From: Nico Weber 
Date: Wed, 26 Dec 2018 16:06:26 +0000
Subject: Pass a concrete triple for two OpenMP tests that depend on TLS

Not all %itanium_abi_triple values support TLS. Makes
OpenMP/declare_reduction_codegen.cpp, OpenMP/parallel_copyin_codegen.cpp for
%itanium_abi_triples without TLS support.

Alternatively we could pass -fnoopenmp-use-tls and tweak some of the CHECK
lines, but this seems a bit simpler.

Fixes PR40156.

Differential Revision: https://reviews.llvm.org/D56086


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350067 91177308-0d34-0410-b5e6-96231b3b80d8
---
 test/OpenMP/declare_reduction_codegen.cpp | 12 +++++-----
 test/OpenMP/parallel_copyin_codegen.cpp   | 40 +++++++++++++++----------------
 2 files changed, 26 insertions(+), 26 deletions(-)

diff --git a/test/OpenMP/declare_reduction_codegen.cpp b/test/OpenMP/declare_reduction_codegen.cpp
index 90dbd47214..d0e355cac0 100644
--- a/test/OpenMP/declare_reduction_codegen.cpp
+++ b/test/OpenMP/declare_reduction_codegen.cpp
@@ -1,10 +1,10 @@
-// RUN: %clang_cc1 -verify -fopenmp -x c++ -emit-llvm %s -triple %itanium_abi_triple -fexceptions -fcxx-exceptions -o - -femit-all-decls -disable-llvm-passes | FileCheck %s
-// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple %itanium_abi_triple -fexceptions -fcxx-exceptions -emit-pch -o %t %s -femit-all-decls -disable-llvm-passes
-// RUN: %clang_cc1 -fopenmp -x c++ -triple %itanium_abi_triple -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - -femit-all-decls -disable-llvm-passes | FileCheck --check-prefix=CHECK-LOAD %s
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -emit-llvm %s -triple x86_64-linux -fexceptions -fcxx-exceptions -o - -femit-all-decls -disable-llvm-passes | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple x86_64-linux -fexceptions -fcxx-exceptions -emit-pch -o %t %s -femit-all-decls -disable-llvm-passes
+// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-linux -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - -femit-all-decls -disable-llvm-passes | FileCheck --check-prefix=CHECK-LOAD %s
 
-// RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -emit-llvm %s -triple %itanium_abi_triple -fexceptions -fcxx-exceptions -o - -femit-all-decls -disable-llvm-passes | FileCheck --check-prefix SIMD-ONLY0 %s
-// RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -triple %itanium_abi_triple -fexceptions -fcxx-exceptions -emit-pch -o %t %s -femit-all-decls -disable-llvm-passes
-// RUN: %clang_cc1 -fopenmp-simd -x c++ -triple %itanium_abi_triple -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - -femit-all-decls -disable-llvm-passes | FileCheck --check-prefix SIMD-ONLY0 %s
+// RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -emit-llvm %s -triple x86_64-linux -fexceptions -fcxx-exceptions -o - -femit-all-decls -disable-llvm-passes | FileCheck --check-prefix SIMD-ONLY0 %s
+// RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -triple x86_64-linux -fexceptions -fcxx-exceptions -emit-pch -o %t %s -femit-all-decls -disable-llvm-passes
+// RUN: %clang_cc1 -fopenmp-simd -x c++ -triple x86_64-linux -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - -femit-all-decls -disable-llvm-passes | FileCheck --check-prefix SIMD-ONLY0 %s
 // SIMD-ONLY0-NOT: {{__kmpc|__tgt}}
 // expected-no-diagnostics
 
diff --git a/test/OpenMP/parallel_copyin_codegen.cpp b/test/OpenMP/parallel_copyin_codegen.cpp
index 5c2a5b5c41..5e056b9ccb 100644
--- a/test/OpenMP/parallel_copyin_codegen.cpp
+++ b/test/OpenMP/parallel_copyin_codegen.cpp
@@ -1,30 +1,30 @@
-// RUN: %clang_cc1 -verify -fopenmp -fnoopenmp-use-tls -x c++ -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck %s
-// RUN: %clang_cc1 -fopenmp -fnoopenmp-use-tls -x c++ -std=c++11 -triple %itanium_abi_triple -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -fnoopenmp-use-tls -x c++ -triple %itanium_abi_triple -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
-// RUN: %clang_cc1 -verify -fopenmp -fnoopenmp-use-tls -x c++ -std=c++11 -DLAMBDA -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck -check-prefix=LAMBDA %s
-// RUN: %clang_cc1 -verify -fopenmp -fnoopenmp-use-tls -x c++ -fblocks -DBLOCKS -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck -check-prefix=BLOCKS %s
+// RUN: %clang_cc1 -verify -fopenmp -fnoopenmp-use-tls -x c++ -triple x86_64-linux -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -fnoopenmp-use-tls -x c++ -std=c++11 -triple x86_64-linux -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fnoopenmp-use-tls -x c++ -triple x86_64-linux -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -verify -fopenmp -fnoopenmp-use-tls -x c++ -std=c++11 -DLAMBDA -triple x86_64-linux -emit-llvm %s -o - | FileCheck -check-prefix=LAMBDA %s
+// RUN: %clang_cc1 -verify -fopenmp -fnoopenmp-use-tls -x c++ -fblocks -DBLOCKS -triple x86_64-linux -emit-llvm %s -o - | FileCheck -check-prefix=BLOCKS %s
 // RUN: %clang_cc1 -verify -fopenmp -fnoopenmp-use-tls -x c++ -std=c++11 -DARRAY -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=ARRAY %s
 
-// RUN: %clang_cc1 -verify -fopenmp-simd -fnoopenmp-use-tls -x c++ -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY0 %s
-// RUN: %clang_cc1 -fopenmp-simd -fnoopenmp-use-tls -x c++ -std=c++11 -triple %itanium_abi_triple -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp-simd -fnoopenmp-use-tls -x c++ -triple %itanium_abi_triple -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY0 %s
-// RUN: %clang_cc1 -verify -fopenmp-simd -fnoopenmp-use-tls -x c++ -std=c++11 -DLAMBDA -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY0 %s
-// RUN: %clang_cc1 -verify -fopenmp-simd -fnoopenmp-use-tls -x c++ -fblocks -DBLOCKS -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY0 %s
+// RUN: %clang_cc1 -verify -fopenmp-simd -fnoopenmp-use-tls -x c++ -triple x86_64-linux -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY0 %s
+// RUN: %clang_cc1 -fopenmp-simd -fnoopenmp-use-tls -x c++ -std=c++11 -triple x86_64-linux -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp-simd -fnoopenmp-use-tls -x c++ -triple x86_64-linux -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY0 %s
+// RUN: %clang_cc1 -verify -fopenmp-simd -fnoopenmp-use-tls -x c++ -std=c++11 -DLAMBDA -triple x86_64-linux -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY0 %s
+// RUN: %clang_cc1 -verify -fopenmp-simd -fnoopenmp-use-tls -x c++ -fblocks -DBLOCKS -triple x86_64-linux -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY0 %s
 // RUN: %clang_cc1 -verify -fopenmp-simd -fnoopenmp-use-tls -x c++ -std=c++11 -DARRAY -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY0 %s
 // SIMD-ONLY0-NOT: {{__kmpc|__tgt}}
 
-// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck %s -check-prefix=TLS-CHECK
-// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple %itanium_abi_triple -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -x c++ -triple %itanium_abi_triple -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -check-prefix=TLS-CHECK
-// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -DLAMBDA -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck -check-prefix=TLS-LAMBDA %s
-// RUN: %clang_cc1 -verify -fopenmp -x c++ -fblocks -DBLOCKS -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck -check-prefix=TLS-BLOCKS %s
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-linux -emit-llvm %s -o - | FileCheck %s -check-prefix=TLS-CHECK
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple x86_64-linux -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-linux -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -check-prefix=TLS-CHECK
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -DLAMBDA -triple x86_64-linux -emit-llvm %s -o - | FileCheck -check-prefix=TLS-LAMBDA %s
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -fblocks -DBLOCKS -triple x86_64-linux -emit-llvm %s -o - | FileCheck -check-prefix=TLS-BLOCKS %s
 // RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -DARRAY -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck -check-prefix=TLS-ARRAY %s
 
-// RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY1 %s
-// RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -triple %itanium_abi_triple -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp-simd -x c++ -triple %itanium_abi_triple -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY1 %s
-// RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -std=c++11 -DLAMBDA -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY1 %s
-// RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -fblocks -DBLOCKS -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY1 %s
+// RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -triple x86_64-linux -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY1 %s
+// RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -triple x86_64-linux -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp-simd -x c++ -triple x86_64-linux -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY1 %s
+// RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -std=c++11 -DLAMBDA -triple x86_64-linux -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY1 %s
+// RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -fblocks -DBLOCKS -triple x86_64-linux -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY1 %s
 // RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -std=c++11 -DARRAY -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY1 %s
 // SIMD-ONLY1-NOT: {{__kmpc|__tgt}}
 // expected-no-diagnostics
-- 
cgit v1.2.3


From f9e2ca2ab17197472bbde11fe6cc6115c2a5dc09 Mon Sep 17 00:00:00 2001
From: Reid Kleckner 
Date: Wed, 26 Dec 2018 17:44:40 +0000
Subject: Ignore ConstantExpr in IgnoreParens

Summary:
This moves it up from IgnoreParenImpCasts to IgnoreParens, so that more
helpers ignore it. For most clients, this ensures that these helpers
behave the same with and without C++17 enabled, which is what appears to
introduce these new expression nodes.

Fixes PR39881

Reviewers: void, rsmith

Subscribers: cfe-commits

Differential Revision: https://reviews.llvm.org/D55853

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350068 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/AST/Expr.cpp                        | 8 ++++----
 test/CodeGenCXX/mangle-ms-templates.cpp | 2 ++
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 11191c4682..6aa1199add 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -2596,6 +2596,10 @@ Expr* Expr::IgnoreParens() {
         continue;
       }
     }
+    if (ConstantExpr *CE = dyn_cast(E)) {
+      E = CE->getSubExpr();
+      continue;
+    }
     return E;
   }
 }
@@ -2718,10 +2722,6 @@ Expr *Expr::IgnoreParenImpCasts() {
       E = NTTP->getReplacement();
       continue;
     }
-    if (ConstantExpr *CE = dyn_cast(E)) {
-      E = CE->getSubExpr();
-      continue;
-    }
     return E;
   }
 }
diff --git a/test/CodeGenCXX/mangle-ms-templates.cpp b/test/CodeGenCXX/mangle-ms-templates.cpp
index 6055465537..469a23afc8 100644
--- a/test/CodeGenCXX/mangle-ms-templates.cpp
+++ b/test/CodeGenCXX/mangle-ms-templates.cpp
@@ -1,5 +1,7 @@
 // RUN: %clang_cc1 -std=c++11 -fms-compatibility-version=19 -emit-llvm %s -o - -fms-extensions -fdelayed-template-parsing -triple=i386-pc-win32 | FileCheck %s
 // RUN: %clang_cc1 -std=c++11 -fms-compatibility-version=19 -emit-llvm %s -o - -fms-extensions -fdelayed-template-parsing -triple=x86_64-pc-win32 | FileCheck -check-prefix X64 %s
+// RUN: %clang_cc1 -std=c++17 -fms-compatibility-version=19 -emit-llvm %s -o - -fms-extensions -fdelayed-template-parsing -triple=i386-pc-win32 | FileCheck %s
+// RUN: %clang_cc1 -std=c++17 -fms-compatibility-version=19 -emit-llvm %s -o - -fms-extensions -fdelayed-template-parsing -triple=x86_64-pc-win32 | FileCheck -check-prefix X64 %s
 
 template
 class Class {
-- 
cgit v1.2.3


From 12391ef6d41a0afb89a515d47c360578f651f5e3 Mon Sep 17 00:00:00 2001
From: Reid Kleckner 
Date: Wed, 26 Dec 2018 20:07:52 +0000
Subject: [MS] Mangle return adjusting thunks with the public access specifier

MSVC does this, so we should too.

Fixes PR40138

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350071 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/AST/MicrosoftMangle.cpp                    | 18 ++++++++++------
 test/CodeGenCXX/mangle-ms-thunks-covariant.cpp | 29 ++++++++++++++++++++++++++
 2 files changed, 41 insertions(+), 6 deletions(-)
 create mode 100644 test/CodeGenCXX/mangle-ms-thunks-covariant.cpp

diff --git a/lib/AST/MicrosoftMangle.cpp b/lib/AST/MicrosoftMangle.cpp
index caa3af598d..92e9679e49 100644
--- a/lib/AST/MicrosoftMangle.cpp
+++ b/lib/AST/MicrosoftMangle.cpp
@@ -2939,14 +2939,14 @@ void MicrosoftMangleContextImpl::mangleCXXName(const NamedDecl *D,
 //      ::= 
 //    ::=  
 //                          
-static void mangleThunkThisAdjustment(const CXXMethodDecl *MD,
+static void mangleThunkThisAdjustment(AccessSpecifier AS,
                                       const ThisAdjustment &Adjustment,
                                       MicrosoftCXXNameMangler &Mangler,
                                       raw_ostream &Out) {
   if (!Adjustment.Virtual.isEmpty()) {
     Out << '$';
     char AccessSpec;
-    switch (MD->getAccess()) {
+    switch (AS) {
     case AS_none:
       llvm_unreachable("Unsupported access specifier");
     case AS_private:
@@ -2974,7 +2974,7 @@ static void mangleThunkThisAdjustment(const CXXMethodDecl *MD,
       Mangler.mangleNumber(-static_cast(Adjustment.NonVirtual));
     }
   } else if (Adjustment.NonVirtual != 0) {
-    switch (MD->getAccess()) {
+    switch (AS) {
     case AS_none:
       llvm_unreachable("Unsupported access specifier");
     case AS_private:
@@ -2988,7 +2988,7 @@ static void mangleThunkThisAdjustment(const CXXMethodDecl *MD,
     }
     Mangler.mangleNumber(-static_cast(Adjustment.NonVirtual));
   } else {
-    switch (MD->getAccess()) {
+    switch (AS) {
     case AS_none:
       llvm_unreachable("Unsupported access specifier");
     case AS_private:
@@ -3019,7 +3019,13 @@ void MicrosoftMangleContextImpl::mangleThunk(const CXXMethodDecl *MD,
   MicrosoftCXXNameMangler Mangler(*this, MHO);
   Mangler.getStream() << '?';
   Mangler.mangleName(MD);
-  mangleThunkThisAdjustment(MD, Thunk.This, Mangler, MHO);
+
+  // Usually the thunk uses the access specifier of the new method, but if this
+  // is a covariant return thunk, then MSVC always uses the public access
+  // specifier, and we do the same.
+  AccessSpecifier AS = Thunk.Return.isEmpty() ? MD->getAccess() : AS_public;
+  mangleThunkThisAdjustment(AS, Thunk.This, Mangler, MHO);
+
   if (!Thunk.Return.isEmpty())
     assert(Thunk.Method != nullptr &&
            "Thunk info should hold the overridee decl");
@@ -3040,7 +3046,7 @@ void MicrosoftMangleContextImpl::mangleCXXDtorThunk(
   MicrosoftCXXNameMangler Mangler(*this, MHO, DD, Type);
   Mangler.getStream() << "??_E";
   Mangler.mangleName(DD->getParent());
-  mangleThunkThisAdjustment(DD, Adjustment, Mangler, MHO);
+  mangleThunkThisAdjustment(DD->getAccess(), Adjustment, Mangler, MHO);
   Mangler.mangleFunctionType(DD->getType()->castAs(), DD);
 }
 
diff --git a/test/CodeGenCXX/mangle-ms-thunks-covariant.cpp b/test/CodeGenCXX/mangle-ms-thunks-covariant.cpp
new file mode 100644
index 0000000000..47b1a38ffe
--- /dev/null
+++ b/test/CodeGenCXX/mangle-ms-thunks-covariant.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -fno-rtti-data -std=c++11 -fms-extensions -emit-llvm %s -o - -triple=x86_64-pc-win32 -fms-compatibility-version=19.00 | FileCheck %s --check-prefix=CHECK
+
+namespace t1 {
+struct A {
+public:
+  virtual ~A();
+  virtual A *f();
+};
+struct B {
+public:
+  virtual ~B();
+
+private:
+  virtual B *f();
+};
+struct C : A, B {
+  virtual ~C();
+
+protected:
+  virtual C *f();
+};
+C c;
+}
+// Main external C::f impl:
+// CHECK-DAG: "?f@C@t1@@MEAAPEAU12@XZ"
+// New slot in C's vftable for B, returns C* directly:
+// CHECK-DAG: "?f@C@t1@@O7EAAPEAU12@XZ"
+// Return-adjusting thunk in C's vftable for B:
+// CHECK-DAG: "?f@C@t1@@W7EAAPEAUB@2@XZ"
-- 
cgit v1.2.3


From e2e4a2f49fa200f42a380979c29a04a87605b688 Mon Sep 17 00:00:00 2001
From: Reid Kleckner 
Date: Wed, 26 Dec 2018 21:04:08 +0000
Subject: [clang-cl] Treat inputs as C++ with /E, like MSVC

midl invokes the compiler on .idl files with /E. Before this change, we
would treat unrecognized inputs as object files. Now we pre-process to
stdout as expected. I checked that MSVC defines __cplusplus when invoked
this way, so treating the input as C++ seems like the right thing to do.

After this change, I was able to run midl like this with clang-cl:
$ midl -cpp_cmd clang-cl.exe foo.idl

Things worked for the example IDL file in the Microsoft documentation,
but beyond that, I don't know if this will work well.

Fixes PR40140

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350072 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/Driver/Driver.cpp  |  5 ++++-
 test/Driver/cl-idl.cpp | 18 ++++++++++++++++++
 2 files changed, 22 insertions(+), 1 deletion(-)
 create mode 100644 test/Driver/cl-idl.cpp

diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp
index dfc0faac7b..725bf273ed 100644
--- a/lib/Driver/Driver.cpp
+++ b/lib/Driver/Driver.cpp
@@ -2057,7 +2057,8 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args,
           Ty = types::TY_C;
         } else {
           // Otherwise lookup by extension.
-          // Fallback is C if invoked as C preprocessor or Object otherwise.
+          // Fallback is C if invoked as C preprocessor, C++ if invoked with
+          // clang-cl /E, or Object otherwise.
           // We use a host hook here because Darwin at least has its own
           // idea of what .s is.
           if (const char *Ext = strrchr(Value, '.'))
@@ -2066,6 +2067,8 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args,
           if (Ty == types::TY_INVALID) {
             if (CCCIsCPP())
               Ty = types::TY_C;
+            else if (IsCLMode() && Args.hasArgNoClaim(options::OPT_E))
+              Ty = types::TY_CXX;
             else
               Ty = types::TY_Object;
           }
diff --git a/test/Driver/cl-idl.cpp b/test/Driver/cl-idl.cpp
new file mode 100644
index 0000000000..7843ab3133
--- /dev/null
+++ b/test/Driver/cl-idl.cpp
@@ -0,0 +1,18 @@
+// Note: %s must be preceded by --, otherwise it may be interpreted as a
+// command-line option, e.g. on Mac where %s is commonly under /Users.
+
+// Test that 'clang-cl /E' treats inputs as C++ if the extension is
+// unrecognized. midl relies on this. See PR40140.
+
+// Use a plain .cpp extension first.
+// RUN: %clang_cl /E -- %s | FileCheck %s
+
+// Copy to use .idl as the extension.
+// RUN: cp %s %t.idl
+// RUN: %clang_cl /E -- %t.idl | FileCheck %s
+
+#ifdef __cplusplus
+struct IsCPlusPlus {};
+#endif
+
+// CHECK: struct IsCPlusPlus {};
-- 
cgit v1.2.3


From 27ff8dcc77fd7c9f1bcf181b25eaa7d68777fdfe Mon Sep 17 00:00:00 2001
From: David Chisnall 
Date: Thu, 27 Dec 2018 14:44:36 +0000
Subject: [objc-gnustep] Fix a copy-and-paste error.

We were emitting the null class symbol in the wrong section, which meant
that programs that contained no Objective-C classes would fail to link.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350092 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/CodeGen/CGObjCGNU.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/CodeGen/CGObjCGNU.cpp b/lib/CodeGen/CGObjCGNU.cpp
index cb140bf9e0..534650b110 100644
--- a/lib/CodeGen/CGObjCGNU.cpp
+++ b/lib/CodeGen/CGObjCGNU.cpp
@@ -1547,7 +1547,7 @@ class CGObjCGNUstep2 : public CGObjCGNUstep {
             sectionName());
       if (!EmittedClass) {
         createNullGlobal(".objc_null_cls_init_ref", NULLPtr,
-            sectionName());
+            sectionName());
         createNullGlobal(".objc_null_class_ref", { NULLPtr, NULLPtr },
             sectionName());
       }
-- 
cgit v1.2.3


From 9c3471a784eb5339b2dd9749626faf50659b4d3c Mon Sep 17 00:00:00 2001
From: Alexey Bataev 
Date: Fri, 28 Dec 2018 17:27:32 +0000
Subject: [OPENMP]Fix processing of the clauses on target combined directives.

For constants with the predefined data-sharing clauses we may had
troubles with the target combined directives. It may cause compiler
crash in some corner cases.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350127 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/Sema/SemaOpenMP.cpp              | 11 +++++++----
 test/OpenMP/target_teams_codegen.cpp | 21 +++++++++++++++++++++
 2 files changed, 28 insertions(+), 4 deletions(-)

diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp
index 24e9ef4aaa..b4eb466476 100644
--- a/lib/Sema/SemaOpenMP.cpp
+++ b/lib/Sema/SemaOpenMP.cpp
@@ -1179,10 +1179,13 @@ const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D,
         RD->hasMutableFields())) {
     // Variables with const-qualified type having no mutable member may be
     // listed in a firstprivate clause, even if they are static data members.
-    DSAVarData DVarTemp =
-        hasDSA(D, [](OpenMPClauseKind C) { return C == OMPC_firstprivate; },
-               MatchesAlways, FromParent);
-    if (DVarTemp.CKind == OMPC_firstprivate && DVarTemp.RefExpr)
+    DSAVarData DVarTemp = hasInnermostDSA(
+        D,
+        [](OpenMPClauseKind C) {
+          return C == OMPC_firstprivate || C == OMPC_shared;
+        },
+        MatchesAlways, FromParent);
+    if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr)
       return DVarTemp;
 
     DVar.CKind = OMPC_shared;
diff --git a/test/OpenMP/target_teams_codegen.cpp b/test/OpenMP/target_teams_codegen.cpp
index bd6eb8cb1c..0448933111 100644
--- a/test/OpenMP/target_teams_codegen.cpp
+++ b/test/OpenMP/target_teams_codegen.cpp
@@ -74,6 +74,8 @@
 // CHECK-DAG: @{{.*}} = weak constant i8 0
 // CHECK-DAG: @{{.*}} = weak constant i8 0
 // CHECK-DAG: @{{.*}} = weak constant i8 0
+// CHECK-DAG: @{{.*}} = weak constant i8 0
+// CHECK-DAG: @{{.*}} = weak constant i8 0
 
 // TCHECK: @{{.+}} = weak constant [[ENTTY]]
 // TCHECK: @{{.+}} = weak constant [[ENTTY]]
@@ -82,6 +84,8 @@
 // TCHECK: @{{.+}} = weak constant [[ENTTY]]
 // TCHECK: @{{.+}} = weak constant [[ENTTY]]
 // TCHECK: @{{.+}} = weak constant [[ENTTY]]
+// TCHECK: @{{.+}} = weak constant [[ENTTY]]
+// TCHECK: @{{.+}} = weak constant [[ENTTY]]
 // TCHECK-NOT: @{{.+}} = weak constant [[ENTTY]]
 
 // Check if offloading descriptor is created.
@@ -836,4 +840,21 @@ int bar(int n){
 // CHECK:       define internal {{.*}}void [[OMP_OUTLINED7]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, [10 x i32]* {{.+}})
 // To reduce complexity, we're only going as far as validating the signature of the outlined parallel function.
 
+void foo1() {
+  const int n = 0;
+  #pragma omp target teams shared(n)
+  #pragma omp parallel firstprivate(n)
+  (void)n;
+}
+void foo() {
+  const int n = 0;
+  #pragma omp target teams firstprivate(n)
+  #pragma omp parallel shared(n)
+  (void)n;
+}
+
+// define {{.*}}void @__omp_offloading_{{.*}}foo1{{.*}}_l841(i[[SZ]] %{{.+}})
+// define internal void {{@.+}}(i32* {{.+}}, i32* {{.+}}, i[[SZ]] %{{.+}})
+// define {{.*}}void @__omp_offloading_{{.*}}foo1{{.*}}_l847(i[[SZ]] %{{.+}})
+// define internal void {{@.+}}(i32* {{.+}}, i32* {{.+}}, i32* dereferenceable{{.+}})
 #endif
-- 
cgit v1.2.3


From bd0803d06773d50b43983536115a664590980800 Mon Sep 17 00:00:00 2001
From: David Chisnall 
Date: Fri, 28 Dec 2018 17:44:54 +0000
Subject: [objc-gnustep2] Fix a bug in category generation.

We were not emitting a protocol definition while generating the category
method list.  This was fine in most cases, because something else in the
library typically referenced any given protocol, but it caused linker
failures if the category was the only reference to a given protocol.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350130 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/CodeGen/CGObjCGNU.cpp                     | 26 ++++++++++++++++++++------
 test/CodeGenObjC/gnustep2-category-protocol.m | 25 +++++++++++++++++++++++++
 2 files changed, 45 insertions(+), 6 deletions(-)
 create mode 100644 test/CodeGenObjC/gnustep2-category-protocol.m

diff --git a/lib/CodeGen/CGObjCGNU.cpp b/lib/CodeGen/CGObjCGNU.cpp
index 534650b110..548bd6b3fd 100644
--- a/lib/CodeGen/CGObjCGNU.cpp
+++ b/lib/CodeGen/CGObjCGNU.cpp
@@ -277,6 +277,8 @@ protected:
     Fields.addInt(Int8Ty, 0);
   }
 
+  virtual llvm::Constant *GenerateCategoryProtocolList(const
+      ObjCCategoryDecl *OCD);
   virtual ConstantArrayBuilder PushPropertyListHeader(ConstantStructBuilder &Fields,
       int count) {
       // int count;
@@ -1164,6 +1166,15 @@ class CGObjCGNUstep2 : public CGObjCGNUstep {
     return MethodList.finishAndCreateGlobal(".objc_protocol_method_list",
                                             CGM.getPointerAlign());
   }
+  llvm::Constant *GenerateCategoryProtocolList(const ObjCCategoryDecl *OCD)
+    override {
+    SmallVector Protocols;
+    for (const auto *PI : OCD->getReferencedProtocols())
+      Protocols.push_back(
+          llvm::ConstantExpr::getBitCast(GenerateProtocolRef(PI),
+            ProtocolPtrTy));
+    return GenerateProtocolList(Protocols);
+  }
 
   llvm::Value *LookupIMPSuper(CodeGenFunction &CGF, Address ObjCSuper,
                               llvm::Value *cmd, MessageSendInfo &MSI) override {
@@ -3099,18 +3110,21 @@ llvm::Constant *CGObjCGNU::MakeBitField(ArrayRef bits) {
   return ptr;
 }
 
+llvm::Constant *CGObjCGNU::GenerateCategoryProtocolList(const
+    ObjCCategoryDecl *OCD) {
+  SmallVector Protocols;
+  for (const auto *PD : OCD->getReferencedProtocols())
+    Protocols.push_back(PD->getNameAsString());
+  return GenerateProtocolList(Protocols);
+}
+
 void CGObjCGNU::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
   const ObjCInterfaceDecl *Class = OCD->getClassInterface();
   std::string ClassName = Class->getNameAsString();
   std::string CategoryName = OCD->getNameAsString();
 
   // Collect the names of referenced protocols
-  SmallVector Protocols;
   const ObjCCategoryDecl *CatDecl = OCD->getCategoryDecl();
-  const ObjCList &Protos = CatDecl->getReferencedProtocols();
-  for (ObjCList::iterator I = Protos.begin(),
-       E = Protos.end(); I != E; ++I)
-    Protocols.push_back((*I)->getNameAsString());
 
   ConstantInitBuilder Builder(CGM);
   auto Elements = Builder.beginStruct();
@@ -3132,7 +3146,7 @@ void CGObjCGNU::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
           GenerateMethodList(ClassName, CategoryName, ClassMethods, true),
           PtrTy);
   // Protocol list
-  Elements.addBitCast(GenerateProtocolList(Protocols), PtrTy);
+  Elements.addBitCast(GenerateCategoryProtocolList(CatDecl), PtrTy);
   if (isRuntime(ObjCRuntime::GNUstep, 2)) {
     const ObjCCategoryDecl *Category =
       Class->FindCategoryDeclaration(OCD->getIdentifier());
diff --git a/test/CodeGenObjC/gnustep2-category-protocol.m b/test/CodeGenObjC/gnustep2-category-protocol.m
new file mode 100644
index 0000000000..6463474507
--- /dev/null
+++ b/test/CodeGenObjC/gnustep2-category-protocol.m
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-freebsd -S -emit-llvm -fobjc-runtime=gnustep-2.0 -o - %s | FileCheck %s
+
+// Regression test.  We weren't emitting definitions for protocols used in
+// categories, causing linker errors when the category was the only reference
+// to a protocol in a binary.
+
+// CHECK: @._OBJC_PROTOCOL_Y = global 
+// CHEKC-SAME: section "__objc_protocols", comdat, align 8
+
+
+@interface X
+{
+id isa;
+}
+@end
+@implementation X
+@end
+
+@protocol Y @end
+
+@interface X (y) 
+@end
+@implementation X (y) @end
+
+
-- 
cgit v1.2.3


From 293aad519f86c5e3b2961093080f380393f4782a Mon Sep 17 00:00:00 2001
From: Richard Trieu 
Date: Sat, 29 Dec 2018 02:02:30 +0000
Subject: Add vtable anchor to classes.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350143 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/AST/DeclCXX.h      | 1 +
 include/clang/AST/DeclTemplate.h | 1 +
 include/clang/Lex/ModuleMap.h    | 2 ++
 lib/AST/DeclCXX.cpp              | 2 ++
 lib/AST/DeclTemplate.cpp         | 2 ++
 lib/Lex/ModuleMap.cpp            | 2 ++
 6 files changed, 10 insertions(+)

diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index 58e01bf0f0..8452806701 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -3918,6 +3918,7 @@ class MSPropertyDecl : public DeclaratorDecl {
       : DeclaratorDecl(MSProperty, DC, L, N, T, TInfo, StartL),
         GetterId(Getter), SetterId(Setter) {}
 
+  void anchor() override;
 public:
   friend class ASTDeclReader;
 
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h
index 9e01c4950d..f6e3d8f300 100644
--- a/include/clang/AST/DeclTemplate.h
+++ b/include/clang/AST/DeclTemplate.h
@@ -751,6 +751,7 @@ class RedeclarableTemplateDecl : public TemplateDecl,
     return getMostRecentDecl();
   }
 
+  void anchor() override;
 protected:
   template  struct SpecEntryTraits {
     using DeclType = EntryType;
diff --git a/include/clang/Lex/ModuleMap.h b/include/clang/Lex/ModuleMap.h
index 4daa1dd817..a38c8d7819 100644
--- a/include/clang/Lex/ModuleMap.h
+++ b/include/clang/Lex/ModuleMap.h
@@ -45,6 +45,8 @@ class SourceManager;
 /// A mechanism to observe the actions of the module map parser as it
 /// reads module map files.
 class ModuleMapCallbacks {
+  virtual void anchor();
+
 public:
   virtual ~ModuleMapCallbacks() = default;
 
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index 33f159417b..2893fca859 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -2910,6 +2910,8 @@ void DecompositionDecl::printName(llvm::raw_ostream &os) const {
   os << ']';
 }
 
+void MSPropertyDecl::anchor() {}
+
 MSPropertyDecl *MSPropertyDecl::Create(ASTContext &C, DeclContext *DC,
                                        SourceLocation L, DeclarationName N,
                                        QualType T, TypeSourceInfo *TInfo,
diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp
index 04e1803281..76f29dac16 100644
--- a/lib/AST/DeclTemplate.cpp
+++ b/lib/AST/DeclTemplate.cpp
@@ -149,6 +149,8 @@ void *allocateDefaultArgStorageChain(const ASTContext &C) {
 // RedeclarableTemplateDecl Implementation
 //===----------------------------------------------------------------------===//
 
+void RedeclarableTemplateDecl::anchor() {}
+
 RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() const {
   if (Common)
     return Common;
diff --git a/lib/Lex/ModuleMap.cpp b/lib/Lex/ModuleMap.cpp
index 13d2b728f5..cff950b703 100644
--- a/lib/Lex/ModuleMap.cpp
+++ b/lib/Lex/ModuleMap.cpp
@@ -54,6 +54,8 @@
 
 using namespace clang;
 
+void ModuleMapCallbacks::anchor() {}
+
 void ModuleMap::resolveLinkAsDependencies(Module *Mod) {
   auto PendingLinkAs = PendingLinkAsModule.find(Mod->Name);
   if (PendingLinkAs != PendingLinkAsModule.end()) {
-- 
cgit v1.2.3


From 30abdb44ab9b2503694a58bb409e8a8ab898cc62 Mon Sep 17 00:00:00 2001
From: Akira Hatanaka 
Date: Sat, 29 Dec 2018 17:28:30 +0000
Subject: [CodeGen] Replace '@' characters in block descriptors' symbol names
 with '\1'.

'@' can't be used in block descriptors' symbol names since it is
reserved on ELF platforms as a separator between symbol names and symbol
versions.

See the discussion here: https://reviews.llvm.org/D50783.

Differential Revision: https://reviews.llvm.org/D54539

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350157 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/CodeGen/CGBlocks.cpp                     |  3 +++
 test/CodeGenObjC/block-desc-str.m            | 14 ++++++++++++++
 test/CodeGenObjCXX/block-nested-in-lambda.mm |  4 ++--
 3 files changed, 19 insertions(+), 2 deletions(-)
 create mode 100644 test/CodeGenObjC/block-desc-str.m

diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp
index 06b794fc8d..239a805913 100644
--- a/lib/CodeGen/CGBlocks.cpp
+++ b/lib/CodeGen/CGBlocks.cpp
@@ -161,6 +161,9 @@ static std::string getBlockDescriptorName(const CGBlockInfo &BlockInfo,
 
   std::string TypeAtEncoding =
       CGM.getContext().getObjCEncodingForBlock(BlockInfo.getBlockExpr());
+  /// Replace occurrences of '@' with '\1'. '@' is reserved on ELF platforms as
+  /// a separator between symbol name and symbol version.
+  std::replace(TypeAtEncoding.begin(), TypeAtEncoding.end(), '@', '\1');
   Name += "e" + llvm::to_string(TypeAtEncoding.size()) + "_" + TypeAtEncoding;
   Name += "l" + CGM.getObjCRuntime().getRCBlockLayoutStr(CGM, BlockInfo);
   return Name;
diff --git a/test/CodeGenObjC/block-desc-str.m b/test/CodeGenObjC/block-desc-str.m
new file mode 100644
index 0000000000..44d2f21433
--- /dev/null
+++ b/test/CodeGenObjC/block-desc-str.m
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-freebsd -emit-llvm -fobjc-runtime=gnustep-1.7 -fblocks -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -emit-llvm -fobjc-runtime=gcc -fblocks -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple=x86_64-apple-darwin10 -emit-llvm -fblocks -o - %s | FileCheck %s
+
+// Test that descriptor symbol names don't include '@'.
+
+// CHECK: @[[STR:.*]] = private unnamed_addr constant [6 x i8] c"v8@?0\00"
+// CHECK: @"__block_descriptor_40_8_32o_e5_v8\01?0l" = linkonce_odr hidden unnamed_addr constant { i64, i64, i8*, i8*, i8*, {{.*}} } { i64 0, i64 40, i8* bitcast ({{.*}} to i8*), i8* bitcast ({{.*}} to i8*), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @[[STR]], i32 0, i32 0), {{.*}} }, align 8
+
+typedef void (^BlockTy)(void);
+
+void test(id a) {
+  BlockTy b = ^{ (void)a; };
+}
diff --git a/test/CodeGenObjCXX/block-nested-in-lambda.mm b/test/CodeGenObjCXX/block-nested-in-lambda.mm
index 4122d89e8f..be1ad8117c 100644
--- a/test/CodeGenObjCXX/block-nested-in-lambda.mm
+++ b/test/CodeGenObjCXX/block-nested-in-lambda.mm
@@ -35,7 +35,7 @@ void use(id);
 // CHECK-LABEL: define void @_ZN18CaptureByReference5test0Ev(
 // CHECK-LABEL: define internal void @"_ZZN18CaptureByReference5test0EvENK3$_1clEv"(
 // CHECK: %[[BLOCK_DESCRIPTOR:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8** }>, <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8** }>* %{{.*}}, i32 0, i32 4
-// CHECK: store %[[STRUCT_BLOCK_DESCRIPTOR]]* bitcast ({ i64, i64, i8*, i64 }* @"__block_descriptor_40_e5_v8@?0ls32l8" to %[[STRUCT_BLOCK_DESCRIPTOR]]*), %[[STRUCT_BLOCK_DESCRIPTOR]]** %[[BLOCK_DESCRIPTOR]], align 8
+// CHECK: store %[[STRUCT_BLOCK_DESCRIPTOR]]* bitcast ({ i64, i64, i8*, i64 }* @"__block_descriptor_40_e5_v8\01?0ls32l8" to %[[STRUCT_BLOCK_DESCRIPTOR]]*), %[[STRUCT_BLOCK_DESCRIPTOR]]** %[[BLOCK_DESCRIPTOR]], align 8
 
 void test0() {
   id a = getObj();
@@ -48,7 +48,7 @@ void test0() {
 // CHECK-LABEL: define void @_ZN18CaptureByReference5test1Ev(
 // CHECK-LABEL: define internal void @"_ZZN18CaptureByReference5test1EvENK3$_2clEv"(
 // CHECK: %[[BLOCK_DESCRIPTOR:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8*, i8*, i8** }>, <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8*, i8*, i8** }>* %{{.*}}, i32 0, i32 4
-// CHECK: store %[[STRUCT_BLOCK_DESCRIPTOR]]* bitcast ({ i64, i64, i8*, i8*, i8*, i64 }* @"__block_descriptor_56_8_32s40s_e5_v8@?0l" to %[[STRUCT_BLOCK_DESCRIPTOR]]*), %[[STRUCT_BLOCK_DESCRIPTOR]]** %[[BLOCK_DESCRIPTOR]], align 8
+// CHECK: store %[[STRUCT_BLOCK_DESCRIPTOR]]* bitcast ({ i64, i64, i8*, i8*, i8*, i64 }* @"__block_descriptor_56_8_32s40s_e5_v8\01?0l" to %[[STRUCT_BLOCK_DESCRIPTOR]]*), %[[STRUCT_BLOCK_DESCRIPTOR]]** %[[BLOCK_DESCRIPTOR]], align 8
 
 // CHECK-LABEL: define linkonce_odr hidden void @__copy_helper_block_8_32s40s(
 // CHECK-NOT: call void @llvm.objc.storeStrong(
-- 
cgit v1.2.3


From 8af75eb70aabcf11cf4f7ffd69ac0ebb5f1bd046 Mon Sep 17 00:00:00 2001
From: Mike Spertus 
Date: Sun, 30 Dec 2018 20:22:37 +0000
Subject: DeclAccessPair visualizer should be expandable

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350167 91177308-0d34-0410-b5e6-96231b3b80d8
---
 utils/ClangVisualizers/clang.natvis | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/utils/ClangVisualizers/clang.natvis b/utils/ClangVisualizers/clang.natvis
index b59b62a7e2..3bcf7d6103 100644
--- a/utils/ClangVisualizers/clang.natvis
+++ b/utils/ClangVisualizers/clang.natvis
@@ -553,6 +553,10 @@ For later versions of Visual Studio, no setup is required-->
     b
     {*(clang::NamedDecl *)(Ptr&~Mask)}
     {*this,view(access)} {*this,view(decl)}
+    
+      (clang::AccessSpecifier)(Ptr&Mask),en
+      *(clang::NamedDecl *)(Ptr&~Mask)
+    
   
   
     {Decls}
-- 
cgit v1.2.3


From 4abdc59b18598c47000cdc8560a0dd575bc8197d Mon Sep 17 00:00:00 2001
From: Mike Spertus 
Date: Mon, 31 Dec 2018 23:01:34 +0000
Subject: Make clearer which clang::type subclasses have visualizers

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350182 91177308-0d34-0410-b5e6-96231b3b80d8
---
 utils/ClangVisualizers/clang.natvis | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/utils/ClangVisualizers/clang.natvis b/utils/ClangVisualizers/clang.natvis
index 3bcf7d6103..7ddcb5db5f 100644
--- a/utils/ClangVisualizers/clang.natvis
+++ b/utils/ClangVisualizers/clang.natvis
@@ -38,7 +38,7 @@ For later versions of Visual Studio, no setup is required-->
     {*(clang::PackExpansionType *)this}
     {*(clang::LocInfoType *)this}
     {*this,view(poly)}
-    {*this,view(cmn)} 
+    No visualizer yet for {(clang::Type::TypeClass)TypeBits.TC,en}Type 
     {*this,view(cmn)}  {{{*this,view(poly)}}}
     
       (clang::Type::TypeClass)TypeBits.TC
-- 
cgit v1.2.3


From dce246b32a243c7fa6e7182815806882fe00a5a3 Mon Sep 17 00:00:00 2001
From: Sylvestre Ledru 
Date: Tue, 1 Jan 2019 12:32:08 +0000
Subject: clang-format-diff: add an example with hg

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350191 91177308-0d34-0410-b5e6-96231b3b80d8
---
 docs/ClangFormat.rst | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/docs/ClangFormat.rst b/docs/ClangFormat.rst
index e9c236735b..f2228c5750 100644
--- a/docs/ClangFormat.rst
+++ b/docs/ClangFormat.rst
@@ -200,6 +200,12 @@ So to reformat all the lines in the latest :program:`git` commit, just do:
 
   git diff -U0 --no-color HEAD^ | clang-format-diff.py -i -p1
 
+With Mercurial/:program:`hg`:
+
+.. code-block:: console
+
+  hg diff -U0 --color=never | clang-format-diff.py -i -p1
+
 In an SVN client, you can do:
 
 .. code-block:: console
-- 
cgit v1.2.3


From 6cda55ec841c34fa8c4490d8e8a3f013f7779e16 Mon Sep 17 00:00:00 2001
From: Sylvestre Ledru 
Date: Tue, 1 Jan 2019 12:51:14 +0000
Subject: Fix some typos in the clang doc. Fixed with: $ codespell -w
 ClangFormatStyleOptions.rst Toolchain.rst LanguageExtensions.rst
 ClangCommandLineReference.rst

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350192 91177308-0d34-0410-b5e6-96231b3b80d8
---
 docs/ClangCommandLineReference.rst | 2 +-
 docs/ClangFormatStyleOptions.rst   | 2 +-
 docs/LanguageExtensions.rst        | 2 +-
 docs/Toolchain.rst                 | 6 +++---
 4 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/docs/ClangCommandLineReference.rst b/docs/ClangCommandLineReference.rst
index 61abd05e0c..e852c3e387 100644
--- a/docs/ClangCommandLineReference.rst
+++ b/docs/ClangCommandLineReference.rst
@@ -158,7 +158,7 @@ Compile CUDA code for host only.  Has no effect on non-CUDA compilations.
 
 .. option:: --cuda-include-ptx=, --no-cuda-include-ptx=
 
-Include PTX for the follwing GPU architecture (e.g. sm\_35) or 'all'. May be specified more than once.
+Include PTX for the following GPU architecture (e.g. sm\_35) or 'all'. May be specified more than once.
 
 .. option:: --cuda-noopt-device-debug, --no-cuda-noopt-device-debug
 
diff --git a/docs/ClangFormatStyleOptions.rst b/docs/ClangFormatStyleOptions.rst
index c9f4c4589a..054d5c32c6 100644
--- a/docs/ClangFormatStyleOptions.rst
+++ b/docs/ClangFormatStyleOptions.rst
@@ -1398,7 +1398,7 @@ the configuration (without a prefix: ``Auto``).
 **JavaImportGroups** (``std::vector``)
   A vector of prefixes ordered by the desired groups for Java imports.
 
-  Each group is seperated by a newline. Static imports will also follow the
+  Each group is separated by a newline. Static imports will also follow the
   same grouping convention above all non-static imports. One group's prefix
   can be a subset of another - the longest prefix is always matched. Within
   a group, the imports are ordered lexicographically.
diff --git a/docs/LanguageExtensions.rst b/docs/LanguageExtensions.rst
index 7d878150de..c800a96e6d 100644
--- a/docs/LanguageExtensions.rst
+++ b/docs/LanguageExtensions.rst
@@ -2725,7 +2725,7 @@ same namespace. For instance:
 Without the namespaces on the macros, ``other_function`` will be annotated with
 ``[[noreturn]]`` instead of ``__attribute__((unavailable))``. This may seem like
 a contrived example, but its very possible for this kind of situation to appear
-in real code if the pragmas are spread out accross a large file.
+in real code if the pragmas are spread out across a large file.
 
 Subject Match Rules
 -------------------
diff --git a/docs/Toolchain.rst b/docs/Toolchain.rst
index 0da20eb046..3540708a38 100644
--- a/docs/Toolchain.rst
+++ b/docs/Toolchain.rst
@@ -100,14 +100,14 @@ currently-supported languages are:
 
 In each case, GCC will be invoked to compile the input.
 
-Assember
---------
+Assembler
+---------
 
 Clang can either use LLVM's integrated assembler or an external system-specific
 tool (for instance, the GNU Assembler on GNU OSes) to produce machine code from
 assembly.
 By default, Clang uses LLVM's integrated assembler on all targets where it is
-supported. If you wish to use the system assember instead, use the
+supported. If you wish to use the system assembler instead, use the
 ``-fno-integrated-as`` option.
 
 Linker
-- 
cgit v1.2.3


From ebdcbe69deb63001169cdedab652f4e7c01c02cf Mon Sep 17 00:00:00 2001
From: Petr Hosek 
Date: Wed, 2 Jan 2019 05:11:57 +0000
Subject: [CMake][Fuchsia] Include check-lld in the list of bootstrap targets

This allows running lld tests when doing 2-stage toolchain build.

Differential Revision: https://reviews.llvm.org/D56181

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350202 91177308-0d34-0410-b5e6-96231b3b80d8
---
 cmake/caches/Fuchsia.cmake | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/cmake/caches/Fuchsia.cmake b/cmake/caches/Fuchsia.cmake
index e711f501a7..cc3baa294d 100644
--- a/cmake/caches/Fuchsia.cmake
+++ b/cmake/caches/Fuchsia.cmake
@@ -82,14 +82,17 @@ set(CLANG_BOOTSTRAP_TARGETS
   check-all
   check-llvm
   check-clang
+  check-lld
   llvm-config
   test-suite
   test-depends
   llvm-test-depends
   clang-test-depends
+  lld-test-depends
   distribution
   install-distribution
   install-distribution-stripped
+  install-distribution-toolchain
   clang CACHE STRING "")
 
 get_cmake_property(variableNames VARIABLES)
-- 
cgit v1.2.3


From 2e2fb522c7a62757682e17dd1ead78294d6251c4 Mon Sep 17 00:00:00 2001
From: Pete Cooper 
Date: Wed, 2 Jan 2019 17:25:30 +0000
Subject: Only convert objc messages to alloc to objc_alloc if the receiver is
 a class.

r348687 converted [Foo alloc] to objc_alloc(Foo).  However the objc runtime method only takes a Class, not an arbitrary pointer.

This makes sure we are messaging a class before we convert these messages.

rdar://problem/46943703

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350224 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/CodeGen/CGObjC.cpp                               |  9 ++++++---
 test/CodeGenObjC/convert-messages-to-runtime-calls.m | 17 ++++++++++++++++-
 2 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp
index 8d24b15f76..9c66ff0e8f 100644
--- a/lib/CodeGen/CGObjC.cpp
+++ b/lib/CodeGen/CGObjC.cpp
@@ -370,7 +370,8 @@ static Optional
 tryGenerateSpecializedMessageSend(CodeGenFunction &CGF, QualType ResultType,
                                   llvm::Value *Receiver,
                                   const CallArgList& Args, Selector Sel,
-                                  const ObjCMethodDecl *method) {
+                                  const ObjCMethodDecl *method,
+                                  bool isClassMessage) {
   auto &CGM = CGF.CGM;
   if (!CGM.getCodeGenOpts().ObjCConvertMessagesToRuntimeCalls)
     return None;
@@ -378,7 +379,8 @@ tryGenerateSpecializedMessageSend(CodeGenFunction &CGF, QualType ResultType,
   auto &Runtime = CGM.getLangOpts().ObjCRuntime;
   switch (Sel.getMethodFamily()) {
   case OMF_alloc:
-    if (Runtime.shouldUseRuntimeFunctionsForAlloc() &&
+    if (isClassMessage &&
+        Runtime.shouldUseRuntimeFunctionsForAlloc() &&
         ResultType->isObjCObjectPointerType()) {
         // [Foo alloc] -> objc_alloc(Foo)
         if (Sel.isUnarySelector() && Sel.getNameForSlot(0) == "alloc")
@@ -550,7 +552,8 @@ RValue CodeGenFunction::EmitObjCMessageExpr(const ObjCMessageExpr *E,
     // Call runtime methods directly if we can.
     if (Optional SpecializedResult =
             tryGenerateSpecializedMessageSend(*this, ResultType, Receiver, Args,
-                                              E->getSelector(), method)) {
+                                              E->getSelector(), method,
+                                              isClassMessage)) {
       result = RValue::get(SpecializedResult.getValue());
     } else {
       result = Runtime.GenerateMessageSend(*this, Return, ResultType,
diff --git a/test/CodeGenObjC/convert-messages-to-runtime-calls.m b/test/CodeGenObjC/convert-messages-to-runtime-calls.m
index adbbd4b173..8ce024fe80 100644
--- a/test/CodeGenObjC/convert-messages-to-runtime-calls.m
+++ b/test/CodeGenObjC/convert-messages-to-runtime-calls.m
@@ -54,7 +54,9 @@ void test2(void* x) {
 @class A;
 @interface B
 + (A*) alloc;
-+ (A*)allocWithZone:(void*)zone;
++ (A*) allocWithZone:(void*)zone;
+- (A*) alloc;
+- (A*) allocWithZone:(void*)zone;
 - (A*) retain;
 - (A*) autorelease;
 @end
@@ -79,6 +81,19 @@ A* test_allocWithZone_class_ptr() {
   return [B allocWithZone:nil];
 }
 
+// Only call objc_alloc on a Class, not an instance
+// CHECK-LABEL: define {{.*}}void @test_alloc_instance
+void test_alloc_instance(A *a) {
+  // CALLS: {{call.*@objc_alloc}}
+  // CALLS: {{call.*@objc_allocWithZone}}
+  // CALLS: {{call.*@objc_msgSend}}
+  // CALLS: {{call.*@objc_msgSend}}
+  [A alloc];
+  [A allocWithZone:nil];
+  [a alloc];
+  [a allocWithZone:nil];
+}
+
 // Make sure we get a bitcast on the return type as the
 // call will return i8* which we have to cast to A*
 // CHECK-LABEL: define {{.*}}void @test_retain_class_ptr
-- 
cgit v1.2.3


From 4d12ac09c5078ff950fa6fda4d7c2b3495e65408 Mon Sep 17 00:00:00 2001
From: Patrick Lyster 
Date: Wed, 2 Jan 2019 19:28:48 +0000
Subject: [OpenMP] Added support for explicit mapping of classes using 'this'
 pointer. Differential revision: https://reviews.llvm.org/D55982

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350252 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/Basic/DiagnosticSemaKinds.td |  8 ++++
 lib/CodeGen/CGOpenMPRuntime.cpp            | 11 ++++-
 lib/Sema/SemaOpenMP.cpp                    | 72 +++++++++++++++++++++++++++++-
 test/OpenMP/target_ast_print.cpp           | 35 +++++++++++++++
 test/OpenMP/target_codegen.cpp             | 50 ++++++++++++++++++++-
 test/OpenMP/target_messages.cpp            | 12 +++++
 6 files changed, 183 insertions(+), 5 deletions(-)

diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 46cf0a423e..c69566a2d2 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -9076,6 +9076,14 @@ def note_omp_requires_previous_clause : Note <
   "%0 clause previously used here">;
 def err_omp_invalid_scope : Error <
   "'#pragma omp %0' directive must appear only in file scope">;
+def note_omp_invalid_length_on_this_ptr_mapping : Note <
+  "expected length on mapping of 'this' array section expression to be '1'">;
+def note_omp_invalid_lower_bound_on_this_ptr_mapping : Note <
+  "expected lower bound on mapping of 'this' array section expression to be '0' or not specified">;
+def note_omp_invalid_subscript_on_this_ptr_map : Note <
+  "expected 'this' subscript expression on map clause to be 'this[0]'">;
+def err_omp_invalid_map_this_expr : Error <
+  "invalid 'this' expression on 'map' clause">;
 } // end of OpenMP category
 
 let CategoryName = "Related Result Type Issue" in {
diff --git a/lib/CodeGen/CGOpenMPRuntime.cpp b/lib/CodeGen/CGOpenMPRuntime.cpp
index 746d3d3e64..8176093840 100644
--- a/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -6992,15 +6992,22 @@ private:
     // components.
     bool IsExpressionFirstInfo = true;
     Address BP = Address::invalid();
+    const Expr *AssocExpr = I->getAssociatedExpression();
+    const auto *AE = dyn_cast(AssocExpr);
+    const auto *OASE = dyn_cast(AssocExpr);
 
-    if (isa(I->getAssociatedExpression())) {
+    if (isa(AssocExpr)) {
       // The base is the 'this' pointer. The content of the pointer is going
       // to be the base of the field being mapped.
       BP = CGF.LoadCXXThisAddress();
+    } else if ((AE && isa(AE->getBase()->IgnoreParenImpCasts())) ||
+               (OASE &&
+                isa(OASE->getBase()->IgnoreParenImpCasts()))) {
+      BP = CGF.EmitOMPSharedLValue(AssocExpr).getAddress();
     } else {
       // The base is the reference to the variable.
       // BP = &Var.
-      BP = CGF.EmitOMPSharedLValue(I->getAssociatedExpression()).getAddress();
+      BP = CGF.EmitOMPSharedLValue(AssocExpr).getAddress();
       if (const auto *VD =
               dyn_cast_or_null(I->getAssociatedDeclaration())) {
         if (llvm::Optional Res =
diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp
index b4eb466476..78bef59ff6 100644
--- a/lib/Sema/SemaOpenMP.cpp
+++ b/lib/Sema/SemaOpenMP.cpp
@@ -22,6 +22,7 @@
 #include "clang/AST/StmtCXX.h"
 #include "clang/AST/StmtOpenMP.h"
 #include "clang/AST/StmtVisitor.h"
+#include "clang/AST/TypeOrdering.h"
 #include "clang/Basic/OpenMPKinds.h"
 #include "clang/Sema/Initialization.h"
 #include "clang/Sema/Lookup.h"
@@ -146,6 +147,7 @@ private:
     SourceLocation InnerTeamsRegionLoc;
     /// Reference to the taskgroup task_reduction reference expression.
     Expr *TaskgroupReductionRef = nullptr;
+    llvm::DenseSet MappedClassesQualTypes;
     SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,
                  Scope *CurScope, SourceLocation Loc)
         : Directive(DKind), DirectiveName(Name), CurScope(CurScope),
@@ -660,6 +662,19 @@ public:
     return llvm::make_range(StackElem.DoacrossDepends.end(),
                             StackElem.DoacrossDepends.end());
   }
+
+  // Store types of classes which have been explicitly mapped
+  void addMappedClassesQualTypes(QualType QT) {
+    SharingMapTy &StackElem = Stack.back().first.back();
+    StackElem.MappedClassesQualTypes.insert(QT);
+  }
+
+  // Return set of mapped classes types
+  bool isClassPreviouslyMapped(QualType QT) const {
+    const SharingMapTy &StackElem = Stack.back().first.back();
+    return StackElem.MappedClassesQualTypes.count(QT) != 0;
+  }
+
 };
 bool isParallelOrTaskRegion(OpenMPDirectiveKind DKind) {
   return isOpenMPParallelDirective(DKind) || isOpenMPTaskingDirective(DKind) ||
@@ -2267,7 +2282,7 @@ public:
       return;
     auto *FD = dyn_cast(E->getMemberDecl());
     OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
-    if (isa(E->getBase()->IgnoreParens())) {
+    if (auto *TE = dyn_cast(E->getBase()->IgnoreParens())) {
       if (!FD)
         return;
       DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false);
@@ -2294,6 +2309,12 @@ public:
         //
         if (FD->isBitField())
           return;
+
+        // Check to see if the member expression is referencing a class that
+        // has already been explicitly mapped
+        if (Stack->isClassPreviouslyMapped(TE->getType()))
+          return;
+
         ImplicitMap.emplace_back(E);
         return;
       }
@@ -12448,6 +12469,19 @@ static const Expr *checkMapClauseExpressionBase(
                                                       E->getType()))
         AllowWholeSizeArraySection = false;
 
+      if (const auto *TE = dyn_cast(E)) {
+        Expr::EvalResult Result;
+        if (CurE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext())) {
+          if (!Result.Val.getInt().isNullValue()) {
+            SemaRef.Diag(CurE->getIdx()->getExprLoc(),
+                         diag::err_omp_invalid_map_this_expr);
+            SemaRef.Diag(CurE->getIdx()->getExprLoc(),
+                         diag::note_omp_invalid_subscript_on_this_ptr_map);
+          }
+        }
+        RelevantExpr = TE;
+      }
+
       // Record the component - we don't have any declaration associated.
       CurComponents.emplace_back(CurE, nullptr);
     } else if (auto *CurE = dyn_cast(E)) {
@@ -12494,6 +12528,30 @@ static const Expr *checkMapClauseExpressionBase(
         return nullptr;
       }
 
+      if (const auto *TE = dyn_cast(E)) {
+        Expr::EvalResult ResultR;
+        Expr::EvalResult ResultL;
+        if (CurE->getLength()->EvaluateAsInt(ResultR,
+                                             SemaRef.getASTContext())) {
+          if (!ResultR.Val.getInt().isOneValue()) {
+            SemaRef.Diag(CurE->getLength()->getExprLoc(),
+                         diag::err_omp_invalid_map_this_expr);
+            SemaRef.Diag(CurE->getLength()->getExprLoc(),
+                         diag::note_omp_invalid_length_on_this_ptr_mapping);
+          }
+        }
+        if (CurE->getLowerBound() && CurE->getLowerBound()->EvaluateAsInt(
+                                        ResultL, SemaRef.getASTContext())) {
+          if (!ResultL.Val.getInt().isNullValue()) {
+            SemaRef.Diag(CurE->getLowerBound()->getExprLoc(),
+                         diag::err_omp_invalid_map_this_expr);
+            SemaRef.Diag(CurE->getLowerBound()->getExprLoc(),
+                         diag::note_omp_invalid_lower_bound_on_this_ptr_mapping);
+          }
+        }
+        RelevantExpr = TE;
+      }
+
       // Record the component - we don't have any declaration associated.
       CurComponents.emplace_back(CurE, nullptr);
     } else {
@@ -12831,6 +12889,18 @@ checkMappableExpressionList(Sema &SemaRef, DSAStackTy *DSAS,
     assert(!CurComponents.empty() &&
            "Invalid mappable expression information.");
 
+    if (const auto *TE = dyn_cast(BE)) {
+      // Add store "this" pointer to class in DSAStackTy for future checking
+      DSAS->addMappedClassesQualTypes(TE->getType());
+      // Skip restriction checking for variable or field declarations
+      MVLI.ProcessedVarList.push_back(RE);
+      MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
+      MVLI.VarComponents.back().append(CurComponents.begin(),
+                                       CurComponents.end());
+      MVLI.VarBaseDeclarations.push_back(nullptr);
+      continue;
+    }
+
     // For the following checks, we rely on the base declaration which is
     // expected to be associated with the last component. The declaration is
     // expected to be a variable or a field (if 'this' is being mapped).
diff --git a/test/OpenMP/target_ast_print.cpp b/test/OpenMP/target_ast_print.cpp
index 2734294ff6..9b866b789a 100644
--- a/test/OpenMP/target_ast_print.cpp
+++ b/test/OpenMP/target_ast_print.cpp
@@ -191,6 +191,41 @@ T tmain(T argc, T *argv) {
 // CHECK-NEXT: #pragma omp target defaultmap(tofrom: scalar)
 // CHECK-NEXT: foo()
 
+// CHECK-LABEL: class S {
+class S {
+  void foo() {
+// CHECK-NEXT: void foo() {
+    int a = 0;
+// CHECK-NEXT: int a = 0;
+    #pragma omp target map(this[0])
+// CHECK-NEXT: #pragma omp target map(tofrom: this[0])
+      a++;
+// CHECK-NEXT: a++;
+    #pragma omp target map(this[:1])
+// CHECK-NEXT: #pragma omp target map(tofrom: this[:1])
+      a++;
+// CHECK-NEXT: a++;
+    #pragma omp target map((this)[0])
+// CHECK-NEXT: #pragma omp target map(tofrom: (this)[0])
+      a++;
+// CHECK-NEXT: a++;
+    #pragma omp target map(this[:a])
+// CHECK-NEXT: #pragma omp target map(tofrom: this[:a])
+      a++;
+// CHECK-NEXT: a++;
+    #pragma omp target map(this[a:1])
+// CHECK-NEXT: #pragma omp target map(tofrom: this[a:1])
+      a++;
+// CHECK-NEXT: a++;
+    #pragma omp target map(this[a])
+// CHECK-NEXT: #pragma omp target map(tofrom: this[a])
+      a++;
+// CHECK-NEXT: a++;
+  }
+// CHECK-NEXT: }
+};
+// CHECK-NEXT: };
+
 // CHECK-LABEL: int main(int argc, char **argv) {
 int main (int argc, char **argv) {
   int i, j, a[20], always, close;
diff --git a/test/OpenMP/target_codegen.cpp b/test/OpenMP/target_codegen.cpp
index 6395dd354f..a5026cf660 100644
--- a/test/OpenMP/target_codegen.cpp
+++ b/test/OpenMP/target_codegen.cpp
@@ -40,6 +40,7 @@
 
 // CHECK-DAG: [[TT:%.+]] = type { i64, i8 }
 // CHECK-DAG: [[S1:%.+]] = type { double }
+// CHECK-DAG: [[S2:%.+]] = type { i32, i32, i32 }
 // CHECK-DAG: [[ENTTY:%.+]] = type { i8*, i8*, i[[SZ:32|64]], i32, i32 }
 // CHECK-DAG: [[DEVTY:%.+]] = type { i8*, i8*, [[ENTTY]]*, [[ENTTY]]* }
 // CHECK-DAG: [[DSCTY:%.+]] = type { i32, [[DEVTY]]*, [[ENTTY]]*, [[ENTTY]]* }
@@ -48,8 +49,8 @@
 
 // CHECK-DAG: $[[REGFN:\.omp_offloading\..+]] = comdat
 
-// We have 8 target regions, but only 7 that actually will generate offloading
-// code and have mapped arguments, and only 5 have all-constant map sizes.
+// We have 9 target regions, but only 8 that actually will generate offloading
+// code and have mapped arguments, and only 6 have all-constant map sizes.
 
 // CHECK-DAG: [[SIZET:@.+]] = private unnamed_addr constant [2 x i[[SZ]]] [i[[SZ]] 0, i[[SZ]] 4]
 // CHECK-DAG: [[MAPT:@.+]] = private unnamed_addr constant [2 x i64] [i64 544, i64 800]
@@ -63,6 +64,9 @@
 // CHECK-DAG: [[SIZET6:@.+]] = private unnamed_addr constant [4 x i[[SZ]]] [i[[SZ]] 4, i[[SZ]] 2, i[[SZ]] 1, i[[SZ]] 40]
 // CHECK-DAG: [[MAPT6:@.+]] = private unnamed_addr constant [4 x i64] [i64 800, i64 800, i64 800, i64 547]
 // CHECK-DAG: [[MAPT7:@.+]] = private unnamed_addr constant [6 x i64] [i64 32, i64 281474976711171, i64 800, i64 288, i64 288, i64 547]
+// CHECK-DAG: [[SIZET9:@.+]] = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 12]
+// CHECK-DAG: [[MAPT10:@.+]] = private unnamed_addr constant [1 x i64] [i64 35]
+// CHECK-DAG: @{{.*}} = weak constant i8 0
 // CHECK-DAG: @{{.*}} = weak constant i8 0
 // CHECK-DAG: @{{.*}} = weak constant i8 0
 // CHECK-DAG: @{{.*}} = weak constant i8 0
@@ -80,6 +84,7 @@
 // TCHECK: @{{.+}} = weak constant [[ENTTY]]
 // TCHECK: @{{.+}} = weak constant [[ENTTY]]
 // TCHECK: @{{.+}} = weak constant [[ENTTY]]
+// TCHECK: @{{.+}} = weak constant [[ENTTY]]
 // TCHECK-NOT: @{{.+}} = weak constant [[ENTTY]]
 
 // Check if offloading descriptor is created.
@@ -691,6 +696,31 @@ int bar(int n){
 
 // CHECK:       [[IFEND]]
 
+// CHECK: define {{.*}}@{{.*}}zee{{.*}}
+
+// CHECK:       [[LOCAL_THIS:%.+]] = alloca [[S2]]*
+// CHECK:       [[BP:%.+]] = alloca [1 x i8*]
+// CHECK:       [[P:%.+]] = alloca [1 x i8*]
+// CHECK:       [[LOCAL_THIS1:%.+]] = load [[S2]]*, [[S2]]** [[LOCAL_THIS]]
+// CHECK:       [[ARR_IDX:%.+]] = getelementptr inbounds [[S2]], [[S2]]* [[LOCAL_THIS1]], i[[SZ]] 0
+// CHECK:       [[ARR_IDX2:%.+]] = getelementptr inbounds [[S2]], [[S2]]* [[LOCAL_THIS1]], i[[SZ]] 0
+
+// CHECK-DAG:   [[BPADDR0:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[BP]], i32 0, i32 0    
+// CHECK-DAG:   [[PADDR0:%.+]] =  getelementptr inbounds [1 x i8*], [1 x i8*]* [[P]], i32 0, i32 0
+// CHECK-DAG:   [[CBPADDR0:%.+]] = bitcast i8** [[BPADDR0]] to [[S2]]**
+// CHECK-DAG:   [[CPADDR0:%.+]] = bitcast i8** [[PADDR0]] to [[S2]]**
+// CHECK-DAG:   store [[S2]]* [[ARR_IDX]], [[S2]]** [[CBPADDR0]]
+// CHECK-DAG:   store [[S2]]* [[ARR_IDX2]], [[S2]]** [[CPADDR0]]
+
+// CHECK:       [[BPR:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[BP]], i32 0, i32 0
+// CHECK:       [[PR:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[P]], i32 0, i32 0
+// CHECK:       [[RET:%.+]] = call i32 @__tgt_target(i64 -1, i8* @{{[^,]+}}, i32 1, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* getelementptr inbounds ([1 x i[[SZ]]], [1 x i[[SZ]]]* [[SIZET9]], i32 0, i32 0), i64* getelementptr inbounds ([1 x i64], [1 x i64]* [[MAPT10]], i32 0, i32 0))
+// CHECK-NEXT:  [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
+// CHECK-NEXT:  br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]]
+// CHECK:       [[FAIL]]
+// CHECK:       call void [[HVT0:@.+]]([[S2]]* [[LOCAL_THIS1]])
+// CHECK-NEXT:  br label %[[END]]
+// CHECK:       [[END]]
 
 // Check that the offloading functions are emitted and that the arguments are
 // correct and loaded correctly for the target regions of the callees of bar().
@@ -765,4 +795,20 @@ void bar () {
 pragma_target
 {}
 }
+
+class S2 {
+  int a, b, c;
+
+public:
+  void zee() {
+    #pragma omp target map(this[0])
+      a++;
+  }
+};
+
+int main () {
+  S2 bar;
+  bar.zee();
+}
+
 #endif
diff --git a/test/OpenMP/target_messages.cpp b/test/OpenMP/target_messages.cpp
index 4fa8272ab4..9bd8b3749e 100644
--- a/test/OpenMP/target_messages.cpp
+++ b/test/OpenMP/target_messages.cpp
@@ -43,6 +43,18 @@ void bar() {
 void foo() {
 }
 
+class S {
+  public:
+  void zee() {
+    #pragma omp target map(this[:2]) // expected-note {{expected length on mapping of 'this' array section expression to be '1'}} // expected-error {{invalid 'this' expression on 'map' clause}}
+      int a;
+    #pragma omp target map(this[1:1]) // expected-note {{expected lower bound on mapping of 'this' array section expression to be '0' or not specified}} // expected-error {{invalid 'this' expression on 'map' clause}}
+      int b;
+    #pragma omp target map(this[1]) // expected-note {{expected 'this' subscript expression on map clause to be 'this[0]'}} // expected-error {{invalid 'this' expression on 'map' clause}}
+      int c;
+  }
+};
+
 #pragma omp target // expected-error {{unexpected OpenMP directive '#pragma omp target'}}
 
 int main(int argc, char **argv) {
-- 
cgit v1.2.3


From b75a3fb79b87dfb587f6c966c7fe2c795e296811 Mon Sep 17 00:00:00 2001
From: Nico Weber 
Date: Thu, 3 Jan 2019 00:17:02 +0000
Subject: Make test/Driver/darwin-sdk-version.c pass if the host triple is
 32-bit

For some reason, the cmake build on my macbook has
LLVM_HOST_TRIPLE:STRING=i386-apple-darwin16.7.0 .
test/Driver/darwin-sdk-version.c assumed that the host triple is 64-bit, so
make it resilient against 32-bit host triples.

Differential Revision: https://reviews.llvm.org/D56067


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350278 91177308-0d34-0410-b5e6-96231b3b80d8
---
 test/Driver/darwin-sdk-version.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/test/Driver/darwin-sdk-version.c b/test/Driver/darwin-sdk-version.c
index 89f587ede2..9c1eec0ee4 100644
--- a/test/Driver/darwin-sdk-version.c
+++ b/test/Driver/darwin-sdk-version.c
@@ -5,10 +5,10 @@
 //
 // RUN: rm -rf %t/SDKs/MacOSX10.10.sdk
 // RUN: mkdir -p %t/SDKs/MacOSX10.10.sdk
-// RUN: %clang -isysroot %t/SDKs/MacOSX10.10.sdk -c -### %s 2>&1 \
+// RUN: %clang -m64 -isysroot %t/SDKs/MacOSX10.10.sdk -c -### %s 2>&1 \
 // RUN:   | FileCheck --check-prefix=INFER_SDK_VERSION %s
 // RUN: sed -e 's/10\.14/10\.8/g' %S/Inputs/MacOSX10.14.sdk/SDKSettings.json > %t/SDKs/MacOSX10.10.sdk/SDKSettings.json
-// RUN: %clang -isysroot %t/SDKs/MacOSX10.10.sdk -c -### %s 2>&1 \
+// RUN: %clang -m64 -isysroot %t/SDKs/MacOSX10.10.sdk -c -### %s 2>&1 \
 // RUN:   | FileCheck --check-prefix=INFER_DEPLOYMENT_TARGET_VERSION %s
 // REQUIRES: system-darwin && native
 //
-- 
cgit v1.2.3


From fabf27a17e9d842a0f721237b0e2fcd3713f6010 Mon Sep 17 00:00:00 2001
From: Alex Lorenz 
Date: Thu, 3 Jan 2019 01:13:33 +0000
Subject: [libclang] CoroutineBody/Coreturn statements are UnexposedStmts and
 not Exprs

This change ensures that the libclang CXCursor represents the CoroutineBody
and the Coreturn statement using the appropriate CXCursor_UnexposedStmt kind
instead of CXCursor_UnexposedExpr. The problem with CXCursor_UnexposedExpr is
that the consumer functions assumed that CoroutineBody/Coreturn statements
were valid expressions and performed an invalid downcast to Expr causing
assertion failures or other crashes.

rdar://40204290


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350282 91177308-0d34-0410-b5e6-96231b3b80d8
---
 test/Index/coroutines.cpp   | 24 ++++++++++++++++++++++++
 tools/libclang/CXCursor.cpp |  9 ++++++---
 2 files changed, 30 insertions(+), 3 deletions(-)
 create mode 100644 test/Index/coroutines.cpp

diff --git a/test/Index/coroutines.cpp b/test/Index/coroutines.cpp
new file mode 100644
index 0000000000..be9ddc0b6f
--- /dev/null
+++ b/test/Index/coroutines.cpp
@@ -0,0 +1,24 @@
+// RUN: c-index-test -test-load-source all -c %s -fsyntax-only -target x86_64-apple-darwin9 -fcoroutines-ts -std=c++1z -I%S/../SemaCXX/Inputs | FileCheck %s
+#include "std-coroutine.h"
+
+using std::experimental::suspend_always;
+using std::experimental::suspend_never;
+
+struct promise_void {
+  void get_return_object();
+  suspend_always initial_suspend();
+  suspend_always final_suspend();
+  void return_void();
+  void unhandled_exception();
+};
+
+template <>
+struct std::experimental::coroutine_traits { using promise_type = promise_void; };
+
+void CoroutineTestRet() {
+  co_return;
+}
+// CHECK: [[@LINE-3]]:25: UnexposedStmt=
+// CHECK-SAME: [[@LINE-4]]:25 - [[@LINE-2]]:2]
+// CHECK: [[@LINE-4]]:5: UnexposedStmt=
+// CHECK-SAME: [[@LINE-5]]:5 - [[@LINE-5]]:14]
diff --git a/tools/libclang/CXCursor.cpp b/tools/libclang/CXCursor.cpp
index b8c2529169..99e4319fc1 100644
--- a/tools/libclang/CXCursor.cpp
+++ b/tools/libclang/CXCursor.cpp
@@ -241,16 +241,19 @@ CXCursor cxcursor::MakeCXCursor(const Stmt *S, const Decl *Parent,
   case Stmt::SEHLeaveStmtClass:
     K = CXCursor_SEHLeaveStmt;
     break;
-  
+
+  case Stmt::CoroutineBodyStmtClass:
+  case Stmt::CoreturnStmtClass:
+    K = CXCursor_UnexposedStmt;
+    break;
+
   case Stmt::ArrayTypeTraitExprClass:
   case Stmt::AsTypeExprClass:
   case Stmt::AtomicExprClass:
   case Stmt::BinaryConditionalOperatorClass:
   case Stmt::TypeTraitExprClass:
-  case Stmt::CoroutineBodyStmtClass:
   case Stmt::CoawaitExprClass:
   case Stmt::DependentCoawaitExprClass:
-  case Stmt::CoreturnStmtClass:
   case Stmt::CoyieldExprClass:
   case Stmt::CXXBindTemporaryExprClass:
   case Stmt::CXXDefaultArgExprClass:
-- 
cgit v1.2.3


From bfbe338a893dde6ba65b2bed6ffea1652a592819 Mon Sep 17 00:00:00 2001
From: Alex Lorenz 
Date: Thu, 3 Jan 2019 01:30:50 +0000
Subject: Fix incorrect column numbers in test from r350282.

After the test was reformatted using clang-format the numbers became invalid.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350283 91177308-0d34-0410-b5e6-96231b3b80d8
---
 test/Index/coroutines.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/test/Index/coroutines.cpp b/test/Index/coroutines.cpp
index be9ddc0b6f..5853437926 100644
--- a/test/Index/coroutines.cpp
+++ b/test/Index/coroutines.cpp
@@ -20,5 +20,5 @@ void CoroutineTestRet() {
 }
 // CHECK: [[@LINE-3]]:25: UnexposedStmt=
 // CHECK-SAME: [[@LINE-4]]:25 - [[@LINE-2]]:2]
-// CHECK: [[@LINE-4]]:5: UnexposedStmt=
-// CHECK-SAME: [[@LINE-5]]:5 - [[@LINE-5]]:14]
+// CHECK: [[@LINE-4]]:3: UnexposedStmt=
+// CHECK-SAME: [[@LINE-5]]:3 - [[@LINE-5]]:12]
-- 
cgit v1.2.3


From 0e55e1c2d00e984de5fc3830649c5d2f8698e516 Mon Sep 17 00:00:00 2001
From: Philip Pfaffe 
Date: Thu, 3 Jan 2019 13:42:44 +0000
Subject: [NewPM] Port Msan

Summary:
Keeping msan a function pass requires replacing the module level initialization:
That means, don't define a ctor function which calls __msan_init, instead just
declare the init function at the first access, and add that to the global ctors
list.

Changes:
- Pull the actual sanitizer and the wrapper pass apart.
- Add a newpm msan pass. The function pass inserts calls to runtime
  library functions, for which it inserts declarations as necessary.
- Update tests.

Caveats:
- There is one test that I dropped, because it specifically tested the
  definition of the ctor.

Reviewers: chandlerc, fedor.sergeev, leonardchan, vitalybuka

Subscribers: sdardis, nemanjai, javed.absar, hiraditya, kbarton, bollu, atanasyan, jsji

Differential Revision: https://reviews.llvm.org/D55647

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350305 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/CodeGen/BackendUtil.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/lib/CodeGen/BackendUtil.cpp b/lib/CodeGen/BackendUtil.cpp
index 52fc08de9b..3280417a91 100644
--- a/lib/CodeGen/BackendUtil.cpp
+++ b/lib/CodeGen/BackendUtil.cpp
@@ -53,6 +53,7 @@
 #include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h"
 #include "llvm/Transforms/InstCombine/InstCombine.h"
 #include "llvm/Transforms/Instrumentation.h"
+#include "llvm/Transforms/Instrumentation/MemorySanitizer.h"
 #include "llvm/Transforms/Instrumentation/BoundsChecking.h"
 #include "llvm/Transforms/Instrumentation/GCOVProfiler.h"
 #include "llvm/Transforms/ObjCARC.h"
@@ -276,7 +277,7 @@ static void addGeneralOptsForMemorySanitizer(const PassManagerBuilder &Builder,
   const CodeGenOptions &CGOpts = BuilderWrapper.getCGOpts();
   int TrackOrigins = CGOpts.SanitizeMemoryTrackOrigins;
   bool Recover = CGOpts.SanitizeRecover.has(SanitizerKind::Memory);
-  PM.add(createMemorySanitizerPass(TrackOrigins, Recover, CompileKernel));
+  PM.add(createMemorySanitizerLegacyPassPass(TrackOrigins, Recover, CompileKernel));
 
   // MemorySanitizer inserts complex instrumentation that mostly follows
   // the logic of the original code, but operates on "shadow" values.
-- 
cgit v1.2.3


From ec8c48fb7d4ee1ee940ab3255f3e25b3e289ab8d Mon Sep 17 00:00:00 2001
From: Aaron Ballman 
Date: Thu, 3 Jan 2019 14:24:31 +0000
Subject: Diagnose an unused result from a call through a function pointer
 whose return type is marked [[nodiscard]].

When a function returns a type and that type was declared [[nodiscard]], we diagnose any unused results from that call as though the function were marked nodiscard. The same behavior should apply to calls through a function pointer.

This addresses PR31526.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350317 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/AST/Decl.h                           |  8 ------
 include/clang/AST/Expr.h                           |  9 +++++++
 lib/AST/Decl.cpp                                   | 14 -----------
 lib/AST/Expr.cpp                                   | 19 ++++++++++----
 lib/Sema/SemaStmt.cpp                              | 11 ++++----
 .../CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p2.cpp | 29 ++++++++++++++++++++++
 6 files changed, 57 insertions(+), 33 deletions(-)

diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index 3145f35ead..52703e60aa 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -2327,14 +2327,6 @@ public:
         getASTContext());
   }
 
-  /// Returns the WarnUnusedResultAttr that is either declared on this
-  /// function, or its return type declaration.
-  const Attr *getUnusedResultAttr() const;
-
-  /// Returns true if this function or its return type has the
-  /// warn_unused_result attribute.
-  bool hasUnusedResultAttr() const { return getUnusedResultAttr() != nullptr; }
-
   /// Returns the storage class as written in the source. For the
   /// computed linkage of symbol, see getLinkage.
   StorageClass getStorageClass() const {
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index 156782b330..025ef0642a 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -2624,6 +2624,15 @@ public:
   /// type.
   QualType getCallReturnType(const ASTContext &Ctx) const;
 
+  /// Returns the WarnUnusedResultAttr that is either declared on the called
+  /// function, or its return type declaration.
+  const Attr *getUnusedResultAttr(const ASTContext &Ctx) const;
+
+  /// Returns true if this call expression should warn on unused results.
+  bool hasUnusedResultAttr(const ASTContext &Ctx) const {
+    return getUnusedResultAttr(Ctx) != nullptr;
+  }
+
   SourceLocation getRParenLoc() const { return RParenLoc; }
   void setRParenLoc(SourceLocation L) { RParenLoc = L; }
 
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index b32e5d9aa0..5536358b1e 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -3231,20 +3231,6 @@ SourceRange FunctionDecl::getExceptionSpecSourceRange() const {
   return FTL.getExceptionSpecRange();
 }
 
-const Attr *FunctionDecl::getUnusedResultAttr() const {
-  QualType RetType = getReturnType();
-  if (const auto *Ret = RetType->getAsRecordDecl()) {
-    if (const auto *R = Ret->getAttr())
-      return R;
-  } else if (const auto *ET = RetType->getAs()) {
-    if (const EnumDecl *ED = ET->getDecl()) {
-      if (const auto *R = ED->getAttr())
-        return R;
-    }
-  }
-  return getAttr();
-}
-
 /// For an inline function definition in C, or for a gnu_inline function
 /// in C++, determine whether the definition will be externally visible.
 ///
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 6aa1199add..0775ff5773 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -1412,6 +1412,19 @@ QualType CallExpr::getCallReturnType(const ASTContext &Ctx) const {
   return FnType->getReturnType();
 }
 
+const Attr *CallExpr::getUnusedResultAttr(const ASTContext &Ctx) const {
+  // If the return type is a struct, union, or enum that is marked nodiscard,
+  // then return the return type attribute.
+  if (const TagDecl *TD = getCallReturnType(Ctx)->getAsTagDecl())
+    if (const auto *A = TD->getAttr())
+      return A;
+
+  // Otherwise, see if the callee is marked nodiscard and return that attribute
+  // instead.
+  const Decl *D = getCalleeDecl();
+  return D ? D->getAttr() : nullptr;
+}
+
 SourceLocation CallExpr::getBeginLoc() const {
   if (isa(this))
     return cast(this)->getBeginLoc();
@@ -2323,16 +2336,12 @@ bool Expr::isUnusedResultAWarning(const Expr *&WarnE, SourceLocation &Loc,
     // If this is a direct call, get the callee.
     const CallExpr *CE = cast(this);
     if (const Decl *FD = CE->getCalleeDecl()) {
-      const FunctionDecl *Func = dyn_cast(FD);
-      bool HasWarnUnusedResultAttr = Func ? Func->hasUnusedResultAttr()
-                                          : FD->hasAttr();
-
       // If the callee has attribute pure, const, or warn_unused_result, warn
       // about it. void foo() { strlen("bar"); } should warn.
       //
       // Note: If new cases are added here, DiagnoseUnusedExprResult should be
       // updated to match for QoI.
-      if (HasWarnUnusedResultAttr ||
+      if (CE->hasUnusedResultAttr(Ctx) ||
           FD->hasAttr() || FD->hasAttr()) {
         WarnE = this;
         Loc = CE->getCallee()->getBeginLoc();
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index 47130cf480..dacf8d0cf4 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -259,17 +259,16 @@ void Sema::DiagnoseUnusedExprResult(const Stmt *S) {
     if (E->getType()->isVoidType())
       return;
 
+    if (const Attr *A = CE->getUnusedResultAttr(Context)) {
+      Diag(Loc, diag::warn_unused_result) << A << R1 << R2;
+      return;
+    }
+
     // If the callee has attribute pure, const, or warn_unused_result, warn with
     // a more specific message to make it clear what is happening. If the call
     // is written in a macro body, only warn if it has the warn_unused_result
     // attribute.
     if (const Decl *FD = CE->getCalleeDecl()) {
-      if (const Attr *A = isa(FD)
-                              ? cast(FD)->getUnusedResultAttr()
-                              : FD->getAttr()) {
-        Diag(Loc, diag::warn_unused_result) << A << R1 << R2;
-        return;
-      }
       if (ShouldSuppress)
         return;
       if (FD->hasAttr()) {
diff --git a/test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p2.cpp b/test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p2.cpp
index 49c418a687..43de9343bd 100644
--- a/test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p2.cpp
+++ b/test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p2.cpp
@@ -32,6 +32,35 @@ void g() {
   // OK, warning suppressed.
   (void)fp();
 }
+
+namespace PR31526 {
+typedef E (*fp1)();
+typedef S (*fp2)();
+
+typedef S S_alias;
+typedef S_alias (*fp3)();
+
+typedef fp2 fp2_alias;
+
+void f() {
+  fp1 one;
+  fp2 two;
+  fp3 three;
+  fp2_alias four;
+
+  one(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  two(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  three(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  four(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+  // These are all okay because of the explicit cast to void.
+  (void)one();
+  (void)two();
+  (void)three();
+  (void)four();
+}
+} // namespace PR31526
+
 #ifdef EXT
 // expected-warning@4 {{use of the 'nodiscard' attribute is a C++17 extension}}
 // expected-warning@8 {{use of the 'nodiscard' attribute is a C++17 extension}}
-- 
cgit v1.2.3


From 903bbb72f3332216c5f8f64dd452d10f52d4eb5c Mon Sep 17 00:00:00 2001
From: Serge Guelton 
Date: Thu, 3 Jan 2019 14:26:56 +0000
Subject: Portable Python script across Python version

StringIO is obsoleted in Python3, replaced by io.BytesIO or io.StringIO depending on the use.

Differential Revision: https://reviews.llvm.org/D55196

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350318 91177308-0d34-0410-b5e6-96231b3b80d8
---
 bindings/python/tests/cindex/test_translation_unit.py |  7 ++++---
 tools/clang-format/clang-format-diff.py               |  9 +++++----
 tools/scan-view/share/ScanView.py                     | 16 +++++++++++-----
 3 files changed, 20 insertions(+), 12 deletions(-)

diff --git a/bindings/python/tests/cindex/test_translation_unit.py b/bindings/python/tests/cindex/test_translation_unit.py
index b3075eb85d..f3e770a936 100644
--- a/bindings/python/tests/cindex/test_translation_unit.py
+++ b/bindings/python/tests/cindex/test_translation_unit.py
@@ -6,6 +6,7 @@ if 'CLANG_LIBRARY_PATH' in os.environ:
 from contextlib import contextmanager
 import gc
 import os
+import sys
 import tempfile
 import unittest
 
@@ -93,10 +94,10 @@ int SOME_DEFINE;
         self.assertEqual(spellings[-1], 'y')
 
     def test_unsaved_files_2(self):
-        try:
-            from StringIO import StringIO
-        except:
+        if sys.version_info.major >= 3:
             from io import StringIO
+        else:
+            from io import BytesIO as StringIO
         tu = TranslationUnit.from_source('fake.c', unsaved_files = [
                 ('fake.c', StringIO('int x;'))])
         spellings = [c.spelling for c in tu.cursor.get_children()]
diff --git a/tools/clang-format/clang-format-diff.py b/tools/clang-format/clang-format-diff.py
index 54347ce759..d6d3510416 100755
--- a/tools/clang-format/clang-format-diff.py
+++ b/tools/clang-format/clang-format-diff.py
@@ -28,10 +28,11 @@ import difflib
 import re
 import subprocess
 import sys
-try:
-  from StringIO import StringIO
-except ImportError:
-   from io import StringIO
+
+if sys.version_info.major >= 3:
+    from io import StringIO
+else:
+    from io import BytesIO as StringIO
 
 
 def main():
diff --git a/tools/scan-view/share/ScanView.py b/tools/scan-view/share/ScanView.py
index da30f36187..c40366b2e8 100644
--- a/tools/scan-view/share/ScanView.py
+++ b/tools/scan-view/share/ScanView.py
@@ -13,7 +13,12 @@ except ImportError:
     from urllib.parse import urlparse, unquote
 
 import posixpath
-import StringIO
+
+if sys.version_info.major >= 3:
+    from io import StringIO, BytesIO
+else:
+    from io import BytesIO, BytesIO as StringIO
+
 import re
 import shutil
 import threading
@@ -117,7 +122,7 @@ class ReporterThread(threading.Thread):
         except Reporter.ReportFailure as e:
             self.status = e.value
         except Exception as e:
-            s = StringIO.StringIO()
+            s = StringIO()
             import traceback
             print('Unhandled Exception
', file=s)
             traceback.print_exc(file=s)
@@ -275,7 +280,7 @@ class ScanViewRequestHandler(SimpleHTTPRequestHandler):
 
     def handle_exception(self, exc):
         import traceback
-        s = StringIO.StringIO()
+        s = StringIO()
         print("INTERNAL ERROR\n", file=s)
         traceback.print_exc(file=s)
         f = self.send_string(s.getvalue(), 'text/plain')
@@ -739,15 +744,16 @@ File Bug
         return f
 
     def send_string(self, s, ctype='text/html', headers=True, mtime=None):
+        encoded_s = s.encode()
         if headers:
             self.send_response(200)
             self.send_header("Content-type", ctype)
-            self.send_header("Content-Length", str(len(s)))
+            self.send_header("Content-Length", str(len(encoded_s)))
             if mtime is None:
                 mtime = self.dynamic_mtime
             self.send_header("Last-Modified", self.date_time_string(mtime))
             self.end_headers()
-        return StringIO.StringIO(s)
+        return BytesIO(encoded_s)
 
     def send_patched_file(self, path, ctype):
         # Allow a very limited set of variables. This is pretty gross.
-- 
cgit v1.2.3


From 5ea2db053a254aad9ead28908017434c422826b7 Mon Sep 17 00:00:00 2001
From: Serge Guelton 
Date: Thu, 3 Jan 2019 14:27:05 +0000
Subject: Portable Python script across Python version

Get rid of Python version specific shebang.

Differential Revision: https://reviews.llvm.org/D55207

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350319 91177308-0d34-0410-b5e6-96231b3b80d8
---
 utils/check_cfc/check_cfc.py      | 2 +-
 utils/check_cfc/obj_diff.py       | 2 +-
 utils/check_cfc/test_check_cfc.py | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/utils/check_cfc/check_cfc.py b/utils/check_cfc/check_cfc.py
index 4ad88c8b75..311f502f80 100755
--- a/utils/check_cfc/check_cfc.py
+++ b/utils/check_cfc/check_cfc.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2.7
+#!/usr/bin/env python
 
 """Check CFC - Check Compile Flow Consistency
 
diff --git a/utils/check_cfc/obj_diff.py b/utils/check_cfc/obj_diff.py
index 1302834432..a0951c5bcd 100755
--- a/utils/check_cfc/obj_diff.py
+++ b/utils/check_cfc/obj_diff.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2.7
+#!/usr/bin/env python
 
 from __future__ import absolute_import, division, print_function
 
diff --git a/utils/check_cfc/test_check_cfc.py b/utils/check_cfc/test_check_cfc.py
index e304ff5927..0808252a2c 100755
--- a/utils/check_cfc/test_check_cfc.py
+++ b/utils/check_cfc/test_check_cfc.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2.7
+#!/usr/bin/env python
 
 """Test internal functions within check_cfc.py."""
 
-- 
cgit v1.2.3


From f69e6504d9b12b972343b6f4fe0ec7b1e11711ab Mon Sep 17 00:00:00 2001
From: Alexey Bataev 
Date: Thu, 3 Jan 2019 16:25:35 +0000
Subject: [OPENMP][NVPTX]Use __kmpc_barrier_simple_spmd(nullptr, 0) instead of
 nvvm_barrier0.

Use runtime functions instead of the direct call to the nvvm intrinsics.
It allows to prevent some dangerous LLVM optimizations, that breaks the
code for the NVPTX target.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350328 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp               | 41 ++++++++++++++------
 lib/CodeGen/CGOpenMPRuntimeNVPTX.h                 |  3 ++
 test/OpenMP/nvptx_data_sharing.cpp                 | 10 ++---
 test/OpenMP/nvptx_parallel_codegen.cpp             | 24 ++++++------
 test/OpenMP/nvptx_parallel_for_codegen.cpp         |  6 +--
 test/OpenMP/nvptx_target_codegen.cpp               | 44 +++++++++++-----------
 test/OpenMP/nvptx_target_teams_codegen.cpp         | 12 +++---
 .../nvptx_target_teams_distribute_codegen.cpp      |  6 +--
 8 files changed, 83 insertions(+), 63 deletions(-)

diff --git a/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp b/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp
index 5e2676bf16..97b8f79a9f 100644
--- a/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp
+++ b/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp
@@ -96,8 +96,11 @@ enum OpenMPRTLFunctionNVPTX {
   OMPRTL_NVPTX__kmpc_get_team_static_memory,
   /// Call to void __kmpc_restore_team_static_memory(int16_t is_shared);
   OMPRTL_NVPTX__kmpc_restore_team_static_memory,
-  // Call to void __kmpc_barrier(ident_t *loc, kmp_int32 global_tid);
+  /// Call to void __kmpc_barrier(ident_t *loc, kmp_int32 global_tid);
   OMPRTL__kmpc_barrier,
+  /// Call to void __kmpc_barrier_simple_spmd(ident_t *loc, kmp_int32
+  /// global_tid);
+  OMPRTL__kmpc_barrier_simple_spmd,
 };
 
 /// Pre(post)-action for different OpenMP constructs specialized for NVPTX.
@@ -640,17 +643,6 @@ static llvm::Value *getNVPTXNumThreads(CodeGenFunction &CGF) {
       "nvptx_num_threads");
 }
 
-/// Get barrier to synchronize all threads in a block.
-static void getNVPTXCTABarrier(CodeGenFunction &CGF) {
-  llvm::Function *F = llvm::Intrinsic::getDeclaration(
-      &CGF.CGM.getModule(), llvm::Intrinsic::nvvm_barrier0);
-  F->addFnAttr(llvm::Attribute::Convergent);
-  CGF.EmitRuntimeCall(F);
-}
-
-/// Synchronize all GPU threads in a block.
-static void syncCTAThreads(CodeGenFunction &CGF) { getNVPTXCTABarrier(CGF); }
-
 /// Get the value of the thread_limit clause in the teams directive.
 /// For the 'generic' execution mode, the runtime encodes thread_limit in
 /// the launch parameters, always starting thread_limit+warpSize threads per
@@ -1813,6 +1805,17 @@ CGOpenMPRuntimeNVPTX::createNVPTXRuntimeFunction(unsigned Function) {
     cast(RTLFn)->addFnAttr(llvm::Attribute::Convergent);
     break;
   }
+  case OMPRTL__kmpc_barrier_simple_spmd: {
+    // Build void __kmpc_barrier_simple_spmd(ident_t *loc, kmp_int32
+    // global_tid);
+    llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
+    auto *FnTy =
+        llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
+    RTLFn =
+        CGM.CreateRuntimeFunction(FnTy, /*Name*/ "__kmpc_barrier_simple_spmd");
+    cast(RTLFn)->addFnAttr(llvm::Attribute::Convergent);
+    break;
+  }
   }
   return RTLFn;
 }
@@ -2665,6 +2668,20 @@ void CGOpenMPRuntimeNVPTX::emitSPMDParallelCall(
   }
 }
 
+void CGOpenMPRuntimeNVPTX::syncCTAThreads(CodeGenFunction &CGF) {
+  // Always emit simple barriers!
+  if (!CGF.HaveInsertPoint())
+    return;
+  // Build call __kmpc_barrier_simple_spmd(nullptr, 0);
+  // This function does not use parameters, so we can emit just default values.
+  llvm::Value *Args[] = {
+      llvm::ConstantPointerNull::get(
+          cast(getIdentTyPointerTy())),
+      llvm::ConstantInt::get(CGF.Int32Ty, /*V=*/0, /*isSigned=*/true)};
+  CGF.EmitRuntimeCall(
+      createNVPTXRuntimeFunction(OMPRTL__kmpc_barrier_simple_spmd), Args);
+}
+
 void CGOpenMPRuntimeNVPTX::emitBarrierCall(CodeGenFunction &CGF,
                                            SourceLocation Loc,
                                            OpenMPDirectiveKind Kind, bool,
diff --git a/lib/CodeGen/CGOpenMPRuntimeNVPTX.h b/lib/CodeGen/CGOpenMPRuntimeNVPTX.h
index 8fb3b0a061..6091610c37 100644
--- a/lib/CodeGen/CGOpenMPRuntimeNVPTX.h
+++ b/lib/CodeGen/CGOpenMPRuntimeNVPTX.h
@@ -58,6 +58,9 @@ private:
 
   bool requiresFullRuntime() const { return RequiresFullRuntime; }
 
+  /// Get barrier to synchronize all threads in a block.
+  void syncCTAThreads(CodeGenFunction &CGF);
+
   /// Emit the worker function for the current target region.
   void emitWorkerFunction(WorkerFunctionState &WST);
 
diff --git a/test/OpenMP/nvptx_data_sharing.cpp b/test/OpenMP/nvptx_data_sharing.cpp
index 3baee007fa..df9c3ee83b 100644
--- a/test/OpenMP/nvptx_data_sharing.cpp
+++ b/test/OpenMP/nvptx_data_sharing.cpp
@@ -34,7 +34,7 @@ void test_ds(){
 
 /// ========= In the worker function ========= ///
 // CK1: {{.*}}define internal void @__omp_offloading{{.*}}test_ds{{.*}}_worker()
-// CK1: call void @llvm.nvvm.barrier0()
+// CK1: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0)
 // CK1-NOT: call void @__kmpc_data_sharing_init_stack
 
 /// ========= In the kernel function ========= ///
@@ -59,8 +59,8 @@ void test_ds(){
 // CK1: [[SHARGSTMP2:%.+]] = getelementptr inbounds i8*, i8** [[SHARGSTMP1]], i64 0
 // CK1: [[SHAREDVAR:%.+]] = bitcast i32* [[A]] to i8*
 // CK1: store i8* [[SHAREDVAR]], i8** [[SHARGSTMP2]]
-// CK1: call void @llvm.nvvm.barrier0()
-// CK1: call void @llvm.nvvm.barrier0()
+// CK1: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0)
+// CK1: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0)
 // CK1: call void @__kmpc_end_sharing_variables()
 // CK1: store i32 100, i32* [[B]]
 // CK1: call void @__kmpc_kernel_prepare_parallel({{.*}}, i16 1)
@@ -72,8 +72,8 @@ void test_ds(){
 // CK1: [[SHARGSTMP12:%.+]] = getelementptr inbounds i8*, i8** [[SHARGSTMP3]], i64 1
 // CK1: [[SHAREDVAR2:%.+]] = bitcast i32* [[A]] to i8*
 // CK1: store i8* [[SHAREDVAR2]], i8** [[SHARGSTMP12]]
-// CK1: call void @llvm.nvvm.barrier0()
-// CK1: call void @llvm.nvvm.barrier0()
+// CK1: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0)
+// CK1: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0)
 // CK1: call void @__kmpc_end_sharing_variables()
 // CK1: [[SHARED_MEM_FLAG:%.+]] = load i16, i16* [[KERNEL_SHARED]],
 // CK1: call void @__kmpc_restore_team_static_memory(i16 [[SHARED_MEM_FLAG]])
diff --git a/test/OpenMP/nvptx_parallel_codegen.cpp b/test/OpenMP/nvptx_parallel_codegen.cpp
index 821897cc0f..21a616d091 100644
--- a/test/OpenMP/nvptx_parallel_codegen.cpp
+++ b/test/OpenMP/nvptx_parallel_codegen.cpp
@@ -88,7 +88,7 @@ int bar(int n){
 // CHECK: br label {{%?}}[[AWAIT_WORK:.+]]
 //
 // CHECK: [[AWAIT_WORK]]
-// CHECK: call void @llvm.nvvm.barrier0()
+// CHECK: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0)
 // CHECK: [[KPR:%.+]] = call i1 @__kmpc_kernel_parallel(i8** [[OMP_WORK_FN]]
 // CHECK: [[KPRB:%.+]] = zext i1 [[KPR]] to i8
 // store i8 [[KPRB]], i8* [[OMP_EXEC_STATUS]], align 1
@@ -127,7 +127,7 @@ int bar(int n){
 // CHECK: br label {{%?}}[[BAR_PARALLEL]]
 //
 // CHECK: [[BAR_PARALLEL]]
-// CHECK: call void @llvm.nvvm.barrier0()
+// CHECK: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0)
 // CHECK: br label {{%?}}[[AWAIT_WORK]]
 //
 // CHECK: [[EXIT]]
@@ -164,21 +164,21 @@ int bar(int n){
 // CHECK: [[MTMP1:%.+]] = sub nuw i32 [[MNTH]], [[MWS]]
 // CHECK: call void @__kmpc_kernel_init(i32 [[MTMP1]]
 // CHECK: call void @__kmpc_kernel_prepare_parallel(i8* bitcast (void (i16, i32)* [[PARALLEL_FN1]]_wrapper to i8*),
-// CHECK: call void @llvm.nvvm.barrier0()
-// CHECK: call void @llvm.nvvm.barrier0()
+// CHECK: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0)
+// CHECK: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0)
 // CHECK: call void @__kmpc_serialized_parallel(
 // CHECK: {{call|invoke}} void [[PARALLEL_FN3:@.+]](
 // CHECK: call void @__kmpc_end_serialized_parallel(
 // CHECK: call void @__kmpc_kernel_prepare_parallel(i8* bitcast (void (i16, i32)* [[PARALLEL_FN2]]_wrapper to i8*),
-// CHECK: call void @llvm.nvvm.barrier0()
-// CHECK: call void @llvm.nvvm.barrier0()
+// CHECK: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0)
+// CHECK: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0)
 // CHECK-64-DAG: load i32, i32* [[REF_A]]
 // CHECK-32-DAG: load i32, i32* [[LOCAL_A]]
 // CHECK: br label {{%?}}[[TERMINATE:.+]]
 //
 // CHECK: [[TERMINATE]]
 // CHECK: call void @__kmpc_kernel_deinit(
-// CHECK: call void @llvm.nvvm.barrier0()
+// CHECK: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0)
 // CHECK: br label {{%?}}[[EXIT]]
 //
 // CHECK: [[EXIT]]
@@ -207,7 +207,7 @@ int bar(int n){
 // CHECK: br label {{%?}}[[AWAIT_WORK:.+]]
 //
 // CHECK: [[AWAIT_WORK]]
-// CHECK: call void @llvm.nvvm.barrier0()
+// CHECK: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0)
 // CHECK: [[KPR:%.+]] = call i1 @__kmpc_kernel_parallel(i8** [[OMP_WORK_FN]],
 // CHECK: [[KPRB:%.+]] = zext i1 [[KPR]] to i8
 // store i8 [[KPRB]], i8* [[OMP_EXEC_STATUS]], align 1
@@ -237,7 +237,7 @@ int bar(int n){
 // CHECK: br label {{%?}}[[BAR_PARALLEL]]
 //
 // CHECK: [[BAR_PARALLEL]]
-// CHECK: call void @llvm.nvvm.barrier0()
+// CHECK: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0)
 // CHECK: br label {{%?}}[[AWAIT_WORK]]
 //
 // CHECK: [[EXIT]]
@@ -289,8 +289,8 @@ int bar(int n){
 //
 // CHECK: [[IF_THEN]]
 // CHECK: call void @__kmpc_kernel_prepare_parallel(i8* bitcast (void (i16, i32)* [[PARALLEL_FN4]]_wrapper to i8*),
-// CHECK: call void @llvm.nvvm.barrier0()
-// CHECK: call void @llvm.nvvm.barrier0()
+// CHECK: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0)
+// CHECK: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0)
 // CHECK: br label {{%?}}[[IF_END:.+]]
 //
 // CHECK: [[IF_ELSE]]
@@ -309,7 +309,7 @@ int bar(int n){
 //
 // CHECK: [[TERMINATE]]
 // CHECK: call void @__kmpc_kernel_deinit(
-// CHECK: call void @llvm.nvvm.barrier0()
+// CHECK: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0)
 // CHECK: br label {{%?}}[[EXIT]]
 //
 // CHECK: [[EXIT]]
diff --git a/test/OpenMP/nvptx_parallel_for_codegen.cpp b/test/OpenMP/nvptx_parallel_for_codegen.cpp
index 6a8601f3ae..92783d6085 100644
--- a/test/OpenMP/nvptx_parallel_for_codegen.cpp
+++ b/test/OpenMP/nvptx_parallel_for_codegen.cpp
@@ -37,7 +37,7 @@ int bar(int n){
 // CHECK-DAG: [[KERNEL_SHARED:@.+]] = internal unnamed_addr constant i16 1
 
 // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+template.+l12}}_worker()
-// CHECK: call void @llvm.nvvm.barrier0()
+// CHECK: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0)
 // CHECK: call i1 @__kmpc_kernel_parallel(
 // CHECK: call void @__omp_outlined___wrapper(
 
@@ -52,8 +52,8 @@ int bar(int n){
 // CHECK: [[STACK:%.+]] = getelementptr inbounds i8, i8* [[KERNEL_RD]], i{{64|32}} 0
 // CHECK: call void @__kmpc_kernel_prepare_parallel(
 // CHECK: call void @__kmpc_begin_sharing_variables({{.*}}, i64 2)
-// CHECK: call void @llvm.nvvm.barrier0()
-// CHECK: call void @llvm.nvvm.barrier0()
+// CHECK: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0)
+// CHECK: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0)
 // CHECK: call void @__kmpc_end_sharing_variables()
 // CHECK: [[IS_SHARED:%.+]] = load i16, i16* [[KERNEL_SHARED]],
 // CHECK: call void @__kmpc_restore_team_static_memory(i16 [[IS_SHARED]])
diff --git a/test/OpenMP/nvptx_target_codegen.cpp b/test/OpenMP/nvptx_target_codegen.cpp
index 033ed1e684..ff44c0e8fb 100644
--- a/test/OpenMP/nvptx_target_codegen.cpp
+++ b/test/OpenMP/nvptx_target_codegen.cpp
@@ -52,8 +52,8 @@ struct TT{
 // CHECK: [[ARG_PTR2:%.+]] = getelementptr inbounds i8*, i8** [[ARG_PTRS]], i{{[0-9]+}} 1
 // CHECK: [[BC:%.+]] = bitcast i32** [[PTR2_REF]] to i8*
 // CHECK: store i8* [[BC]], i8** [[ARG_PTR2]],
-// CHECK: call void @llvm.nvvm.barrier0()
-// CHECK: call void @llvm.nvvm.barrier0()
+// CHECK: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0)
+// CHECK: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0)
 // CHECK: call void @__kmpc_end_sharing_variables()
 void targetBar(int *Ptr1, int *Ptr2) {
 #pragma omp target map(Ptr1[:0], Ptr2)
@@ -78,7 +78,7 @@ int foo(int n) {
   // CHECK: br label {{%?}}[[AWAIT_WORK:.+]]
   //
   // CHECK: [[AWAIT_WORK]]
-  // CHECK: call void @llvm.nvvm.barrier0()
+  // CHECK: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0)
   // CHECK: [[WORK:%.+]] = load i8*, i8** [[OMP_WORK_FN]],
   // CHECK: [[SHOULD_EXIT:%.+]] = icmp eq i8* [[WORK]], null
   // CHECK: br i1 [[SHOULD_EXIT]], label {{%?}}[[EXIT:.+]], label {{%?}}[[SEL_WORKERS:.+]]
@@ -95,7 +95,7 @@ int foo(int n) {
   // CHECK: br label {{%?}}[[BAR_PARALLEL]]
   //
   // CHECK: [[BAR_PARALLEL]]
-  // CHECK: call void @llvm.nvvm.barrier0()
+  // CHECK: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0)
   // CHECK: br label {{%?}}[[AWAIT_WORK]]
   //
   // CHECK: [[EXIT]]
@@ -129,7 +129,7 @@ int foo(int n) {
   //
   // CHECK: [[TERMINATE]]
   // CHECK: call void @__kmpc_kernel_deinit(
-  // CHECK: call void @llvm.nvvm.barrier0()
+  // CHECK: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0)
   // CHECK: br label {{%?}}[[EXIT]]
   //
   // CHECK: [[EXIT]]
@@ -151,7 +151,7 @@ int foo(int n) {
   // CHECK: br label {{%?}}[[AWAIT_WORK:.+]]
   //
   // CHECK: [[AWAIT_WORK]]
-  // CHECK: call void @llvm.nvvm.barrier0()
+  // CHECK: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0)
   // CHECK: [[WORK:%.+]] = load i8*, i8** [[OMP_WORK_FN]],
   // CHECK: [[SHOULD_EXIT:%.+]] = icmp eq i8* [[WORK]], null
   // CHECK: br i1 [[SHOULD_EXIT]], label {{%?}}[[EXIT:.+]], label {{%?}}[[SEL_WORKERS:.+]]
@@ -168,7 +168,7 @@ int foo(int n) {
   // CHECK: br label {{%?}}[[BAR_PARALLEL]]
   //
   // CHECK: [[BAR_PARALLEL]]
-  // CHECK: call void @llvm.nvvm.barrier0()
+  // CHECK: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0)
   // CHECK: br label {{%?}}[[AWAIT_WORK]]
   //
   // CHECK: [[EXIT]]
@@ -206,7 +206,7 @@ int foo(int n) {
   //
   // CHECK: [[TERMINATE]]
   // CHECK: call void @__kmpc_kernel_deinit(
-  // CHECK: call void @llvm.nvvm.barrier0()
+  // CHECK: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0)
   // CHECK: br label {{%?}}[[EXIT]]
   //
   // CHECK: [[EXIT]]
@@ -225,7 +225,7 @@ int foo(int n) {
   // CHECK: br label {{%?}}[[AWAIT_WORK:.+]]
   //
   // CHECK: [[AWAIT_WORK]]
-  // CHECK: call void @llvm.nvvm.barrier0()
+  // CHECK: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0)
   // CHECK: [[WORK:%.+]] = load i8*, i8** [[OMP_WORK_FN]],
   // CHECK: [[SHOULD_EXIT:%.+]] = icmp eq i8* [[WORK]], null
   // CHECK: br i1 [[SHOULD_EXIT]], label {{%?}}[[EXIT:.+]], label {{%?}}[[SEL_WORKERS:.+]]
@@ -242,7 +242,7 @@ int foo(int n) {
   // CHECK: br label {{%?}}[[BAR_PARALLEL]]
   //
   // CHECK: [[BAR_PARALLEL]]
-  // CHECK: call void @llvm.nvvm.barrier0()
+  // CHECK: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0)
   // CHECK: br label {{%?}}[[AWAIT_WORK]]
   //
   // CHECK: [[EXIT]]
@@ -316,7 +316,7 @@ int foo(int n) {
   //
   // CHECK: [[TERMINATE]]
   // CHECK: call void @__kmpc_kernel_deinit(
-  // CHECK: call void @llvm.nvvm.barrier0()
+  // CHECK: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0)
   // CHECK: br label {{%?}}[[EXIT]]
   //
   // CHECK: [[EXIT]]
@@ -417,7 +417,7 @@ int baz(int f, double &a) {
   // CHECK: br label {{%?}}[[AWAIT_WORK:.+]]
   //
   // CHECK: [[AWAIT_WORK]]
-  // CHECK: call void @llvm.nvvm.barrier0()
+  // CHECK: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0)
   // CHECK: [[WORK:%.+]] = load i8*, i8** [[OMP_WORK_FN]],
   // CHECK: [[SHOULD_EXIT:%.+]] = icmp eq i8* [[WORK]], null
   // CHECK: br i1 [[SHOULD_EXIT]], label {{%?}}[[EXIT:.+]], label {{%?}}[[SEL_WORKERS:.+]]
@@ -434,7 +434,7 @@ int baz(int f, double &a) {
   // CHECK: br label {{%?}}[[BAR_PARALLEL]]
   //
   // CHECK: [[BAR_PARALLEL]]
-  // CHECK: call void @llvm.nvvm.barrier0()
+  // CHECK: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0)
   // CHECK: br label {{%?}}[[AWAIT_WORK]]
   //
   // CHECK: [[EXIT]]
@@ -487,7 +487,7 @@ int baz(int f, double &a) {
   //
   // CHECK: [[TERMINATE]]
   // CHECK: call void @__kmpc_kernel_deinit(
-  // CHECK: call void @llvm.nvvm.barrier0()
+  // CHECK: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0)
   // CHECK: br label {{%?}}[[EXIT]]
   //
   // CHECK: [[EXIT]]
@@ -503,7 +503,7 @@ int baz(int f, double &a) {
   // CHECK: br label {{%?}}[[AWAIT_WORK:.+]]
   //
   // CHECK: [[AWAIT_WORK]]
-  // CHECK: call void @llvm.nvvm.barrier0()
+  // CHECK: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0)
   // CHECK: [[WORK:%.+]] = load i8*, i8** [[OMP_WORK_FN]],
   // CHECK: [[SHOULD_EXIT:%.+]] = icmp eq i8* [[WORK]], null
   // CHECK: br i1 [[SHOULD_EXIT]], label {{%?}}[[EXIT:.+]], label {{%?}}[[SEL_WORKERS:.+]]
@@ -523,7 +523,7 @@ int baz(int f, double &a) {
   // CHECK: br label {{%?}}[[BAR_PARALLEL]]
   //
   // CHECK: [[BAR_PARALLEL]]
-  // CHECK: call void @llvm.nvvm.barrier0()
+  // CHECK: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0)
   // CHECK: br label {{%?}}[[AWAIT_WORK]]
   //
   // CHECK: [[EXIT]]
@@ -581,7 +581,7 @@ int baz(int f, double &a) {
   //
   // CHECK: [[TERMINATE]]
   // CHECK: call void @__kmpc_kernel_deinit(
-  // CHECK: call void @llvm.nvvm.barrier0()
+  // CHECK: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0)
   // CHECK: br label {{%?}}[[EXIT]]
   //
   // CHECK: [[EXIT]]
@@ -633,8 +633,8 @@ int baz(int f, double &a) {
   // CHECK: [[REF:%.+]] = getelementptr inbounds i8*, i8** [[SHARED]], i{{64|32}} 0
   // CHECK: [[F_REF:%.+]] = bitcast i32* [[F_PTR]] to i8*
   // CHECK: store i8* [[F_REF]], i8** [[REF]],
-  // CHECK: call void @llvm.nvvm.barrier0()
-  // CHECK: call void @llvm.nvvm.barrier0()
+  // CHECK: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0)
+  // CHECK: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0)
   // CHECK: call void @__kmpc_end_sharing_variables()
   // CHECK: br label
 
@@ -656,7 +656,7 @@ int baz(int f, double &a) {
   // CHECK: br label {{%?}}[[AWAIT_WORK:.+]]
   //
   // CHECK: [[AWAIT_WORK]]
-  // CHECK: call void @llvm.nvvm.barrier0()
+  // CHECK: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0)
   // CHECK: [[WORK:%.+]] = load i8*, i8** [[OMP_WORK_FN]],
   // CHECK: [[SHOULD_EXIT:%.+]] = icmp eq i8* [[WORK]], null
   // CHECK: br i1 [[SHOULD_EXIT]], label {{%?}}[[EXIT:.+]], label {{%?}}[[SEL_WORKERS:.+]]
@@ -673,7 +673,7 @@ int baz(int f, double &a) {
   // CHECK: br label {{%?}}[[BAR_PARALLEL]]
   //
   // CHECK: [[BAR_PARALLEL]]
-  // CHECK: call void @llvm.nvvm.barrier0()
+  // CHECK: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0)
   // CHECK: br label {{%?}}[[AWAIT_WORK]]
   //
   // CHECK: [[EXIT]]
@@ -725,7 +725,7 @@ int baz(int f, double &a) {
   //
   // CHECK: [[TERMINATE]]
   // CHECK: call void @__kmpc_kernel_deinit(
-  // CHECK: call void @llvm.nvvm.barrier0()
+  // CHECK: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0)
   // CHECK: br label {{%?}}[[EXIT]]
   //
   // CHECK: [[EXIT]]
diff --git a/test/OpenMP/nvptx_target_teams_codegen.cpp b/test/OpenMP/nvptx_target_teams_codegen.cpp
index 33c8b065d3..069eecb607 100644
--- a/test/OpenMP/nvptx_target_teams_codegen.cpp
+++ b/test/OpenMP/nvptx_target_teams_codegen.cpp
@@ -67,7 +67,7 @@ int bar(int n){
   // CHECK: br label {{%?}}[[AWAIT_WORK:.+]]
   //
   // CHECK: [[AWAIT_WORK]]
-  // CHECK: call void @llvm.nvvm.barrier0()
+  // CHECK: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0)
   // CHECK: [[KPR:%.+]] = call i1 @__kmpc_kernel_parallel(i8** [[OMP_WORK_FN]], i16 1)
   // CHECK: [[KPRB:%.+]] = zext i1 [[KPR]] to i8
   // store i8 [[KPRB]], i8* [[OMP_EXEC_STATUS]], align 1
@@ -88,7 +88,7 @@ int bar(int n){
   // CHECK: br label {{%?}}[[BAR_PARALLEL]]
   //
   // CHECK: [[BAR_PARALLEL]]
-  // CHECK: call void @llvm.nvvm.barrier0()
+  // CHECK: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0)
   // CHECK: br label {{%?}}[[AWAIT_WORK]]
   //
   // CHECK: [[EXIT]]
@@ -134,7 +134,7 @@ int bar(int n){
   //
   // CHECK: [[TERMINATE]]
   // CHECK: call void @__kmpc_kernel_deinit(
-  // CHECK: call void @llvm.nvvm.barrier0()
+  // CHECK: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0)
   // CHECK: br label {{%?}}[[EXIT]]
   //
   // CHECK: [[EXIT]]
@@ -153,7 +153,7 @@ int bar(int n){
   // CHECK: br label {{%?}}[[AWAIT_WORK:.+]]
   //
   // CHECK: [[AWAIT_WORK]]
-  // CHECK: call void @llvm.nvvm.barrier0()
+  // CHECK: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0)
   // CHECK: [[KPR:%.+]] = call i1 @__kmpc_kernel_parallel(i8** [[OMP_WORK_FN]], i16 1)
   // CHECK: [[KPRB:%.+]] = zext i1 [[KPR]] to i8
   // store i8 [[KPRB]], i8* [[OMP_EXEC_STATUS]], align 1
@@ -174,7 +174,7 @@ int bar(int n){
   // CHECK: br label {{%?}}[[BAR_PARALLEL]]
   //
   // CHECK: [[BAR_PARALLEL]]
-  // CHECK: call void @llvm.nvvm.barrier0()
+  // CHECK: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0)
   // CHECK: br label {{%?}}[[AWAIT_WORK]]
   //
   // CHECK: [[EXIT]]
@@ -220,7 +220,7 @@ int bar(int n){
   //
   // CHECK: [[TERMINATE]]
   // CHECK: call void @__kmpc_kernel_deinit(
-  // CHECK: call void @llvm.nvvm.barrier0()
+  // CHECK: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0)
   // CHECK: br label {{%?}}[[EXIT]]
   //
   // CHECK: [[EXIT]]
diff --git a/test/OpenMP/nvptx_target_teams_distribute_codegen.cpp b/test/OpenMP/nvptx_target_teams_distribute_codegen.cpp
index a13762549c..cf007427ec 100644
--- a/test/OpenMP/nvptx_target_teams_distribute_codegen.cpp
+++ b/test/OpenMP/nvptx_target_teams_distribute_codegen.cpp
@@ -73,15 +73,15 @@ int bar(int n){
   // CHECK: [[SHARED_VARS_BUF:%.+]] = load i8**, i8*** [[SHARED_VARS_PTR]],
   // CHECK: [[I_ADDR_BC:%.+]] = bitcast i32* [[I_ADDR]] to i8*
   // CHECK: store i8* [[I_ADDR_BC]], i8** [[SHARED_VARS_BUF]],
-  // CHECK: call void @llvm.nvvm.barrier0()
-  // CHECK: call void @llvm.nvvm.barrier0()
+  // CHECK: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0)
+  // CHECK: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0)
   // CHECK: call void @__kmpc_end_sharing_variables()
   // CHECK: call void @__kmpc_for_static_fini(
   // CHECK: br label {{%?}}[[TERMINATE:.+]]
   //
   // CHECK: [[TERMINATE]]
   // CHECK: call void @__kmpc_kernel_deinit(
-  // CHECK: call void @llvm.nvvm.barrier0()
+  // CHECK: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0)
   // CHECK: br label {{%?}}[[EXIT]]
   //
   // CHECK: [[EXIT]]
-- 
cgit v1.2.3


From a11ecd118716ebfbbcf77a48fffe7fa7bddad738 Mon Sep 17 00:00:00 2001
From: Arnaud Bienner 
Date: Thu, 3 Jan 2019 17:45:28 +0000
Subject: Make -Wstring-plus-int warns even if when the result is not out of
 bounds

Summary: Patch by Arnaud Bienner

Reviewers: sylvestre.ledru, thakis, serge-sans-paille

Reviewed By: thakis

Subscribers: arphaman, dyung, anemet, llvm-commits, cfe-commits

Differential Revision: https://reviews.llvm.org/D55382

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350335 91177308-0d34-0410-b5e6-96231b3b80d8
---
 bindings/python/tests/cindex/test_diagnostics.py |  4 ++--
 lib/Sema/SemaExpr.cpp                            | 10 ----------
 test/SemaCXX/string-plus-int.cpp                 | 23 +++++++++++------------
 3 files changed, 13 insertions(+), 24 deletions(-)

diff --git a/bindings/python/tests/cindex/test_diagnostics.py b/bindings/python/tests/cindex/test_diagnostics.py
index 79d7a5fd41..c17d5b28ef 100644
--- a/bindings/python/tests/cindex/test_diagnostics.py
+++ b/bindings/python/tests/cindex/test_diagnostics.py
@@ -51,7 +51,7 @@ class TestDiagnostics(unittest.TestCase):
         self.assertEqual(tu.diagnostics[0].fixits[0].value, '.f0 = ')
 
     def test_diagnostic_range(self):
-        tu = get_tu('void f() { int i = "a" + 1; }')
+        tu = get_tu('void f() { int i = "a"; }')
         self.assertEqual(len(tu.diagnostics), 1)
         self.assertEqual(tu.diagnostics[0].severity, Diagnostic.Warning)
         self.assertEqual(tu.diagnostics[0].location.line, 1)
@@ -63,7 +63,7 @@ class TestDiagnostics(unittest.TestCase):
         self.assertEqual(tu.diagnostics[0].ranges[0].start.line, 1)
         self.assertEqual(tu.diagnostics[0].ranges[0].start.column, 20)
         self.assertEqual(tu.diagnostics[0].ranges[0].end.line, 1)
-        self.assertEqual(tu.diagnostics[0].ranges[0].end.column, 27)
+        self.assertEqual(tu.diagnostics[0].ranges[0].end.column, 23)
         with self.assertRaises(IndexError):
             tu.diagnostics[0].ranges[1].start.line
 
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index d38ae0fdc8..f8b991b7c7 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -9143,16 +9143,6 @@ static void diagnoseStringPlusInt(Sema &Self, SourceLocation OpLoc,
   if (!IsStringPlusInt || IndexExpr->isValueDependent())
     return;
 
-  Expr::EvalResult Result;
-  if (IndexExpr->EvaluateAsInt(Result, Self.getASTContext())) {
-    llvm::APSInt index = Result.Val.getInt();
-    unsigned StrLenWithNull = StrExpr->getLength() + 1;
-    if (index.isNonNegative() &&
-        index <= llvm::APSInt(llvm::APInt(index.getBitWidth(), StrLenWithNull),
-                              index.isUnsigned()))
-      return;
-  }
-
   SourceRange DiagRange(LHSExpr->getBeginLoc(), RHSExpr->getEndLoc());
   Self.Diag(OpLoc, diag::warn_string_plus_int)
       << DiagRange << IndexExpr->IgnoreImpCasts()->getType();
diff --git a/test/SemaCXX/string-plus-int.cpp b/test/SemaCXX/string-plus-int.cpp
index fe9c719496..448fb49fb4 100644
--- a/test/SemaCXX/string-plus-int.cpp
+++ b/test/SemaCXX/string-plus-int.cpp
@@ -31,37 +31,36 @@ void f(int index) {
   consume("foo" + 5);  // expected-warning {{adding 'int' to a string does not append to the string}} expected-note {{use array indexing to silence this warning}}
   consume("foo" + index);  // expected-warning {{adding 'int' to a string does not append to the string}} expected-note {{use array indexing to silence this warning}}
   consume("foo" + kMyEnum);  // expected-warning {{adding 'MyEnum' to a string does not append to the string}} expected-note {{use array indexing to silence this warning}}
+  consume("foo" + kMySmallEnum); // expected-warning {{adding 'MyEnum' to a string does not append to the string}} expected-note {{use array indexing to silence this warning}}
 
   consume(5 + "foo");  // expected-warning {{adding 'int' to a string does not append to the string}} expected-note {{use array indexing to silence this warning}}
   consume(index + "foo");  // expected-warning {{adding 'int' to a string does not append to the string}} expected-note {{use array indexing to silence this warning}}
   consume(kMyEnum + "foo");  // expected-warning {{adding 'MyEnum' to a string does not append to the string}} expected-note {{use array indexing to silence this warning}}
+  consume(kMySmallEnum + "foo"); // expected-warning {{adding 'MyEnum' to a string does not append to the string}} expected-note {{use array indexing to silence this warning}}
 
   // FIXME: suggest replacing with "foo"[5]
   consumeChar(*("foo" + 5));  // expected-warning {{adding 'int' to a string does not append to the string}} expected-note {{use array indexing to silence this warning}}
   consumeChar(*(5 + "foo"));  // expected-warning {{adding 'int' to a string does not append to the string}} expected-note {{use array indexing to silence this warning}}
 
   consume(L"foo" + 5);  // expected-warning {{adding 'int' to a string does not append to the string}} expected-note {{use array indexing to silence this warning}}
+  consume(L"foo" + 2); // expected-warning {{adding 'int' to a string does not append to the string}} expected-note {{use array indexing to silence this warning}}
+
+  consume("foo" + 3);  // expected-warning {{adding 'int' to a string does not append to the string}} expected-note {{use array indexing to silence this warning}}
+  consume("foo" + 4);  // expected-warning {{adding 'int' to a string does not append to the string}} expected-note {{use array indexing to silence this warning}}
+  consume("\pfoo" + 4);  // expected-warning {{adding 'int' to a string does not append to the string}} expected-note {{use array indexing to silence this warning}}
+
+  #define A "foo"
+  #define B "bar"
+  consume(A B + sizeof(A) - 1); // expected-warning {{to a string does not append to the string}} expected-note {{use array indexing to silence this warning}}
 
   // Should not warn.
   consume(&("foo"[3]));
   consume(&("foo"[index]));
   consume(&("foo"[kMyEnum]));
-  consume("foo" + kMySmallEnum);
-  consume(kMySmallEnum + "foo");
 
-  consume(L"foo" + 2);
-
-  consume("foo" + 3);  // Points at the \0
-  consume("foo" + 4);  // Points 1 past the \0, which is legal too.
-  consume("\pfoo" + 4);  // Pascal strings don't have a trailing \0, but they
-                         // have a leading length byte, so this is fine too.
 
   consume("foo" + kMyOperatorOverloadedEnum);
   consume(kMyOperatorOverloadedEnum + "foo");
-
-  #define A "foo"
-  #define B "bar"
-  consume(A B + sizeof(A) - 1);
 }
 
 template 
-- 
cgit v1.2.3


From 5f2efcd632af7e02e05ec9473f3875caf449ecd5 Mon Sep 17 00:00:00 2001
From: Nico Weber 
Date: Thu, 3 Jan 2019 18:26:06 +0000
Subject: Validate -add-plugin arguments.

-plugin already prints an error if the name of an unknown plugin is passed.
-add-plugin used to silently ignore that, now it errors too.

Differential Revision: https://reviews.llvm.org/D56273


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350340 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/Frontend/CompilerInvocation.cpp | 16 +++++++++++++++-
 test/Frontend/plugin-unknown.c      |  5 +++++
 2 files changed, 20 insertions(+), 1 deletion(-)
 create mode 100644 test/Frontend/plugin-unknown.c

diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index 220cad2738..39152fda99 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -33,6 +33,7 @@
 #include "clang/Frontend/DependencyOutputOptions.h"
 #include "clang/Frontend/FrontendDiagnostic.h"
 #include "clang/Frontend/FrontendOptions.h"
+#include "clang/Frontend/FrontendPluginRegistry.h"
 #include "clang/Frontend/LangStandard.h"
 #include "clang/Frontend/MigratorOptions.h"
 #include "clang/Frontend/PreprocessorOutputOptions.h"
@@ -1663,7 +1664,20 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
     Opts.ProgramAction = frontend::PluginAction;
     Opts.ActionName = A->getValue();
   }
-  Opts.AddPluginActions = Args.getAllArgValues(OPT_add_plugin);
+  for (const std::string &Arg : Args.getAllArgValues(OPT_add_plugin)) {
+    bool Found = false;
+    for (FrontendPluginRegistry::iterator it = FrontendPluginRegistry::begin(),
+                                          ie = FrontendPluginRegistry::end();
+         it != ie; ++it) {
+      if (it->getName() == Arg)
+        Found = true;
+    }
+    if (!Found) {
+      Diags.Report(diag::err_fe_invalid_plugin_name) << Arg;
+      continue;
+    }
+    Opts.AddPluginActions.push_back(Arg);
+  }
   for (const auto *AA : Args.filtered(OPT_plugin_arg))
     Opts.PluginArgs[AA->getValue(0)].emplace_back(AA->getValue(1));
 
diff --git a/test/Frontend/plugin-unknown.c b/test/Frontend/plugin-unknown.c
new file mode 100644
index 0000000000..5b225ae663
--- /dev/null
+++ b/test/Frontend/plugin-unknown.c
@@ -0,0 +1,5 @@
+// RUN: not %clang_cc1 -plugin asdf %s 2>&1 | FileCheck %s
+// RUN: not %clang_cc1 -add-plugin asdf %s 2>&1 | FileCheck --check-prefix=ADD %s
+
+// CHECK: unable to find plugin 'asdf'
+// ADD: unable to find plugin 'asdf'
-- 
cgit v1.2.3


From 700276059e0a944bb0f0418891a1f52e1bd0af9b Mon Sep 17 00:00:00 2001
From: Evgeniy Stepanov 
Date: Thu, 3 Jan 2019 22:41:10 +0000
Subject: [cmake] Fix monorepo + LLVM_BUILD_EXTERNAL_COMPILER_RT=ON.

In cmake 3.10.2, if (${VARIABLE_NAME}) seems to always be false no
matter what documentation says (or maybe I just failed at reading).

Anyway, if (VARIABLE_NAME) seems to do what this code intended.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350361 91177308-0d34-0410-b5e6-96231b3b80d8
---
 runtime/CMakeLists.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/runtime/CMakeLists.txt b/runtime/CMakeLists.txt
index 9c2f5cd9cf..3de9612180 100644
--- a/runtime/CMakeLists.txt
+++ b/runtime/CMakeLists.txt
@@ -28,7 +28,7 @@ set(COMPILER_RT_SRC_ROOT ${LLVM_MAIN_SRC_DIR}/projects/compiler-rt)
 # variable) as in add_llvm_external_project
 if(NOT EXISTS ${COMPILER_RT_SRC_ROOT})
   # We don't want to set it if LLVM_EXTERNAL_COMPILER_RT_SOURCE_DIR is ""
-  if(${LLVM_EXTERNAL_COMPILER_RT_SOURCE_DIR})
+  if(LLVM_EXTERNAL_COMPILER_RT_SOURCE_DIR)
     set(COMPILER_RT_SRC_ROOT ${LLVM_EXTERNAL_COMPILER_RT_SOURCE_DIR})
   endif()
 endif()
-- 
cgit v1.2.3


From 5fb6331bb72954ba8799595aba6d5ee35cfe3af9 Mon Sep 17 00:00:00 2001
From: Evgeniy Stepanov 
Date: Thu, 3 Jan 2019 22:50:45 +0000
Subject: Fix check-hwasan with LLVM_BUILD_EXTERNAL_COMPILER_RT=ON

Add a forwarding target for check-hwasan in clang.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350363 91177308-0d34-0410-b5e6-96231b3b80d8
---
 runtime/CMakeLists.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/runtime/CMakeLists.txt b/runtime/CMakeLists.txt
index 3de9612180..6f453f96d7 100644
--- a/runtime/CMakeLists.txt
+++ b/runtime/CMakeLists.txt
@@ -126,7 +126,7 @@ if(LLVM_BUILD_EXTERNAL_COMPILER_RT AND EXISTS ${COMPILER_RT_SRC_ROOT}/)
       FileCheck count not llvm-nm llvm-objdump llvm-symbolizer)
 
     # Add top-level targets for various compiler-rt test suites.
-    set(COMPILER_RT_TEST_SUITES check-fuzzer check-asan check-asan-dynamic check-dfsan
+    set(COMPILER_RT_TEST_SUITES check-fuzzer check-asan check-hwasan check-asan-dynamic check-dfsan
       check-lsan check-msan check-sanitizer check-tsan check-ubsan check-ubsan-minimal
       check-profile check-cfi check-cfi-and-supported check-safestack)
     foreach(test_suite ${COMPILER_RT_TEST_SUITES})
-- 
cgit v1.2.3


From c2024f6ec2c636a7da713bf50a19a5990746aa4a Mon Sep 17 00:00:00 2001
From: Mike Spertus 
Date: Thu, 3 Jan 2019 23:24:39 +0000
Subject: Fix MSVC visualizations for ActionResult and OpaquePtr

Mainly just fixing buggy code. Also removed unnecessary visualizers
for specializations of OpaquePtr



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350371 91177308-0d34-0410-b5e6-96231b3b80d8
---
 utils/ClangVisualizers/clang.natvis | 40 ++++++++-----------------------------
 1 file changed, 8 insertions(+), 32 deletions(-)

diff --git a/utils/ClangVisualizers/clang.natvis b/utils/ClangVisualizers/clang.natvis
index 7ddcb5db5f..24c4715cca 100644
--- a/utils/ClangVisualizers/clang.natvis
+++ b/utils/ClangVisualizers/clang.natvis
@@ -492,18 +492,6 @@ For later versions of Visual Studio, no setup is required-->
       *(clang::Type *)this, view(cmn)
     
   
-  
-    {*(clang::QualType *)this}
-    
-      *(clang::QualType *)this
-    
-  
-  
-    {*(clang::QualType *)this}
-    
-      *(clang::QualType *)this
-    
-  
   
     {($T1 *)Ptr}
     
@@ -568,30 +556,18 @@ For later versions of Visual Studio, no setup is required-->
     {Ambiguity,en}: {Decls}
     {ResultKind,en}: {Decls}
   
-  
-    Invalid
-    Valid
-   
-  
+  
     Invalid
-    Valid
+    Unset
+    {Val}
   
-  
-    {*this,view(packedValidity)}: {($T1 *)(PtrWithInvalid&~1)}
+  
+    Invalid
+    Unset
+    {($T1)(PtrWithInvalid&~1)}
     
       (bool)(PtrWithInvalid&1)
-      ($T1 *)(PtrWithInvalid&~1)
-    
-  
-  
-    {*this,view(unpackedValidity)}: {Val}
-  
-  
-    {*this,view(packed)}
-    {*this,view(unpacked)}
-    
-      *this,view(packed)
-      *this,view(unpacked)
+      ($T1)(PtrWithInvalid&~1)
     
   
 
-- 
cgit v1.2.3


From c72bf467c95d38f437f2dbacddf38611c21aa99a Mon Sep 17 00:00:00 2001
From: Daniel Dunbar 
Date: Thu, 3 Jan 2019 23:24:50 +0000
Subject: Adopt SwiftABIInfo for WebAssembly.

Summary:
 - This adopts SwiftABIInfo as the base class for WebAssemblyABIInfo, which is in keeping with what is done for other targets for which Swift is supported.

 - This is a minimal patch to unblock exploration of WASM support for Swift (https://bugs.swift.org/browse/SR-9307)

Reviewers: rjmccall, sunfish

Reviewed By: rjmccall

Subscribers: ahti, dschuff, sbc100, jgravelle-google, aheejin, cfe-commits

Differential Revision: https://reviews.llvm.org/D56188

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350372 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/CodeGen/TargetInfo.cpp | 23 +++++++++++++++++------
 1 file changed, 17 insertions(+), 6 deletions(-)

diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp
index ae080f5bbd..89ec73670a 100644
--- a/lib/CodeGen/TargetInfo.cpp
+++ b/lib/CodeGen/TargetInfo.cpp
@@ -720,10 +720,12 @@ ABIArgInfo DefaultABIInfo::classifyReturnType(QualType RetTy) const {
 // This is a very simple ABI that relies a lot on DefaultABIInfo.
 //===----------------------------------------------------------------------===//
 
-class WebAssemblyABIInfo final : public DefaultABIInfo {
+class WebAssemblyABIInfo final : public SwiftABIInfo {
+  DefaultABIInfo defaultInfo;
+
 public:
   explicit WebAssemblyABIInfo(CodeGen::CodeGenTypes &CGT)
-      : DefaultABIInfo(CGT) {}
+      : SwiftABIInfo(CGT), defaultInfo(CGT) {}
 
 private:
   ABIArgInfo classifyReturnType(QualType RetTy) const;
@@ -741,6 +743,15 @@ private:
 
   Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
                     QualType Ty) const override;
+
+  bool shouldPassIndirectlyForSwift(ArrayRef scalars,
+                                    bool asReturnValue) const override {
+    return occupiesMoreThan(CGT, scalars, /*total*/ 4);
+  }
+
+  bool isSwiftErrorInRegister() const override {
+    return false;
+  }
 };
 
 class WebAssemblyTargetCodeGenInfo final : public TargetCodeGenInfo {
@@ -778,7 +789,7 @@ ABIArgInfo WebAssemblyABIInfo::classifyArgumentType(QualType Ty) const {
   }
 
   // Otherwise just do the default thing.
-  return DefaultABIInfo::classifyArgumentType(Ty);
+  return defaultInfo.classifyArgumentType(Ty);
 }
 
 ABIArgInfo WebAssemblyABIInfo::classifyReturnType(QualType RetTy) const {
@@ -798,7 +809,7 @@ ABIArgInfo WebAssemblyABIInfo::classifyReturnType(QualType RetTy) const {
   }
 
   // Otherwise just do the default thing.
-  return DefaultABIInfo::classifyReturnType(RetTy);
+  return defaultInfo.classifyReturnType(RetTy);
 }
 
 Address WebAssemblyABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
@@ -8307,7 +8318,7 @@ ABIArgInfo ARCABIInfo::getIndirectByRef(QualType Ty, bool HasFreeRegs) const {
 }
 
 ABIArgInfo ARCABIInfo::getIndirectByValue(QualType Ty) const {
-  // Compute the byval alignment. 
+  // Compute the byval alignment.
   const unsigned MinABIStackAlignInBytes = 4;
   unsigned TypeAlign = getContext().getTypeAlign(Ty) / 8;
   return ABIArgInfo::getIndirect(CharUnits::fromQuantity(4), /*ByVal=*/true,
@@ -8371,7 +8382,7 @@ ABIArgInfo ARCABIInfo::classifyReturnType(QualType RetTy) const {
   if (RetTy->isAnyComplexType())
     return ABIArgInfo::getDirectInReg();
 
-  // Arguments of size > 4 registers are indirect.  
+  // Arguments of size > 4 registers are indirect.
   auto RetSize = llvm::alignTo(getContext().getTypeSize(RetTy), 32) / 32;
   if (RetSize > 4)
     return getIndirectByRef(RetTy, /*HasFreeRegs*/ true);
-- 
cgit v1.2.3


From dfe36d72bcb3226bc633eafaf7487612b2e75f0e Mon Sep 17 00:00:00 2001
From: Anastasia Stulova 
Date: Fri, 4 Jan 2019 11:50:36 +0000
Subject: [Basic] Extend DiagnosticEngine to store and format Qualifiers.

Qualifiers can now be streamed into the DiagnosticEngine using
regular << operator. If Qualifiers are empty 'unqualified' will
be printed in the diagnostic otherwise regular qual syntax is
used.

Differential Revision: https://reviews.llvm.org/D56198



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350386 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/AST/Type.h                     | 18 ++++++++++++++++++
 include/clang/Basic/Diagnostic.h             |  3 +++
 include/clang/Basic/DiagnosticSemaKinds.td   | 24 ++++--------------------
 lib/AST/ASTDiagnostic.cpp                    | 14 ++++++++++++++
 lib/Basic/Diagnostic.cpp                     |  1 +
 lib/Sema/SemaOverload.cpp                    |  8 +++-----
 test/SemaCXX/addr-of-overloaded-function.cpp | 14 +++++++-------
 test/SemaCXX/warn-overloaded-virtual.cpp     |  2 +-
 8 files changed, 51 insertions(+), 33 deletions(-)

diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
index cff63d0926..d4c97b1b5e 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -6701,6 +6701,24 @@ inline const Type *Type::getPointeeOrArrayElementType() const {
   return type;
 }
 
+/// Insertion operator for diagnostics. This allows sending Qualifiers into a
+/// diagnostic with <<.
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+                                           Qualifiers Q) {
+  DB.AddTaggedVal(Q.getAsOpaqueValue(),
+                  DiagnosticsEngine::ArgumentKind::ak_qual);
+  return DB;
+}
+
+/// Insertion operator for partial diagnostics. This allows sending Qualifiers
+/// into a diagnostic with <<.
+inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
+                                           Qualifiers Q) {
+  PD.AddTaggedVal(Q.getAsOpaqueValue(),
+                  DiagnosticsEngine::ArgumentKind::ak_qual);
+  return PD;
+}
+
 /// Insertion operator for diagnostics.  This allows sending QualType's into a
 /// diagnostic with <<.
 inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
diff --git a/include/clang/Basic/Diagnostic.h b/include/clang/Basic/Diagnostic.h
index d7e1c62890..a516721ace 100644
--- a/include/clang/Basic/Diagnostic.h
+++ b/include/clang/Basic/Diagnostic.h
@@ -177,6 +177,9 @@ public:
     /// IdentifierInfo
     ak_identifierinfo,
 
+    /// Qualifiers
+    ak_qual,
+
     /// QualType
     ak_qualtype,
 
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index c69566a2d2..375f9515b2 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1809,11 +1809,7 @@ def err_init_conversion_failed : Error<
   "|: different number of parameters (%5 vs %6)"
   "|: type mismatch at %ordinal5 parameter%diff{ ($ vs $)|}6,7"
   "|: different return type%diff{ ($ vs $)|}5,6"
-  "|: different qualifiers ("
-  "%select{none|const|restrict|const and restrict|volatile|const and volatile|"
-  "volatile and restrict|const, volatile, and restrict}5 vs "
-  "%select{none|const|restrict|const and restrict|volatile|const and volatile|"
-  "volatile and restrict|const, volatile, and restrict}6)"
+  "|: different qualifiers (%5 vs %6)"
   "|: different exception specifications}4">;
 
 def err_lvalue_to_rvalue_ref : Error<"rvalue reference %diff{to type $ cannot "
@@ -3593,11 +3589,7 @@ def note_ovl_candidate : Note<
     "| has type mismatch at %ordinal5 parameter"
     "%diff{ (expected $ but has $)|}6,7"
     "| has different return type%diff{ ($ expected but has $)|}5,6"
-    "| has different qualifiers (expected "
-    "%select{none|const|restrict|const and restrict|volatile|const and volatile"
-    "|volatile and restrict|const, volatile, and restrict}5 but found "
-    "%select{none|const|restrict|const and restrict|volatile|const and volatile"
-    "|volatile and restrict|const, volatile, and restrict}6)"
+    "| has different qualifiers (expected %5 but found %6)"
     "| has different exception specification}4">;
 
 def note_ovl_candidate_inherited_constructor : Note<
@@ -6470,11 +6462,7 @@ def note_hidden_overloaded_virtual_declared_here : Note<
   "|: different number of parameters (%2 vs %3)"
   "|: type mismatch at %ordinal2 parameter%diff{ ($ vs $)|}3,4"
   "|: different return type%diff{ ($ vs $)|}2,3"
-  "|: different qualifiers ("
-  "%select{none|const|restrict|const and restrict|volatile|const and volatile|"
-  "volatile and restrict|const, volatile, and restrict}2 vs "
-  "%select{none|const|restrict|const and restrict|volatile|const and volatile|"
-  "volatile and restrict|const, volatile, and restrict}3)"
+  "|: different qualifiers (%2 vs %3)"
   "|: different exception specifications}1">;
 def warn_using_directive_in_header : Warning<
   "using namespace directive in global context in header">,
@@ -6748,11 +6736,7 @@ def err_typecheck_convert_incompatible : Error<
   "|: different number of parameters (%5 vs %6)"
   "|: type mismatch at %ordinal5 parameter%diff{ ($ vs $)|}6,7"
   "|: different return type%diff{ ($ vs $)|}5,6"
-  "|: different qualifiers ("
-  "%select{none|const|restrict|const and restrict|volatile|const and volatile|"
-  "volatile and restrict|const, volatile, and restrict}5 vs "
-  "%select{none|const|restrict|const and restrict|volatile|const and volatile|"
-  "volatile and restrict|const, volatile, and restrict}6)"
+  "|: different qualifiers (%5 vs %6)"
   "|: different exception specifications}4">;
 def err_typecheck_missing_return_type_incompatible : Error<
   "%diff{return type $ must match previous return type $|"
diff --git a/lib/AST/ASTDiagnostic.cpp b/lib/AST/ASTDiagnostic.cpp
index 50d2d2999e..dd05855585 100644
--- a/lib/AST/ASTDiagnostic.cpp
+++ b/lib/AST/ASTDiagnostic.cpp
@@ -334,6 +334,20 @@ void clang::FormatASTNodeDiagnosticArgument(
 
   switch (Kind) {
     default: llvm_unreachable("unknown ArgumentKind");
+    case DiagnosticsEngine::ak_qual: {
+      assert(Modifier.empty() && Argument.empty() &&
+             "Invalid modifier for Qualfiers argument");
+
+      Qualifiers Q(Qualifiers::fromOpaqueValue(Val));
+      auto S = Q.getAsString();
+      if (S.empty()) {
+        OS << "unqualified";
+        NeedQuotes = false;
+      } else {
+        OS << Q.getAsString();
+      }
+      break;
+    }
     case DiagnosticsEngine::ak_qualtype_pair: {
       TemplateDiffTypes &TDT = *reinterpret_cast(Val);
       QualType FromType =
diff --git a/lib/Basic/Diagnostic.cpp b/lib/Basic/Diagnostic.cpp
index ffe92e157e..56c54cb907 100644
--- a/lib/Basic/Diagnostic.cpp
+++ b/lib/Basic/Diagnostic.cpp
@@ -983,6 +983,7 @@ FormatDiagnostic(const char *DiagStr, const char *DiagEnd,
       llvm::raw_svector_ostream(OutStr) << '\'' << II->getName() << '\'';
       break;
     }
+    case DiagnosticsEngine::ak_qual:
     case DiagnosticsEngine::ak_qualtype:
     case DiagnosticsEngine::ak_declarationname:
     case DiagnosticsEngine::ak_nameddecl:
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 94f7979f66..6f50dd9bcc 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -2824,11 +2824,9 @@ void Sema::HandleFunctionTypeMismatch(PartialDiagnostic &PDiag,
     return;
   }
 
-  // FIXME: OpenCL: Need to consider address spaces
-  unsigned FromQuals = FromFunction->getTypeQuals().getCVRUQualifiers();
-  unsigned ToQuals = ToFunction->getTypeQuals().getCVRUQualifiers();
-  if (FromQuals != ToQuals) {
-    PDiag << ft_qualifer_mismatch << ToQuals << FromQuals;
+  if (FromFunction->getTypeQuals() != ToFunction->getTypeQuals()) {
+    PDiag << ft_qualifer_mismatch << ToFunction->getTypeQuals()
+          << FromFunction->getTypeQuals();
     return;
   }
 
diff --git a/test/SemaCXX/addr-of-overloaded-function.cpp b/test/SemaCXX/addr-of-overloaded-function.cpp
index cca847b4d2..6b6734bae1 100644
--- a/test/SemaCXX/addr-of-overloaded-function.cpp
+++ b/test/SemaCXX/addr-of-overloaded-function.cpp
@@ -221,13 +221,13 @@ namespace test1 {
 
   void QualifierTest() {
     void (Qualifiers::*X)();
-    X = &Qualifiers::C; // expected-error-re {{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} const': different qualifiers (none vs const)}}
-    X = &Qualifiers::V; // expected-error-re{{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} volatile': different qualifiers (none vs volatile)}}
-    X = &Qualifiers::R; // expected-error-re{{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} __restrict': different qualifiers (none vs restrict)}}
-    X = &Qualifiers::CV; // expected-error-re{{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} const volatile': different qualifiers (none vs const and volatile)}}
-    X = &Qualifiers::CR; // expected-error-re{{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} const __restrict': different qualifiers (none vs const and restrict)}}
-    X = &Qualifiers::VR; // expected-error-re{{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} volatile __restrict': different qualifiers (none vs volatile and restrict)}}
-    X = &Qualifiers::CVR; // expected-error-re{{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} const volatile __restrict': different qualifiers (none vs const, volatile, and restrict)}}
+    X = &Qualifiers::C; // expected-error-re {{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} const': different qualifiers (unqualified vs 'const')}}
+    X = &Qualifiers::V; // expected-error-re{{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} volatile': different qualifiers (unqualified vs 'volatile')}}
+    X = &Qualifiers::R; // expected-error-re{{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} __restrict': different qualifiers (unqualified vs '__restrict')}}
+    X = &Qualifiers::CV; // expected-error-re{{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} const volatile': different qualifiers (unqualified vs 'const volatile')}}
+    X = &Qualifiers::CR; // expected-error-re{{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} const __restrict': different qualifiers (unqualified vs 'const __restrict')}}
+    X = &Qualifiers::VR; // expected-error-re{{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} volatile __restrict': different qualifiers (unqualified vs 'volatile __restrict')}}
+    X = &Qualifiers::CVR; // expected-error-re{{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} const volatile __restrict': different qualifiers (unqualified vs 'const volatile __restrict')}}
   }
 
   struct Dummy {
diff --git a/test/SemaCXX/warn-overloaded-virtual.cpp b/test/SemaCXX/warn-overloaded-virtual.cpp
index 6204826192..271416d04d 100644
--- a/test/SemaCXX/warn-overloaded-virtual.cpp
+++ b/test/SemaCXX/warn-overloaded-virtual.cpp
@@ -130,7 +130,7 @@ namespace {
     virtual int foo(int*) const;
     // expected-note@-1{{type mismatch at 1st parameter ('int *' vs 'int')}}
     virtual int foo(int) volatile;
-    // expected-note@-1{{different qualifiers (volatile vs const)}}
+    // expected-note@-1{{different qualifiers ('volatile' vs 'const')}}
   };
 
   class B : public A {
-- 
cgit v1.2.3


From 4e3dd793d75b1710618a091fa8a037c5a75c2525 Mon Sep 17 00:00:00 2001
From: Erich Keane 
Date: Fri, 4 Jan 2019 15:24:06 +0000
Subject: Prevent unreachable when checking invalid multiversion decls.

CPUSpecifc/CPUDispatch call resolution assumed that all declarations
that would be passed are valid, however this was an invalid assumption.
This patch deals with those situations by making the valid version take
priority.  Note that the checked ordering is arbitrary, since both are
replaced by calls to the resolver later.

Change-Id: I7ff2ec88c55a721d51bc1f39ea1a1fe242b4e45f

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350398 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/Sema/SemaOverload.cpp    |  5 +++++
 test/Sema/attr-cpuspecific.c | 12 ++++++++++++
 2 files changed, 17 insertions(+)

diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 6f50dd9bcc..257eef435f 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -9023,6 +9023,11 @@ static bool isBetterMultiversionCandidate(const OverloadCandidate &Cand1,
       !Cand2.Function->isMultiVersion())
     return false;
 
+  // If Cand1 is invalid, it cannot be a better match, if Cand2 is invalid, this
+  // is obviously better.
+  if (Cand1.Function->isInvalidDecl()) return false;
+  if (Cand2.Function->isInvalidDecl()) return true;
+
   // If this is a cpu_dispatch/cpu_specific multiversion situation, prefer
   // cpu_dispatch, else arbitrarily based on the identifiers.
   bool Cand1CPUDisp = Cand1.Function->hasAttr();
diff --git a/test/Sema/attr-cpuspecific.c b/test/Sema/attr-cpuspecific.c
index 4d21a8c894..d15a65ea1f 100644
--- a/test/Sema/attr-cpuspecific.c
+++ b/test/Sema/attr-cpuspecific.c
@@ -92,3 +92,15 @@ __vectorcall int __attribute__((cpu_specific(sandybridge))) diff_cc(void);
 int __attribute__((cpu_dispatch(atom))) disp_with_body(void) {
   return 5;
 }
+
+// expected-error@+1 {{invalid option 'INVALID'}}
+int __attribute__((cpu_specific(INVALID))) called_invalid_value(void){ return 1;}
+// expected-warning@+3 {{attribute declaration must precede definition}}
+// expected-note@-2 2 {{previous definition is here}}
+// expected-error@+1 {{redefinition of}}
+int __attribute__((cpu_specific(pentium_iii))) called_invalid_value(void){ return 2;}
+int __attribute__((cpu_specific(pentium_4))) called_invalid_value(void){ return 3;}
+
+int use3(void) {
+  return called_invalid_value();
+}
-- 
cgit v1.2.3


From bf91d084aea415a34bd7d8fbb2ca5c8c4aa74db9 Mon Sep 17 00:00:00 2001
From: Aaron Ballman 
Date: Fri, 4 Jan 2019 16:58:14 +0000
Subject: Refactor the way we handle diagnosing unused expression results.

Rather than sprinkle calls to DiagnoseUnusedExprResult() around in places where we want diagnostics, we now diagnose unused expression statements and full expressions in a more generic way when acting on the final expression statement. This results in more appropriate diagnostics for [[nodiscard]] where we were previously lacking them, such as when the body of a for loop is not a compound statement.

This patch fixes PR39837.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350404 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/Parse/Parser.h                     |  5 ++
 include/clang/Sema/Sema.h                        | 19 +++----
 lib/Parse/ParseObjc.cpp                          |  2 +-
 lib/Parse/ParseOpenMP.cpp                        | 14 ++---
 lib/Parse/ParseStmt.cpp                          | 26 ++++++++--
 lib/Sema/SemaCoroutine.cpp                       | 17 ++++---
 lib/Sema/SemaDecl.cpp                            |  6 +--
 lib/Sema/SemaDeclCXX.cpp                         | 14 ++---
 lib/Sema/SemaExpr.cpp                            |  5 +-
 lib/Sema/SemaExprCXX.cpp                         |  2 +
 lib/Sema/SemaLambda.cpp                          |  2 +-
 lib/Sema/SemaOpenMP.cpp                          | 55 ++++++++++++--------
 lib/Sema/SemaStmt.cpp                            | 65 ++++++++++--------------
 lib/Sema/TreeTransform.h                         | 15 +++---
 test/CXX/stmt.stmt/stmt.select/p3.cpp            |  9 ++--
 test/CodeCompletion/pragma-macro-token-caching.c |  2 +-
 test/Parser/cxx1z-init-statement.cpp             |  8 +--
 test/Parser/switch-recovery.cpp                  |  2 +-
 test/SemaCXX/cxx1z-init-statement.cpp            |  8 +--
 test/SemaCXX/for-range-examples.cpp              |  2 +-
 test/SemaCXX/warn-unused-result.cpp              | 40 +++++++++++++++
 21 files changed, 196 insertions(+), 122 deletions(-)

diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h
index 46e4431913..438ff0e2ed 100644
--- a/include/clang/Parse/Parser.h
+++ b/include/clang/Parse/Parser.h
@@ -360,6 +360,11 @@ class Parser : public CodeCompletionHandler {
   /// just a regular sub-expression.
   SourceLocation ExprStatementTokLoc;
 
+  /// Tests whether an expression value is discarded based on token lookahead.
+  /// It will return true if the lexer is currently processing the })
+  /// terminating a GNU statement expression and false otherwise.
+  bool isExprValueDiscarded();
+
 public:
   Parser(Preprocessor &PP, Sema &Actions, bool SkipFunctionBodies);
   ~Parser() override;
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index 6d002b3710..92bebcae7c 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -1365,6 +1365,7 @@ public:
   void PopCompoundScope();
 
   sema::CompoundScopeInfo &getCurCompoundScope() const;
+  bool isCurCompoundStmtAStmtExpr() const;
 
   bool hasAnyUnrecoverableErrorsInThisFunction() const;
 
@@ -3685,16 +3686,17 @@ public:
     return MakeFullExpr(Arg, Arg ? Arg->getExprLoc() : SourceLocation());
   }
   FullExprArg MakeFullExpr(Expr *Arg, SourceLocation CC) {
-    return FullExprArg(ActOnFinishFullExpr(Arg, CC).get());
+    return FullExprArg(
+        ActOnFinishFullExpr(Arg, CC, /*DiscardedValue*/ false).get());
   }
   FullExprArg MakeFullDiscardedValueExpr(Expr *Arg) {
     ExprResult FE =
-      ActOnFinishFullExpr(Arg, Arg ? Arg->getExprLoc() : SourceLocation(),
-                          /*DiscardedValue*/ true);
+        ActOnFinishFullExpr(Arg, Arg ? Arg->getExprLoc() : SourceLocation(),
+                            /*DiscardedValue*/ true);
     return FullExprArg(FE.get());
   }
 
-  StmtResult ActOnExprStmt(ExprResult Arg);
+  StmtResult ActOnExprStmt(ExprResult Arg, bool DiscardedValue = true);
   StmtResult ActOnExprStmtError();
 
   StmtResult ActOnNullStmt(SourceLocation SemiLoc,
@@ -5340,13 +5342,12 @@ public:
   CreateMaterializeTemporaryExpr(QualType T, Expr *Temporary,
                                  bool BoundToLvalueReference);
 
-  ExprResult ActOnFinishFullExpr(Expr *Expr) {
-    return ActOnFinishFullExpr(Expr, Expr ? Expr->getExprLoc()
-                                          : SourceLocation());
+  ExprResult ActOnFinishFullExpr(Expr *Expr, bool DiscardedValue) {
+    return ActOnFinishFullExpr(
+        Expr, Expr ? Expr->getExprLoc() : SourceLocation(), DiscardedValue);
   }
   ExprResult ActOnFinishFullExpr(Expr *Expr, SourceLocation CC,
-                                 bool DiscardedValue = false,
-                                 bool IsConstexpr = false);
+                                 bool DiscardedValue, bool IsConstexpr = false);
   StmtResult ActOnFinishFullStmt(Stmt *Stmt);
 
   // Marks SS invalid if it represents an incomplete type.
diff --git a/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp
index c8d7bda3d6..bd55f71793 100644
--- a/lib/Parse/ParseObjc.cpp
+++ b/lib/Parse/ParseObjc.cpp
@@ -2741,7 +2741,7 @@ StmtResult Parser::ParseObjCAtStatement(SourceLocation AtLoc) {
 
   // Otherwise, eat the semicolon.
   ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);
-  return Actions.ActOnExprStmt(Res);
+  return Actions.ActOnExprStmt(Res, isExprValueDiscarded());
 }
 
 ExprResult Parser::ParseObjCAtExpression(SourceLocation AtLoc) {
diff --git a/lib/Parse/ParseOpenMP.cpp b/lib/Parse/ParseOpenMP.cpp
index 17c3fa3cf2..dd2a8aae9f 100644
--- a/lib/Parse/ParseOpenMP.cpp
+++ b/lib/Parse/ParseOpenMP.cpp
@@ -314,7 +314,7 @@ Parser::ParseOpenMPDeclareReductionDirective(AccessSpecifier AS) {
     Actions.ActOnOpenMPDeclareReductionCombinerStart(getCurScope(), D);
     ExprResult CombinerResult =
         Actions.ActOnFinishFullExpr(ParseAssignmentExpression().get(),
-                                    D->getLocation(), /*DiscardedValue=*/true);
+                                    D->getLocation(), /*DiscardedValue*/ false);
     Actions.ActOnOpenMPDeclareReductionCombinerEnd(D, CombinerResult.get());
 
     if (CombinerResult.isInvalid() && Tok.isNot(tok::r_paren) &&
@@ -356,7 +356,7 @@ Parser::ParseOpenMPDeclareReductionDirective(AccessSpecifier AS) {
           if (Actions.getLangOpts().CPlusPlus) {
             InitializerResult = Actions.ActOnFinishFullExpr(
                 ParseAssignmentExpression().get(), D->getLocation(),
-                /*DiscardedValue=*/true);
+                /*DiscardedValue*/ false);
           } else {
             ConsumeToken();
             ParseOpenMPReductionInitializerForDecl(OmpPrivParm);
@@ -364,7 +364,7 @@ Parser::ParseOpenMPDeclareReductionDirective(AccessSpecifier AS) {
         } else {
           InitializerResult = Actions.ActOnFinishFullExpr(
               ParseAssignmentExpression().get(), D->getLocation(),
-              /*DiscardedValue=*/true);
+              /*DiscardedValue*/ false);
         }
         Actions.ActOnOpenMPDeclareReductionInitializerEnd(
             D, InitializerResult.get(), OmpPrivParm);
@@ -1455,7 +1455,7 @@ ExprResult Parser::ParseOpenMPParensExpr(StringRef ClauseName,
   ExprResult LHS(ParseCastExpression(
       /*isUnaryExpression=*/false, /*isAddressOfOperand=*/false, NotTypeCast));
   ExprResult Val(ParseRHSOfBinaryExpression(LHS, prec::Conditional));
-  Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc);
+  Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc, /*DiscardedValue*/ false);
 
   // Parse ')'.
   RLoc = Tok.getLocation();
@@ -1711,7 +1711,8 @@ OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind,
     SourceLocation ELoc = Tok.getLocation();
     ExprResult LHS(ParseCastExpression(false, false, NotTypeCast));
     Val = ParseRHSOfBinaryExpression(LHS, prec::Conditional);
-    Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc);
+    Val =
+        Actions.ActOnFinishFullExpr(Val.get(), ELoc, /*DiscardedValue*/ false);
   }
 
   // Parse ')'.
@@ -1996,7 +1997,8 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
     Data.ColonLoc = Tok.getLocation();
     SourceLocation ELoc = ConsumeToken();
     ExprResult Tail = ParseAssignmentExpression();
-    Tail = Actions.ActOnFinishFullExpr(Tail.get(), ELoc);
+    Tail =
+        Actions.ActOnFinishFullExpr(Tail.get(), ELoc, /*DiscardedValue*/ false);
     if (Tail.isUsable())
       Data.TailExpr = Tail.get();
     else
diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp
index 313793c3e8..2974e6a245 100644
--- a/lib/Parse/ParseStmt.cpp
+++ b/lib/Parse/ParseStmt.cpp
@@ -439,7 +439,7 @@ StmtResult Parser::ParseExprStatement() {
 
   // Otherwise, eat the semicolon.
   ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);
-  return Actions.ActOnExprStmt(Expr);
+  return Actions.ActOnExprStmt(Expr, isExprValueDiscarded());
 }
 
 /// ParseSEHTryBlockCommon
@@ -958,6 +958,16 @@ bool Parser::ConsumeNullStmt(StmtVector &Stmts) {
   return true;
 }
 
+bool Parser::isExprValueDiscarded() {
+  if (Actions.isCurCompoundStmtAStmtExpr()) {
+    // Look to see if the next two tokens close the statement expression;
+    // if so, this expression statement is the last statement in a
+    // statment expression.
+    return Tok.isNot(tok::r_brace) || NextToken().isNot(tok::r_paren);
+  }
+  return true;
+}
+
 /// ParseCompoundStatementBody - Parse a sequence of statements and invoke the
 /// ActOnCompoundStmt action.  This expects the '{' to be the current token, and
 /// consume the '}' at the end of the block.  It does not manipulate the scope
@@ -1062,7 +1072,7 @@ StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) {
         // Eat the semicolon at the end of stmt and convert the expr into a
         // statement.
         ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);
-        R = Actions.ActOnExprStmt(Res);
+        R = Actions.ActOnExprStmt(Res, isExprValueDiscarded());
       }
     }
 
@@ -1698,8 +1708,16 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) {
     if (!Value.isInvalid()) {
       if (ForEach)
         FirstPart = Actions.ActOnForEachLValueExpr(Value.get());
-      else
-        FirstPart = Actions.ActOnExprStmt(Value);
+      else {
+        // We already know this is not an init-statement within a for loop, so
+        // if we are parsing a C++11 range-based for loop, we should treat this
+        // expression statement as being a discarded value expression because
+        // we will err below. This way we do not warn on an unused expression
+        // that was an error in the first place, like with: for (expr : expr);
+        bool IsRangeBasedFor =
+            getLangOpts().CPlusPlus11 && !ForEach && Tok.is(tok::colon);
+        FirstPart = Actions.ActOnExprStmt(Value, !IsRangeBasedFor);
+      }
     }
 
     if (Tok.is(tok::semi)) {
diff --git a/lib/Sema/SemaCoroutine.cpp b/lib/Sema/SemaCoroutine.cpp
index cc79238470..a84116c1bc 100644
--- a/lib/Sema/SemaCoroutine.cpp
+++ b/lib/Sema/SemaCoroutine.cpp
@@ -647,7 +647,7 @@ bool Sema::ActOnCoroutineBodyStart(Scope *SC, SourceLocation KWLoc,
       return StmtError();
     Suspend = BuildResolvedCoawaitExpr(Loc, Suspend.get(),
                                        /*IsImplicit*/ true);
-    Suspend = ActOnFinishFullExpr(Suspend.get());
+    Suspend = ActOnFinishFullExpr(Suspend.get(), /*DiscardedValue*/ false);
     if (Suspend.isInvalid()) {
       Diag(Loc, diag::note_coroutine_promise_suspend_implicitly_required)
           << ((Name == "initial_suspend") ? 0 : 1);
@@ -868,7 +868,7 @@ StmtResult Sema::BuildCoreturnStmt(SourceLocation Loc, Expr *E,
   if (PC.isInvalid())
     return StmtError();
 
-  Expr *PCE = ActOnFinishFullExpr(PC.get()).get();
+  Expr *PCE = ActOnFinishFullExpr(PC.get(), /*DiscardedValue*/ false).get();
 
   Stmt *Res = new (Context) CoreturnStmt(Loc, E, PCE, IsImplicit);
   return Res;
@@ -1237,7 +1237,7 @@ bool CoroutineStmtBuilder::makeNewAndDeleteExpr() {
 
   ExprResult NewExpr =
       S.ActOnCallExpr(S.getCurScope(), NewRef.get(), Loc, NewArgs, Loc);
-  NewExpr = S.ActOnFinishFullExpr(NewExpr.get());
+  NewExpr = S.ActOnFinishFullExpr(NewExpr.get(), /*DiscardedValue*/ false);
   if (NewExpr.isInvalid())
     return false;
 
@@ -1263,7 +1263,8 @@ bool CoroutineStmtBuilder::makeNewAndDeleteExpr() {
 
   ExprResult DeleteExpr =
       S.ActOnCallExpr(S.getCurScope(), DeleteRef.get(), Loc, DeleteArgs, Loc);
-  DeleteExpr = S.ActOnFinishFullExpr(DeleteExpr.get());
+  DeleteExpr =
+      S.ActOnFinishFullExpr(DeleteExpr.get(), /*DiscardedValue*/ false);
   if (DeleteExpr.isInvalid())
     return false;
 
@@ -1348,7 +1349,8 @@ bool CoroutineStmtBuilder::makeOnException() {
 
   ExprResult UnhandledException = buildPromiseCall(S, Fn.CoroutinePromise, Loc,
                                                    "unhandled_exception", None);
-  UnhandledException = S.ActOnFinishFullExpr(UnhandledException.get(), Loc);
+  UnhandledException = S.ActOnFinishFullExpr(UnhandledException.get(), Loc,
+                                             /*DiscardedValue*/ false);
   if (UnhandledException.isInvalid())
     return false;
 
@@ -1401,7 +1403,8 @@ bool CoroutineStmtBuilder::makeGroDeclAndReturnStmt() {
          "get_return_object type must no longer be dependent");
 
   if (FnRetType->isVoidType()) {
-    ExprResult Res = S.ActOnFinishFullExpr(this->ReturnValue, Loc);
+    ExprResult Res =
+        S.ActOnFinishFullExpr(this->ReturnValue, Loc, /*DiscardedValue*/ false);
     if (Res.isInvalid())
       return false;
 
@@ -1433,7 +1436,7 @@ bool CoroutineStmtBuilder::makeGroDeclAndReturnStmt() {
   if (Res.isInvalid())
     return false;
 
-  Res = S.ActOnFinishFullExpr(Res.get());
+  Res = S.ActOnFinishFullExpr(Res.get(), /*DiscardedValue*/ false);
   if (Res.isInvalid())
     return false;
 
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 80cafbedf5..40b0ed3779 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -11204,9 +11204,9 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
   //   struct T { S a, b; } t = { Temp(), Temp() }
   //
   // we should destroy the first Temp before constructing the second.
-  ExprResult Result = ActOnFinishFullExpr(Init, VDecl->getLocation(),
-                                          false,
-                                          VDecl->isConstexpr());
+  ExprResult Result =
+      ActOnFinishFullExpr(Init, VDecl->getLocation(),
+                          /*DiscardedValue*/ false, VDecl->isConstexpr());
   if (Result.isInvalid()) {
     VDecl->setInvalidDecl();
     return;
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 8973d63255..2b380bf0dc 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -1205,7 +1205,7 @@ static bool checkTupleLikeDecomposition(Sema &S,
     E = Seq.Perform(S, Entity, Kind, Init);
     if (E.isInvalid())
       return true;
-    E = S.ActOnFinishFullExpr(E.get(), Loc);
+    E = S.ActOnFinishFullExpr(E.get(), Loc, /*DiscardedValue*/ false);
     if (E.isInvalid())
       return true;
     RefVD->setInit(E.get());
@@ -3682,7 +3682,7 @@ void Sema::ActOnFinishCXXInClassMemberInitializer(Decl *D,
   // C++11 [class.base.init]p7:
   //   The initialization of each base and member constitutes a
   //   full-expression.
-  Init = ActOnFinishFullExpr(Init.get(), InitLoc);
+  Init = ActOnFinishFullExpr(Init.get(), InitLoc, /*DiscardedValue*/ false);
   if (Init.isInvalid()) {
     FD->setInvalidDecl();
     return;
@@ -4040,7 +4040,8 @@ Sema::BuildMemberInitializer(ValueDecl *Member, Expr *Init,
     // C++11 [class.base.init]p7:
     //   The initialization of each base and member constitutes a
     //   full-expression.
-    MemberInit = ActOnFinishFullExpr(MemberInit.get(), InitRange.getBegin());
+    MemberInit = ActOnFinishFullExpr(MemberInit.get(), InitRange.getBegin(),
+                                     /*DiscardedValue*/ false);
     if (MemberInit.isInvalid())
       return true;
 
@@ -4095,8 +4096,8 @@ Sema::BuildDelegatingInitializer(TypeSourceInfo *TInfo, Expr *Init,
   // C++11 [class.base.init]p7:
   //   The initialization of each base and member constitutes a
   //   full-expression.
-  DelegationInit = ActOnFinishFullExpr(DelegationInit.get(),
-                                       InitRange.getBegin());
+  DelegationInit = ActOnFinishFullExpr(
+      DelegationInit.get(), InitRange.getBegin(), /*DiscardedValue*/ false);
   if (DelegationInit.isInvalid())
     return true;
 
@@ -4225,7 +4226,8 @@ Sema::BuildBaseInitializer(QualType BaseType, TypeSourceInfo *BaseTInfo,
   // C++11 [class.base.init]p7:
   //   The initialization of each base and member constitutes a
   //   full-expression.
-  BaseInit = ActOnFinishFullExpr(BaseInit.get(), InitRange.getBegin());
+  BaseInit = ActOnFinishFullExpr(BaseInit.get(), InitRange.getBegin(),
+                                 /*DiscardedValue*/ false);
   if (BaseInit.isInvalid())
     return true;
 
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index f8b991b7c7..aa4b23b15c 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -4736,8 +4736,9 @@ bool Sema::CheckCXXDefaultArgExpr(SourceLocation CallLoc, FunctionDecl *FD,
     if (Result.isInvalid())
       return true;
 
-    Result = ActOnFinishFullExpr(Result.getAs(),
-                                 Param->getOuterLocStart());
+    Result =
+        ActOnFinishFullExpr(Result.getAs(), Param->getOuterLocStart(),
+                            /*DiscardedValue*/ false);
     if (Result.isInvalid())
       return true;
 
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index 730c426076..1c210d332e 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -7803,6 +7803,8 @@ ExprResult Sema::ActOnFinishFullExpr(Expr *FE, SourceLocation CC,
     FullExpr = IgnoredValueConversions(FullExpr.get());
     if (FullExpr.isInvalid())
       return ExprError();
+
+    DiagnoseUnusedExprResult(FullExpr.get());
   }
 
   FullExpr = CorrectDelayedTyposInExpr(FullExpr.get());
diff --git a/lib/Sema/SemaLambda.cpp b/lib/Sema/SemaLambda.cpp
index 6dc93d0761..c1c4572aa2 100644
--- a/lib/Sema/SemaLambda.cpp
+++ b/lib/Sema/SemaLambda.cpp
@@ -1724,7 +1724,7 @@ ExprResult Sema::BuildBlockForLambdaConversion(SourceLocation CurrentLocation,
                                                  /*NRVO=*/false),
       CurrentLocation, Src);
   if (!Init.isInvalid())
-    Init = ActOnFinishFullExpr(Init.get());
+    Init = ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false);
 
   if (Init.isInvalid())
     return ExprError();
diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp
index 78bef59ff6..59c4b49bfb 100644
--- a/lib/Sema/SemaOpenMP.cpp
+++ b/lib/Sema/SemaOpenMP.cpp
@@ -5320,7 +5320,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
         LastIteration.get(), UB.get());
     EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(),
                              CondOp.get());
-    EUB = SemaRef.ActOnFinishFullExpr(EUB.get());
+    EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false);
 
     // If we have a combined directive that combines 'distribute', 'for' or
     // 'simd' we need to be able to access the bounds of the schedule of the
@@ -5349,7 +5349,8 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
                                      LastIteration.get(), CombUB.get());
       CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(),
                                    CombCondOp.get());
-      CombEUB = SemaRef.ActOnFinishFullExpr(CombEUB.get());
+      CombEUB =
+          SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false);
 
       const CapturedDecl *CD = cast(AStmt)->getCapturedDecl();
       // We expect to have at least 2 more parameters than the 'parallel'
@@ -5383,7 +5384,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
             ? LB.get()
             : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
     Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
-    Init = SemaRef.ActOnFinishFullExpr(Init.get());
+    Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false);
 
     if (isOpenMPLoopBoundSharingDirective(DKind)) {
       Expr *CombRHS =
@@ -5394,7 +5395,8 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
               : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
       CombInit =
           SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS);
-      CombInit = SemaRef.ActOnFinishFullExpr(CombInit.get());
+      CombInit =
+          SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false);
     }
   }
 
@@ -5426,7 +5428,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
   if (!Inc.isUsable())
     return 0;
   Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get());
-  Inc = SemaRef.ActOnFinishFullExpr(Inc.get());
+  Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false);
   if (!Inc.isUsable())
     return 0;
 
@@ -5444,7 +5446,8 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
     // LB = LB + ST
     NextLB =
         SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get());
-    NextLB = SemaRef.ActOnFinishFullExpr(NextLB.get());
+    NextLB =
+        SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false);
     if (!NextLB.isUsable())
       return 0;
     // UB + ST
@@ -5454,7 +5457,8 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
     // UB = UB + ST
     NextUB =
         SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get());
-    NextUB = SemaRef.ActOnFinishFullExpr(NextUB.get());
+    NextUB =
+        SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false);
     if (!NextUB.isUsable())
       return 0;
     if (isOpenMPLoopBoundSharingDirective(DKind)) {
@@ -5465,7 +5469,8 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
       // LB = LB + ST
       CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(),
                                       CombNextLB.get());
-      CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get());
+      CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(),
+                                               /*DiscardedValue*/ false);
       if (!CombNextLB.isUsable())
         return 0;
       // UB + ST
@@ -5476,7 +5481,8 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
       // UB = UB + ST
       CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(),
                                       CombNextUB.get());
-      CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get());
+      CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(),
+                                               /*DiscardedValue*/ false);
       if (!CombNextUB.isUsable())
         return 0;
     }
@@ -5497,7 +5503,8 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
     assert(DistInc.isUsable() && "distribute inc expr was not built");
     DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(),
                                  DistInc.get());
-    DistInc = SemaRef.ActOnFinishFullExpr(DistInc.get());
+    DistInc =
+        SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false);
     assert(DistInc.isUsable() && "distribute inc expr was not built");
 
     // Build expression: UB = min(UB, prevUB) for #for in composite or combined
@@ -5509,7 +5516,8 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
         DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get());
     PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(),
                                  CondOp.get());
-    PrevEUB = SemaRef.ActOnFinishFullExpr(PrevEUB.get());
+    PrevEUB =
+        SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false);
 
     // Build IV <= PrevUB to be used in parallel for is in combination with
     // a distribute directive with schedule(static, 1)
@@ -5613,8 +5621,10 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
   Built.IterationVarRef = IV.get();
   Built.LastIteration = LastIteration.get();
   Built.NumIterations = NumIterations.get();
-  Built.CalcLastIteration =
-      SemaRef.ActOnFinishFullExpr(CalcLastIteration.get()).get();
+  Built.CalcLastIteration = SemaRef
+                                .ActOnFinishFullExpr(CalcLastIteration.get(),
+                                                     /*DiscardedValue*/ false)
+                                .get();
   Built.PreCond = PreCond.get();
   Built.PreInits = buildPreInits(C, Captures);
   Built.Cond = Cond.get();
@@ -10267,8 +10277,8 @@ OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef VarList,
                                          PseudoDstExpr, PseudoSrcExpr);
     if (AssignmentOp.isInvalid())
       continue;
-    AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), ELoc,
-                                       /*DiscardedValue=*/true);
+    AssignmentOp =
+        ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
     if (AssignmentOp.isInvalid())
       continue;
 
@@ -11274,7 +11284,8 @@ static bool actOnOMPReductionKindClause(
                            BO_Assign, LHSDRE, ConditionalOp);
         }
         if (ReductionOp.isUsable())
-          ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get());
+          ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(),
+                                              /*DiscardedValue*/ false);
       }
       if (!ReductionOp.isUsable())
         continue;
@@ -11612,7 +11623,7 @@ OMPClause *Sema::ActOnOpenMPLinearClause(
         buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc);
     ExprResult CalcStep =
         BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr);
-    CalcStep = ActOnFinishFullExpr(CalcStep.get());
+    CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false);
 
     // Warn about zero linear step (it would be probably better specified as
     // making corresponding variables 'const').
@@ -11700,7 +11711,7 @@ static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
     else
       Update = *CurPrivate;
     Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(),
-                                         /*DiscardedValue=*/true);
+                                         /*DiscardedValue*/ false);
 
     // Build final: Var = InitExpr + NumIterations * Step
     ExprResult Final;
@@ -11711,7 +11722,7 @@ static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
     else
       Final = *CurPrivate;
     Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(),
-                                        /*DiscardedValue=*/true);
+                                        /*DiscardedValue*/ false);
 
     if (!Update.isUsable() || !Final.isUsable()) {
       Updates.push_back(nullptr);
@@ -11879,7 +11890,7 @@ OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef VarList,
     if (AssignmentOp.isInvalid())
       continue;
     AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
-                                       /*DiscardedValue=*/true);
+                                       /*DiscardedValue*/ false);
     if (AssignmentOp.isInvalid())
       continue;
 
@@ -11987,8 +11998,8 @@ OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef VarList,
         DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr);
     if (AssignmentOp.isInvalid())
       continue;
-    AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), ELoc,
-                                       /*DiscardedValue=*/true);
+    AssignmentOp =
+        ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
     if (AssignmentOp.isInvalid())
       continue;
 
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index dacf8d0cf4..9e30c9a396 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -42,12 +42,11 @@
 using namespace clang;
 using namespace sema;
 
-StmtResult Sema::ActOnExprStmt(ExprResult FE) {
+StmtResult Sema::ActOnExprStmt(ExprResult FE, bool DiscardedValue) {
   if (FE.isInvalid())
     return StmtError();
 
-  FE = ActOnFinishFullExpr(FE.get(), FE.get()->getExprLoc(),
-                           /*DiscardedValue*/ true);
+  FE = ActOnFinishFullExpr(FE.get(), FE.get()->getExprLoc(), DiscardedValue);
   if (FE.isInvalid())
     return StmtError();
 
@@ -348,6 +347,10 @@ sema::CompoundScopeInfo &Sema::getCurCompoundScope() const {
   return getCurFunction()->CompoundScopes.back();
 }
 
+bool Sema::isCurCompoundStmtAStmtExpr() const {
+  return getCurCompoundScope().IsStmtExpr;
+}
+
 StmtResult Sema::ActOnCompoundStmt(SourceLocation L, SourceLocation R,
                                    ArrayRef Elts, bool isStmtExpr) {
   const unsigned NumElts = Elts.size();
@@ -370,14 +373,6 @@ StmtResult Sema::ActOnCompoundStmt(SourceLocation L, SourceLocation R,
       Diag(D->getLocation(), diag::ext_mixed_decls_code);
     }
   }
-  // Warn about unused expressions in statements.
-  for (unsigned i = 0; i != NumElts; ++i) {
-    // Ignore statements that are last in a statement expression.
-    if (isStmtExpr && i == NumElts - 1)
-      continue;
-
-    DiagnoseUnusedExprResult(Elts[i]);
-  }
 
   // Check for suspicious empty body (null statement) in `for' and `while'
   // statements.  Don't do anything for template instantiations, this just adds
@@ -469,15 +464,12 @@ Sema::ActOnCaseStmt(SourceLocation CaseLoc, ExprResult LHSVal,
 
 /// ActOnCaseStmtBody - This installs a statement as the body of a case.
 void Sema::ActOnCaseStmtBody(Stmt *S, Stmt *SubStmt) {
-  DiagnoseUnusedExprResult(SubStmt);
   cast(S)->setSubStmt(SubStmt);
 }
 
 StmtResult
 Sema::ActOnDefaultStmt(SourceLocation DefaultLoc, SourceLocation ColonLoc,
                        Stmt *SubStmt, Scope *CurScope) {
-  DiagnoseUnusedExprResult(SubStmt);
-
   if (getCurFunction()->SwitchStack.empty()) {
     Diag(DefaultLoc, diag::err_default_not_in_switch);
     return SubStmt;
@@ -571,9 +563,6 @@ StmtResult Sema::BuildIfStmt(SourceLocation IfLoc, bool IsConstexpr,
   if (IsConstexpr || isa(Cond.get().second))
     setFunctionHasBranchProtectedScope();
 
-  DiagnoseUnusedExprResult(thenStmt);
-  DiagnoseUnusedExprResult(elseStmt);
-
   return IfStmt::Create(Context, IfLoc, IsConstexpr, InitStmt, Cond.get().first,
                         Cond.get().second, thenStmt, ElseLoc, elseStmt);
 }
@@ -1301,8 +1290,6 @@ StmtResult Sema::ActOnWhileStmt(SourceLocation WhileLoc, ConditionResult Cond,
       !Diags.isIgnored(diag::warn_comma_operator, CondVal.second->getExprLoc()))
     CommaVisitor(*this).Visit(CondVal.second);
 
-  DiagnoseUnusedExprResult(Body);
-
   if (isa(Body))
     getCurCompoundScope().setHasEmptyLoopBodies();
 
@@ -1322,7 +1309,7 @@ Sema::ActOnDoStmt(SourceLocation DoLoc, Stmt *Body,
     return StmtError();
   Cond = CondResult.get();
 
-  CondResult = ActOnFinishFullExpr(Cond, DoLoc);
+  CondResult = ActOnFinishFullExpr(Cond, DoLoc, /*DiscardedValue*/ false);
   if (CondResult.isInvalid())
     return StmtError();
   Cond = CondResult.get();
@@ -1332,8 +1319,6 @@ Sema::ActOnDoStmt(SourceLocation DoLoc, Stmt *Body,
       !Diags.isIgnored(diag::warn_comma_operator, Cond->getExprLoc()))
     CommaVisitor(*this).Visit(Cond);
 
-  DiagnoseUnusedExprResult(Body);
-
   return new (Context) DoStmt(Body, Cond, DoLoc, WhileLoc, CondRParen);
 }
 
@@ -1778,11 +1763,6 @@ StmtResult Sema::ActOnForStmt(SourceLocation ForLoc, SourceLocation LParenLoc,
     CommaVisitor(*this).Visit(Second.get().second);
 
   Expr *Third  = third.release().getAs();
-
-  DiagnoseUnusedExprResult(First);
-  DiagnoseUnusedExprResult(Third);
-  DiagnoseUnusedExprResult(Body);
-
   if (isa(Body))
     getCurCompoundScope().setHasEmptyLoopBodies();
 
@@ -1802,7 +1782,7 @@ StmtResult Sema::ActOnForEachLValueExpr(Expr *E) {
   if (result.isInvalid()) return StmtError();
   E = result.get();
 
-  ExprResult FullExpr = ActOnFinishFullExpr(E);
+  ExprResult FullExpr = ActOnFinishFullExpr(E, /*DiscardedValue*/ false);
   if (FullExpr.isInvalid())
     return StmtError();
   return StmtResult(static_cast(FullExpr.get()));
@@ -1956,7 +1936,8 @@ Sema::ActOnObjCForCollectionStmt(SourceLocation ForLoc,
   if (CollectionExprResult.isInvalid())
     return StmtError();
 
-  CollectionExprResult = ActOnFinishFullExpr(CollectionExprResult.get());
+  CollectionExprResult =
+      ActOnFinishFullExpr(CollectionExprResult.get(), /*DiscardedValue*/ false);
   if (CollectionExprResult.isInvalid())
     return StmtError();
 
@@ -2593,7 +2574,8 @@ StmtResult Sema::BuildCXXForRangeStmt(SourceLocation ForLoc,
     if (!NotEqExpr.isInvalid())
       NotEqExpr = CheckBooleanCondition(ColonLoc, NotEqExpr.get());
     if (!NotEqExpr.isInvalid())
-      NotEqExpr = ActOnFinishFullExpr(NotEqExpr.get());
+      NotEqExpr =
+          ActOnFinishFullExpr(NotEqExpr.get(), /*DiscardedValue*/ false);
     if (NotEqExpr.isInvalid()) {
       Diag(RangeLoc, diag::note_for_range_invalid_iterator)
         << RangeLoc << 0 << BeginRangeRef.get()->getType();
@@ -2616,7 +2598,7 @@ StmtResult Sema::BuildCXXForRangeStmt(SourceLocation ForLoc,
       // co_await during the initial parse.
       IncrExpr = ActOnCoawaitExpr(S, CoawaitLoc, IncrExpr.get());
     if (!IncrExpr.isInvalid())
-      IncrExpr = ActOnFinishFullExpr(IncrExpr.get());
+      IncrExpr = ActOnFinishFullExpr(IncrExpr.get(), /*DiscardedValue*/ false);
     if (IncrExpr.isInvalid()) {
       Diag(RangeLoc, diag::note_for_range_invalid_iterator)
         << RangeLoc << 2 << BeginRangeRef.get()->getType() ;
@@ -2871,7 +2853,7 @@ Sema::ActOnIndirectGotoStmt(SourceLocation GotoLoc, SourceLocation StarLoc,
       return StmtError();
   }
 
-  ExprResult ExprRes = ActOnFinishFullExpr(E);
+  ExprResult ExprRes = ActOnFinishFullExpr(E, /*DiscardedValue*/ false);
   if (ExprRes.isInvalid())
     return StmtError();
   E = ExprRes.get();
@@ -3221,7 +3203,8 @@ Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
           ExpressionEvaluationContext::DiscardedStatement &&
       (HasDeducedReturnType || CurCap->HasImplicitReturnType)) {
     if (RetValExp) {
-      ExprResult ER = ActOnFinishFullExpr(RetValExp, ReturnLoc);
+      ExprResult ER =
+          ActOnFinishFullExpr(RetValExp, ReturnLoc, /*DiscardedValue*/ false);
       if (ER.isInvalid())
         return StmtError();
       RetValExp = ER.get();
@@ -3348,7 +3331,8 @@ Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
   }
 
   if (RetValExp) {
-    ExprResult ER = ActOnFinishFullExpr(RetValExp, ReturnLoc);
+    ExprResult ER =
+        ActOnFinishFullExpr(RetValExp, ReturnLoc, /*DiscardedValue*/ false);
     if (ER.isInvalid())
       return StmtError();
     RetValExp = ER.get();
@@ -3578,7 +3562,8 @@ StmtResult Sema::BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
           ExpressionEvaluationContext::DiscardedStatement &&
       FnRetType->getContainedAutoType()) {
     if (RetValExp) {
-      ExprResult ER = ActOnFinishFullExpr(RetValExp, ReturnLoc);
+      ExprResult ER =
+          ActOnFinishFullExpr(RetValExp, ReturnLoc, /*DiscardedValue*/ false);
       if (ER.isInvalid())
         return StmtError();
       RetValExp = ER.get();
@@ -3672,7 +3657,8 @@ StmtResult Sema::BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
       }
 
       if (RetValExp) {
-        ExprResult ER = ActOnFinishFullExpr(RetValExp, ReturnLoc);
+        ExprResult ER =
+            ActOnFinishFullExpr(RetValExp, ReturnLoc, /*DiscardedValue*/ false);
         if (ER.isInvalid())
           return StmtError();
         RetValExp = ER.get();
@@ -3751,7 +3737,8 @@ StmtResult Sema::BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
     }
 
     if (RetValExp) {
-      ExprResult ER = ActOnFinishFullExpr(RetValExp, ReturnLoc);
+      ExprResult ER =
+          ActOnFinishFullExpr(RetValExp, ReturnLoc, /*DiscardedValue*/ false);
       if (ER.isInvalid())
         return StmtError();
       RetValExp = ER.get();
@@ -3804,7 +3791,7 @@ StmtResult Sema::BuildObjCAtThrowStmt(SourceLocation AtLoc, Expr *Throw) {
     if (Result.isInvalid())
       return StmtError();
 
-    Result = ActOnFinishFullExpr(Result.get());
+    Result = ActOnFinishFullExpr(Result.get(), /*DiscardedValue*/ false);
     if (Result.isInvalid())
       return StmtError();
     Throw = Result.get();
@@ -3876,7 +3863,7 @@ Sema::ActOnObjCAtSynchronizedOperand(SourceLocation atLoc, Expr *operand) {
   }
 
   // The operand to @synchronized is a full-expression.
-  return ActOnFinishFullExpr(operand);
+  return ActOnFinishFullExpr(operand, /*DiscardedValue*/ false);
 }
 
 StmtResult
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index 9de4e8d654..df14768cbe 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -328,7 +328,7 @@ public:
   /// other mechanism.
   ///
   /// \returns the transformed statement.
-  StmtResult TransformStmt(Stmt *S);
+  StmtResult TransformStmt(Stmt *S, bool DiscardedValue = false);
 
   /// Transform the given statement.
   ///
@@ -3269,8 +3269,8 @@ private:
                                       bool DeducibleTSTContext);
 };
 
-template
-StmtResult TreeTransform::TransformStmt(Stmt *S) {
+template 
+StmtResult TreeTransform::TransformStmt(Stmt *S, bool DiscardedValue) {
   if (!S)
     return S;
 
@@ -3294,7 +3294,7 @@ StmtResult TreeTransform::TransformStmt(Stmt *S) {
       if (E.isInvalid())
         return StmtError();
 
-      return getSema().ActOnExprStmt(E);
+      return getSema().ActOnExprStmt(E, DiscardedValue);
     }
   }
 
@@ -4715,7 +4715,8 @@ TreeTransform::TransformVariableArrayType(TypeLocBuilder &TLB,
   }
   if (SizeResult.isInvalid())
     return QualType();
-  SizeResult = SemaRef.ActOnFinishFullExpr(SizeResult.get());
+  SizeResult =
+      SemaRef.ActOnFinishFullExpr(SizeResult.get(), /*DiscardedValue*/ false);
   if (SizeResult.isInvalid())
     return QualType();
 
@@ -6520,7 +6521,9 @@ TreeTransform::TransformCompoundStmt(CompoundStmt *S,
   bool SubStmtChanged = false;
   SmallVector Statements;
   for (auto *B : S->body()) {
-    StmtResult Result = getDerived().TransformStmt(B);
+    StmtResult Result =
+        getDerived().TransformStmt(B, !IsStmtExpr || B != S->body_back());
+
     if (Result.isInvalid()) {
       // Immediately fail if this was a DeclStmt, since it's very
       // likely that this will cause problems for future statements.
diff --git a/test/CXX/stmt.stmt/stmt.select/p3.cpp b/test/CXX/stmt.stmt/stmt.select/p3.cpp
index 7a6a408ec9..4804cc559d 100644
--- a/test/CXX/stmt.stmt/stmt.select/p3.cpp
+++ b/test/CXX/stmt.stmt/stmt.select/p3.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
-// RUN: %clang_cc1 -fsyntax-only -std=c++1z -Wc++14-compat -verify %s -DCPP17
+// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value -verify %s
+// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value -std=c++1z -Wc++14-compat -verify %s -DCPP17
 
 int f();
 
@@ -71,7 +71,6 @@ void whileInitStatement() {
 // last loop above. It would be nice to remove this.
 void whileInitStatement2() {
   while (; false) {} // expected-error {{expected expression}}
-  // expected-warning@-1 {{expression result unused}}
-  // expected-error@-2 {{expected ';' after expression}}
-  // expected-error@-3 {{expected expression}}
+  // expected-error@-1 {{expected ';' after expression}}
+  // expected-error@-2 {{expected expression}}
 }
diff --git a/test/CodeCompletion/pragma-macro-token-caching.c b/test/CodeCompletion/pragma-macro-token-caching.c
index 432706e85c..59b6621b56 100644
--- a/test/CodeCompletion/pragma-macro-token-caching.c
+++ b/test/CodeCompletion/pragma-macro-token-caching.c
@@ -12,7 +12,7 @@ void completeParam(int param) {
 
 void completeParamPragmaError(int param) {
     Outer(__extension__({ _Pragma(2) })); // expected-error {{_Pragma takes a parenthesized string literal}}
-    param;
+    param; // expected-warning {{expression result unused}}
 }
 
 // RUN: %clang_cc1 -fsyntax-only -verify -code-completion-at=%s:16:1 %s | FileCheck %s
diff --git a/test/Parser/cxx1z-init-statement.cpp b/test/Parser/cxx1z-init-statement.cpp
index 3d119ef8e7..ade60dc762 100644
--- a/test/Parser/cxx1z-init-statement.cpp
+++ b/test/Parser/cxx1z-init-statement.cpp
@@ -13,9 +13,9 @@ int f() {
   if (T(n) = 0; n) {}
 
   // init-statement expressions
-  if (T{f()}; f()) {}
-  if (T{f()}, g, h; f()) {} // expected-warning 2{{unused}}
-  if (T(f()), g, h + 1; f()) {} // expected-warning 2{{unused}}
+  if (T{f()}; f()) {} // expected-warning {{expression result unused}}
+  if (T{f()}, g, h; f()) {} // expected-warning 2{{unused}} expected-warning {{expression result unused}}
+  if (T(f()), g, h + 1; f()) {} // expected-warning 2{{unused}} expected-warning {{expression result unused}}
 
   // condition declarations
   if (T(n){g}) {}
@@ -35,7 +35,7 @@ int f() {
 
   // Likewise for 'switch'
   switch (int n; n) {}
-  switch (g; int g = 5) {}
+  switch (g; int g = 5) {} // expected-warning {{expression result unused}}
 
   if (int a, b; int c = a) { // expected-note 6{{previous}}
     int a; // expected-error {{redefinition}}
diff --git a/test/Parser/switch-recovery.cpp b/test/Parser/switch-recovery.cpp
index a3a0178cd1..eacd017ab2 100644
--- a/test/Parser/switch-recovery.cpp
+++ b/test/Parser/switch-recovery.cpp
@@ -105,7 +105,7 @@ void test9(int x) { // expected-note {{'x' declared here}}
               expected-error {{expected expression}}
     8:: x; // expected-error {{expected ';' after expression}} \
               expected-error {{no member named 'x' in the global namespace; did you mean simply 'x'?}} \
-              expected-warning 2 {{expression result unused}}
+              expected-warning {{expression result unused}}
     9:: :y; // expected-error {{expected ';' after expression}} \
                expected-error {{expected unqualified-id}} \
                expected-warning {{expression result unused}}
diff --git a/test/SemaCXX/cxx1z-init-statement.cpp b/test/SemaCXX/cxx1z-init-statement.cpp
index d37acd08ce..eea2589ab7 100644
--- a/test/SemaCXX/cxx1z-init-statement.cpp
+++ b/test/SemaCXX/cxx1z-init-statement.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -std=c++1z -verify %s
-// RUN: %clang_cc1 -std=c++17 -verify %s
+// RUN: %clang_cc1 -std=c++1z -Wno-unused-value -verify %s
+// RUN: %clang_cc1 -std=c++17 -Wno-unused-value -verify %s
 
 void testIf() {
   int x = 0;
@@ -12,7 +12,7 @@ void testIf() {
     int x = 0; // expected-error {{redefinition of 'x'}}
 
   if (x; int a = 0) ++a;
-  if (x, +x; int a = 0) // expected-note 2 {{previous definition is here}} expected-warning {{unused}}
+  if (x, +x; int a = 0) // expected-note 2 {{previous definition is here}}
     int a = 0; // expected-error {{redefinition of 'a'}}
   else
     int a = 0; // expected-error {{redefinition of 'a'}}
@@ -48,7 +48,7 @@ void testSwitch() {
       ++a;
   }
 
-  switch (x, +x; int a = 0) { // expected-note {{previous definition is here}} expected-warning {{unused}}
+  switch (x, +x; int a = 0) { // expected-note {{previous definition is here}}
     case 0:
       int a = 0; // expected-error {{redefinition of 'a'}} // expected-note {{previous definition is here}}
     case 1:
diff --git a/test/SemaCXX/for-range-examples.cpp b/test/SemaCXX/for-range-examples.cpp
index 477789b56c..5424b7a8ee 100644
--- a/test/SemaCXX/for-range-examples.cpp
+++ b/test/SemaCXX/for-range-examples.cpp
@@ -244,7 +244,7 @@ void foo ()
 { 
   int b = 1, a[b];
   a[0] = 0;
-  [&] { for (int c : a) 0; } ();
+  [&] { for (int c : a) 0; } (); // expected-warning {{expression result unused}}
 }
 
 
diff --git a/test/SemaCXX/warn-unused-result.cpp b/test/SemaCXX/warn-unused-result.cpp
index 88f5ab1e85..f1de4618a7 100644
--- a/test/SemaCXX/warn-unused-result.cpp
+++ b/test/SemaCXX/warn-unused-result.cpp
@@ -33,6 +33,36 @@ void test() {
   const S &s4 = g1();
 }
 
+void testSubstmts(int i) {
+  switch (i) {
+  case 0:
+    f(); // expected-warning {{ignoring return value}}
+  default:
+    f(); // expected-warning {{ignoring return value}}
+  }
+
+  if (i)
+    f(); // expected-warning {{ignoring return value}}
+  else
+    f(); // expected-warning {{ignoring return value}}
+
+  while (i)
+    f(); // expected-warning {{ignoring return value}}
+
+  do
+    f(); // expected-warning {{ignoring return value}}
+  while (i);
+
+  for (f(); // expected-warning {{ignoring return value}}
+       ;
+       f() // expected-warning {{ignoring return value}}
+      )
+    f(); // expected-warning {{ignoring return value}}
+
+  f(),  // expected-warning {{ignoring return value}}
+  (void)f();
+}
+
 struct X {
  int foo() __attribute__((warn_unused_result));
 };
@@ -206,3 +236,13 @@ void f() {
   (void)++p;
 }
 } // namespace
+
+namespace PR39837 {
+[[clang::warn_unused_result]] int f(int);
+
+void g() {
+  int a[2];
+  for (int b : a)
+    f(b); // expected-warning {{ignoring return value}}
+}
+} // namespace PR39837
-- 
cgit v1.2.3


From 4bc17f2c87761c830959b2cf3a2a381b84a909ae Mon Sep 17 00:00:00 2001
From: Aaron Ballman 
Date: Fri, 4 Jan 2019 17:20:00 +0000
Subject: Add two new pragmas for controlling software pipelining
 optimizations.

This patch adds #pragma clang loop pipeline and #pragma clang loop pipeline_initiation_interval for debugging or reducing compile time purposes. It is possible to disable SWP for concrete loops to save compilation time or to find bugs by not doing SWP to certain loops. It is possible to set value of initiation interval to concrete number to save compilation time by not doing extra pipeliner passes or to check created schedule for specific initiation interval.

Patch by Alexey Lapshin.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350414 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/Basic/Attr.td                 | 10 +++--
 include/clang/Basic/AttrDocs.td             | 58 +++++++++++++++++++++++++++--
 include/clang/Basic/DiagnosticParseKinds.td |  5 ++-
 lib/CodeGen/CGLoopInfo.cpp                  | 38 ++++++++++++++++++-
 lib/CodeGen/CGLoopInfo.h                    | 14 +++++++
 lib/Parse/ParsePragma.cpp                   | 36 ++++++++++++------
 lib/Sema/SemaStmtAttr.cpp                   | 36 ++++++++++++------
 test/CodeGenCXX/pragma-pipeline.cpp         | 47 +++++++++++++++++++++++
 test/Parser/pragma-loop.cpp                 |  2 +-
 test/Parser/pragma-pipeline.cpp             | 33 ++++++++++++++++
 test/Parser/pragma-unroll-and-jam.cpp       |  2 +-
 test/Sema/pragma-pipeline.cpp               | 34 +++++++++++++++++
 12 files changed, 280 insertions(+), 35 deletions(-)
 create mode 100644 test/CodeGenCXX/pragma-pipeline.cpp
 create mode 100644 test/Parser/pragma-pipeline.cpp
 create mode 100644 test/Sema/pragma-pipeline.cpp

diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td
index b3c7a4f4b8..271f979f8a 100644
--- a/include/clang/Basic/Attr.td
+++ b/include/clang/Basic/Attr.td
@@ -2867,7 +2867,9 @@ def LoopHint : Attr {
   /// unroll_count: unrolls loop 'Value' times.
   /// unroll_and_jam: attempt to unroll and jam loop if State == Enable.
   /// unroll_and_jam_count: unroll and jams loop 'Value' times.
-  /// distribute: attempt to distribute loop if State == Enable
+  /// distribute: attempt to distribute loop if State == Enable.
+  /// pipeline: disable pipelining loop if State == Disable.
+  /// pipeline_initiation_interval: create loop schedule with initiation interval equal to 'Value'.
 
   /// #pragma unroll  directive
   /// : fully unrolls loop.
@@ -2882,10 +2884,10 @@ def LoopHint : Attr {
   let Args = [EnumArgument<"Option", "OptionType",
                           ["vectorize", "vectorize_width", "interleave", "interleave_count",
                            "unroll", "unroll_count", "unroll_and_jam", "unroll_and_jam_count",
-                           "distribute"],
+                           "pipeline", "pipeline_initiation_interval", "distribute"],
                           ["Vectorize", "VectorizeWidth", "Interleave", "InterleaveCount",
                            "Unroll", "UnrollCount", "UnrollAndJam", "UnrollAndJamCount",
-                           "Distribute"]>,
+                           "PipelineDisabled", "PipelineInitiationInterval", "Distribute"]>,
               EnumArgument<"State", "LoopHintState",
                            ["enable", "disable", "numeric", "assume_safety", "full"],
                            ["Enable", "Disable", "Numeric", "AssumeSafety", "Full"]>,
@@ -2902,6 +2904,8 @@ def LoopHint : Attr {
     case UnrollCount: return "unroll_count";
     case UnrollAndJam: return "unroll_and_jam";
     case UnrollAndJamCount: return "unroll_and_jam_count";
+    case PipelineDisabled: return "pipeline";
+    case PipelineInitiationInterval: return "pipeline_initiation_interval";
     case Distribute: return "distribute";
     }
     llvm_unreachable("Unhandled LoopHint option.");
diff --git a/include/clang/Basic/AttrDocs.td b/include/clang/Basic/AttrDocs.td
index 9017a631f7..532773fc95 100644
--- a/include/clang/Basic/AttrDocs.td
+++ b/include/clang/Basic/AttrDocs.td
@@ -2578,10 +2578,10 @@ def LoopHintDocs : Documentation {
   let Heading = "#pragma clang loop";
   let Content = [{
 The ``#pragma clang loop`` directive allows loop optimization hints to be
-specified for the subsequent loop. The directive allows vectorization,
-interleaving, and unrolling to be enabled or disabled. Vector width as well
-as interleave and unrolling count can be manually specified. See
-`language extensions
+specified for the subsequent loop. The directive allows pipelining to be
+disabled, or vectorization, interleaving, and unrolling to be enabled or disabled.
+Vector width, interleave count, unrolling count, and the initiation interval
+for pipelining can be explicitly specified. See `language extensions
 `_
 for details.
   }];
@@ -2642,6 +2642,56 @@ for further details including limitations of the unroll hints.
   }];
 }
 
+def PipelineHintDocs : Documentation {
+  let Category = DocCatStmt;
+  let Heading = "#pragma clang loop pipeline, #pragma clang loop pipeline_initiation_interval";
+  let Content = [{
+    Software Pipelining optimization is a technique used to optimize loops by
+  utilizing instruction-level parallelism. It reorders loop instructions to
+  overlap iterations. As a result, the next iteration starts before the previous
+  iteration has finished. The module scheduling technique creates a schedule for
+  one iteration such that when repeating at regular intervals, no inter-iteration
+  dependencies are violated. This constant interval(in cycles) between the start
+  of iterations is called the initiation interval. i.e. The initiation interval
+  is the number of cycles between two iterations of an unoptimized loop in the
+  newly created schedule. A new, optimized loop is created such that a single iteration
+  of the loop executes in the same number of cycles as the initiation interval.
+    For further details see .
+
+  ``#pragma clang loop pipeline and #pragma loop pipeline_initiation_interval``
+  could be used as hints for the software pipelining optimization. The pragma is
+  placed immediately before a for, while, do-while, or a C++11 range-based for
+  loop.
+
+  Using ``#pragma clang loop pipeline(disable)`` avoids the software pipelining
+  optimization. The disable state can only be specified:
+
+  .. code-block:: c++
+
+  #pragma clang loop pipeline(disable)
+  for (...) {
+    ...
+  }
+
+  Using ``#pragma loop pipeline_initiation_interval`` instructs
+  the software pipeliner to try the specified initiation interval.
+  If a schedule was found then the resulting loop iteration would have
+  the specified cycle count. If a schedule was not found then loop
+  remains unchanged. The initiation interval must be a positive number
+  greater than zero:
+
+  .. code-block:: c++
+
+  #pragma loop pipeline_initiation_interval(10)
+  for (...) {
+    ...
+  }
+
+  }];
+}
+
+
+
 def OpenCLUnrollHintDocs : Documentation {
   let Category = DocCatStmt;
   let Content = [{
diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td
index bb5d2a18d4..06281e2904 100644
--- a/include/clang/Basic/DiagnosticParseKinds.td
+++ b/include/clang/Basic/DiagnosticParseKinds.td
@@ -1184,7 +1184,8 @@ def err_pragma_loop_missing_argument : Error<
   "'enable'%select{|, 'full'}1%select{|, 'assume_safety'}2 or 'disable'}0">;
 def err_pragma_loop_invalid_option : Error<
   "%select{invalid|missing}0 option%select{ %1|}0; expected vectorize, "
-  "vectorize_width, interleave, interleave_count, unroll, unroll_count, or distribute">;
+  "vectorize_width, interleave, interleave_count, unroll, unroll_count, "
+  "pipeline, pipeline_initiation_interval, or distribute">;
 
 def err_pragma_fp_invalid_option : Error<
   "%select{invalid|missing}0 option%select{ %1|}0; expected contract">;
@@ -1197,6 +1198,8 @@ def err_pragma_fp_scope : Error<
 
 def err_pragma_invalid_keyword : Error<
   "invalid argument; expected 'enable'%select{|, 'full'}0%select{|, 'assume_safety'}1 or 'disable'">;
+def err_pragma_pipeline_invalid_keyword : Error<
+    "invalid argument; expected 'disable'">;
 
 // Pragma unroll support.
 def warn_pragma_unroll_cuda_value_in_parens : Warning<
diff --git a/lib/CodeGen/CGLoopInfo.cpp b/lib/CodeGen/CGLoopInfo.cpp
index 6cbf801ae6..fd0a9c773a 100644
--- a/lib/CodeGen/CGLoopInfo.cpp
+++ b/lib/CodeGen/CGLoopInfo.cpp
@@ -25,7 +25,8 @@ static MDNode *createMetadata(LLVMContext &Ctx, const LoopAttributes &Attrs,
 
   if (!Attrs.IsParallel && Attrs.VectorizeWidth == 0 &&
       Attrs.InterleaveCount == 0 && Attrs.UnrollCount == 0 &&
-      Attrs.UnrollAndJamCount == 0 &&
+      Attrs.UnrollAndJamCount == 0 && !Attrs.PipelineDisabled &&
+      Attrs.PipelineInitiationInterval == 0 &&
       Attrs.VectorizeEnable == LoopAttributes::Unspecified &&
       Attrs.UnrollEnable == LoopAttributes::Unspecified &&
       Attrs.UnrollAndJamEnable == LoopAttributes::Unspecified &&
@@ -128,6 +129,22 @@ static MDNode *createMetadata(LLVMContext &Ctx, const LoopAttributes &Attrs,
         Ctx, {MDString::get(Ctx, "llvm.loop.parallel_accesses"), AccGroup}));
   }
 
+  if (Attrs.PipelineDisabled) {
+    Metadata *Vals[] = {
+        MDString::get(Ctx, "llvm.loop.pipeline.disable"),
+        ConstantAsMetadata::get(ConstantInt::get(
+            Type::getInt1Ty(Ctx), (Attrs.PipelineDisabled == true)))};
+    Args.push_back(MDNode::get(Ctx, Vals));
+  }
+
+  if (Attrs.PipelineInitiationInterval > 0) {
+    Metadata *Vals[] = {
+        MDString::get(Ctx, "llvm.loop.pipeline.initiationinterval"),
+        ConstantAsMetadata::get(ConstantInt::get(
+            Type::getInt32Ty(Ctx), Attrs.PipelineInitiationInterval))};
+    Args.push_back(MDNode::get(Ctx, Vals));
+  }
+
   // Set the first operand to itself.
   MDNode *LoopID = MDNode::get(Ctx, Args);
   LoopID->replaceOperandWith(0, LoopID);
@@ -139,7 +156,8 @@ LoopAttributes::LoopAttributes(bool IsParallel)
       UnrollEnable(LoopAttributes::Unspecified),
       UnrollAndJamEnable(LoopAttributes::Unspecified), VectorizeWidth(0),
       InterleaveCount(0), UnrollCount(0), UnrollAndJamCount(0),
-      DistributeEnable(LoopAttributes::Unspecified) {}
+      DistributeEnable(LoopAttributes::Unspecified), PipelineDisabled(false),
+      PipelineInitiationInterval(0) {}
 
 void LoopAttributes::clear() {
   IsParallel = false;
@@ -151,6 +169,8 @@ void LoopAttributes::clear() {
   UnrollEnable = LoopAttributes::Unspecified;
   UnrollAndJamEnable = LoopAttributes::Unspecified;
   DistributeEnable = LoopAttributes::Unspecified;
+  PipelineDisabled = false;
+  PipelineInitiationInterval = 0;
 }
 
 LoopInfo::LoopInfo(BasicBlock *Header, const LoopAttributes &Attrs,
@@ -230,10 +250,14 @@ void LoopInfoStack::push(BasicBlock *Header, clang::ASTContext &Ctx,
       case LoopHintAttr::Distribute:
         setDistributeState(false);
         break;
+      case LoopHintAttr::PipelineDisabled:
+        setPipelineDisabled(true);
+        break;
       case LoopHintAttr::UnrollCount:
       case LoopHintAttr::UnrollAndJamCount:
       case LoopHintAttr::VectorizeWidth:
       case LoopHintAttr::InterleaveCount:
+      case LoopHintAttr::PipelineInitiationInterval:
         llvm_unreachable("Options cannot be disabled.");
         break;
       }
@@ -257,6 +281,8 @@ void LoopInfoStack::push(BasicBlock *Header, clang::ASTContext &Ctx,
       case LoopHintAttr::UnrollAndJamCount:
       case LoopHintAttr::VectorizeWidth:
       case LoopHintAttr::InterleaveCount:
+      case LoopHintAttr::PipelineDisabled:
+      case LoopHintAttr::PipelineInitiationInterval:
         llvm_unreachable("Options cannot enabled.");
         break;
       }
@@ -276,6 +302,8 @@ void LoopInfoStack::push(BasicBlock *Header, clang::ASTContext &Ctx,
       case LoopHintAttr::VectorizeWidth:
       case LoopHintAttr::InterleaveCount:
       case LoopHintAttr::Distribute:
+      case LoopHintAttr::PipelineDisabled:
+      case LoopHintAttr::PipelineInitiationInterval:
         llvm_unreachable("Options cannot be used to assume mem safety.");
         break;
       }
@@ -295,6 +323,8 @@ void LoopInfoStack::push(BasicBlock *Header, clang::ASTContext &Ctx,
       case LoopHintAttr::VectorizeWidth:
       case LoopHintAttr::InterleaveCount:
       case LoopHintAttr::Distribute:
+      case LoopHintAttr::PipelineDisabled:
+      case LoopHintAttr::PipelineInitiationInterval:
         llvm_unreachable("Options cannot be used with 'full' hint.");
         break;
       }
@@ -313,11 +343,15 @@ void LoopInfoStack::push(BasicBlock *Header, clang::ASTContext &Ctx,
       case LoopHintAttr::UnrollAndJamCount:
         setUnrollAndJamCount(ValueInt);
         break;
+      case LoopHintAttr::PipelineInitiationInterval:
+        setPipelineInitiationInterval(ValueInt);
+        break;
       case LoopHintAttr::Unroll:
       case LoopHintAttr::UnrollAndJam:
       case LoopHintAttr::Vectorize:
       case LoopHintAttr::Interleave:
       case LoopHintAttr::Distribute:
+      case LoopHintAttr::PipelineDisabled:
         llvm_unreachable("Options cannot be assigned a value.");
         break;
       }
diff --git a/lib/CodeGen/CGLoopInfo.h b/lib/CodeGen/CGLoopInfo.h
index 201cbb7894..84ba03bfb0 100644
--- a/lib/CodeGen/CGLoopInfo.h
+++ b/lib/CodeGen/CGLoopInfo.h
@@ -66,6 +66,12 @@ struct LoopAttributes {
 
   /// Value for llvm.loop.distribute.enable metadata.
   LVEnableState DistributeEnable;
+
+  /// Value for llvm.loop.pipeline.disable metadata.
+  bool PipelineDisabled;
+
+  /// Value for llvm.loop.pipeline.iicount metadata.
+  unsigned PipelineInitiationInterval;
 };
 
 /// Information used when generating a structured loop.
@@ -171,6 +177,14 @@ public:
   /// \brief Set the unroll count for the next loop pushed.
   void setUnrollAndJamCount(unsigned C) { StagedAttrs.UnrollAndJamCount = C; }
 
+  /// Set the pipeline disabled state.
+  void setPipelineDisabled(bool S) { StagedAttrs.PipelineDisabled = S; }
+
+  /// Set the pipeline initiation interval.
+  void setPipelineInitiationInterval(unsigned C) {
+    StagedAttrs.PipelineInitiationInterval = C;
+  }
+
 private:
   /// Returns true if there is LoopInfo on the stack.
   bool hasInfo() const { return !Active.empty(); }
diff --git a/lib/Parse/ParsePragma.cpp b/lib/Parse/ParsePragma.cpp
index 3204cf08ec..380eb64997 100644
--- a/lib/Parse/ParsePragma.cpp
+++ b/lib/Parse/ParsePragma.cpp
@@ -1057,20 +1057,23 @@ bool Parser::HandlePragmaLoopHint(LoopHint &Hint) {
   bool OptionUnroll = false;
   bool OptionUnrollAndJam = false;
   bool OptionDistribute = false;
+  bool OptionPipelineDisabled = false;
   bool StateOption = false;
   if (OptionInfo) { // Pragma Unroll does not specify an option.
     OptionUnroll = OptionInfo->isStr("unroll");
     OptionUnrollAndJam = OptionInfo->isStr("unroll_and_jam");
     OptionDistribute = OptionInfo->isStr("distribute");
+    OptionPipelineDisabled = OptionInfo->isStr("pipeline");
     StateOption = llvm::StringSwitch(OptionInfo->getName())
                       .Case("vectorize", true)
                       .Case("interleave", true)
                       .Default(false) ||
-                  OptionUnroll || OptionUnrollAndJam || OptionDistribute;
+                  OptionUnroll || OptionUnrollAndJam || OptionDistribute ||
+                  OptionPipelineDisabled;
   }
 
-  bool AssumeSafetyArg =
-      !OptionUnroll && !OptionUnrollAndJam && !OptionDistribute;
+  bool AssumeSafetyArg = !OptionUnroll && !OptionUnrollAndJam &&
+                         !OptionDistribute && !OptionPipelineDisabled;
   // Verify loop hint has an argument.
   if (Toks[0].is(tok::eof)) {
     ConsumeAnnotationToken();
@@ -1087,16 +1090,21 @@ bool Parser::HandlePragmaLoopHint(LoopHint &Hint) {
     SourceLocation StateLoc = Toks[0].getLocation();
     IdentifierInfo *StateInfo = Toks[0].getIdentifierInfo();
 
-    bool Valid =
-        StateInfo && llvm::StringSwitch(StateInfo->getName())
-                         .Cases("enable", "disable", true)
-                         .Case("full", OptionUnroll || OptionUnrollAndJam)
-                         .Case("assume_safety", AssumeSafetyArg)
-                         .Default(false);
+    bool Valid = StateInfo &&
+                 llvm::StringSwitch(StateInfo->getName())
+                     .Case("disable", true)
+                     .Case("enable", !OptionPipelineDisabled)
+                     .Case("full", OptionUnroll || OptionUnrollAndJam)
+                     .Case("assume_safety", AssumeSafetyArg)
+                     .Default(false);
     if (!Valid) {
-      Diag(Toks[0].getLocation(), diag::err_pragma_invalid_keyword)
-          << /*FullKeyword=*/(OptionUnroll || OptionUnrollAndJam)
-          << /*AssumeSafetyKeyword=*/AssumeSafetyArg;
+      if (OptionPipelineDisabled) {
+        Diag(Toks[0].getLocation(), diag::err_pragma_pipeline_invalid_keyword);
+      } else {
+        Diag(Toks[0].getLocation(), diag::err_pragma_invalid_keyword)
+            << /*FullKeyword=*/(OptionUnroll || OptionUnrollAndJam)
+            << /*AssumeSafetyKeyword=*/AssumeSafetyArg;
+      }
       return false;
     }
     if (Toks.size() > 2)
@@ -2810,6 +2818,8 @@ static bool ParseLoopHintValue(Preprocessor &PP, Token &Tok, Token PragmaName,
 ///    'vectorize_width' '(' loop-hint-value ')'
 ///    'interleave_count' '(' loop-hint-value ')'
 ///    'unroll_count' '(' loop-hint-value ')'
+///    'pipeline' '(' disable ')'
+///    'pipeline_initiation_interval' '(' loop-hint-value ')'
 ///
 ///  loop-hint-keyword:
 ///    'enable'
@@ -2869,6 +2879,8 @@ void PragmaLoopHintHandler::HandlePragma(Preprocessor &PP,
                            .Case("vectorize_width", true)
                            .Case("interleave_count", true)
                            .Case("unroll_count", true)
+                           .Case("pipeline", true)
+                           .Case("pipeline_initiation_interval", true)
                            .Default(false);
     if (!OptionValid) {
       PP.Diag(Tok.getLocation(), diag::err_pragma_loop_invalid_option)
diff --git a/lib/Sema/SemaStmtAttr.cpp b/lib/Sema/SemaStmtAttr.cpp
index 91f7997166..a8e54b36b2 100644
--- a/lib/Sema/SemaStmtAttr.cpp
+++ b/lib/Sema/SemaStmtAttr.cpp
@@ -147,11 +147,15 @@ static Attr *handleLoopHintAttr(Sema &S, Stmt *St, const ParsedAttr &A,
                  .Case("interleave_count", LoopHintAttr::InterleaveCount)
                  .Case("unroll", LoopHintAttr::Unroll)
                  .Case("unroll_count", LoopHintAttr::UnrollCount)
+                 .Case("pipeline", LoopHintAttr::PipelineDisabled)
+                 .Case("pipeline_initiation_interval",
+                       LoopHintAttr::PipelineInitiationInterval)
                  .Case("distribute", LoopHintAttr::Distribute)
                  .Default(LoopHintAttr::Vectorize);
     if (Option == LoopHintAttr::VectorizeWidth ||
         Option == LoopHintAttr::InterleaveCount ||
-        Option == LoopHintAttr::UnrollCount) {
+        Option == LoopHintAttr::UnrollCount ||
+        Option == LoopHintAttr::PipelineInitiationInterval) {
       assert(ValueExpr && "Attribute must have a valid value expression.");
       if (S.CheckLoopHintExpr(ValueExpr, St->getBeginLoc()))
         return nullptr;
@@ -159,7 +163,8 @@ static Attr *handleLoopHintAttr(Sema &S, Stmt *St, const ParsedAttr &A,
     } else if (Option == LoopHintAttr::Vectorize ||
                Option == LoopHintAttr::Interleave ||
                Option == LoopHintAttr::Unroll ||
-               Option == LoopHintAttr::Distribute) {
+               Option == LoopHintAttr::Distribute ||
+               Option == LoopHintAttr::PipelineDisabled) {
       assert(StateLoc && StateLoc->Ident && "Loop hint must have an argument");
       if (StateLoc->Ident->isStr("disable"))
         State = LoopHintAttr::Disable;
@@ -182,9 +187,9 @@ static Attr *handleLoopHintAttr(Sema &S, Stmt *St, const ParsedAttr &A,
 static void
 CheckForIncompatibleAttributes(Sema &S,
                                const SmallVectorImpl &Attrs) {
-  // There are 5 categories of loop hints attributes: vectorize, interleave,
-  // unroll, unroll_and_jam and distribute. Except for distribute they come
-  // in two variants: a state form and a numeric form.  The state form
+  // There are 6 categories of loop hints attributes: vectorize, interleave,
+  // unroll, unroll_and_jam, pipeline and distribute. Except for distribute they
+  // come in two variants: a state form and a numeric form.  The state form
   // selectively defaults/enables/disables the transformation for the loop
   // (for unroll, default indicates full unrolling rather than enabling the
   // transformation). The numeric form form provides an integer hint (for
@@ -194,11 +199,8 @@ CheckForIncompatibleAttributes(Sema &S,
   struct {
     const LoopHintAttr *StateAttr;
     const LoopHintAttr *NumericAttr;
-  } HintAttrs[] = {{nullptr, nullptr},
-                   {nullptr, nullptr},
-                   {nullptr, nullptr},
-                   {nullptr, nullptr},
-                   {nullptr, nullptr}};
+  } HintAttrs[] = {{nullptr, nullptr}, {nullptr, nullptr}, {nullptr, nullptr},
+                   {nullptr, nullptr}, {nullptr, nullptr}, {nullptr, nullptr}};
 
   for (const auto *I : Attrs) {
     const LoopHintAttr *LH = dyn_cast(I);
@@ -208,7 +210,14 @@ CheckForIncompatibleAttributes(Sema &S,
       continue;
 
     LoopHintAttr::OptionType Option = LH->getOption();
-    enum { Vectorize, Interleave, Unroll, UnrollAndJam, Distribute } Category;
+    enum {
+      Vectorize,
+      Interleave,
+      Unroll,
+      UnrollAndJam,
+      Distribute,
+      Pipeline
+    } Category;
     switch (Option) {
     case LoopHintAttr::Vectorize:
     case LoopHintAttr::VectorizeWidth:
@@ -230,6 +239,10 @@ CheckForIncompatibleAttributes(Sema &S,
       // Perform the check for duplicated 'distribute' hints.
       Category = Distribute;
       break;
+    case LoopHintAttr::PipelineDisabled:
+    case LoopHintAttr::PipelineInitiationInterval:
+      Category = Pipeline;
+      break;
     };
 
     assert(Category < sizeof(HintAttrs) / sizeof(HintAttrs[0]));
@@ -238,6 +251,7 @@ CheckForIncompatibleAttributes(Sema &S,
     if (Option == LoopHintAttr::Vectorize ||
         Option == LoopHintAttr::Interleave || Option == LoopHintAttr::Unroll ||
         Option == LoopHintAttr::UnrollAndJam ||
+        Option == LoopHintAttr::PipelineDisabled ||
         Option == LoopHintAttr::Distribute) {
       // Enable|Disable|AssumeSafety hint.  For example, vectorize(enable).
       PrevAttr = CategoryState.StateAttr;
diff --git a/test/CodeGenCXX/pragma-pipeline.cpp b/test/CodeGenCXX/pragma-pipeline.cpp
new file mode 100644
index 0000000000..6846f15443
--- /dev/null
+++ b/test/CodeGenCXX/pragma-pipeline.cpp
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -triple hexagon -std=c++11 -emit-llvm -o - %s | FileCheck %s
+
+void pipeline_disabled(int *List, int Length, int Value) {
+// CHECK-LABEL: define {{.*}} @_Z17pipeline_disabled
+#pragma clang loop pipeline(disable)
+  for (int i = 0; i < Length; i++) {
+    // CHECK: br label {{.*}}, !llvm.loop ![[LOOP_1:.*]]
+    List[i] = Value;
+  }
+}
+
+void pipeline_not_disabled(int *List, int Length, int Value) {
+  // CHECK-LABEL: define {{.*}} @_Z21pipeline_not_disabled
+  for (int i = 0; i < Length; i++) {
+    List[i] = Value;
+  }
+}
+
+void pipeline_initiation_interval(int *List, int Length, int Value) {
+// CHECK-LABEL: define {{.*}} @_Z28pipeline_initiation_interval 
+#pragma clang loop pipeline_initiation_interval(10)
+  for (int i = 0; i < Length; i++) {
+    // CHECK: br label {{.*}}, !llvm.loop ![[LOOP_3:.*]]
+    List[i] = Value;
+  }
+}
+
+void pipeline_disabled_on_nested_loop(int *List, int Length, int Value) {
+  // CHECK-LABEL: define {{.*}} @_Z32pipeline_disabled_on_nested_loop
+  for (int i = 0; i < Length; i++) {
+#pragma clang loop pipeline(disable)
+    for (int j = 0; j < Length; j++) {
+      // CHECK: br label {{.*}}, !llvm.loop ![[LOOP_4:.*]]
+      List[i * Length + j] = Value;
+    }
+  }
+}
+
+// CHECK: ![[LOOP_1]] = distinct !{![[LOOP_1]], ![[PIPELINE_DISABLE:.*]]}
+// CHECK: ![[PIPELINE_DISABLE]] = !{!"llvm.loop.pipeline.disable", i1 true}
+
+// CHECK-NOT:llvm.loop.pipeline
+
+// CHECK: ![[LOOP_3]] = distinct !{![[LOOP_3]], ![[PIPELINE_II_10:.*]]}
+// CHECK: ![[PIPELINE_II_10]] = !{!"llvm.loop.pipeline.initiationinterval", i32 10}
+
+// CHECK: ![[LOOP_4]] = distinct !{![[LOOP_4]], ![[PIPELINE_DISABLE]]}
diff --git a/test/Parser/pragma-loop.cpp b/test/Parser/pragma-loop.cpp
index 3db0fc4596..be765170f8 100644
--- a/test/Parser/pragma-loop.cpp
+++ b/test/Parser/pragma-loop.cpp
@@ -147,7 +147,7 @@ void test(int *List, int Length) {
 /* expected-error {{missing argument; expected 'enable', 'full' or 'disable'}} */ #pragma clang loop unroll()
 /* expected-error {{missing argument; expected 'enable' or 'disable'}} */ #pragma clang loop distribute()
 
-/* expected-error {{missing option; expected vectorize, vectorize_width, interleave, interleave_count, unroll, unroll_count, or distribute}} */ #pragma clang loop
+/* expected-error {{missing option; expected vectorize, vectorize_width, interleave, interleave_count, unroll, unroll_count, pipeline, pipeline_initiation_interval, or distribute}} */ #pragma clang loop
 /* expected-error {{invalid option 'badkeyword'}} */ #pragma clang loop badkeyword
 /* expected-error {{invalid option 'badkeyword'}} */ #pragma clang loop badkeyword(enable)
 /* expected-error {{invalid option 'badkeyword'}} */ #pragma clang loop vectorize(enable) badkeyword(4)
diff --git a/test/Parser/pragma-pipeline.cpp b/test/Parser/pragma-pipeline.cpp
new file mode 100644
index 0000000000..e500d4d2d5
--- /dev/null
+++ b/test/Parser/pragma-pipeline.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -std=c++11 -verify %s
+
+// Note that this puts the expected lines before the directives to work around
+// limitations in the -verify mode.
+
+void test(int *List, int Length, int Value) {
+  int i = 0;
+
+#pragma clang loop pipeline(disable)
+  for (int i = 0; i < Length; i++) {
+    List[i] = Value;
+  }
+
+#pragma clang loop pipeline_initiation_interval(10)
+  for (int i = 0; i < Length; i++) {
+    List[i] = Value;
+  }
+
+/* expected-error {{expected ')'}} */ #pragma clang loop pipeline(disable
+/* expected-error {{invalid argument; expected 'disable'}} */ #pragma clang loop pipeline(enable)
+/* expected-error {{invalid argument; expected 'disable'}} */ #pragma clang loop pipeline(error)
+/* expected-error {{expected '('}} */ #pragma clang loop pipeline disable
+/* expected-error {{missing argument; expected an integer value}} */ #pragma clang loop pipeline_initiation_interval()
+/* expected-error {{use of undeclared identifier 'error'}} */ #pragma clang loop pipeline_initiation_interval(error)
+/* expected-error {{expected '('}} */ #pragma clang loop pipeline_initiation_interval 1 2
+/* expected-error {{expected ')'}} */ #pragma clang loop pipeline_initiation_interval(1
+  for (int i = 0; i < Length; i++) {
+    for (int j = 0; j < Length; j++) {
+      List[i * Length + j] = Value;
+    }
+  }
+
+}
diff --git a/test/Parser/pragma-unroll-and-jam.cpp b/test/Parser/pragma-unroll-and-jam.cpp
index 8452156f69..ef1867aa19 100644
--- a/test/Parser/pragma-unroll-and-jam.cpp
+++ b/test/Parser/pragma-unroll-and-jam.cpp
@@ -67,7 +67,7 @@ void test(int *List, int Length, int Value) {
   }
 
 // pragma clang unroll_and_jam is disabled for the moment
-/* expected-error {{invalid option 'unroll_and_jam'; expected vectorize, vectorize_width, interleave, interleave_count, unroll, unroll_count, or distribute}} */ #pragma clang loop unroll_and_jam(4)
+/* expected-error {{invalid option 'unroll_and_jam'; expected vectorize, vectorize_width, interleave, interleave_count, unroll, unroll_count, pipeline, pipeline_initiation_interval, or distribute}} */ #pragma clang loop unroll_and_jam(4)
   for (int i = 0; i < Length; i++) {
     for (int j = 0; j < Length; j++) {
       List[i * Length + j] = Value;
diff --git a/test/Sema/pragma-pipeline.cpp b/test/Sema/pragma-pipeline.cpp
new file mode 100644
index 0000000000..7b277601d0
--- /dev/null
+++ b/test/Sema/pragma-pipeline.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+
+#pragma clang loop pipeline(disable) /* expected-error {{expected unqualified-id}} */
+int main() {
+  for (int i = 0; i < 10; ++i)
+    ;
+}
+
+void test(int *List, int Length, int Value) {
+  int i = 0;
+
+/* expected-error {{invalid argument of type 'double'; expected an integer type}} */ #pragma clang loop pipeline_initiation_interval(1.0)
+/* expected-error {{invalid value '0'; must be positive}} */ #pragma clang loop pipeline_initiation_interval(0)
+/* expected-error {{invalid value '-1'; must be positive}} */ #pragma clang loop pipeline_initiation_interval(-1)
+  for (int i = 0; i < Length; i++) {
+    for (int j = 0; j < Length; j++) {
+      List[i * Length + j] = Value;
+    }
+  }
+
+#pragma clang loop pipeline(disable) 
+/* expected-error {{expected a for, while, or do-while loop to follow '#pragma clang loop'}} */ int j = Length;
+#pragma clang loop pipeline_initiation_interval(4)
+/* expected-error {{expected a for, while, or do-while loop to follow '#pragma clang loop'}} */ int k = Length;
+
+#pragma clang loop pipeline(disable)
+#pragma clang loop pipeline_initiation_interval(4) /* expected-error {{incompatible directives 'pipeline(disable)' and 'pipeline_initiation_interval(4)'}} */
+  for (int i = 0; i < Length; i++) {
+    List[i] = Value;
+  }
+
+#pragma clang loop pipeline(disable)
+/* expected-error {{expected statement}} */ }
+
-- 
cgit v1.2.3


From 1188822bbcdd02f816e857f1c15df32d0d8c5336 Mon Sep 17 00:00:00 2001
From: Alexey Bataev 
Date: Fri, 4 Jan 2019 17:25:09 +0000
Subject: [OPENMP][NVPTX]Use new functions from the runtime library.

Updated codegen to use the new functions from the runtime library.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350415 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp               | 73 +++++++++++++---------
 test/OpenMP/nvptx_data_sharing.cpp                 |  4 +-
 ...tx_distribute_parallel_generic_mode_codegen.cpp |  4 +-
 test/OpenMP/nvptx_parallel_codegen.cpp             |  4 +-
 test/OpenMP/nvptx_parallel_for_codegen.cpp         |  4 +-
 test/OpenMP/nvptx_target_codegen.cpp               |  2 +-
 .../nvptx_target_parallel_reduction_codegen.cpp    |  6 +-
 .../nvptx_target_teams_distribute_codegen.cpp      |  2 +-
 ...arget_teams_distribute_parallel_for_codegen.cpp |  4 +-
 ..._teams_distribute_parallel_for_simd_codegen.cpp |  4 +-
 test/OpenMP/nvptx_teams_codegen.cpp                |  8 +--
 test/OpenMP/nvptx_teams_reduction_codegen.cpp      |  6 +-
 12 files changed, 67 insertions(+), 54 deletions(-)

diff --git a/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp b/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp
index 97b8f79a9f..21911c96f3 100644
--- a/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp
+++ b/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp
@@ -56,12 +56,12 @@ enum OpenMPRTLFunctionNVPTX {
   /// Call to int64_t __kmpc_shuffle_int64(int64_t element,
   /// int16_t lane_offset, int16_t warp_size);
   OMPRTL_NVPTX__kmpc_shuffle_int64,
-  /// Call to __kmpc_nvptx_parallel_reduce_nowait(kmp_int32
+  /// Call to __kmpc_nvptx_parallel_reduce_nowait_v2(ident_t *loc, kmp_int32
   /// global_tid, kmp_int32 num_vars, size_t reduce_size, void* reduce_data,
   /// void (*kmp_ShuffleReductFctPtr)(void *rhsData, int16_t lane_id, int16_t
   /// lane_offset, int16_t shortCircuit),
   /// void (*kmp_InterWarpCopyFctPtr)(void* src, int32_t warp_num));
-  OMPRTL_NVPTX__kmpc_parallel_reduce_nowait,
+  OMPRTL_NVPTX__kmpc_parallel_reduce_nowait_v2,
   /// Call to __kmpc_nvptx_teams_reduce_nowait_simple(ident_t *loc, kmp_int32
   /// global_tid, kmp_critical_name *lck)
   OMPRTL_NVPTX__kmpc_nvptx_teams_reduce_nowait_simple,
@@ -91,10 +91,11 @@ enum OpenMPRTLFunctionNVPTX {
   OMPRTL_NVPTX__kmpc_parallel_level,
   /// Call to int8_t __kmpc_is_spmd_exec_mode();
   OMPRTL_NVPTX__kmpc_is_spmd_exec_mode,
-  /// Call to void __kmpc_get_team_static_memory(const void *buf, size_t size,
-  /// int16_t is_shared, const void **res);
+  /// Call to void __kmpc_get_team_static_memory(int16_t isSPMDExecutionMode,
+  /// const void *buf, size_t size, int16_t is_shared, const void **res);
   OMPRTL_NVPTX__kmpc_get_team_static_memory,
-  /// Call to void __kmpc_restore_team_static_memory(int16_t is_shared);
+  /// Call to void __kmpc_restore_team_static_memory(int16_t
+  /// isSPMDExecutionMode, int16_t is_shared);
   OMPRTL_NVPTX__kmpc_restore_team_static_memory,
   /// Call to void __kmpc_barrier(ident_t *loc, kmp_int32 global_tid);
   OMPRTL__kmpc_barrier,
@@ -1646,12 +1647,12 @@ CGOpenMPRuntimeNVPTX::createNVPTXRuntimeFunction(unsigned Function) {
     RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_shuffle_int64");
     break;
   }
-  case OMPRTL_NVPTX__kmpc_parallel_reduce_nowait: {
-    // Build int32_t kmpc_nvptx_parallel_reduce_nowait(kmp_int32 global_tid,
-    // kmp_int32 num_vars, size_t reduce_size, void* reduce_data,
-    // void (*kmp_ShuffleReductFctPtr)(void *rhsData, int16_t lane_id, int16_t
-    // lane_offset, int16_t Algorithm Version),
-    // void (*kmp_InterWarpCopyFctPtr)(void* src, int warp_num));
+  case OMPRTL_NVPTX__kmpc_parallel_reduce_nowait_v2: {
+    // Build int32_t kmpc_nvptx_parallel_reduce_nowait_v2(ident_t *loc,
+    // kmp_int32 global_tid, kmp_int32 num_vars, size_t reduce_size, void*
+    // reduce_data, void (*kmp_ShuffleReductFctPtr)(void *rhsData, int16_t
+    // lane_id, int16_t lane_offset, int16_t Algorithm Version), void
+    // (*kmp_InterWarpCopyFctPtr)(void* src, int warp_num));
     llvm::Type *ShuffleReduceTypeParams[] = {CGM.VoidPtrTy, CGM.Int16Ty,
                                              CGM.Int16Ty, CGM.Int16Ty};
     auto *ShuffleReduceFnTy =
@@ -1661,7 +1662,8 @@ CGOpenMPRuntimeNVPTX::createNVPTXRuntimeFunction(unsigned Function) {
     auto *InterWarpCopyFnTy =
         llvm::FunctionType::get(CGM.VoidTy, InterWarpCopyTypeParams,
                                 /*isVarArg=*/false);
-    llvm::Type *TypeParams[] = {CGM.Int32Ty,
+    llvm::Type *TypeParams[] = {getIdentTyPointerTy(),
+                                CGM.Int32Ty,
                                 CGM.Int32Ty,
                                 CGM.SizeTy,
                                 CGM.VoidPtrTy,
@@ -1670,7 +1672,7 @@ CGOpenMPRuntimeNVPTX::createNVPTXRuntimeFunction(unsigned Function) {
     auto *FnTy =
         llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg=*/false);
     RTLFn = CGM.CreateRuntimeFunction(
-        FnTy, /*Name=*/"__kmpc_nvptx_parallel_reduce_nowait");
+        FnTy, /*Name=*/"__kmpc_nvptx_parallel_reduce_nowait_v2");
     break;
   }
   case OMPRTL_NVPTX__kmpc_end_reduce_nowait: {
@@ -1779,19 +1781,21 @@ CGOpenMPRuntimeNVPTX::createNVPTXRuntimeFunction(unsigned Function) {
     break;
   }
   case OMPRTL_NVPTX__kmpc_get_team_static_memory: {
-    // Build void __kmpc_get_team_static_memory(const void *buf, size_t size,
-    // int16_t is_shared, const void **res);
-    llvm::Type *TypeParams[] = {CGM.VoidPtrTy, CGM.SizeTy, CGM.Int16Ty,
-                                CGM.VoidPtrPtrTy};
+    // Build void __kmpc_get_team_static_memory(int16_t isSPMDExecutionMode,
+    // const void *buf, size_t size, int16_t is_shared, const void **res);
+    llvm::Type *TypeParams[] = {CGM.Int16Ty, CGM.VoidPtrTy, CGM.SizeTy,
+                                CGM.Int16Ty, CGM.VoidPtrPtrTy};
     auto *FnTy =
         llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
     RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_get_team_static_memory");
     break;
   }
   case OMPRTL_NVPTX__kmpc_restore_team_static_memory: {
-    // Build void __kmpc_restore_team_static_memory(int16_t is_shared);
+    // Build void __kmpc_restore_team_static_memory(int16_t isSPMDExecutionMode,
+    // int16_t is_shared);
+    llvm::Type *TypeParams[] = {CGM.Int16Ty, CGM.Int16Ty};
     auto *FnTy =
-        llvm::FunctionType::get(CGM.VoidTy, CGM.Int16Ty, /*isVarArg=*/false);
+        llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
     RTLFn =
         CGM.CreateRuntimeFunction(FnTy, "__kmpc_restore_team_static_memory");
     break;
@@ -2211,8 +2215,11 @@ void CGOpenMPRuntimeNVPTX::emitGenericVarsProlog(CodeGenFunction &CGF,
             CGM.getContext().getSizeType(), Loc);
         llvm::Value *ResAddr = Bld.CreatePointerBitCastOrAddrSpaceCast(
             KernelStaticGlobalized, CGM.VoidPtrPtrTy);
-        llvm::Value *GlobalRecordSizeArg[] = {StaticGlobalized, Ld,
-                                              IsInSharedMemory, ResAddr};
+        llvm::Value *GlobalRecordSizeArg[] = {
+            llvm::ConstantInt::get(
+                CGM.Int16Ty,
+                getExecutionMode() == CGOpenMPRuntimeNVPTX::EM_SPMD ? 1 : 0),
+            StaticGlobalized, Ld, IsInSharedMemory, ResAddr};
         CGF.EmitRuntimeCall(createNVPTXRuntimeFunction(
                                 OMPRTL_NVPTX__kmpc_get_team_static_memory),
                             GlobalRecordSizeArg);
@@ -2400,10 +2407,15 @@ void CGOpenMPRuntimeNVPTX::emitGenericVarsEpilog(CodeGenFunction &CGF,
               Address(GlobalizedRecords.back().UseSharedMemory,
                       CGM.getContext().getTypeAlignInChars(Int16Ty)),
               /*Volatile=*/false, Int16Ty, GlobalizedRecords.back().Loc);
+          llvm::Value *Args[] = {
+              llvm::ConstantInt::get(
+                  CGM.Int16Ty,
+                  getExecutionMode() == CGOpenMPRuntimeNVPTX::EM_SPMD ? 1 : 0),
+              IsInSharedMemory};
           CGF.EmitRuntimeCall(
               createNVPTXRuntimeFunction(
                   OMPRTL_NVPTX__kmpc_restore_team_static_memory),
-              IsInSharedMemory);
+              Args);
         }
       } else {
         CGF.EmitRuntimeCall(createNVPTXRuntimeFunction(
@@ -3608,7 +3620,7 @@ static llvm::Value *emitShuffleAndReduceFunction(
 /// 3. Call the OpenMP runtime on the GPU to reduce within a team
 ///    and store the result on the team master:
 ///
-///     __kmpc_nvptx_parallel_reduce_nowait(...,
+///     __kmpc_nvptx_parallel_reduce_nowait_v2(...,
 ///        reduceData, shuffleReduceFn, interWarpCpyFn)
 ///
 ///     where:
@@ -3779,7 +3791,7 @@ static llvm::Value *emitShuffleAndReduceFunction(
 /// Intra-Team Reduction
 ///
 /// This function, as implemented in the runtime call
-/// '__kmpc_nvptx_parallel_reduce_nowait', aggregates data across OpenMP
+/// '__kmpc_nvptx_parallel_reduce_nowait_v2', aggregates data across OpenMP
 /// threads in a team.  It first reduces within a warp using the
 /// aforementioned algorithms.  We then proceed to gather all such
 /// reduced values at the first warp.
@@ -3802,7 +3814,7 @@ static llvm::Value *emitShuffleAndReduceFunction(
 /// 'loadAndReduceDataFn' to load and reduce values from the array, i.e.,
 /// the k'th worker reduces every k'th element.
 ///
-/// Finally, a call is made to '__kmpc_nvptx_parallel_reduce_nowait' to
+/// Finally, a call is made to '__kmpc_nvptx_parallel_reduce_nowait_v2' to
 /// reduce across workers and compute a globally reduced value.
 ///
 void CGOpenMPRuntimeNVPTX::emitReduction(
@@ -3832,6 +3844,7 @@ void CGOpenMPRuntimeNVPTX::emitReduction(
   // RedList, shuffle_reduce_func, interwarp_copy_func);
   // or
   // Build res = __kmpc_reduce_teams_nowait_simple(, , );
+  llvm::Value *RTLoc = emitUpdateLocation(CGF, Loc);
   llvm::Value *ThreadId = getThreadID(CGF, Loc);
 
   llvm::Value *Res;
@@ -3886,19 +3899,19 @@ void CGOpenMPRuntimeNVPTX::emitReduction(
     llvm::Value *InterWarpCopyFn =
         emitInterWarpCopyFunction(CGM, Privates, ReductionArrayTy, Loc);
 
-    llvm::Value *Args[] = {ThreadId,
+    llvm::Value *Args[] = {RTLoc,
+                           ThreadId,
                            CGF.Builder.getInt32(RHSExprs.size()),
                            ReductionArrayTySize,
                            RL,
                            ShuffleAndReduceFn,
                            InterWarpCopyFn};
 
-    Res = CGF.EmitRuntimeCall(
-        createNVPTXRuntimeFunction(OMPRTL_NVPTX__kmpc_parallel_reduce_nowait),
-        Args);
+    Res = CGF.EmitRuntimeCall(createNVPTXRuntimeFunction(
+                                  OMPRTL_NVPTX__kmpc_parallel_reduce_nowait_v2),
+                              Args);
   } else {
     assert(TeamsReduction && "expected teams reduction.");
-    llvm::Value *RTLoc = emitUpdateLocation(CGF, Loc);
     std::string Name = getName({"reduction"});
     llvm::Value *Lock = getCriticalRegionLock(Name);
     llvm::Value *Args[] = {RTLoc, ThreadId, Lock};
diff --git a/test/OpenMP/nvptx_data_sharing.cpp b/test/OpenMP/nvptx_data_sharing.cpp
index df9c3ee83b..7b21d82794 100644
--- a/test/OpenMP/nvptx_data_sharing.cpp
+++ b/test/OpenMP/nvptx_data_sharing.cpp
@@ -46,7 +46,7 @@ void test_ds(){
 // CK1: call void @__kmpc_data_sharing_init_stack
 // CK1: [[SHARED_MEM_FLAG:%.+]] = load i16, i16* [[KERNEL_SHARED]],
 // CK1: [[SIZE:%.+]] = load i64, i64* [[KERNEL_SIZE]],
-// CK1: call void @__kmpc_get_team_static_memory(i8* addrspacecast (i8 addrspace(3)* getelementptr inbounds ([[MEM_TY]], [[MEM_TY]] addrspace(3)* [[SHARED_GLOBAL_RD]], i32 0, i32 0, i32 0) to i8*), i64 [[SIZE]], i16 [[SHARED_MEM_FLAG]], i8** addrspacecast (i8* addrspace(3)* [[KERNEL_PTR]] to i8**))
+// CK1: call void @__kmpc_get_team_static_memory(i16 0, i8* addrspacecast (i8 addrspace(3)* getelementptr inbounds ([[MEM_TY]], [[MEM_TY]] addrspace(3)* [[SHARED_GLOBAL_RD]], i32 0, i32 0, i32 0) to i8*), i64 [[SIZE]], i16 [[SHARED_MEM_FLAG]], i8** addrspacecast (i8* addrspace(3)* [[KERNEL_PTR]] to i8**))
 // CK1: [[KERNEL_RD:%.+]] = load i8*, i8* addrspace(3)* [[KERNEL_PTR]],
 // CK1: [[GLOBALSTACK:%.+]] = getelementptr inbounds i8, i8* [[KERNEL_RD]], i64 0
 // CK1: [[GLOBALSTACK2:%.+]] = bitcast i8* [[GLOBALSTACK]] to %struct._globalized_locals_ty*
@@ -76,7 +76,7 @@ void test_ds(){
 // CK1: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0)
 // CK1: call void @__kmpc_end_sharing_variables()
 // CK1: [[SHARED_MEM_FLAG:%.+]] = load i16, i16* [[KERNEL_SHARED]],
-// CK1: call void @__kmpc_restore_team_static_memory(i16 [[SHARED_MEM_FLAG]])
+// CK1: call void @__kmpc_restore_team_static_memory(i16 0, i16 [[SHARED_MEM_FLAG]])
 // CK1: call void @__kmpc_kernel_deinit(i16 1)
 
 /// ========= In the data sharing wrapper function ========= ///
diff --git a/test/OpenMP/nvptx_distribute_parallel_generic_mode_codegen.cpp b/test/OpenMP/nvptx_distribute_parallel_generic_mode_codegen.cpp
index 4e763bd139..d9056eeff5 100644
--- a/test/OpenMP/nvptx_distribute_parallel_generic_mode_codegen.cpp
+++ b/test/OpenMP/nvptx_distribute_parallel_generic_mode_codegen.cpp
@@ -30,7 +30,7 @@ int main(int argc, char **argv) {
 // CHECK-LABEL: define internal void @__omp_offloading_{{.*}}_main_l17_worker(
 
 // CHECK: define weak void @__omp_offloading_{{.*}}_main_l17([10 x i32]* dereferenceable(40) %{{.+}}, [10 x i32]* dereferenceable(40) %{{.+}}, i32* dereferenceable(4) %{{.+}}, i{{64|32}} %{{.+}}, [10 x i32]* dereferenceable(40) %{{.+}})
-// CHECK: call void @__kmpc_get_team_static_memory(i8* addrspacecast (i8 addrspace(3)* getelementptr inbounds ([[MEM_TY]], [[MEM_TY]] addrspace(3)* [[SHARED_GLOBAL_RD]], i32 0, i32 0, i32 0) to i8*), i{{64|32}} 84, i16 1, i8** addrspacecast (i8* addrspace(3)* [[KERNEL_PTR]] to i8**))
+// CHECK: call void @__kmpc_get_team_static_memory(i16 0, i8* addrspacecast (i8 addrspace(3)* getelementptr inbounds ([[MEM_TY]], [[MEM_TY]] addrspace(3)* [[SHARED_GLOBAL_RD]], i32 0, i32 0, i32 0) to i8*), i{{64|32}} 84, i16 1, i8** addrspacecast (i8* addrspace(3)* [[KERNEL_PTR]] to i8**))
 // CHECK: [[PTR:%.+]] = load i8*, i8* addrspace(3)* [[KERNEL_PTR]],
 // CHECK: [[STACK:%.+]] = bitcast i8* [[PTR]] to %struct._globalized_locals_ty*
 // CHECK: [[ARGC:%.+]] = load i32, i32* %{{.+}}, align
@@ -46,7 +46,7 @@ int main(int argc, char **argv) {
 
 // CHECK: call void @__kmpc_for_static_fini(%struct.ident_t* @
 
-// CHECK: call void @__kmpc_restore_team_static_memory(i16 1)
+// CHECK: call void @__kmpc_restore_team_static_memory(i16 0, i16 1)
 
 // CHECK: define internal void [[PARALLEL]](
 // CHECK-NOT: call i8* @__kmpc_data_sharing_push_stack(
diff --git a/test/OpenMP/nvptx_parallel_codegen.cpp b/test/OpenMP/nvptx_parallel_codegen.cpp
index 21a616d091..04089ce3f5 100644
--- a/test/OpenMP/nvptx_parallel_codegen.cpp
+++ b/test/OpenMP/nvptx_parallel_codegen.cpp
@@ -330,7 +330,7 @@ int bar(int n){
 // CHECK-64: [[CONV:%.+]] = bitcast i64* [[A_ADDR]] to i32*
 // CHECK: [[IS_SHARED:%.+]] = load i16, i16* [[KERNEL_SHARED]],
 // CHECK: [[SIZE:%.+]] = load i{{64|32}}, i{{64|32}}* [[KERNEL_SIZE]],
-// CHECK: call void @__kmpc_get_team_static_memory(i8* addrspacecast (i8 addrspace(3)* getelementptr inbounds ([[MEM_TY]], [[MEM_TY]] addrspace(3)* [[SHARED_GLOBAL_RD]], i32 0, i32 0, i32 0) to i8*), i{{64|32}} [[SIZE]], i16 [[IS_SHARED]], i8** addrspacecast (i8* addrspace(3)* [[KERNEL_PTR]] to i8**))
+// CHECK: call void @__kmpc_get_team_static_memory(i16 0, i8* addrspacecast (i8 addrspace(3)* getelementptr inbounds ([[MEM_TY]], [[MEM_TY]] addrspace(3)* [[SHARED_GLOBAL_RD]], i32 0, i32 0, i32 0) to i8*), i{{64|32}} [[SIZE]], i16 [[IS_SHARED]], i8** addrspacecast (i8* addrspace(3)* [[KERNEL_PTR]] to i8**))
 // CHECK: [[KERNEL_RD:%.+]] = load i8*, i8* addrspace(3)* [[KERNEL_PTR]],
 // CHECK: [[STACK:%.+]] = getelementptr inbounds i8, i8* [[KERNEL_RD]], i{{64|32}} 0
 // CHECK: [[BC:%.+]] = bitcast i8* [[STACK]] to %struct._globalized_locals_ty*
@@ -339,7 +339,7 @@ int bar(int n){
 // CHECK: [[GLOBAL_A_ADDR:%.+]] = getelementptr inbounds %struct._globalized_locals_ty, %struct._globalized_locals_ty* [[BC]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
 // CHECK: store i32 [[A]], i32* [[GLOBAL_A_ADDR]],
 // CHECK: [[IS_SHARED:%.+]] = load i16, i16* [[KERNEL_SHARED]],
-// CHECK: call void @__kmpc_restore_team_static_memory(i16 [[IS_SHARED]])
+// CHECK: call void @__kmpc_restore_team_static_memory(i16 0, i16 [[IS_SHARED]])
 
 // CHECK-LABEL: define internal void @{{.+}}(i32* noalias %{{.+}}, i32* noalias %{{.+}}, i32* dereferenceable{{.*}})
 // CHECK:  [[CC:%.+]] = alloca i32,
diff --git a/test/OpenMP/nvptx_parallel_for_codegen.cpp b/test/OpenMP/nvptx_parallel_for_codegen.cpp
index 92783d6085..1446ba50ce 100644
--- a/test/OpenMP/nvptx_parallel_for_codegen.cpp
+++ b/test/OpenMP/nvptx_parallel_for_codegen.cpp
@@ -47,7 +47,7 @@ int bar(int n){
 // CHECK: call void @__kmpc_data_sharing_init_stack()
 // CHECK: [[IS_SHARED:%.+]] = load i16, i16* [[KERNEL_SHARED]],
 // CHECK: [[SIZE:%.+]] = load i{{64|32}}, i{{64|32}}* [[KERNEL_SIZE]],
-// CHECK: call void @__kmpc_get_team_static_memory(i8* addrspacecast (i8 addrspace(3)* getelementptr inbounds ([[MEM_TY]], [[MEM_TY]] addrspace(3)* [[SHARED_GLOBAL_RD]], i32 0, i32 0, i32 0) to i8*), i64 %7, i16 %6, i8** addrspacecast (i8* addrspace(3)* [[KERNEL_PTR]] to i8**))
+// CHECK: call void @__kmpc_get_team_static_memory(i16 0, i8* addrspacecast (i8 addrspace(3)* getelementptr inbounds ([[MEM_TY]], [[MEM_TY]] addrspace(3)* [[SHARED_GLOBAL_RD]], i32 0, i32 0, i32 0) to i8*), i64 %7, i16 %6, i8** addrspacecast (i8* addrspace(3)* [[KERNEL_PTR]] to i8**))
 // CHECK: [[KERNEL_RD:%.+]] = load i8*, i8* addrspace(3)* [[KERNEL_PTR]],
 // CHECK: [[STACK:%.+]] = getelementptr inbounds i8, i8* [[KERNEL_RD]], i{{64|32}} 0
 // CHECK: call void @__kmpc_kernel_prepare_parallel(
@@ -56,7 +56,7 @@ int bar(int n){
 // CHECK: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0)
 // CHECK: call void @__kmpc_end_sharing_variables()
 // CHECK: [[IS_SHARED:%.+]] = load i16, i16* [[KERNEL_SHARED]],
-// CHECK: call void @__kmpc_restore_team_static_memory(i16 [[IS_SHARED]])
+// CHECK: call void @__kmpc_restore_team_static_memory(i16 0, i16 [[IS_SHARED]])
 // CHECK: call void @__kmpc_kernel_deinit(i16 1)
 
 // CHECK: define internal void @__omp_outlined__(
diff --git a/test/OpenMP/nvptx_target_codegen.cpp b/test/OpenMP/nvptx_target_codegen.cpp
index ff44c0e8fb..b05ee9dee6 100644
--- a/test/OpenMP/nvptx_target_codegen.cpp
+++ b/test/OpenMP/nvptx_target_codegen.cpp
@@ -37,7 +37,7 @@ struct TT{
 // CHECK: store i32** [[PTR2_REF]], i32*** [[PTR2_REF_PTR:%.+]],
 // CHECK: [[PTR2_REF:%.+]] = load i32**, i32*** [[PTR2_REF_PTR]],
 // CHECK: call void @__kmpc_kernel_init(
-// CHECK: call void @__kmpc_get_team_static_memory(i8* addrspacecast (i8 addrspace(3)* getelementptr inbounds ([[MAP_TY]], [[MAP_TY]] addrspace(3)* @{{.+}}, i32 0, i32 0, i32 0) to i8*), i{{64|32}} %{{.+}}, i16 %{{.+}}, i8** addrspacecast (i8* addrspace(3)* [[BUF_PTR:@.+]] to i8**))
+// CHECK: call void @__kmpc_get_team_static_memory(i16 0, i8* addrspacecast (i8 addrspace(3)* getelementptr inbounds ([[MAP_TY]], [[MAP_TY]] addrspace(3)* @{{.+}}, i32 0, i32 0, i32 0) to i8*), i{{64|32}} %{{.+}}, i16 %{{.+}}, i8** addrspacecast (i8* addrspace(3)* [[BUF_PTR:@.+]] to i8**))
 // CHECK: [[BUF:%.+]] = load i8*, i8* addrspace(3)* [[BUF_PTR]],
 // CHECK: [[BUF_OFFS:%.+]] = getelementptr inbounds i8, i8* [[BUF]], i{{[0-9]+}} 0
 // CHECK: [[BUF:%.+]] = bitcast i8* [[BUF_OFFS]] to [[GLOB_TY]]*
diff --git a/test/OpenMP/nvptx_target_parallel_reduction_codegen.cpp b/test/OpenMP/nvptx_target_parallel_reduction_codegen.cpp
index 34ad93b695..4f06f33e68 100644
--- a/test/OpenMP/nvptx_target_parallel_reduction_codegen.cpp
+++ b/test/OpenMP/nvptx_target_parallel_reduction_codegen.cpp
@@ -72,7 +72,7 @@ int bar(int n){
   // CHECK: [[E_CAST:%.+]] = bitcast double* [[E]] to i8*
   // CHECK: store i8* [[E_CAST]], i8** [[PTR1]], align
   // CHECK: [[ARG_RL:%.+]] = bitcast [[RLT]]* [[RL]] to i8*
-  // CHECK: [[RET:%.+]] = call i32 @__kmpc_nvptx_parallel_reduce_nowait(i32 {{.+}}, i32 1, i{{32|64}} {{4|8}}, i8* [[ARG_RL]], void (i8*, i16, i16, i16)* [[SHUFFLE_REDUCE_FN:@.+]], void (i8*, i32)* [[WARP_COPY_FN:@.+]])
+  // CHECK: [[RET:%.+]] = call i32 @__kmpc_nvptx_parallel_reduce_nowait_v2(%struct.ident_t* @{{.+}}, i32 {{.+}}, i32 1, i{{32|64}} {{4|8}}, i8* [[ARG_RL]], void (i8*, i16, i16, i16)* [[SHUFFLE_REDUCE_FN:@.+]], void (i8*, i32)* [[WARP_COPY_FN:@.+]])
   // CHECK: [[CMP:%.+]] = icmp eq i32 [[RET]], 1
   // CHECK: br i1 [[CMP]], label
 
@@ -273,7 +273,7 @@ int bar(int n){
   // CHECK: [[D_CAST:%.+]] = bitcast float* [[D]] to i8*
   // CHECK: store i8* [[D_CAST]], i8** [[PTR2]], align
   // CHECK: [[ARG_RL:%.+]] = bitcast [[RLT]]* [[RL]] to i8*
-  // CHECK: [[RET:%.+]] = call i32 @__kmpc_nvptx_parallel_reduce_nowait(i32 {{.+}}, i32 2, i{{32|64}} {{8|16}}, i8* [[ARG_RL]], void (i8*, i16, i16, i16)* [[SHUFFLE_REDUCE_FN:@.+]], void (i8*, i32)* [[WARP_COPY_FN:@.+]])
+  // CHECK: [[RET:%.+]] = call i32 @__kmpc_nvptx_parallel_reduce_nowait_v2(%struct.ident_t* @{{.+}}, i32 {{.+}}, i32 2, i{{32|64}} {{8|16}}, i8* [[ARG_RL]], void (i8*, i16, i16, i16)* [[SHUFFLE_REDUCE_FN:@.+]], void (i8*, i32)* [[WARP_COPY_FN:@.+]])
   // CHECK: [[CMP:%.+]] = icmp eq i32 [[RET]], 1
   // CHECK: br i1 [[CMP]], label
   // CHECK: [[C_INV8:%.+]] = load i8, i8* [[C_IN:%.+]], align
@@ -560,7 +560,7 @@ int bar(int n){
   // CHECK: [[B_CAST:%.+]] = bitcast i16* [[B]] to i8*
   // CHECK: store i8* [[B_CAST]], i8** [[PTR2]], align
   // CHECK: [[ARG_RL:%.+]] = bitcast [[RLT]]* [[RL]] to i8*
-  // CHECK: [[RET:%.+]] = call i32 @__kmpc_nvptx_parallel_reduce_nowait(i32 {{.+}}, i32 2, i{{32|64}} {{8|16}}, i8* [[ARG_RL]], void (i8*, i16, i16, i16)* [[SHUFFLE_REDUCE_FN:@.+]], void (i8*, i32)* [[WARP_COPY_FN:@.+]])
+  // CHECK: [[RET:%.+]] = call i32 @__kmpc_nvptx_parallel_reduce_nowait_v2(%struct.ident_t* @{{.+}}, i32 {{.+}}, i32 2, i{{32|64}} {{8|16}}, i8* [[ARG_RL]], void (i8*, i16, i16, i16)* [[SHUFFLE_REDUCE_FN:@.+]], void (i8*, i32)* [[WARP_COPY_FN:@.+]])
   // CHECK: [[CMP:%.+]] = icmp eq i32 [[RET]], 1
   // CHECK: br i1 [[CMP]], label
 
diff --git a/test/OpenMP/nvptx_target_teams_distribute_codegen.cpp b/test/OpenMP/nvptx_target_teams_distribute_codegen.cpp
index cf007427ec..3a0e513827 100644
--- a/test/OpenMP/nvptx_target_teams_distribute_codegen.cpp
+++ b/test/OpenMP/nvptx_target_teams_distribute_codegen.cpp
@@ -62,7 +62,7 @@ int bar(int n){
   // CHECK-DAG: [[MWS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
   // CHECK: [[MTMP1:%.+]] = sub nuw i32 [[MNTH]], [[MWS]]
   // CHECK: call void @__kmpc_kernel_init(i32 [[MTMP1]]
-  // CHECK: call void @__kmpc_get_team_static_memory(i8* addrspacecast (i8 addrspace(3)* getelementptr inbounds ([[MEM_TY]], [[MEM_TY]] addrspace(3)* @{{.+}}, i32 0, i32 0, i32 0) to i8*), i{{64|32}} 4, i16 1, i8** addrspacecast (i8* addrspace(3)* [[BUF:@.+]] to i8**))
+  // CHECK: call void @__kmpc_get_team_static_memory(i16 0, i8* addrspacecast (i8 addrspace(3)* getelementptr inbounds ([[MEM_TY]], [[MEM_TY]] addrspace(3)* @{{.+}}, i32 0, i32 0, i32 0) to i8*), i{{64|32}} 4, i16 1, i8** addrspacecast (i8* addrspace(3)* [[BUF:@.+]] to i8**))
   // CHECK: [[PTR:%.+]] = load i8*, i8* addrspace(3)* [[BUF]],
   // CHECK: [[RD:%.+]] = bitcast i8* [[PTR]] to [[GLOB_TY:%.+]]*
   // CHECK: [[I_ADDR:%.+]] = getelementptr inbounds [[GLOB_TY]], [[GLOB_TY]]* [[RD]], i32 0, i32 0
diff --git a/test/OpenMP/nvptx_target_teams_distribute_parallel_for_codegen.cpp b/test/OpenMP/nvptx_target_teams_distribute_parallel_for_codegen.cpp
index 2ecb9ca0e2..c4df348329 100644
--- a/test/OpenMP/nvptx_target_teams_distribute_parallel_for_codegen.cpp
+++ b/test/OpenMP/nvptx_target_teams_distribute_parallel_for_codegen.cpp
@@ -83,14 +83,14 @@ int bar(int n){
 // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+}}_l32(
 // CHECK-DAG: [[THREAD_LIMIT:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
 // CHECK: call void @__kmpc_spmd_kernel_init(i32 [[THREAD_LIMIT]], i16 0, i16 0)
-// CHECK: call void @__kmpc_get_team_static_memory(i8* addrspacecast (i8 addrspace(3)* getelementptr inbounds ([[MEM_TY]], [[MEM_TY]] addrspace(3)* [[SHARED_GLOBAL_RD]], i32 0, i32 0, i32 0) to i8*), i{{64|32}} 4, i16 1, i8** addrspacecast (i8* addrspace(3)* [[KERNEL_PTR]] to i8**))
+// CHECK: call void @__kmpc_get_team_static_memory(i16 1, i8* addrspacecast (i8 addrspace(3)* getelementptr inbounds ([[MEM_TY]], [[MEM_TY]] addrspace(3)* [[SHARED_GLOBAL_RD]], i32 0, i32 0, i32 0) to i8*), i{{64|32}} 4, i16 1, i8** addrspacecast (i8* addrspace(3)* [[KERNEL_PTR]] to i8**))
 // CHECK: [[TEAM_ALLOC:%.+]] = load i8*, i8* addrspace(3)* [[KERNEL_PTR]],
 // CHECK: [[BC:%.+]] = bitcast i8* [[TEAM_ALLOC]] to [[REC:%.+]]*
 // CHECK: getelementptr inbounds [[REC]], [[REC]]* [[BC]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
 // CHECK: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, {{.+}} 91,
 // CHECK: {{call|invoke}} void [[OUTL1:@.+]](
 // CHECK: call void @__kmpc_for_static_fini(
-// CHECK: call void @__kmpc_restore_team_static_memory(i16 1)
+// CHECK: call void @__kmpc_restore_team_static_memory(i16 1, i16 1)
 // CHECK: call void @__kmpc_spmd_kernel_deinit_v2(i16 0)
 // CHECK: ret void
 
diff --git a/test/OpenMP/nvptx_target_teams_distribute_parallel_for_simd_codegen.cpp b/test/OpenMP/nvptx_target_teams_distribute_parallel_for_simd_codegen.cpp
index c4db1bc579..21fb46fc51 100644
--- a/test/OpenMP/nvptx_target_teams_distribute_parallel_for_simd_codegen.cpp
+++ b/test/OpenMP/nvptx_target_teams_distribute_parallel_for_simd_codegen.cpp
@@ -71,14 +71,14 @@ int bar(int n){
 // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+}}_l30(
 // CHECK-DAG: [[THREAD_LIMIT:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
 // CHECK: call void @__kmpc_spmd_kernel_init(i32 [[THREAD_LIMIT]], i16 0, i16 0)
-// CHECK: call void @__kmpc_get_team_static_memory(i8* addrspacecast (i8 addrspace(3)* getelementptr inbounds ([[MEM_TY]], [[MEM_TY]] addrspace(3)* [[SHARED_GLOBAL_RD]], i32 0, i32 0, i32 0) to i8*), i{{64|32}} 4, i16 1, i8** addrspacecast (i8* addrspace(3)* [[KERNEL_PTR]] to i8**))
+// CHECK: call void @__kmpc_get_team_static_memory(i16 1, i8* addrspacecast (i8 addrspace(3)* getelementptr inbounds ([[MEM_TY]], [[MEM_TY]] addrspace(3)* [[SHARED_GLOBAL_RD]], i32 0, i32 0, i32 0) to i8*), i{{64|32}} 4, i16 1, i8** addrspacecast (i8* addrspace(3)* [[KERNEL_PTR]] to i8**))
 // CHECK: [[TEAM_ALLOC:%.+]] = load i8*, i8* addrspace(3)* [[KERNEL_PTR]],
 // CHECK: [[BC:%.+]] = bitcast i8* [[TEAM_ALLOC]] to [[REC:%.+]]*
 // CHECK: getelementptr inbounds [[REC]], [[REC]]* [[BC]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
 // CHECK: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, {{.+}} 91,
 // CHECK: {{call|invoke}} void [[OUTL1:@.+]](
 // CHECK: call void @__kmpc_for_static_fini(
-// CHECK: call void @__kmpc_restore_team_static_memory(i16 1)
+// CHECK: call void @__kmpc_restore_team_static_memory(i16 1, i16 1)
 // CHECK: call void @__kmpc_spmd_kernel_deinit_v2(i16 0)
 // CHECK: ret void
 
diff --git a/test/OpenMP/nvptx_teams_codegen.cpp b/test/OpenMP/nvptx_teams_codegen.cpp
index b259a4b938..2d1ab9f063 100644
--- a/test/OpenMP/nvptx_teams_codegen.cpp
+++ b/test/OpenMP/nvptx_teams_codegen.cpp
@@ -46,7 +46,7 @@ int main (int argc, char **argv) {
 // CK1-64:  [[CONV:%.+]] = bitcast i{{[0-9]+}}* [[ARGCADDR]] to i{{[0-9]+}}*
 // CK1: [[IS_SHARED:%.+]] = load i16, i16* [[KERNEL_SHARED1]],
 // CK1: [[SIZE:%.+]] = load i{{64|32}}, i{{64|32}}* [[KERNEL_SIZE1]],
-// CK1: call void @__kmpc_get_team_static_memory(i8* addrspacecast (i8 addrspace(3)* getelementptr inbounds ([[MEM_TY]], [[MEM_TY]] addrspace(3)* [[SHARED_GLOBAL_RD]], i32 0, i32 0, i32 0) to i8*), i{{64|32}} [[SIZE]], i16 [[IS_SHARED]], i8** addrspacecast (i8* addrspace(3)* [[KERNEL_PTR]] to i8**))
+// CK1: call void @__kmpc_get_team_static_memory(i16 0, i8* addrspacecast (i8 addrspace(3)* getelementptr inbounds ([[MEM_TY]], [[MEM_TY]] addrspace(3)* [[SHARED_GLOBAL_RD]], i32 0, i32 0, i32 0) to i8*), i{{64|32}} [[SIZE]], i16 [[IS_SHARED]], i8** addrspacecast (i8* addrspace(3)* [[KERNEL_PTR]] to i8**))
 // CK1: [[KERNEL_RD:%.+]] = load i8*, i8* addrspace(3)* [[KERNEL_PTR]],
 // CK1: [[GLOBALSTACK:%.+]] = getelementptr inbounds i8, i8* [[KERNEL_RD]], i{{64|32}} 0
 // CK1-64:  [[ARG:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[CONV]]
@@ -67,7 +67,7 @@ int main (int argc, char **argv) {
 // CK1: store i{{.+}}** [[ARGC]], i{{.+}}*** [[ARGCADDR]]
 // CK1: [[IS_SHARED:%.+]] = load i16, i16* [[KERNEL_SHARED2]],
 // CK1: [[SIZE:%.+]] = load i{{64|32}}, i{{64|32}}* [[KERNEL_SIZE2]],
-// CK1: call void @__kmpc_get_team_static_memory(i8* addrspacecast (i8 addrspace(3)* getelementptr inbounds ([[MEM_TY]], [[MEM_TY]] addrspace(3)* [[SHARED_GLOBAL_RD]], i32 0, i32 0, i32 0) to i8*), i{{64|32}} [[SIZE]], i16 [[IS_SHARED]], i8** addrspacecast (i8* addrspace(3)* [[KERNEL_PTR]] to i8**))
+// CK1: call void @__kmpc_get_team_static_memory(i16 0, i8* addrspacecast (i8 addrspace(3)* getelementptr inbounds ([[MEM_TY]], [[MEM_TY]] addrspace(3)* [[SHARED_GLOBAL_RD]], i32 0, i32 0, i32 0) to i8*), i{{64|32}} [[SIZE]], i16 [[IS_SHARED]], i8** addrspacecast (i8* addrspace(3)* [[KERNEL_PTR]] to i8**))
 // CK1: [[KERNEL_RD:%.+]] = load i8*, i8* addrspace(3)* [[KERNEL_PTR]],
 // CK1: [[GLOBALSTACK:%.+]] = getelementptr inbounds i8, i8* [[KERNEL_RD]], i{{64|32}} 0
 // CK1: [[ARG:%.+]] = load i{{[0-9]+}}**, i{{[0-9]+}}*** [[ARGCADDR]]
@@ -137,7 +137,7 @@ int main (int argc, char **argv) {
 // CK2-64: [[CONV:%.+]] = bitcast i64* [[ARGCADDR]] to i32*
 // CK2: [[IS_SHARED:%.+]] = load i16, i16* [[KERNEL_SHARED1]],
 // CK2: [[SIZE:%.+]] = load i{{64|32}}, i{{64|32}}* [[KERNEL_SIZE1]],
-// CK2: call void @__kmpc_get_team_static_memory(i8* addrspacecast (i8 addrspace(3)* getelementptr inbounds ([[MEM_TY]], [[MEM_TY]] addrspace(3)* [[SHARED_GLOBAL_RD]], i32 0, i32 0, i32 0) to i8*), i{{64|32}} [[SIZE]], i16 [[IS_SHARED]], i8** addrspacecast (i8* addrspace(3)* [[KERNEL_PTR]] to i8**))
+// CK2: call void @__kmpc_get_team_static_memory(i16 0, i8* addrspacecast (i8 addrspace(3)* getelementptr inbounds ([[MEM_TY]], [[MEM_TY]] addrspace(3)* [[SHARED_GLOBAL_RD]], i32 0, i32 0, i32 0) to i8*), i{{64|32}} [[SIZE]], i16 [[IS_SHARED]], i8** addrspacecast (i8* addrspace(3)* [[KERNEL_PTR]] to i8**))
 // CK2: [[KERNEL_RD:%.+]] = load i8*, i8* addrspace(3)* [[KERNEL_PTR]],
 // CK2: [[GLOBALSTACK:%.+]] = getelementptr inbounds i8, i8* [[KERNEL_RD]], i{{64|32}} 0
 // CK2-64:  [[ARG:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[CONV]]
@@ -162,7 +162,7 @@ int main (int argc, char **argv) {
 // CK2: store i{{[0-9]+}}** [[ARGC]], i{{[0-9]+}}*** [[ARGCADDR]],
 // CK2: [[IS_SHARED:%.+]] = load i16, i16* [[KERNEL_SHARED2]],
 // CK2: [[SIZE:%.+]] = load i{{64|32}}, i{{64|32}}* [[KERNEL_SIZE2]],
-// CK2: call void @__kmpc_get_team_static_memory(i8* addrspacecast (i8 addrspace(3)* getelementptr inbounds ([[MEM_TY]], [[MEM_TY]] addrspace(3)* [[SHARED_GLOBAL_RD]], i32 0, i32 0, i32 0) to i8*), i{{64|32}} [[SIZE]], i16 [[IS_SHARED]], i8** addrspacecast (i8* addrspace(3)* [[KERNEL_PTR]] to i8**))
+// CK2: call void @__kmpc_get_team_static_memory(i16 0, i8* addrspacecast (i8 addrspace(3)* getelementptr inbounds ([[MEM_TY]], [[MEM_TY]] addrspace(3)* [[SHARED_GLOBAL_RD]], i32 0, i32 0, i32 0) to i8*), i{{64|32}} [[SIZE]], i16 [[IS_SHARED]], i8** addrspacecast (i8* addrspace(3)* [[KERNEL_PTR]] to i8**))
 // CK2: [[KERNEL_RD:%.+]] = load i8*, i8* addrspace(3)* [[KERNEL_PTR]],
 // CK2: [[GLOBALSTACK:%.+]] = getelementptr inbounds i8, i8* [[KERNEL_RD]], i{{64|32}} 0
 // CK2: [[ARG:%.+]] = load i{{[0-9]+}}**, i{{[0-9]+}}*** [[ARGCADDR]]
diff --git a/test/OpenMP/nvptx_teams_reduction_codegen.cpp b/test/OpenMP/nvptx_teams_reduction_codegen.cpp
index 818f0739b2..b0246e2ee8 100644
--- a/test/OpenMP/nvptx_teams_reduction_codegen.cpp
+++ b/test/OpenMP/nvptx_teams_reduction_codegen.cpp
@@ -137,7 +137,7 @@ int bar(int n){
   //
   // CHECK: call void @__kmpc_spmd_kernel_init(
   // CHECK: call void @__kmpc_data_sharing_init_stack_spmd()
-  // CHECK: call void @__kmpc_get_team_static_memory(i8* addrspacecast (i8 addrspace(3)* getelementptr inbounds ([[MEM_TY:%.+]], %{{.+}} addrspace(3)* [[KERNEL_RD:@.+]], i32 0, i32 0, i32 0) to i8*), i{{64|32}} {{8|16}}, i16 1, i8** addrspacecast (i8* addrspace(3)* [[KERNEL_PTR:@.+]] to i8**))
+  // CHECK: call void @__kmpc_get_team_static_memory(i16 1, i8* addrspacecast (i8 addrspace(3)* getelementptr inbounds ([[MEM_TY:%.+]], %{{.+}} addrspace(3)* [[KERNEL_RD:@.+]], i32 0, i32 0, i32 0) to i8*), i{{64|32}} {{8|16}}, i16 1, i8** addrspacecast (i8* addrspace(3)* [[KERNEL_PTR:@.+]] to i8**))
   // CHECK: [[PTR:%.+]] = load i8*, i8* addrspace(3)* [[KERNEL_PTR]],
   // CHECK: [[GLOBAL_REC:%.+]] = bitcast i8* [[PTR]] to [[GLOB_REC_TY:%.+]]*
   // CHECK-DAG: [[A_ADDR:%.+]] = getelementptr inbounds [[GLOB_REC_TY]], [[GLOB_REC_TY]]* [[GLOBAL_REC]], i32 0, i32 0
@@ -176,7 +176,7 @@ int bar(int n){
   // CHECK: br label %[[EXIT]]
   //
   // CHECK: [[EXIT]]
-  // call void @__kmpc_restore_team_static_memory(i16 1)
+  // CHECK: call void @__kmpc_restore_team_static_memory(i16 1, i16 1)
   // CHECK: call void @__kmpc_spmd_kernel_deinit_v2(i16 1)
 
   // CHECK: define internal void [[OUTLINED]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, i32* dereferenceable{{.+}}, i16* dereferenceable{{.+}})
@@ -210,7 +210,7 @@ int bar(int n){
   // CHECK: [[B_CAST:%.+]] = bitcast i16* [[B]] to i8*
   // CHECK: store i8* [[B_CAST]], i8** [[PTR2]], align
   // CHECK: [[ARG_RL:%.+]] = bitcast [[RLT]]* [[RL]] to i8*
-  // CHECK: [[RET:%.+]] = call i32 @__kmpc_nvptx_parallel_reduce_nowait(i32 {{.+}}, i32 2, i[[SZ]] {{8|16}}, i8* [[ARG_RL]], void (i8*, i16, i16, i16)* [[PAR_SHUFFLE_REDUCE_FN:@.+]], void (i8*, i32)* [[PAR_WARP_COPY_FN:@.+]])
+  // CHECK: [[RET:%.+]] = call i32 @__kmpc_nvptx_parallel_reduce_nowait_v2(%struct.ident_t* [[LOC]], i32 {{.+}}, i32 2, i[[SZ]] {{8|16}}, i8* [[ARG_RL]], void (i8*, i16, i16, i16)* [[PAR_SHUFFLE_REDUCE_FN:@.+]], void (i8*, i32)* [[PAR_WARP_COPY_FN:@.+]])
   // CHECK: [[COND:%.+]] = icmp eq i32 [[RET]], 1
   // CHECK: br i1 [[COND]], label {{%?}}[[IFLABEL:.+]], label {{%?}}[[EXIT:.+]]
   //
-- 
cgit v1.2.3


From 6d306af57388db45495728891bccdad0156c2c28 Mon Sep 17 00:00:00 2001
From: Erik Pilkington 
Date: Fri, 4 Jan 2019 18:33:06 +0000
Subject: [ObjCARC] Add an new attribute, objc_externally_retained

This attribute, called "objc_externally_retained", exposes clang's
notion of pseudo-__strong variables in ARC. Pseudo-strong variables
"borrow" their initializer, meaning that they don't retain/release
it, instead assuming that someone else is keeping their value alive.

If a function is annotated with this attribute, implicitly strong
parameters of that function aren't implicitly retained/released in
the function body, and are implicitly const. This is useful to expose
for performance reasons, most functions don't need the extra safety
of the retain/release, so programmers can opt out as needed.

This attribute can also apply to declarations of local variables,
with similar effect.

Differential revision: https://reviews.llvm.org/D55865

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350422 91177308-0d34-0410-b5e6-96231b3b80d8
---
 docs/AutomaticReferenceCounting.rst                |  87 +++++++++++++---
 include/clang/AST/Decl.h                           |  30 +++---
 include/clang/AST/DeclObjC.h                       |   8 ++
 include/clang/Basic/Attr.td                        |   8 ++
 include/clang/Basic/AttrDocs.td                    |  28 +++++
 include/clang/Basic/DiagnosticSemaKinds.td         |   8 ++
 lib/CodeGen/CGDecl.cpp                             |  28 ++---
 lib/CodeGen/CGExpr.cpp                             |   8 +-
 lib/Sema/SemaDeclAttr.cpp                          |  96 +++++++++++++++--
 lib/Sema/SemaExpr.cpp                              |  12 ++-
 lib/Serialization/ASTReaderDecl.cpp                |   2 +-
 lib/Serialization/ASTWriterDecl.cpp                |   5 +-
 test/CodeGenObjC/externally-retained.m             | 115 +++++++++++++++++++++
 ...pragma-attribute-supported-attributes-list.test |   1 +
 test/SemaObjC/externally-retained-no-arc.m         |   7 ++
 test/SemaObjC/externally-retained.m                | 114 ++++++++++++++++++++
 16 files changed, 500 insertions(+), 57 deletions(-)
 create mode 100644 test/CodeGenObjC/externally-retained.m
 create mode 100644 test/SemaObjC/externally-retained-no-arc.m
 create mode 100644 test/SemaObjC/externally-retained.m

diff --git a/docs/AutomaticReferenceCounting.rst b/docs/AutomaticReferenceCounting.rst
index d8cda0c05f..3e51d2f5d7 100644
--- a/docs/AutomaticReferenceCounting.rst
+++ b/docs/AutomaticReferenceCounting.rst
@@ -1734,20 +1734,78 @@ A program is ill-formed if it refers to the ``NSAutoreleasePool`` class.
   rest of the language.  Not draining the pool during an unwind is apparently
   required by the Objective-C exceptions implementation.
 
+.. _arc.misc.externally_retained:
+
+Externally-Retained Variables
+-----------------------------
+
+In some situations, variables with strong ownership are considered
+externally-retained by the implementation. This means that the variable is
+retained elsewhere, and therefore the implementation can elide retaining and
+releasing its value. Such a variable is implicitly ``const`` for safety. In
+contrast with ``__unsafe_unretained``, an externally-retained variable still
+behaves as a strong variable outside of initialization and destruction. For
+instance, when an externally-retained variable is captured in a block the value
+of the variable is retained and released on block capture and destruction. It
+also affects C++ features such as lambda capture, ``decltype``, and template
+argument deduction.
+
+Implicitly, the implementation assumes that the :ref:`self parameter in a
+non-init method ` and the :ref:`variable in a for-in loop
+` are externally-retained.
+
+Externally-retained semantics can also be opted into with the
+``objc_externally_retained`` attribute. This attribute can apply to strong local
+variables, functions, methods, or blocks:
+
+.. code-block:: objc
+
+  @class WobbleAmount;
+
+  @interface Widget : NSObject
+  -(void)wobble:(WobbleAmount *)amount;
+  @end
+
+  @implementation Widget
+
+  -(void)wobble:(WobbleAmount *)amount
+           __attribute__((objc_externally_retained)) {
+    // 'amount' and 'alias' aren't retained on entry, nor released on exit.
+    __attribute__((objc_externally_retained)) WobbleAmount *alias = amount;
+  }
+  @end
+
+Annotating a function with this attribute makes every parameter with strong
+retainable object pointer type externally-retained, unless the variable was
+explicitly qualified with ``__strong``. For instance, ``first_param`` is
+externally-retained (and therefore ``const``) below, but not ``second_param``:
+
+.. code-block:: objc
+
+  __attribute__((objc_externally_retained))
+  void f(NSArray *first_param, __strong NSArray *second_param) {
+    // ...
+  }
+
+You can test if your compiler has support for ``objc_externally_retained`` with
+``__has_attribute``:
+
+.. code-block:: objc
+
+  #if __has_attribute(objc_externally_retained)
+  // Use externally retained...
+  #endif
+
 .. _arc.misc.self:
 
 ``self``
 --------
 
-The ``self`` parameter variable of an Objective-C method is never actually
-retained by the implementation.  It is undefined behavior, or at least
-dangerous, to cause an object to be deallocated during a message send to that
-object.
-
-To make this safe, for Objective-C instance methods ``self`` is implicitly
-``const`` unless the method is in the :ref:`init family
-`.  Further, ``self`` is **always** implicitly
-``const`` within a class method.
+The ``self`` parameter variable of an non-init Objective-C method is considered
+:ref:`externally-retained ` by the implementation.
+It is undefined behavior, or at least dangerous, to cause an object to be
+deallocated during a message send to that object.  In an init method, ``self``
+follows the :ref:``init family rules ``.
 
 .. admonition:: Rationale
 
@@ -1758,9 +1816,9 @@ To make this safe, for Objective-C instance methods ``self`` is implicitly
   without this retain and release.  Since it's extremely uncommon to actually
   do so, even unintentionally, and since there's no natural way for the
   programmer to remove this retain/release pair otherwise (as there is for
-  other parameters by, say, making the variable ``__unsafe_unretained``), we
-  chose to make this optimizing assumption and shift some amount of risk to the
-  user.
+  other parameters by, say, making the variable ``objc_externally_retained`` or
+  qualifying it with ``__unsafe_unretained``), we chose to make this optimizing
+  assumption and shift some amount of risk to the user.
 
 .. _arc.misc.enumeration:
 
@@ -1769,8 +1827,9 @@ Fast enumeration iteration variables
 
 If a variable is declared in the condition of an Objective-C fast enumeration
 loop, and the variable has no explicit ownership qualifier, then it is
-qualified with ``const __strong`` and objects encountered during the
-enumeration are not actually retained.
+implicitly :ref:`externally-retained ` so that
+objects encountered during the enumeration are not actually retained and
+released.
 
 .. admonition:: Rationale
 
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index 52703e60aa..ac641881ae 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -866,8 +866,12 @@ private:
     unsigned SClass : 3;
     unsigned TSCSpec : 2;
     unsigned InitStyle : 2;
+
+    /// Whether this variable is an ARC pseudo-__strong variable; see
+    /// isARCPseudoStrong() for details.
+    unsigned ARCPseudoStrong : 1;
   };
-  enum { NumVarDeclBits = 7 };
+  enum { NumVarDeclBits = 8 };
 
 protected:
   enum { NumParameterIndexBits = 8 };
@@ -940,10 +944,6 @@ protected:
     /// Whether this variable is the for-in loop declaration in Objective-C.
     unsigned ObjCForDecl : 1;
 
-    /// Whether this variable is an ARC pseudo-__strong
-    /// variable;  see isARCPseudoStrong() for details.
-    unsigned ARCPseudoStrong : 1;
-
     /// Whether this variable is (C++1z) inline.
     unsigned IsInline : 1;
 
@@ -1349,17 +1349,15 @@ public:
     NonParmVarDeclBits.ObjCForDecl = FRD;
   }
 
-  /// Determine whether this variable is an ARC pseudo-__strong
-  /// variable.  A pseudo-__strong variable has a __strong-qualified
-  /// type but does not actually retain the object written into it.
-  /// Generally such variables are also 'const' for safety.
-  bool isARCPseudoStrong() const {
-    return isa(this) ? false : NonParmVarDeclBits.ARCPseudoStrong;
-  }
-  void setARCPseudoStrong(bool ps) {
-    assert(!isa(this));
-    NonParmVarDeclBits.ARCPseudoStrong = ps;
-  }
+  /// Determine whether this variable is an ARC pseudo-__strong variable. A
+  /// pseudo-__strong variable has a __strong-qualified type but does not
+  /// actually retain the object written into it. Generally such variables are
+  /// also 'const' for safety. There are 3 cases where this will be set, 1) if
+  /// the variable is annotated with the objc_externally_retained attribute, 2)
+  /// if its 'self' in a non-init method, or 3) if its the variable in an for-in
+  /// loop.
+  bool isARCPseudoStrong() const { return VarDeclBits.ARCPseudoStrong; }
+  void setARCPseudoStrong(bool PS) { VarDeclBits.ARCPseudoStrong = PS; }
 
   /// Whether this variable is (C++1z) inline.
   bool isInline() const {
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h
index bc10ba42c6..5b57411f97 100644
--- a/include/clang/AST/DeclObjC.h
+++ b/include/clang/AST/DeclObjC.h
@@ -369,6 +369,14 @@ public:
                               NumParams);
   }
 
+  ParmVarDecl *getParamDecl(unsigned Idx) {
+    assert(Idx < NumParams && "Index out of bounds!");
+    return getParams()[Idx];
+  }
+  const ParmVarDecl *getParamDecl(unsigned Idx) const {
+    return const_cast(this)->getParamDecl(Idx);
+  }
+
   /// Sets the method's parameters and selector source locations.
   /// If the method is implicit (not coming from source) \p SelLocs is
   /// ignored.
diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td
index 271f979f8a..311cf943df 100644
--- a/include/clang/Basic/Attr.td
+++ b/include/clang/Basic/Attr.td
@@ -300,6 +300,7 @@ def OpenCL : LangOpt<"OpenCL">;
 def RenderScript : LangOpt<"RenderScript">;
 def ObjC : LangOpt<"ObjC">;
 def BlocksSupported : LangOpt<"Blocks">;
+def ObjCAutoRefCount : LangOpt<"ObjCAutoRefCount">;
 
 // Defines targets for target-specific attributes. Empty lists are unchecked.
 class TargetSpec {
@@ -3141,3 +3142,10 @@ def Uninitialized : InheritableAttr {
   let Subjects = SubjectList<[LocalVar]>;
   let Documentation = [UninitializedDocs];
 }
+
+def ObjCExternallyRetained : InheritableAttr {
+  let LangOpts = [ObjCAutoRefCount];
+  let Spellings = [Clang<"objc_externally_retained">];
+  let Subjects = SubjectList<[NonParmVar, Function, Block, ObjCMethod]>;
+  let Documentation = [ObjCExternallyRetainedDocs];
+}
diff --git a/include/clang/Basic/AttrDocs.td b/include/clang/Basic/AttrDocs.td
index 532773fc95..aae2d1ddfc 100644
--- a/include/clang/Basic/AttrDocs.td
+++ b/include/clang/Basic/AttrDocs.td
@@ -3824,3 +3824,31 @@ def SpeculativeLoadHardeningDocs : Documentation {
   (even after inlining) end up hardened.
   }];
 }
+
+def ObjCExternallyRetainedDocs : Documentation {
+  let Category = DocCatVariable;
+  let Content = [{
+The ``objc_externally_retained`` attribute can be applied to strong local
+variables, functions, methods, or blocks to opt into
+`externally-retained semantics
+`_.
+
+When applied to the definition of a function, method, or block, every parameter
+of the function with implicit strong retainable object pointer type is
+considered externally-retained, and becomes ``const``. By explicitly annotating
+a parameter with ``__strong``, you can opt back into the default
+non-externally-retained behaviour for that parameter. For instance,
+``first_param`` is externally-retained below, but not ``second_param``:
+
+.. code-block:: objc
+
+  __attribute__((objc_externally_retained))
+  void f(NSArray *first_param, __strong NSArray *second_param) {
+    // ...
+  }
+
+Likewise, when applied to a strong local variable, that variable becomes
+``const`` and is considered externally-retained.
+
+When compiled without ``-fobjc-arc``, this attribute is ignored.
+}]; }
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 375f9515b2..0f30aed960 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3485,6 +3485,11 @@ def err_objc_bridged_related_known_method : Error<
 def err_objc_attr_protocol_requires_definition : Error<
   "attribute %0 can only be applied to @protocol definitions, not forward declarations">;
 
+def warn_ignored_objc_externally_retained : Warning<
+  "'objc_externally_retained' can only be applied to local variables "
+  "%select{of retainable type|with strong ownership}0">,
+  InGroup;
+
 // Function Parameter Semantic Analysis.
 def err_param_with_void_type : Error<"argument may not have 'void' type">;
 def err_void_only_param : Error<
@@ -5254,6 +5259,9 @@ def err_typecheck_arc_assign_self_class_method : Error<
 def err_typecheck_arr_assign_enumeration : Error<
   "fast enumeration variables cannot be modified in ARC by default; "
   "declare the variable __strong to allow this">;
+def err_typecheck_arc_assign_externally_retained : Error<
+  "variable declared with 'objc_externally_retained' "
+  "cannot be modified in ARC">;
 def warn_arc_retained_assign : Warning<
   "assigning retained object to %select{weak|unsafe_unretained}0 "
   "%select{property|variable}1"
diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp
index 2262c998af..5959d889b4 100644
--- a/lib/CodeGen/CGDecl.cpp
+++ b/lib/CodeGen/CGDecl.cpp
@@ -797,15 +797,21 @@ void CodeGenFunction::EmitScalarInit(const Expr *init, const ValueDecl *D,
   case Qualifiers::OCL_None:
     llvm_unreachable("present but none");
 
+  case Qualifiers::OCL_Strong: {
+    if (!D || !isa(D) || !cast(D)->isARCPseudoStrong()) {
+      value = EmitARCRetainScalarExpr(init);
+      break;
+    }
+    // If D is pseudo-strong, treat it like __unsafe_unretained here. This means
+    // that we omit the retain, and causes non-autoreleased return values to be
+    // immediately released.
+    LLVM_FALLTHROUGH;
+  }
+
   case Qualifiers::OCL_ExplicitNone:
     value = EmitARCUnsafeUnretainedScalarExpr(init);
     break;
 
-  case Qualifiers::OCL_Strong: {
-    value = EmitARCRetainScalarExpr(init);
-    break;
-  }
-
   case Qualifiers::OCL_Weak: {
     // If it's not accessed by the initializer, try to emit the
     // initialization with a copy or move.
@@ -2324,15 +2330,11 @@ void CodeGenFunction::EmitParmDecl(const VarDecl &D, ParamValue Arg,
       // cleanup to do the release at the end of the function.
       bool isConsumed = D.hasAttr();
 
-      // 'self' is always formally __strong, but if this is not an
-      // init method then we don't want to retain it.
+      // If a parameter is pseudo-strong then we can omit the implicit retain.
       if (D.isARCPseudoStrong()) {
-        const ObjCMethodDecl *method = cast(CurCodeDecl);
-        assert(&D == method->getSelfDecl());
-        assert(lt == Qualifiers::OCL_Strong);
-        assert(qs.hasConst());
-        assert(method->getMethodFamily() != OMF_init);
-        (void) method;
+        assert(lt == Qualifiers::OCL_Strong &&
+               "pseudo-strong variable isn't strong?");
+        assert(qs.hasConst() && "pseudo-strong variable should be const!");
         lt = Qualifiers::OCL_ExplicitNone;
       }
 
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index 6ef1091cc0..34a921e2dc 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -419,8 +419,12 @@ LValue CodeGenFunction::
 EmitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *M) {
   const Expr *E = M->GetTemporaryExpr();
 
-    // FIXME: ideally this would use EmitAnyExprToMem, however, we cannot do so
-    // as that will cause the lifetime adjustment to be lost for ARC
+  assert((!M->getExtendingDecl() || !isa(M->getExtendingDecl()) ||
+          !cast(M->getExtendingDecl())->isARCPseudoStrong()) &&
+         "Reference should never be pseudo-strong!");
+
+  // FIXME: ideally this would use EmitAnyExprToMem, however, we cannot do so
+  // as that will cause the lifetime adjustment to be lost for ARC
   auto ownership = M->getType().getObjCLifetime();
   if (ownership != Qualifiers::OCL_None &&
       ownership != Qualifiers::OCL_ExplicitNone) {
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index 63501d9291..d1db71838f 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -93,6 +93,17 @@ static unsigned getFunctionOrMethodNumParams(const Decl *D) {
   return cast(D)->param_size();
 }
 
+static const ParmVarDecl *getFunctionOrMethodParam(const Decl *D,
+                                                   unsigned Idx) {
+  if (const auto *FD = dyn_cast(D))
+    return FD->getParamDecl(Idx);
+  if (const auto *MD = dyn_cast(D))
+    return MD->getParamDecl(Idx);
+  if (const auto *BD = dyn_cast(D))
+    return BD->getParamDecl(Idx);
+  return nullptr;
+}
+
 static QualType getFunctionOrMethodParamType(const Decl *D, unsigned Idx) {
   if (const FunctionType *FnTy = D->getFunctionType())
     return cast(FnTy)->getParamType(Idx);
@@ -103,12 +114,8 @@ static QualType getFunctionOrMethodParamType(const Decl *D, unsigned Idx) {
 }
 
 static SourceRange getFunctionOrMethodParamRange(const Decl *D, unsigned Idx) {
-  if (const auto *FD = dyn_cast(D))
-    return FD->getParamDecl(Idx)->getSourceRange();
-  if (const auto *MD = dyn_cast(D))
-    return MD->parameters()[Idx]->getSourceRange();
-  if (const auto *BD = dyn_cast(D))
-    return BD->getParamDecl(Idx)->getSourceRange();
+  if (auto *PVD = getFunctionOrMethodParam(D, Idx))
+    return PVD->getSourceRange();
   return SourceRange();
 }
 
@@ -6093,6 +6100,79 @@ static void handleUninitializedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
                  UninitializedAttr(AL.getLoc(), S.Context, Index));
 }
 
+static bool tryMakeVariablePseudoStrong(Sema &S, VarDecl *VD,
+                                        bool DiagnoseFailure) {
+  QualType Ty = VD->getType();
+  if (!Ty->isObjCRetainableType()) {
+    if (DiagnoseFailure) {
+      S.Diag(VD->getBeginLoc(), diag::warn_ignored_objc_externally_retained)
+          << 0;
+    }
+    return false;
+  }
+
+  Qualifiers::ObjCLifetime LifetimeQual = Ty.getQualifiers().getObjCLifetime();
+
+  // Sema::inferObjCARCLifetime must run after processing decl attributes
+  // (because __block lowers to an attribute), so if the lifetime hasn't been
+  // explicitly specified, infer it locally now.
+  if (LifetimeQual == Qualifiers::OCL_None)
+    LifetimeQual = Ty->getObjCARCImplicitLifetime();
+
+  // The attributes only really makes sense for __strong variables; ignore any
+  // attempts to annotate a parameter with any other lifetime qualifier.
+  if (LifetimeQual != Qualifiers::OCL_Strong) {
+    if (DiagnoseFailure) {
+      S.Diag(VD->getBeginLoc(), diag::warn_ignored_objc_externally_retained)
+          << 1;
+    }
+    return false;
+  }
+
+  // Tampering with the type of a VarDecl here is a bit of a hack, but we need
+  // to ensure that the variable is 'const' so that we can error on
+  // modification, which can otherwise over-release.
+  VD->setType(Ty.withConst());
+  VD->setARCPseudoStrong(true);
+  return true;
+}
+
+static void handleObjCExternallyRetainedAttr(Sema &S, Decl *D,
+                                             const ParsedAttr &AL) {
+  if (auto *VD = dyn_cast(D)) {
+    assert(!isa(VD) && "should be diagnosed automatically");
+    if (!VD->hasLocalStorage()) {
+      S.Diag(D->getBeginLoc(), diag::warn_ignored_objc_externally_retained)
+          << 0;
+      return;
+    }
+
+    if (!tryMakeVariablePseudoStrong(S, VD, /*DiagnoseFailure=*/true))
+      return;
+
+    handleSimpleAttribute(S, D, AL);
+    return;
+  }
+
+  // If D is a function-like declaration (method, block, or function), then we
+  // make every parameter psuedo-strong.
+  for (unsigned I = 0, E = getFunctionOrMethodNumParams(D); I != E; ++I) {
+    auto *PVD = const_cast(getFunctionOrMethodParam(D, I));
+    QualType Ty = PVD->getType();
+
+    // If a user wrote a parameter with __strong explicitly, then assume they
+    // want "real" strong semantics for that parameter. This works because if
+    // the parameter was written with __strong, then the strong qualifier will
+    // be non-local.
+    if (Ty.getLocalUnqualifiedType().getQualifiers().getObjCLifetime() ==
+        Qualifiers::OCL_Strong)
+      continue;
+
+    tryMakeVariablePseudoStrong(S, PVD, /*DiagnoseFailure=*/false);
+  }
+  handleSimpleAttribute(S, D, AL);
+}
+
 //===----------------------------------------------------------------------===//
 // Top Level Sema Entry Points
 //===----------------------------------------------------------------------===//
@@ -6788,6 +6868,10 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
   case ParsedAttr::AT_Uninitialized:
     handleUninitializedAttr(S, D, AL);
     break;
+
+  case ParsedAttr::AT_ObjCExternallyRetained:
+    handleObjCExternallyRetainedAttr(S, D, AL);
+    break;
   }
 }
 
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index aa4b23b15c..eddf90178b 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -11214,17 +11214,23 @@ static bool CheckForModifiableLvalue(Expr *E, SourceLocation Loc, Sema &S) {
         if (var->isARCPseudoStrong() &&
             (!var->getTypeSourceInfo() ||
              !var->getTypeSourceInfo()->getType().isConstQualified())) {
-          // There are two pseudo-strong cases:
+          // There are three pseudo-strong cases:
           //  - self
           ObjCMethodDecl *method = S.getCurMethodDecl();
-          if (method && var == method->getSelfDecl())
+          if (method && var == method->getSelfDecl()) {
             DiagID = method->isClassMethod()
               ? diag::err_typecheck_arc_assign_self_class_method
               : diag::err_typecheck_arc_assign_self;
 
+          //  - Objective-C externally_retained attribute.
+          } else if (var->hasAttr() ||
+                     isa(var)) {
+            DiagID = diag::err_typecheck_arc_assign_externally_retained;
+
           //  - fast enumeration variables
-          else
+          } else {
             DiagID = diag::err_typecheck_arr_assign_enumeration;
+          }
 
           SourceRange Assign;
           if (Loc != OrigLoc)
diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp
index 8c1710f660..763ab52757 100644
--- a/lib/Serialization/ASTReaderDecl.cpp
+++ b/lib/Serialization/ASTReaderDecl.cpp
@@ -1350,6 +1350,7 @@ ASTDeclReader::RedeclarableResult ASTDeclReader::VisitVarDeclImpl(VarDecl *VD) {
   VD->VarDeclBits.SClass = (StorageClass)Record.readInt();
   VD->VarDeclBits.TSCSpec = Record.readInt();
   VD->VarDeclBits.InitStyle = Record.readInt();
+  VD->VarDeclBits.ARCPseudoStrong = Record.readInt();
   if (!isa(VD)) {
     VD->NonParmVarDeclBits.IsThisDeclarationADemotedDefinition =
         Record.readInt();
@@ -1357,7 +1358,6 @@ ASTDeclReader::RedeclarableResult ASTDeclReader::VisitVarDeclImpl(VarDecl *VD) {
     VD->NonParmVarDeclBits.NRVOVariable = Record.readInt();
     VD->NonParmVarDeclBits.CXXForRangeDecl = Record.readInt();
     VD->NonParmVarDeclBits.ObjCForDecl = Record.readInt();
-    VD->NonParmVarDeclBits.ARCPseudoStrong = Record.readInt();
     VD->NonParmVarDeclBits.IsInline = Record.readInt();
     VD->NonParmVarDeclBits.IsInlineSpecified = Record.readInt();
     VD->NonParmVarDeclBits.IsConstexpr = Record.readInt();
diff --git a/lib/Serialization/ASTWriterDecl.cpp b/lib/Serialization/ASTWriterDecl.cpp
index 5ec11dda8a..002b43f811 100644
--- a/lib/Serialization/ASTWriterDecl.cpp
+++ b/lib/Serialization/ASTWriterDecl.cpp
@@ -922,13 +922,13 @@ void ASTDeclWriter::VisitVarDecl(VarDecl *D) {
   Record.push_back(D->getStorageClass());
   Record.push_back(D->getTSCSpec());
   Record.push_back(D->getInitStyle());
+  Record.push_back(D->isARCPseudoStrong());
   if (!isa(D)) {
     Record.push_back(D->isThisDeclarationADemotedDefinition());
     Record.push_back(D->isExceptionVariable());
     Record.push_back(D->isNRVOVariable());
     Record.push_back(D->isCXXForRangeDecl());
     Record.push_back(D->isObjCForDecl());
-    Record.push_back(D->isARCPseudoStrong());
     Record.push_back(D->isInline());
     Record.push_back(D->isInlineSpecified());
     Record.push_back(D->isConstexpr());
@@ -1986,6 +1986,7 @@ void ASTWriter::WriteDeclAbbrevs() {
   Abv->Add(BitCodeAbbrevOp(0));                       // SClass
   Abv->Add(BitCodeAbbrevOp(0));                       // TSCSpec
   Abv->Add(BitCodeAbbrevOp(0));                       // InitStyle
+  Abv->Add(BitCodeAbbrevOp(0));                       // ARCPseudoStrong
   Abv->Add(BitCodeAbbrevOp(0));                       // Linkage
   Abv->Add(BitCodeAbbrevOp(0));                       // HasInit
   Abv->Add(BitCodeAbbrevOp(0));                   // HasMemberSpecializationInfo
@@ -2062,12 +2063,12 @@ void ASTWriter::WriteDeclAbbrevs() {
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // SClass
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // TSCSpec
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // InitStyle
+  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isARCPseudoStrong
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsThisDeclarationADemotedDefinition
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isExceptionVariable
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isNRVOVariable
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isCXXForRangeDecl
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isObjCForDecl
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isARCPseudoStrong
   Abv->Add(BitCodeAbbrevOp(0));                         // isInline
   Abv->Add(BitCodeAbbrevOp(0));                         // isInlineSpecified
   Abv->Add(BitCodeAbbrevOp(0));                         // isConstexpr
diff --git a/test/CodeGenObjC/externally-retained.m b/test/CodeGenObjC/externally-retained.m
new file mode 100644
index 0000000000..0b4d0d648b
--- /dev/null
+++ b/test/CodeGenObjC/externally-retained.m
@@ -0,0 +1,115 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.13.0 -fobjc-arc -fblocks -Wno-objc-root-class -O0 %s -S -emit-llvm -o - | FileCheck %s --dump-input-on-failure
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.13.0 -fobjc-arc -fblocks -Wno-objc-root-class -O0 -xobjective-c++ -std=c++11 %s -S -emit-llvm -o - | FileCheck %s --check-prefix CHECKXX --dump-input-on-failure
+
+#define EXT_RET __attribute__((objc_externally_retained))
+
+@interface ObjTy @end
+
+ObjTy *global;
+
+#if __cplusplus
+// Suppress name mangling in C++ mode for the sake of check lines.
+extern "C" void param(ObjTy *p);
+extern "C" void local();
+extern "C" void in_init();
+extern "C" void anchor();
+extern "C" void block_capture(ObjTy *);
+extern "C" void esc(void (^)());
+extern "C" void escp(void (^)(ObjTy *));
+extern "C" void block_param();
+#endif
+
+void param(ObjTy *p) EXT_RET {
+  // CHECK-LABEL: define void @param
+  // CHECK-NOT: llvm.objc.
+  // CHECK ret
+}
+
+void local() {
+  EXT_RET ObjTy *local = global;
+  // CHECK-LABEL: define void @local
+  // CHECK-NOT: llvm.objc.
+  // CHECK: ret
+}
+
+void in_init() {
+  // Test that we do the right thing when a variable appears in it's own
+  // initializer. Here, we release the value stored in 'wat' after overwriting
+  // it, in case it was somehow set to point to a non-null object while it's
+  // initializer is being evaluated.
+  EXT_RET ObjTy *wat = 0 ? wat : global;
+
+  // CHECK-LABEL: define void @in_init
+  // CHECK: [[WAT:%.*]] = alloca
+  // CHECK-NEXT: store {{.*}} null, {{.*}} [[WAT]]
+  // CHECK-NEXT: [[GLOBAL:%.*]] = load {{.*}} @global
+  // CHECK-NEXT: [[WAT_LOAD:%.*]] = load {{.*}} [[WAT]]
+  // CHECK-NEXT: store {{.*}} [[GLOBAL]], {{.*}} [[WAT]]
+  // CHECK-NEXT: [[CASTED:%.*]] = bitcast {{.*}} [[WAT_LOAD]] to
+  // CHECK-NEXT: call void @llvm.objc.release(i8* [[CASTED]])
+
+  // CHECK-NOT: llvm.objc.
+  // CHECK: ret
+}
+
+void esc(void (^)());
+
+void block_capture(ObjTy *obj) EXT_RET {
+  esc(^{ (void)obj; });
+
+  // CHECK-LABEL: define void @block_capture
+  // CHECK-NOT: llvm.objc.
+  // CHECK: call i8* @llvm.objc.retain
+  // CHECK-NOT: llvm.objc.
+  // CHECK: call void @esc
+  // CHECK-NOT: llvm.objc.
+  // CHECK: call void @llvm.objc.storeStrong({{.*}} null)
+  // CHECK-NOT: llvm.objc.
+  // CHECK: ret
+
+  // CHECK-LABEL: define {{.*}} void @__copy_helper_block_
+  // CHECK-NOT: llvm.objc.
+  // CHECK: llvm.objc.storeStrong
+  // CHECK-NOT: llvm.objc.
+  // CHECK: ret
+
+  // CHECK-LABEL: define {{.*}} void @__destroy_helper_block_
+  // CHECK-NOT: llvm.objc.
+  // CHECK: llvm.objc.storeStrong({{.*}} null)
+  // CHECK-NOT: llvm.objc.
+  // CHECK: ret
+}
+
+void escp(void (^)(ObjTy *));
+
+void block_param() {
+  escp(^(ObjTy *p) EXT_RET {});
+
+  // CHECK-LABEL: define internal void @__block_param_block_invoke
+  // CHECK-NOT: llvm.objc.
+  // CHECK: ret
+}
+
+@interface Inter
+-(void)m1: (ObjTy *)w;
+@end
+
+@implementation Inter
+-(void)m1: (ObjTy *) w EXT_RET {
+  // CHECK-LABEL: define internal void @"\01-[Inter m1:]"
+  // CHECK-NOT: llvm.objc.
+  // CHECK: ret
+}
+-(void)m2: (ObjTy *) w EXT_RET {
+  // CHECK-LABEL: define internal void @"\01-[Inter m2:]"
+  // CHECK-NOT: llvm.objc.
+  // CHECK: ret
+}
+@end
+
+#if __cplusplus
+// Verify that the decltype(p) is resolved before 'p' is made implicitly const.
+__attribute__((objc_externally_retained))
+void foo(ObjTy *p, decltype(p) *) {}
+// CHECKXX: _Z3fooP5ObjTyPU8__strongS0_
+#endif
diff --git a/test/Misc/pragma-attribute-supported-attributes-list.test b/test/Misc/pragma-attribute-supported-attributes-list.test
index 48a6bac187..2f4aaa200c 100644
--- a/test/Misc/pragma-attribute-supported-attributes-list.test
+++ b/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -94,6 +94,7 @@
 // CHECK-NEXT: ObjCBridgeRelated (SubjectMatchRule_record)
 // CHECK-NEXT: ObjCException (SubjectMatchRule_objc_interface)
 // CHECK-NEXT: ObjCExplicitProtocolImpl (SubjectMatchRule_objc_protocol)
+// CHECK-NEXT: ObjCExternallyRetained (SubjectMatchRule_variable_not_is_parameter, SubjectMatchRule_function, SubjectMatchRule_block, SubjectMatchRule_objc_method)
 // CHECK-NEXT: ObjCMethodFamily (SubjectMatchRule_objc_method)
 // CHECK-NEXT: ObjCPreciseLifetime (SubjectMatchRule_variable)
 // CHECK-NEXT: ObjCRequiresPropertyDefs (SubjectMatchRule_objc_interface)
diff --git a/test/SemaObjC/externally-retained-no-arc.m b/test/SemaObjC/externally-retained-no-arc.m
new file mode 100644
index 0000000000..a548d6b88d
--- /dev/null
+++ b/test/SemaObjC/externally-retained-no-arc.m
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 %s -verify
+
+@interface NSWidget @end
+
+__attribute__((objc_externally_retained)) void f(NSWidget *p) { // expected-warning{{'objc_externally_retained' attribute ignored}}
+  __attribute__((objc_externally_retained)) NSWidget *w; // expected-warning{{'objc_externally_retained' attribute ignored}}
+}
diff --git a/test/SemaObjC/externally-retained.m b/test/SemaObjC/externally-retained.m
new file mode 100644
index 0000000000..2708fc8eef
--- /dev/null
+++ b/test/SemaObjC/externally-retained.m
@@ -0,0 +1,114 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.13.0 -fobjc-runtime=macosx-10.13.0 -fblocks -fobjc-arc %s -verify
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.13.0 -fobjc-runtime=macosx-10.13.0 -fblocks -fobjc-arc -xobjective-c++ %s -verify
+
+#define EXT_RET __attribute__((objc_externally_retained))
+
+@interface ObjCTy
+@end
+
+void test1() {
+  EXT_RET int a; // expected-warning{{'objc_externally_retained' can only be applied to}}
+  EXT_RET __weak ObjCTy *b; // expected-warning{{'objc_externally_retained' can only be applied to}}
+  EXT_RET __weak int (^c)(); // expected-warning{{'objc_externally_retained' can only be applied to}}
+
+  EXT_RET int (^d)() = ^{return 0;};
+  EXT_RET ObjCTy *e = 0;
+  EXT_RET __strong ObjCTy *f = 0;
+
+  e = 0; // expected-error{{variable declared with 'objc_externally_retained' cannot be modified in ARC}}
+  f = 0; // expected-error{{variable declared with 'objc_externally_retained' cannot be modified in ARC}}
+  d = ^{ return 0; }; // expected-error{{variable declared with 'objc_externally_retained' cannot be modified in ARC}}
+}
+
+void test2(ObjCTy *a);
+
+void test2(ObjCTy *a) EXT_RET {
+  a = 0; // expected-error{{variable declared with 'objc_externally_retained' cannot be modified in ARC}}
+}
+
+EXT_RET ObjCTy *test3; // expected-warning{{'objc_externally_retained' can only be applied to}}
+
+@interface X // expected-warning{{defined without specifying a base class}} expected-note{{add a super class}}
+-(void)m: (ObjCTy *) p;
+@end
+@implementation X
+-(void)m: (ObjCTy *) p EXT_RET {
+  p = 0; // expected-error{{variable declared with 'objc_externally_retained' cannot be modified in ARC}}
+}
+@end
+
+void test4() {
+  __attribute__((objc_externally_retained(0))) ObjCTy *a; // expected-error{{'objc_externally_retained' attribute takes no arguments}}
+}
+
+void test5(ObjCTy *first, __strong ObjCTy *second) EXT_RET {
+  first = 0; // expected-error{{variable declared with 'objc_externally_retained' cannot be modified in ARC}}
+  second = 0; // fine
+}
+
+void test6(ObjCTy *first,
+           __strong ObjCTy *second) EXT_RET {
+  first = 0; // expected-error{{variable declared with 'objc_externally_retained' cannot be modified in ARC}}
+  second = 0;
+}
+
+__attribute__((objc_root_class)) @interface Y @end
+
+@implementation Y
+- (void)test7:(__strong ObjCTy *)first
+    withThird:(ObjCTy *)second EXT_RET {
+  first = 0;
+  second = 0; // expected-error{{variable declared with 'objc_externally_retained' cannot be modified in ARC}}
+}
+@end
+
+void (^blk)(ObjCTy *, ObjCTy *) =
+    ^(__strong ObjCTy *first, ObjCTy *second) EXT_RET {
+  first = 0;
+  second = 0; // expected-error{{variable declared with 'objc_externally_retained' cannot be modified in ARC}}
+};
+
+void test8(EXT_RET ObjCTy *x) {} // expected-warning{{'objc_externally_retained' attribute only applies to variables}}
+
+#pragma clang attribute ext_ret.push(__attribute__((objc_externally_retained)), apply_to=any(function, block, objc_method))
+void test9(ObjCTy *first, __strong ObjCTy *second) {
+  first = 0; // expected-error{{variable declared with 'objc_externally_retained' cannot be modified in ARC}}
+  second = 0;
+}
+void (^test10)(ObjCTy *first, ObjCTy *second) = ^(ObjCTy *first, __strong ObjCTy *second) {
+  first = 0; // expected-error{{variable declared with 'objc_externally_retained' cannot be modified in ARC}}
+  second = 0;
+};
+__attribute__((objc_root_class)) @interface Test11 @end
+@implementation Test11
+-(void)meth: (ObjCTy *)first withSecond:(__strong ObjCTy *)second {
+  first = 0; // expected-error{{variable declared with 'objc_externally_retained' cannot be modified in ARC}}
+  second = 0;
+}
++(void)othermeth: (ObjCTy *)first withSecond:(__strong ObjCTy *)second {
+  first = 0; // expected-error{{variable declared with 'objc_externally_retained' cannot be modified in ARC}}
+  second = 0;
+}
+@end
+
+#if __cplusplus
+class Test12 {
+  void inline_member(ObjCTy *first, __strong ObjCTy *second) {
+    first = 0; // expected-error{{variable declared with 'objc_externally_retained' cannot be modified in ARC}}
+    second = 0;
+  }
+  static void static_inline_member(ObjCTy *first, __strong ObjCTy *second) {
+    first = 0; // expected-error{{variable declared with 'objc_externally_retained' cannot be modified in ARC}}
+    second = 0;
+  }
+};
+#endif
+
+void test13(ObjCTy *first, __weak ObjCTy *second, __unsafe_unretained ObjCTy *third, __strong ObjCTy *fourth) {
+  first = 0; // expected-error{{variable declared with 'objc_externally_retained' cannot be modified in ARC}}
+  second = 0;
+  third = 0;
+  fourth = 0;
+}
+
+#pragma clang attribute ext_ret.pop
-- 
cgit v1.2.3


From 1229779346fd2c2b340ab4db245bb67224c5d97b Mon Sep 17 00:00:00 2001
From: Teresa Johnson 
Date: Fri, 4 Jan 2019 19:05:01 +0000
Subject: [ThinLTO] Clang changes to utilize new pass to handle chains of
 aliases

Summary:
As with NameAnonGlobals, invoke the new CanonicalizeAliases via clang
when using the new PM.

Depends on D54507.

Reviewers: pcc, davidxl

Subscribers: mehdi_amini, inglorion, steven_wu, dexonsmith, cfe-commits

Differential Revision: https://reviews.llvm.org/D55620

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350424 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/CodeGen/BackendUtil.cpp       | 9 +++++++--
 test/CodeGen/lto-newpm-pipeline.c | 3 +++
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/lib/CodeGen/BackendUtil.cpp b/lib/CodeGen/BackendUtil.cpp
index 3280417a91..1311af9168 100644
--- a/lib/CodeGen/BackendUtil.cpp
+++ b/lib/CodeGen/BackendUtil.cpp
@@ -60,6 +60,7 @@
 #include "llvm/Transforms/Scalar.h"
 #include "llvm/Transforms/Scalar/GVN.h"
 #include "llvm/Transforms/Utils.h"
+#include "llvm/Transforms/Utils/CanonicalizeAliases.h"
 #include "llvm/Transforms/Utils/NameAnonGlobals.h"
 #include "llvm/Transforms/Utils/SymbolRewriter.h"
 #include 
@@ -996,9 +997,11 @@ void EmitAssemblyHelper::EmitAssemblyWithNewPassManager(
       if (LangOpts.Sanitize.has(SanitizerKind::LocalBounds))
         MPM.addPass(createModuleToFunctionPassAdaptor(BoundsCheckingPass()));
 
-      // Lastly, add a semantically necessary pass for LTO.
-      if (IsLTO || IsThinLTO)
+      // Lastly, add semantically necessary passes for LTO.
+      if (IsLTO || IsThinLTO) {
+        MPM.addPass(CanonicalizeAliasesPass());
         MPM.addPass(NameAnonGlobalPass());
+      }
     } else {
       // Map our optimization levels into one of the distinct levels used to
       // configure the pipeline.
@@ -1019,10 +1022,12 @@ void EmitAssemblyHelper::EmitAssemblyWithNewPassManager(
       if (IsThinLTO) {
         MPM = PB.buildThinLTOPreLinkDefaultPipeline(
             Level, CodeGenOpts.DebugPassManager);
+        MPM.addPass(CanonicalizeAliasesPass());
         MPM.addPass(NameAnonGlobalPass());
       } else if (IsLTO) {
         MPM = PB.buildLTOPreLinkDefaultPipeline(Level,
                                                 CodeGenOpts.DebugPassManager);
+        MPM.addPass(CanonicalizeAliasesPass());
         MPM.addPass(NameAnonGlobalPass());
       } else {
         MPM = PB.buildPerModuleDefaultPipeline(Level,
diff --git a/test/CodeGen/lto-newpm-pipeline.c b/test/CodeGen/lto-newpm-pipeline.c
index 137c46c964..57391161a6 100644
--- a/test/CodeGen/lto-newpm-pipeline.c
+++ b/test/CodeGen/lto-newpm-pipeline.c
@@ -27,12 +27,14 @@
 
 // CHECK-FULL-O0: Starting llvm::Module pass manager run.
 // CHECK-FULL-O0: Running pass: AlwaysInlinerPass
+// CHECK-FULL-O0-NEXT: Running pass: CanonicalizeAliasesPass
 // CHECK-FULL-O0-NEXT: Running pass: NameAnonGlobalPass
 // CHECK-FULL-O0-NEXT: Running pass: BitcodeWriterPass
 // CHECK-FULL-O0: Finished llvm::Module pass manager run.
 
 // CHECK-THIN-O0: Starting llvm::Module pass manager run.
 // CHECK-THIN-O0: Running pass: AlwaysInlinerPass
+// CHECK-THIN-O0-NEXT: Running pass: CanonicalizeAliasesPass
 // CHECK-THIN-O0-NEXT: Running pass: NameAnonGlobalPass
 // CHECK-THIN-O0-NEXT: Running pass: ThinLTOBitcodeWriterPass
 // CHECK-THIN-O0: Finished llvm::Module pass manager run.
@@ -48,6 +50,7 @@
 // LoopVectorizePass.
 // CHECK-THIN-OPTIMIZED: Starting llvm::Function pass manager run.
 // CHECK-THIN-OPTIMIZED-NOT: Running pass: LoopVectorizePass
+// CHECK-THIN-OPTIMIZED: Running pass: CanonicalizeAliasesPass
 // CHECK-THIN-OPTIMIZED: Running pass: NameAnonGlobalPass
 // CHECK-THIN-OPTIMIZED: Running pass: ThinLTOBitcodeWriterPass
 
-- 
cgit v1.2.3


From 5aa017b125e501db919c6c62be03f0a275ebc63f Mon Sep 17 00:00:00 2001
From: Aaron Enye Shi 
Date: Fri, 4 Jan 2019 19:05:41 +0000
Subject: [HIP][DRIVER][OFFLOAD] Do not unbundle unsupported file types

The offload bundler action should not unbundle the input file types that does not match the action type. This fixes an issue where .so files are unbundled when the action type is object files.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350425 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/Driver/Driver.cpp                   | 12 ++++++++++++
 test/Driver/hip-link-shared-library.hip | 11 +++++++++++
 2 files changed, 23 insertions(+)
 create mode 100644 test/Driver/hip-link-shared-library.hip

diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp
index 725bf273ed..977bff5bf7 100644
--- a/lib/Driver/Driver.cpp
+++ b/lib/Driver/Driver.cpp
@@ -2323,6 +2323,18 @@ class OffloadingActionBuilder final {
       // If this is an unbundling action use it as is for each CUDA toolchain.
       if (auto *UA = dyn_cast(HostAction)) {
         CudaDeviceActions.clear();
+        auto *IA = cast(UA->getInputs().back());
+        std::string FileName = IA->getInputArg().getAsString(Args);
+        // Check if the type of the file is the same as the action. Do not
+        // unbundle it if it is not. Do not unbundle .so files, for example,
+        // which are not object files.
+        if (IA->getType() == types::TY_Object &&
+            (!llvm::sys::path::has_extension(FileName) ||
+             types::lookupTypeForExtension(
+                 llvm::sys::path::extension(FileName).drop_front()) !=
+                 types::TY_Object))
+          return ABRT_Inactive;
+
         for (auto Arch : GpuArchList) {
           CudaDeviceActions.push_back(UA);
           UA->registerDependentActionInfo(ToolChains[0], CudaArchToString(Arch),
diff --git a/test/Driver/hip-link-shared-library.hip b/test/Driver/hip-link-shared-library.hip
new file mode 100644
index 0000000000..2e36dff369
--- /dev/null
+++ b/test/Driver/hip-link-shared-library.hip
@@ -0,0 +1,11 @@
+// RUN: touch %t.o
+// RUN: %clang --hip-link -ccc-print-bindings -target x86_64-linux-gnu \
+// RUN:   --cuda-gpu-arch=gfx803 --cuda-gpu-arch=gfx900 %t.o %S/Inputs/in.so \
+// RUN: 2>&1 | FileCheck %s
+
+// CHECK: # "amdgcn-amd-amdhsa" - "offload bundler", inputs: ["[[IN:.*o]]"], outputs: ["[[OBJ1:.*o]]", "[[OBJ2:.*o]]", "[[OBJ3:.*o]]"]
+// CHECK: # "amdgcn-amd-amdhsa" - "AMDGCN::Linker", inputs: ["[[OBJ2]]"], output: "[[IMG2:.*out]]"
+// CHECK-NOT: offload bundler
+// CHECK: # "amdgcn-amd-amdhsa" - "AMDGCN::Linker", inputs: ["[[OBJ3]]"], output: "[[IMG3:.*out]]"
+// CHECK-NOT: offload bundler
+// CHECK: # "x86_64-unknown-linux-gnu" - "GNU::Linker", inputs: ["[[OBJ1]]", "{{.*}}/Inputs/in.so", "[[IMG2]]", "[[IMG3]]"], output: "a.out"
-- 
cgit v1.2.3


From 5f9f674fea281ebc6beb6c871b27d588d006a900 Mon Sep 17 00:00:00 2001
From: Aaron Enye Shi 
Date: Fri, 4 Jan 2019 19:09:20 +0000
Subject: [HIP][DRIVER][OFFLOAD] Do not unbundle unsupported file types

The offload bundler action should not unbundle the input file types that does not match the action type. This fixes an issue where .so files are unbundled when the action type is object files.

Reviewers: yaxunl

Differential Revision: https://reviews.llvm.org/D56321


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350426 91177308-0d34-0410-b5e6-96231b3b80d8
---
 test/Driver/hip-link-shared-library.hip | 1 +
 1 file changed, 1 insertion(+)

diff --git a/test/Driver/hip-link-shared-library.hip b/test/Driver/hip-link-shared-library.hip
index 2e36dff369..b7b301a9e3 100644
--- a/test/Driver/hip-link-shared-library.hip
+++ b/test/Driver/hip-link-shared-library.hip
@@ -9,3 +9,4 @@
 // CHECK: # "amdgcn-amd-amdhsa" - "AMDGCN::Linker", inputs: ["[[OBJ3]]"], output: "[[IMG3:.*out]]"
 // CHECK-NOT: offload bundler
 // CHECK: # "x86_64-unknown-linux-gnu" - "GNU::Linker", inputs: ["[[OBJ1]]", "{{.*}}/Inputs/in.so", "[[IMG2]]", "[[IMG3]]"], output: "a.out"
+
-- 
cgit v1.2.3


From b4ac732910ee32d004284aaa0632e5bb2fecc5fd Mon Sep 17 00:00:00 2001
From: Peter Collingbourne 
Date: Fri, 4 Jan 2019 19:27:04 +0000
Subject: hwasan: Implement lazy thread initialization for the interceptor ABI.

The problem is similar to D55986 but for threads: a process with the
interceptor hwasan library loaded might have some threads started by
instrumented libraries and some by uninstrumented libraries, and we
need to be able to run instrumented code on the latter.

The solution is to perform per-thread initialization lazily. If a
function needs to access shadow memory or add itself to the per-thread
ring buffer its prologue checks to see whether the value in the
sanitizer TLS slot is null, and if so it calls __hwasan_thread_enter
and reloads from the TLS slot. The runtime does the same thing if it
needs to access this data structure.

This change means that the code generator needs to know whether we
are targeting the interceptor runtime, since we don't want to pay
the cost of lazy initialization when targeting a platform with native
hwasan support. A flag -fsanitize-hwaddress-abi={interceptor,platform}
has been introduced for selecting the runtime ABI to target. The
default ABI is set to interceptor since it's assumed that it will
be more common that users will be compiling application code than
platform code.

Because we can no longer assume that the TLS slot is initialized,
the pthread_create interceptor is no longer necessary, so it has
been removed.

Ideally, lazy initialization should only cost one instruction in the
hot path, but at present the call may cause us to spill arguments
to the stack, which means more instructions in the hot path (or
theoretically in the cold path if the spills are moved with shrink
wrapping). With an appropriately chosen calling convention for
the per-thread initialization function (TODO) the hot path should
always need just one instruction and the cold path should need two
instructions with no spilling required.

Differential Revision: https://reviews.llvm.org/D56038

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350429 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/Basic/CodeGenOptions.h |  2 ++
 include/clang/Driver/CC1Options.td   |  2 ++
 include/clang/Driver/Options.td      |  4 ++++
 include/clang/Driver/SanitizerArgs.h |  1 +
 lib/CodeGen/CGCall.cpp               |  6 ++++++
 lib/Driver/SanitizerArgs.cpp         | 17 +++++++++++++++++
 lib/Frontend/CompilerInvocation.cpp  |  2 ++
 test/CodeGen/default-function-attr.c |  6 ++++++
 test/Driver/fsanitize.c              |  8 ++++++++
 9 files changed, 48 insertions(+)
 create mode 100644 test/CodeGen/default-function-attr.c

diff --git a/include/clang/Basic/CodeGenOptions.h b/include/clang/Basic/CodeGenOptions.h
index a12744ee3d..ec6eda7fb7 100644
--- a/include/clang/Basic/CodeGenOptions.h
+++ b/include/clang/Basic/CodeGenOptions.h
@@ -286,6 +286,8 @@ public:
   /// Set of XRay instrumentation kinds to emit.
   XRayInstrSet XRayInstrumentationBundle;
 
+  std::vector DefaultFunctionAttrs;
+
 public:
   // Define accessors/mutators for code generation options of enumeration type.
 #define CODEGENOPT(Name, Bits, Default)
diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td
index c0e73e56d7..07c7688406 100644
--- a/include/clang/Driver/CC1Options.td
+++ b/include/clang/Driver/CC1Options.td
@@ -163,6 +163,8 @@ let Flags = [CC1Option, CC1AsOption, NoDriverOption] in {
 def debug_info_kind_EQ : Joined<["-"], "debug-info-kind=">;
 def debug_info_macro : Flag<["-"], "debug-info-macro">,
   HelpText<"Emit macro debug information">;
+def default_function_attr : Separate<["-"], "default-function-attr">,
+  HelpText<"Apply given attribute to all functions">;
 def dwarf_version_EQ : Joined<["-"], "dwarf-version=">;
 def debugger_tuning_EQ : Joined<["-"], "debugger-tuning=">;
 def fdebug_compilation_dir : Separate<["-"], "fdebug-compilation-dir">,
diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td
index 809b28b9dd..1c5cae683a 100644
--- a/include/clang/Driver/Options.td
+++ b/include/clang/Driver/Options.td
@@ -998,6 +998,10 @@ def fno_sanitize_address_use_odr_indicator
     : Flag<["-"], "fno-sanitize-address-use-odr-indicator">,
       Group,
       HelpText<"Disable ODR indicator globals">;
+def fsanitize_hwaddress_abi_EQ
+    : Joined<["-"], "fsanitize-hwaddress-abi=">,
+      Group,
+      HelpText<"Select the HWAddressSanitizer ABI to target (interceptor or platform, default interceptor)">;
 def fsanitize_recover : Flag<["-"], "fsanitize-recover">, Group;
 def fno_sanitize_recover : Flag<["-"], "fno-sanitize-recover">,
                            Flags<[CoreOption, DriverOption]>,
diff --git a/include/clang/Driver/SanitizerArgs.h b/include/clang/Driver/SanitizerArgs.h
index 55c5826bfb..02338c2216 100644
--- a/include/clang/Driver/SanitizerArgs.h
+++ b/include/clang/Driver/SanitizerArgs.h
@@ -39,6 +39,7 @@ class SanitizerArgs {
   bool AsanPoisonCustomArrayCookie = false;
   bool AsanGlobalsDeadStripping = false;
   bool AsanUseOdrIndicator = false;
+  std::string HwasanAbi;
   bool LinkCXXRuntimes = false;
   bool NeedPIE = false;
   bool SafeStackRuntime = false;
diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp
index 64e18e171e..09116d465e 100644
--- a/lib/CodeGen/CGCall.cpp
+++ b/lib/CodeGen/CGCall.cpp
@@ -1816,6 +1816,12 @@ void CodeGenModule::ConstructDefaultFnAttrList(StringRef Name, bool HasOptnone,
     if (CodeGenOpts.FlushDenorm)
       FuncAttrs.addAttribute("nvptx-f32ftz", "true");
   }
+
+  for (StringRef Attr : CodeGenOpts.DefaultFunctionAttrs) {
+    StringRef Var, Value;
+    std::tie(Var, Value) = Attr.split('=');
+    FuncAttrs.addAttribute(Var, Value);
+  }
 }
 
 void CodeGenModule::AddDefaultFnAttrs(llvm::Function &F) {
diff --git a/lib/Driver/SanitizerArgs.cpp b/lib/Driver/SanitizerArgs.cpp
index 4e0d7491bb..6667cbb347 100644
--- a/lib/Driver/SanitizerArgs.cpp
+++ b/lib/Driver/SanitizerArgs.cpp
@@ -741,6 +741,18 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
     AsanUseAfterScope = false;
   }
 
+  if (AllAddedKinds & HWAddress) {
+    if (Arg *HwasanAbiArg =
+            Args.getLastArg(options::OPT_fsanitize_hwaddress_abi_EQ)) {
+      HwasanAbi = HwasanAbiArg->getValue();
+      if (HwasanAbi != "platform" && HwasanAbi != "interceptor")
+        D.Diag(clang::diag::err_drv_invalid_value)
+            << HwasanAbiArg->getAsString(Args) << HwasanAbi;
+    } else {
+      HwasanAbi = "interceptor";
+    }
+  }
+
   if (AllAddedKinds & SafeStack) {
     // SafeStack runtime is built into the system on Fuchsia.
     SafeStackRuntime = !TC.getTriple().isOSFuchsia();
@@ -913,6 +925,11 @@ void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
   if (AsanUseOdrIndicator)
     CmdArgs.push_back("-fsanitize-address-use-odr-indicator");
 
+  if (!HwasanAbi.empty()) {
+    CmdArgs.push_back("-default-function-attr");
+    CmdArgs.push_back(Args.MakeArgString("hwasan-abi=" + HwasanAbi));
+  }
+
   // MSan: Workaround for PR16386.
   // ASan: This is mainly to help LSan with cases such as
   // https://github.com/google/sanitizers/issues/373
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index 39152fda99..00083bd622 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -1319,6 +1319,8 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
 
   Opts.SpeculativeLoadHardening = Args.hasArg(OPT_mspeculative_load_hardening);
 
+  Opts.DefaultFunctionAttrs = Args.getAllArgValues(OPT_default_function_attr);
+
   return Success;
 }
 
diff --git a/test/CodeGen/default-function-attr.c b/test/CodeGen/default-function-attr.c
new file mode 100644
index 0000000000..b0d1398a15
--- /dev/null
+++ b/test/CodeGen/default-function-attr.c
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -default-function-attr foo=bar -emit-llvm %s -o - | FileCheck %s
+
+// CHECK: define void @foo() #[[X:[0-9]+]]
+void foo() {}
+
+// CHECK: attributes #[[X]] = {{.*}} "foo"="bar"
diff --git a/test/Driver/fsanitize.c b/test/Driver/fsanitize.c
index 0a82174aaa..de45561714 100644
--- a/test/Driver/fsanitize.c
+++ b/test/Driver/fsanitize.c
@@ -837,3 +837,11 @@
 //
 // RUN: %clang -target x86_64-linux-gnu -fsanitize=scudo,kernel-memory  %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SCUDO-KMSAN
 // CHECK-SCUDO-KMSAN: error: invalid argument '-fsanitize=kernel-memory' not allowed with '-fsanitize=scudo'
+
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=hwaddress %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-HWASAN-INTERCEPTOR-ABI
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=hwaddress -fsanitize-hwaddress-abi=interceptor %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-HWASAN-INTERCEPTOR-ABI
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=hwaddress -fsanitize-hwaddress-abi=platform %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-HWASAN-PLATFORM-ABI
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=hwaddress -fsanitize-hwaddress-abi=foo %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-HWASAN-FOO-ABI
+// CHECK-HWASAN-INTERCEPTOR-ABI: "-default-function-attr" "hwasan-abi=interceptor"
+// CHECK-HWASAN-PLATFORM-ABI: "-default-function-attr" "hwasan-abi=platform"
+// CHECK-HWASAN-FOO-ABI: error: invalid value 'foo' in '-fsanitize-hwaddress-abi=foo'
-- 
cgit v1.2.3


From a615149ee4fd2b6d97dc029c8827e42b025e1379 Mon Sep 17 00:00:00 2001
From: Peter Collingbourne 
Date: Fri, 4 Jan 2019 20:51:54 +0000
Subject: Fix default-function-attr.c so that it works on Windows.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350433 91177308-0d34-0410-b5e6-96231b3b80d8
---
 test/CodeGen/default-function-attr.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/test/CodeGen/default-function-attr.c b/test/CodeGen/default-function-attr.c
index b0d1398a15..1c186e8e55 100644
--- a/test/CodeGen/default-function-attr.c
+++ b/test/CodeGen/default-function-attr.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -default-function-attr foo=bar -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux -default-function-attr foo=bar -emit-llvm %s -o - | FileCheck %s
 
 // CHECK: define void @foo() #[[X:[0-9]+]]
 void foo() {}
-- 
cgit v1.2.3


From f21e62190820e0ae3570ba617043e42a64c1582b Mon Sep 17 00:00:00 2001
From: "Joel E. Denny" 
Date: Fri, 4 Jan 2019 22:11:31 +0000
Subject: [OpenMP] Replace predetermined shared for const variable

The following appears in OpenMP 3.1 sec. 2.9.1.1 as a predetermined
data-sharing attribute:

> Variables with const-qualified type having no mutable member are
> shared.

It does not appear in OpenmP 4.0, 4.5, or 5.0.  This patch removes the
implementation of that attribute when the requested OpenMP version is
greater than 3.1.

One effect of that removal is that `default(none)` affects const
variables without mutable members.

Also, without this patch, if a const variable without mutable members
was explicitly lastprivate or private, it was an error because it was
predetermined shared.  Now, clang instead complains that it's const
without mutable fields, which is a more intelligible diagnostic.  That
should be fine for all of the above versions because they all have
something like the following, which is quoted from OpenMP 5.0
sec. 2.19.3:

> A variable that is privatized must not have a const-qualified type
> unless it is of class type with a mutable member. This restriction does
> not apply to the firstprivate clause.

reduction and linear clauses already have separate checks for const
variables.  Future patches will merge the implementations.

Reviewed By: ABataev

Differential Revision: https://reviews.llvm.org/D56113

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350439 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/Basic/DiagnosticSemaKinds.td         |   2 +
 lib/Sema/SemaOpenMP.cpp                            | 107 +++++++++++++++------
 ...istribute_parallel_for_lastprivate_messages.cpp |  20 ++--
 ...bute_parallel_for_simd_lastprivate_messages.cpp |  20 ++--
 test/OpenMP/distribute_private_messages.cpp        |  16 +--
 .../distribute_simd_lastprivate_messages.cpp       |  20 ++--
 test/OpenMP/for_lastprivate_messages.cpp           |  20 ++--
 test/OpenMP/for_simd_lastprivate_messages.cpp      |  20 ++--
 test/OpenMP/parallel_default_messages.cpp          |  12 ++-
 test/OpenMP/parallel_for_lastprivate_messages.cpp  |  20 ++--
 .../parallel_for_simd_lastprivate_messages.cpp     |  20 ++--
 test/OpenMP/parallel_private_messages.cpp          |  16 +--
 .../parallel_sections_lastprivate_messages.cpp     |  20 ++--
 test/OpenMP/sections_lastprivate_messages.cpp      |  20 ++--
 test/OpenMP/simd_lastprivate_messages.cpp          |  20 ++--
 .../target_parallel_for_lastprivate_messages.cpp   |  20 ++--
 ...rget_parallel_for_simd_lastprivate_messages.cpp |  20 ++--
 test/OpenMP/target_parallel_private_messages.cpp   |  26 ++---
 test/OpenMP/target_simd_lastprivate_messages.cpp   |  20 ++--
 ...arget_teams_distribute_lastprivate_messages.cpp |  20 ++--
 ...istribute_parallel_for_lastprivate_messages.cpp |  20 ++--
 ...ms_distribute_parallel_for_private_messages.cpp |  16 +--
 ...bute_parallel_for_simd_lastprivate_messages.cpp |  20 ++--
 ...stribute_parallel_for_simd_private_messages.cpp |  16 +--
 .../target_teams_distribute_private_messages.cpp   |  16 +--
 ..._teams_distribute_simd_lastprivate_messages.cpp |  20 ++--
 ...rget_teams_distribute_simd_private_messages.cpp |  16 +--
 test/OpenMP/target_teams_private_messages.cpp      |  16 +--
 test/OpenMP/task_private_messages.cpp              |  16 +--
 test/OpenMP/taskloop_lastprivate_messages.cpp      |  20 ++--
 test/OpenMP/taskloop_simd_lastprivate_messages.cpp |  20 ++--
 .../teams_distribute_lastprivate_messages.cpp      |  20 ++--
 ...istribute_parallel_for_lastprivate_messages.cpp |  20 ++--
 ...ms_distribute_parallel_for_private_messages.cpp |  16 +--
 ...bute_parallel_for_simd_lastprivate_messages.cpp |  20 ++--
 ...stribute_parallel_for_simd_private_messages.cpp |  16 +--
 test/OpenMP/teams_distribute_private_messages.cpp  |  16 +--
 .../teams_distribute_simd_lastprivate_messages.cpp |  20 ++--
 .../teams_distribute_simd_private_messages.cpp     |  16 +--
 test/OpenMP/teams_private_messages.cpp             |  16 +--
 40 files changed, 439 insertions(+), 376 deletions(-)

diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 0f30aed960..da0bb5d987 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -8778,6 +8778,8 @@ def err_omp_required_access : Error<
   "%0 variable must be %1">;
 def err_omp_const_variable : Error<
   "const-qualified variable cannot be %0">;
+def err_omp_const_not_mutable_variable : Error<
+  "const-qualified variable without mutable fields cannot be %0">;
 def err_omp_const_reduction_list_item : Error<
   "const-qualified list item cannot be reduction">;
 def err_omp_linear_incomplete_type : Error<
diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp
index 59c4b49bfb..7b702250b8 100644
--- a/lib/Sema/SemaOpenMP.cpp
+++ b/lib/Sema/SemaOpenMP.cpp
@@ -1080,6 +1080,43 @@ bool DSAStackTy::isOpenMPLocal(VarDecl *D, iterator Iter) const {
   return false;
 }
 
+static bool isConstNotMutableType(Sema &SemaRef, ValueDecl *D,
+                                  bool *IsClassType = nullptr) {
+  ASTContext &Context = SemaRef.getASTContext();
+  QualType Type = D->getType().getNonReferenceType().getCanonicalType();
+  bool IsConstant = Type.isConstant(Context);
+  Type = Context.getBaseElementType(Type);
+  const CXXRecordDecl *RD =
+      SemaRef.getLangOpts().CPlusPlus ? Type->getAsCXXRecordDecl() : nullptr;
+  if (const auto *CTSD = dyn_cast_or_null(RD))
+    if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate())
+      RD = CTD->getTemplatedDecl();
+  if (IsClassType)
+    *IsClassType = RD;
+  return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD &&
+                         RD->hasDefinition() && RD->hasMutableFields());
+}
+
+static bool rejectConstNotMutableType(Sema &SemaRef, ValueDecl *D,
+                                      OpenMPClauseKind CKind,
+                                      SourceLocation ELoc) {
+  ASTContext &Context = SemaRef.getASTContext();
+  bool IsClassType;
+  if (isConstNotMutableType(SemaRef, D, &IsClassType)) {
+    SemaRef.Diag(ELoc, IsClassType ? diag::err_omp_const_not_mutable_variable
+                                   : diag::err_omp_const_variable)
+        << getOpenMPClauseName(CKind);
+    VarDecl *VD = dyn_cast(D);
+    bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
+                             VarDecl::DeclarationOnly;
+    SemaRef.Diag(D->getLocation(),
+                 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+        << D;
+    return true;
+  }
+  return false;
+}
+
 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D,
                                                    bool FromParent) {
   D = getCanonicalDecl(D);
@@ -1177,34 +1214,28 @@ const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D,
     return DVar;
   }
 
-  QualType Type = D->getType().getNonReferenceType().getCanonicalType();
-  bool IsConstant = Type.isConstant(SemaRef.getASTContext());
-  Type = SemaRef.getASTContext().getBaseElementType(Type);
-  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
-  // in a Construct, C/C++, predetermined, p.6]
-  //  Variables with const qualified type having no mutable member are
-  //  shared.
-  const CXXRecordDecl *RD =
-      SemaRef.getLangOpts().CPlusPlus ? Type->getAsCXXRecordDecl() : nullptr;
-  if (const auto *CTSD = dyn_cast_or_null(RD))
-    if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate())
-      RD = CTD->getTemplatedDecl();
-  if (IsConstant &&
-      !(SemaRef.getLangOpts().CPlusPlus && RD && RD->hasDefinition() &&
-        RD->hasMutableFields())) {
-    // Variables with const-qualified type having no mutable member may be
-    // listed in a firstprivate clause, even if they are static data members.
-    DSAVarData DVarTemp = hasInnermostDSA(
-        D,
-        [](OpenMPClauseKind C) {
-          return C == OMPC_firstprivate || C == OMPC_shared;
-        },
-        MatchesAlways, FromParent);
-    if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr)
-      return DVarTemp;
+  // The predetermined shared attribute for const-qualified types having no
+  // mutable members was removed after OpenMP 3.1.
+  if (SemaRef.LangOpts.OpenMP <= 31) {
+    // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
+    // in a Construct, C/C++, predetermined, p.6]
+    //  Variables with const qualified type having no mutable member are
+    //  shared.
+    if (isConstNotMutableType(SemaRef, D)) {
+      // Variables with const-qualified type having no mutable member may be
+      // listed in a firstprivate clause, even if they are static data members.
+      DSAVarData DVarTemp = hasInnermostDSA(
+          D,
+          [](OpenMPClauseKind C) {
+            return C == OMPC_firstprivate || C == OMPC_shared;
+          },
+          MatchesAlways, FromParent);
+      if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr)
+        return DVarTemp;
 
-    DVar.CKind = OMPC_shared;
-    return DVar;
+      DVar.CKind = OMPC_shared;
+      return DVar;
+    }
   }
 
   // Explicitly specified attributes and local variables with predetermined
@@ -9791,6 +9822,17 @@ OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef VarList,
       continue;
     Type = Type.getNonReferenceType();
 
+    // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
+    // A variable that is privatized must not have a const-qualified type
+    // unless it is of class type with a mutable member. This restriction does
+    // not apply to the firstprivate clause.
+    //
+    // OpenMP 3.1 [2.9.3.3, private clause, Restrictions]
+    // A variable that appears in a private clause must not have a
+    // const-qualified type unless it is of class type with a mutable member.
+    if (rejectConstNotMutableType(*this, D, OMPC_private, ELoc))
+      continue;
+
     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
     // in a Construct]
     //  Variables with the predetermined data-sharing attributes may not be
@@ -10212,6 +10254,17 @@ OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef VarList,
       continue;
     Type = Type.getNonReferenceType();
 
+    // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
+    // A variable that is privatized must not have a const-qualified type
+    // unless it is of class type with a mutable member. This restriction does
+    // not apply to the firstprivate clause.
+    //
+    // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions]
+    // A variable that appears in a lastprivate clause must not have a
+    // const-qualified type unless it is of class type with a mutable member.
+    if (rejectConstNotMutableType(*this, D, OMPC_lastprivate, ELoc))
+      continue;
+
     OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
     // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
     // in a Construct]
diff --git a/test/OpenMP/distribute_parallel_for_lastprivate_messages.cpp b/test/OpenMP/distribute_parallel_for_lastprivate_messages.cpp
index 655d7117d5..8d93fbbee6 100644
--- a/test/OpenMP/distribute_parallel_for_lastprivate_messages.cpp
+++ b/test/OpenMP/distribute_parallel_for_lastprivate_messages.cpp
@@ -20,7 +20,7 @@ public:
   const S2 &operator =(const S2&) const;
   S2 &operator =(const S2&);
   static float S2s; // expected-note {{static data member is predetermined as shared}}
-  static const float S2sc; // expected-note {{static data member is predetermined as shared}}
+  static const float S2sc; // expected-note {{'S2sc' declared here}}
 };
 const float S2::S2sc = 0;
 const S2 b;
@@ -33,9 +33,9 @@ public:
   S3() : a(0) {}
   S3(S3 &s3) : a(s3.a) {}
 };
-const S3 c;         // expected-note {{global variable is predetermined as shared}}
-const S3 ca[5];     // expected-note {{global variable is predetermined as shared}}
-extern const int f; // expected-note {{global variable is predetermined as shared}}
+const S3 c;         // expected-note {{'c' defined here}}
+const S3 ca[5];     // expected-note {{'ca' defined here}}
+extern const int f; // expected-note {{'f' declared here}}
 class S4 {
   int a;
   S4();             // expected-note 3 {{implicitly declared private here}}
@@ -171,8 +171,8 @@ using A::x;
 }
 
 int main(int argc, char **argv) {
-  const int d = 5;       // expected-note {{constant variable is predetermined as shared}}
-  const int da[5] = {0}; // expected-note {{constant variable is predetermined as shared}}
+  const int d = 5;       // expected-note {{'d' defined here}}
+  const int da[5] = {0}; // expected-note {{'da' defined here}}
   S4 e(4);
   S5 g(5);
   S3 m;
@@ -221,7 +221,7 @@ int main(int argc, char **argv) {
     foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute parallel for lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be lastprivate}} expected-error {{incomplete type 'S1' where a complete type is required}} expected-warning {{Non-trivial type 'const S2' is mapped, only trivial types are guaranteed to be mapped correctly}} expected-warning {{Non-trivial type 'const S3' is mapped, only trivial types are guaranteed to be mapped correctly}}
+#pragma omp distribute parallel for lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 1 {{const-qualified variable without mutable fields cannot be lastprivate}} expected-error 2 {{const-qualified variable cannot be lastprivate}} expected-error {{incomplete type 'S1' where a complete type is required}} expected-warning {{Non-trivial type 'const S2' is mapped, only trivial types are guaranteed to be mapped correctly}} expected-warning {{Non-trivial type 'const S3' is mapped, only trivial types are guaranteed to be mapped correctly}}
   for (i = 0; i < argc; ++i)
     foo();
 #pragma omp target
@@ -241,12 +241,12 @@ int main(int argc, char **argv) {
     foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute parallel for lastprivate(ca) // expected-error {{shared variable cannot be lastprivate}} expected-warning {{Non-trivial type 'const S3 [5]' is mapped, only trivial types are guaranteed to be mapped correctly}}
+#pragma omp distribute parallel for lastprivate(ca) // expected-error {{const-qualified variable without mutable fields cannot be lastprivate}} expected-warning {{Non-trivial type 'const S3 [5]' is mapped, only trivial types are guaranteed to be mapped correctly}}
   for (i = 0; i < argc; ++i)
     foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute parallel for lastprivate(da) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp distribute parallel for lastprivate(da) // expected-error {{const-qualified variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i)
     foo();
   int xa;
@@ -262,7 +262,7 @@ int main(int argc, char **argv) {
     foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute parallel for lastprivate(S2::S2sc) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp distribute parallel for lastprivate(S2::S2sc) // expected-error {{const-qualified variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i)
     foo();
 #pragma omp target
diff --git a/test/OpenMP/distribute_parallel_for_simd_lastprivate_messages.cpp b/test/OpenMP/distribute_parallel_for_simd_lastprivate_messages.cpp
index 58bc1fcd6a..e7f2b7da3f 100644
--- a/test/OpenMP/distribute_parallel_for_simd_lastprivate_messages.cpp
+++ b/test/OpenMP/distribute_parallel_for_simd_lastprivate_messages.cpp
@@ -20,7 +20,7 @@ public:
   const S2 &operator =(const S2&) const;
   S2 &operator =(const S2&);
   static float S2s; // expected-note {{static data member is predetermined as shared}}
-  static const float S2sc; // expected-note {{static data member is predetermined as shared}}
+  static const float S2sc; // expected-note {{'S2sc' declared here}}
 };
 const float S2::S2sc = 0;
 const S2 b;
@@ -33,9 +33,9 @@ public:
   S3() : a(0) {}
   S3(S3 &s3) : a(s3.a) {}
 };
-const S3 c;         // expected-note {{global variable is predetermined as shared}}
-const S3 ca[5];     // expected-note {{global variable is predetermined as shared}}
-extern const int f; // expected-note {{global variable is predetermined as shared}}
+const S3 c;         // expected-note {{'c' defined here}}
+const S3 ca[5];     // expected-note {{'ca' defined here}}
+extern const int f; // expected-note {{'f' declared here}}
 class S4 {
   int a;
   S4();             // expected-note 3 {{implicitly declared private here}}
@@ -171,8 +171,8 @@ using A::x;
 }
 
 int main(int argc, char **argv) {
-  const int d = 5;       // expected-note {{constant variable is predetermined as shared}}
-  const int da[5] = {0}; // expected-note {{constant variable is predetermined as shared}}
+  const int d = 5;       // expected-note {{'d' defined here}}
+  const int da[5] = {0}; // expected-note {{'da' defined here}}
   S4 e(4);
   S5 g(5);
   S3 m;
@@ -221,7 +221,7 @@ int main(int argc, char **argv) {
     foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute parallel for simd lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be lastprivate}} expected-error {{incomplete type 'S1' where a complete type is required}}
+#pragma omp distribute parallel for simd lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 1 {{const-qualified variable without mutable fields cannot be lastprivate}} expected-error 2 {{const-qualified variable cannot be lastprivate}} expected-error {{incomplete type 'S1' where a complete type is required}}
   for (i = 0; i < argc; ++i)
     foo();
 #pragma omp target
@@ -241,12 +241,12 @@ int main(int argc, char **argv) {
     foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute parallel for simd lastprivate(ca) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp distribute parallel for simd lastprivate(ca) // expected-error {{const-qualified variable without mutable fields cannot be lastprivate}}
   for (i = 0; i < argc; ++i)
     foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute parallel for simd lastprivate(da) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp distribute parallel for simd lastprivate(da) // expected-error {{const-qualified variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i)
     foo();
   int xa;
@@ -262,7 +262,7 @@ int main(int argc, char **argv) {
     foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute parallel for simd lastprivate(S2::S2sc) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp distribute parallel for simd lastprivate(S2::S2sc) // expected-error {{const-qualified variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i)
     foo();
 #pragma omp target
diff --git a/test/OpenMP/distribute_private_messages.cpp b/test/OpenMP/distribute_private_messages.cpp
index 3cf2fdc228..55c13a00bb 100644
--- a/test/OpenMP/distribute_private_messages.cpp
+++ b/test/OpenMP/distribute_private_messages.cpp
@@ -24,9 +24,9 @@ class S3 {
 public:
   S3():a(0) { }
 };
-const S3 c; // expected-note {{predetermined as shared}}
-const S3 ca[5]; // expected-note {{predetermined as shared}}
-extern const int f;  // expected-note {{predetermined as shared}}
+const S3 c; // expected-note {{'c' defined here}}
+const S3 ca[5]; // expected-note {{'ca' defined here}}
+extern const int f;  // expected-note {{'f' declared here}}
 class S4 {
   int a;
   S4(); // expected-note {{implicitly declared private here}}
@@ -45,8 +45,8 @@ S3 h;
 
 
 int main(int argc, char **argv) {
-  const int d = 5;  // expected-note {{predetermined as shared}}
-  const int da[5] = { 0 }; // expected-note {{predetermined as shared}}
+  const int d = 5;  // expected-note {{'d' defined here}}
+  const int da[5] = { 0 }; // expected-note {{'da' defined here}}
   S4 e(4);
   S5 g(5);
   int i;
@@ -67,15 +67,15 @@ int main(int argc, char **argv) {
   for (int k = 0; k < argc; ++k) ++k;
   #pragma omp distribute private (S1) // expected-error {{'S1' does not refer to a value}}
   for (int k = 0; k < argc; ++k) ++k;
-  #pragma omp distribute private (a, b, c, d, f) // expected-error {{private variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be private}}
+  #pragma omp distribute private (a, b, c, d, f) // expected-error {{private variable with incomplete type 'S1'}} expected-error 1 {{const-qualified variable without mutable fields cannot be private}} expected-error 2 {{const-qualified variable cannot be private}}
   for (int k = 0; k < argc; ++k) ++k;
   #pragma omp distribute private (argv[1]) // expected-error {{expected variable name}}
   for (int k = 0; k < argc; ++k) ++k;
   #pragma omp distribute private(ba)
   for (int k = 0; k < argc; ++k) ++k;
-  #pragma omp distribute private(ca) // expected-error {{shared variable cannot be private}}
+  #pragma omp distribute private(ca) // expected-error {{const-qualified variable without mutable fields cannot be private}}
   for (int k = 0; k < argc; ++k) ++k;
-  #pragma omp distribute private(da) // expected-error {{shared variable cannot be private}}
+  #pragma omp distribute private(da) // expected-error {{const-qualified variable cannot be private}}
   for (int k = 0; k < argc; ++k) ++k;
   #pragma omp distribute private(S2::S2s) // expected-error {{shared variable cannot be private}}
   for (int k = 0; k < argc; ++k) ++k;
diff --git a/test/OpenMP/distribute_simd_lastprivate_messages.cpp b/test/OpenMP/distribute_simd_lastprivate_messages.cpp
index ec99d9e612..875210ed49 100644
--- a/test/OpenMP/distribute_simd_lastprivate_messages.cpp
+++ b/test/OpenMP/distribute_simd_lastprivate_messages.cpp
@@ -20,7 +20,7 @@ public:
   const S2 &operator =(const S2&) const;
   S2 &operator =(const S2&);
   static float S2s; // expected-note {{static data member is predetermined as shared}}
-  static const float S2sc; // expected-note {{static data member is predetermined as shared}}
+  static const float S2sc; // expected-note {{'S2sc' declared here}}
 };
 const float S2::S2sc = 0;
 const S2 b;
@@ -33,9 +33,9 @@ public:
   S3() : a(0) {}
   S3(S3 &s3) : a(s3.a) {}
 };
-const S3 c;         // expected-note {{global variable is predetermined as shared}}
-const S3 ca[5];     // expected-note {{global variable is predetermined as shared}}
-extern const int f; // expected-note {{global variable is predetermined as shared}}
+const S3 c;         // expected-note {{'c' defined here}}
+const S3 ca[5];     // expected-note {{'ca' defined here}}
+extern const int f; // expected-note {{'f' declared here}}
 class S4 {
   int a;
   S4();             // expected-note 3 {{implicitly declared private here}}
@@ -171,8 +171,8 @@ using A::x;
 }
 
 int main(int argc, char **argv) {
-  const int d = 5;       // expected-note {{constant variable is predetermined as shared}}
-  const int da[5] = {0}; // expected-note {{constant variable is predetermined as shared}}
+  const int d = 5;       // expected-note {{'d' defined here}}
+  const int da[5] = {0}; // expected-note {{'da' defined here}}
   S4 e(4);
   S5 g(5);
   S3 m;
@@ -221,7 +221,7 @@ int main(int argc, char **argv) {
     foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute simd lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be lastprivate}} expected-error {{incomplete type 'S1' where a complete type is required}} expected-warning {{Non-trivial type 'const S2' is mapped, only trivial types are guaranteed to be mapped correctly}} expected-warning {{Non-trivial type 'const S3' is mapped, only trivial types are guaranteed to be mapped correctly}}
+#pragma omp distribute simd lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 1 {{const-qualified variable without mutable fields cannot be lastprivate}} expected-error 2 {{const-qualified variable cannot be lastprivate}} expected-error {{incomplete type 'S1' where a complete type is required}} expected-warning {{Non-trivial type 'const S2' is mapped, only trivial types are guaranteed to be mapped correctly}} expected-warning {{Non-trivial type 'const S3' is mapped, only trivial types are guaranteed to be mapped correctly}}
   for (i = 0; i < argc; ++i)
     foo();
 #pragma omp target
@@ -241,12 +241,12 @@ int main(int argc, char **argv) {
     foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute simd lastprivate(ca) // expected-error {{shared variable cannot be lastprivate}} expected-warning {{Non-trivial type 'const S3 [5]' is mapped, only trivial types are guaranteed to be mapped correctly}}
+#pragma omp distribute simd lastprivate(ca) // expected-error {{const-qualified variable without mutable fields cannot be lastprivate}} expected-warning {{Non-trivial type 'const S3 [5]' is mapped, only trivial types are guaranteed to be mapped correctly}}
   for (i = 0; i < argc; ++i)
     foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute simd lastprivate(da) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp distribute simd lastprivate(da) // expected-error {{const-qualified variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i)
     foo();
   int xa;
@@ -262,7 +262,7 @@ int main(int argc, char **argv) {
     foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute simd lastprivate(S2::S2sc) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp distribute simd lastprivate(S2::S2sc) // expected-error {{const-qualified variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i)
     foo();
 #pragma omp target
diff --git a/test/OpenMP/for_lastprivate_messages.cpp b/test/OpenMP/for_lastprivate_messages.cpp
index 7787ab12d4..1777335c9a 100644
--- a/test/OpenMP/for_lastprivate_messages.cpp
+++ b/test/OpenMP/for_lastprivate_messages.cpp
@@ -20,7 +20,7 @@ public:
   const S2 &operator =(const S2&) const;
   S2 &operator =(const S2&);
   static float S2s; // expected-note {{static data member is predetermined as shared}}
-  static const float S2sc; // expected-note {{static data member is predetermined as shared}}
+  static const float S2sc; // expected-note {{'S2sc' declared here}}
 };
 const float S2::S2sc = 0;
 const S2 b;
@@ -33,9 +33,9 @@ public:
   S3() : a(0) {}
   S3(S3 &s3) : a(s3.a) {}
 };
-const S3 c;         // expected-note {{global variable is predetermined as shared}}
-const S3 ca[5];     // expected-note {{global variable is predetermined as shared}}
-extern const int f; // expected-note {{global variable is predetermined as shared}}
+const S3 c;         // expected-note {{'c' defined here}}
+const S3 ca[5];     // expected-note {{'ca' defined here}}
+extern const int f; // expected-note {{'f' declared here}}
 class S4 {
   int a;
   S4();             // expected-note 3 {{implicitly declared private here}}
@@ -156,8 +156,8 @@ using A::x;
 }
 
 int main(int argc, char **argv) {
-  const int d = 5;       // expected-note {{constant variable is predetermined as shared}}
-  const int da[5] = {0}; // expected-note {{constant variable is predetermined as shared}}
+  const int d = 5;       // expected-note {{'d' defined here}}
+  const int da[5] = {0}; // expected-note {{'da' defined here}}
   S4 e(4);
   S5 g(5);
   S3 m;
@@ -197,7 +197,7 @@ int main(int argc, char **argv) {
   for (i = 0; i < argc; ++i)
     foo();
 #pragma omp parallel
-#pragma omp for lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be lastprivate}}
+#pragma omp for lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 1 {{const-qualified variable without mutable fields cannot be lastprivate}} expected-error 2 {{const-qualified variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i)
     foo();
 #pragma omp parallel
@@ -213,11 +213,11 @@ int main(int argc, char **argv) {
   for (i = 0; i < argc; ++i)
     foo();
 #pragma omp parallel
-#pragma omp for lastprivate(ca) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp for lastprivate(ca) // expected-error {{const-qualified variable without mutable fields cannot be lastprivate}}
   for (i = 0; i < argc; ++i)
     foo();
 #pragma omp parallel
-#pragma omp for lastprivate(da) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp for lastprivate(da) // expected-error {{const-qualified variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i)
     foo();
   int xa;
@@ -230,7 +230,7 @@ int main(int argc, char **argv) {
   for (i = 0; i < argc; ++i)
     foo();
 #pragma omp parallel
-#pragma omp for lastprivate(S2::S2sc) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp for lastprivate(S2::S2sc) // expected-error {{const-qualified variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i)
     foo();
 #pragma omp parallel
diff --git a/test/OpenMP/for_simd_lastprivate_messages.cpp b/test/OpenMP/for_simd_lastprivate_messages.cpp
index 9ed2232d6a..a4bed93365 100644
--- a/test/OpenMP/for_simd_lastprivate_messages.cpp
+++ b/test/OpenMP/for_simd_lastprivate_messages.cpp
@@ -20,7 +20,7 @@ public:
   S2 &operator =(const S2&);
   const S2 &operator =(const S2&) const;
   static float S2s; // expected-note {{static data member is predetermined as shared}}
-  static const float S2sc; // expected-note {{static data member is predetermined as shared}}
+  static const float S2sc; // expected-note {{'S2sc' declared here}}
 };
 const float S2::S2sc = 0;
 const S2 b;
@@ -33,9 +33,9 @@ public:
   S3() : a(0) {}
   S3(S3 &s3) : a(s3.a) {}
 };
-const S3 c;         // expected-note {{global variable is predetermined as shared}}
-const S3 ca[5];     // expected-note {{global variable is predetermined as shared}}
-extern const int f; // expected-note {{global variable is predetermined as shared}}
+const S3 c;         // expected-note {{'c' defined here}}
+const S3 ca[5];     // expected-note {{'ca' defined here}}
+extern const int f; // expected-note {{'f' declared here}}
 class S4 {
   int a;
   S4();             // expected-note 3 {{implicitly declared private here}}
@@ -153,8 +153,8 @@ using A::x;
 }
 
 int main(int argc, char **argv) {
-  const int d = 5;       // expected-note {{constant variable is predetermined as shared}}
-  const int da[5] = {0}; // expected-note {{constant variable is predetermined as shared}}
+  const int d = 5;       // expected-note {{'d' defined here}}
+  const int da[5] = {0}; // expected-note {{'da' defined here}}
   S4 e(4);
   S5 g(5);
   S3 m;
@@ -194,7 +194,7 @@ int main(int argc, char **argv) {
   for (i = 0; i < argc; ++i)
     foo();
 #pragma omp parallel
-#pragma omp for simd lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be lastprivate}}
+#pragma omp for simd lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 1 {{const-qualified variable without mutable fields cannot be lastprivate}} expected-error 2 {{const-qualified variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i)
     foo();
 #pragma omp parallel
@@ -210,11 +210,11 @@ int main(int argc, char **argv) {
   for (i = 0; i < argc; ++i)
     foo();
 #pragma omp parallel
-#pragma omp for simd lastprivate(ca) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp for simd lastprivate(ca) // expected-error {{const-qualified variable without mutable fields cannot be lastprivate}}
   for (i = 0; i < argc; ++i)
     foo();
 #pragma omp parallel
-#pragma omp for simd lastprivate(da) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp for simd lastprivate(da) // expected-error {{const-qualified variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i)
     foo();
   int xa;
@@ -227,7 +227,7 @@ int main(int argc, char **argv) {
   for (i = 0; i < argc; ++i)
     foo();
 #pragma omp parallel
-#pragma omp for simd lastprivate(S2::S2sc) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp for simd lastprivate(S2::S2sc) // expected-error {{const-qualified variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i)
     foo();
 #pragma omp parallel
diff --git a/test/OpenMP/parallel_default_messages.cpp b/test/OpenMP/parallel_default_messages.cpp
index 8b1781bdca..eb4b378f0d 100644
--- a/test/OpenMP/parallel_default_messages.cpp
+++ b/test/OpenMP/parallel_default_messages.cpp
@@ -1,10 +1,15 @@
 // RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - %s
-
-// RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 -o - %s
+// RUN: %clang_cc1 -verify=expected,ge40 -fopenmp-simd -ferror-limit 100 -o - %s
+// RUN: %clang_cc1 -verify=expected,ge40 -fopenmp-version=50 -fopenmp -ferror-limit 100 -o - %s
+// RUN: %clang_cc1 -verify=expected,ge40 -fopenmp-version=40 -fopenmp -ferror-limit 100 -o - %s
+// RUN: %clang_cc1 -verify -fopenmp-version=31 -fopenmp -ferror-limit 100 -o - %s
+// RUN: %clang_cc1 -verify -fopenmp-version=30 -fopenmp -ferror-limit 100 -o - %s
 
 void foo();
 
 int main(int argc, char **argv) {
+  const int c = 0;
+
   #pragma omp parallel default // expected-error {{expected '(' after 'default'}}
   #pragma omp parallel default ( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
   #pragma omp parallel default () // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}}
@@ -19,5 +24,8 @@ int main(int argc, char **argv) {
   #pragma omp parallel default(none)
   #pragma omp parallel default(shared)
   ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
+
+  #pragma omp parallel default(none)
+  (void)c; // ge40-error {{variable 'c' must have explicitly specified data sharing attributes}}
   return 0;
 }
diff --git a/test/OpenMP/parallel_for_lastprivate_messages.cpp b/test/OpenMP/parallel_for_lastprivate_messages.cpp
index 8d2f4b5886..ae635f3421 100644
--- a/test/OpenMP/parallel_for_lastprivate_messages.cpp
+++ b/test/OpenMP/parallel_for_lastprivate_messages.cpp
@@ -20,7 +20,7 @@ public:
   S2 &operator=(const S2 &);
   const S2 &operator=(const S2 &) const;
   static float S2s; // expected-note {{static data member is predetermined as shared}}
-  static const float S2sc; // expected-note {{static data member is predetermined as shared}}
+  static const float S2sc; // expected-note {{'S2sc' declared here}}
 };
 const float S2::S2sc = 0;
 const S2 b;
@@ -33,9 +33,9 @@ public:
   S3() : a(0) {}
   S3(S3 &s3) : a(s3.a) {}
 };
-const S3 c;         // expected-note {{global variable is predetermined as shared}}
-const S3 ca[5];     // expected-note {{global variable is predetermined as shared}}
-extern const int f; // expected-note {{global variable is predetermined as shared}}
+const S3 c;         // expected-note {{'c' defined here}}
+const S3 ca[5];     // expected-note {{'ca' defined here}}
+extern const int f; // expected-note {{'f' declared here}}
 class S4 {
   int a;
   S4();             // expected-note 3 {{implicitly declared private here}}
@@ -136,8 +136,8 @@ using A::x;
 }
 
 int main(int argc, char **argv) {
-  const int d = 5;       // expected-note {{constant variable is predetermined as shared}}
-  const int da[5] = {0}; // expected-note {{constant variable is predetermined as shared}}
+  const int d = 5;       // expected-note {{'d' defined here}}
+  const int da[5] = {0}; // expected-note {{'da' defined here}}
   S4 e(4);
   S5 g(5);
   S3 m;
@@ -168,7 +168,7 @@ int main(int argc, char **argv) {
 #pragma omp parallel for lastprivate(S1) // expected-error {{'S1' does not refer to a value}}
   for (i = 0; i < argc; ++i)
     foo();
-#pragma omp parallel for lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be lastprivate}}
+#pragma omp parallel for lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 1 {{const-qualified variable without mutable fields cannot be lastprivate}} expected-error 2 {{const-qualified variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i)
     foo();
 #pragma omp parallel for lastprivate(argv[1]) // expected-error {{expected variable name}}
@@ -180,10 +180,10 @@ int main(int argc, char **argv) {
 #pragma omp parallel for lastprivate(ba)
   for (i = 0; i < argc; ++i)
     foo();
-#pragma omp parallel for lastprivate(ca) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp parallel for lastprivate(ca) // expected-error {{const-qualified variable without mutable fields cannot be lastprivate}}
   for (i = 0; i < argc; ++i)
     foo();
-#pragma omp parallel for lastprivate(da) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp parallel for lastprivate(da) // expected-error {{const-qualified variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i)
     foo();
   int xa;
@@ -193,7 +193,7 @@ int main(int argc, char **argv) {
 #pragma omp parallel for lastprivate(S2::S2s) // expected-error {{shared variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i)
     foo();
-#pragma omp parallel for lastprivate(S2::S2sc) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp parallel for lastprivate(S2::S2sc) // expected-error {{const-qualified variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i)
     foo();
 #pragma omp parallel for safelen(5) // expected-error {{unexpected OpenMP clause 'safelen' in directive '#pragma omp parallel for'}}
diff --git a/test/OpenMP/parallel_for_simd_lastprivate_messages.cpp b/test/OpenMP/parallel_for_simd_lastprivate_messages.cpp
index 84e0896f1f..5759e835b2 100644
--- a/test/OpenMP/parallel_for_simd_lastprivate_messages.cpp
+++ b/test/OpenMP/parallel_for_simd_lastprivate_messages.cpp
@@ -19,7 +19,7 @@ public:
   S2(S2 &s2) : a(s2.a) {}
   const S2 &operator=(const S2 &) const;
   static float S2s; // expected-note {{static data member is predetermined as shared}}
-  static const float S2sc; // expected-note {{static data member is predetermined as shared}}
+  static const float S2sc; // expected-note {{'S2sc' declared here}}
 };
 const float S2::S2sc = 0;
 const S2 b;
@@ -32,9 +32,9 @@ public:
   S3() : a(0) {}
   S3(S3 &s3) : a(s3.a) {}
 };
-const S3 c;         // expected-note {{global variable is predetermined as shared}}
-const S3 ca[5];     // expected-note {{global variable is predetermined as shared}}
-extern const int f; // expected-note {{global variable is predetermined as shared}}
+const S3 c;         // expected-note {{'c' defined here}}
+const S3 ca[5];     // expected-note {{'ca' defined here}}
+extern const int f; // expected-note {{'f' declared here}}
 class S4 {
   int a;
   S4();          // expected-note 3 {{implicitly declared private here}}
@@ -138,8 +138,8 @@ using A::x;
 }
 
 int main(int argc, char **argv) {
-  const int d = 5;       // expected-note {{constant variable is predetermined as shared}}
-  const int da[5] = {0}; // expected-note {{constant variable is predetermined as shared}}
+  const int d = 5;       // expected-note {{'d' defined here}}
+  const int da[5] = {0}; // expected-note {{'da' defined here}}
   S4 e(4);
   S5 g(5);
   S3 m;
@@ -170,7 +170,7 @@ int main(int argc, char **argv) {
 #pragma omp parallel for simd lastprivate(S1) // expected-error {{'S1' does not refer to a value}}
   for (i = 0; i < argc; ++i)
     foo();
-#pragma omp parallel for simd lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be lastprivate}}
+#pragma omp parallel for simd lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 1 {{const-qualified variable without mutable fields cannot be lastprivate}} expected-error 2 {{const-qualified variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i)
     foo();
 #pragma omp parallel for simd lastprivate(argv[1]) // expected-error {{expected variable name}}
@@ -182,10 +182,10 @@ int main(int argc, char **argv) {
 #pragma omp parallel for simd lastprivate(ba)
   for (i = 0; i < argc; ++i)
     foo();
-#pragma omp parallel for simd lastprivate(ca) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp parallel for simd lastprivate(ca) // expected-error {{const-qualified variable without mutable fields cannot be lastprivate}}
   for (i = 0; i < argc; ++i)
     foo();
-#pragma omp parallel for simd lastprivate(da) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp parallel for simd lastprivate(da) // expected-error {{const-qualified variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i)
     foo();
   int xa;
@@ -195,7 +195,7 @@ int main(int argc, char **argv) {
 #pragma omp parallel for simd lastprivate(S2::S2s) // expected-error {{shared variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i)
     foo();
-#pragma omp parallel for simd lastprivate(S2::S2sc) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp parallel for simd lastprivate(S2::S2sc) // expected-error {{const-qualified variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i)
     foo();
 #pragma omp parallel for simd safelen(5)
diff --git a/test/OpenMP/parallel_private_messages.cpp b/test/OpenMP/parallel_private_messages.cpp
index 4adee55e34..e8fd70d2ff 100644
--- a/test/OpenMP/parallel_private_messages.cpp
+++ b/test/OpenMP/parallel_private_messages.cpp
@@ -24,9 +24,9 @@ class S3 {
 public:
   S3():a(0) { }
 };
-const S3 c; // expected-note {{global variable is predetermined as shared}}
-const S3 ca[5]; // expected-note {{global variable is predetermined as shared}}
-extern const int f; // expected-note {{global variable is predetermined as shared}}
+const S3 c; // expected-note {{'c' defined here}}
+const S3 ca[5]; // expected-note {{'ca' defined here}}
+extern const int f; // expected-note {{'f' declared here}}
 class S4 {
   int a;
   S4(); // expected-note {{implicitly declared private here}}
@@ -52,8 +52,8 @@ using A::x;
 }
 
 int main(int argc, char **argv) {
-  const int d = 5; // expected-note {{constant variable is predetermined as shared}}
-  const int da[5] = { 0 }; // expected-note {{constant variable is predetermined as shared}}
+  const int d = 5; // expected-note {{'d' defined here}}
+  const int da[5] = { 0 }; // expected-note {{'da' defined here}}
   S4 e(4);
   S5 g[] = {5, 6};
   int i;
@@ -66,11 +66,11 @@ int main(int argc, char **argv) {
   #pragma omp parallel private (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
   #pragma omp parallel private (argc argv) // expected-error {{expected ',' or ')' in 'private' clause}}
   #pragma omp parallel private (S1) // expected-error {{'S1' does not refer to a value}}
-  #pragma omp parallel private (a, b, c, d, f) // expected-error {{a private variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be private}}
+  #pragma omp parallel private (a, b, c, d, f) // expected-error {{a private variable with incomplete type 'S1'}} expected-error 1 {{const-qualified variable without mutable fields cannot be private}} expected-error 2 {{const-qualified variable cannot be private}}
   #pragma omp parallel private (argv[1]) // expected-error {{expected variable name}}
   #pragma omp parallel private(ba)
-  #pragma omp parallel private(ca) // expected-error {{shared variable cannot be private}}
-  #pragma omp parallel private(da) // expected-error {{shared variable cannot be private}}
+  #pragma omp parallel private(ca) // expected-error {{const-qualified variable without mutable fields cannot be private}}
+  #pragma omp parallel private(da) // expected-error {{const-qualified variable cannot be private}}
   #pragma omp parallel private(S2::S2s) // expected-error {{shared variable cannot be private}}
   #pragma omp parallel private(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}}
   #pragma omp parallel private(threadvar, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be private}}
diff --git a/test/OpenMP/parallel_sections_lastprivate_messages.cpp b/test/OpenMP/parallel_sections_lastprivate_messages.cpp
index 865dda01a3..25ea4a51dd 100644
--- a/test/OpenMP/parallel_sections_lastprivate_messages.cpp
+++ b/test/OpenMP/parallel_sections_lastprivate_messages.cpp
@@ -19,7 +19,7 @@ public:
   S2(S2 &s2) : a(s2.a) {}
   const S2 &operator=(const S2 &) const;
   static float S2s; // expected-note {{static data member is predetermined as shared}}
-  static const float S2sc; // expected-note {{static data member is predetermined as shared}}
+  static const float S2sc; // expected-note {{'S2sc' declared here}}
 };
 const float S2::S2sc = 0;
 const S2 b;
@@ -32,9 +32,9 @@ public:
   S3() : a(0) {}
   S3(S3 &s3) : a(s3.a) {}
 };
-const S3 c;         // expected-note {{global variable is predetermined as shared}}
-const S3 ca[5];     // expected-note {{global variable is predetermined as shared}}
-extern const int f; // expected-note {{global variable is predetermined as shared}}
+const S3 c;         // expected-note {{'c' defined here}}
+const S3 ca[5];     // expected-note {{'ca' defined here}}
+extern const int f; // expected-note {{'f' declared here}}
 class S4 {
   int a;
   S4();             // expected-note 3 {{implicitly declared private here}}
@@ -153,8 +153,8 @@ using A::x;
 }
 
 int main(int argc, char **argv) {
-  const int d = 5;       // expected-note {{constant variable is predetermined as shared}}
-  const int da[5] = {0}; // expected-note {{constant variable is predetermined as shared}}
+  const int d = 5;       // expected-note {{'d' defined here}}
+  const int da[5] = {0}; // expected-note {{'da' defined here}}
   S4 e(4);
   S5 g(5);
   S3 m;
@@ -193,7 +193,7 @@ int main(int argc, char **argv) {
   {
     foo();
   }
-#pragma omp parallel sections lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be lastprivate}}
+#pragma omp parallel sections lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 1 {{const-qualified variable without mutable fields cannot be lastprivate}} expected-error 2 {{const-qualified variable cannot be lastprivate}}
   {
     foo();
   }
@@ -209,11 +209,11 @@ int main(int argc, char **argv) {
   {
     foo();
   }
-#pragma omp parallel sections lastprivate(ca) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp parallel sections lastprivate(ca) // expected-error {{const-qualified variable without mutable fields cannot be lastprivate}}
   {
     foo();
   }
-#pragma omp parallel sections lastprivate(da) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp parallel sections lastprivate(da) // expected-error {{const-qualified variable cannot be lastprivate}}
   {
     foo();
   }
@@ -226,7 +226,7 @@ int main(int argc, char **argv) {
   {
     foo();
   }
-#pragma omp parallel sections lastprivate(S2::S2sc) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp parallel sections lastprivate(S2::S2sc) // expected-error {{const-qualified variable cannot be lastprivate}}
   {
     foo();
   }
diff --git a/test/OpenMP/sections_lastprivate_messages.cpp b/test/OpenMP/sections_lastprivate_messages.cpp
index e24b58fa29..1f73260541 100644
--- a/test/OpenMP/sections_lastprivate_messages.cpp
+++ b/test/OpenMP/sections_lastprivate_messages.cpp
@@ -19,7 +19,7 @@ public:
   S2(S2 &s2) : a(s2.a) {}
   const S2 &operator=(const S2 &) const;
   static float S2s; // expected-note {{static data member is predetermined as shared}}
-  static const float S2sc; // expected-note {{static data member is predetermined as shared}}
+  static const float S2sc; // expected-note {{'S2sc' declared here}}
 };
 const float S2::S2sc = 0;
 const S2 b;
@@ -32,9 +32,9 @@ public:
   S3() : a(0) {}
   S3(S3 &s3) : a(s3.a) {}
 };
-const S3 c;         // expected-note {{global variable is predetermined as shared}}
-const S3 ca[5];     // expected-note {{global variable is predetermined as shared}}
-extern const int f; // expected-note {{global variable is predetermined as shared}}
+const S3 c;         // expected-note {{'c' defined here}}
+const S3 ca[5];     // expected-note {{'ca' defined here}}
+extern const int f; // expected-note {{'f' declared here}}
 class S4 {
   int a;
   S4();          // expected-note 3 {{implicitly declared private here}}
@@ -167,8 +167,8 @@ using A::x;
 }
 
 int main(int argc, char **argv) {
-  const int d = 5;       // expected-note {{constant variable is predetermined as shared}}
-  const int da[5] = {0}; // expected-note {{constant variable is predetermined as shared}}
+  const int d = 5;       // expected-note {{'d' defined here}}
+  const int da[5] = {0}; // expected-note {{'da' defined here}}
   S4 e(4);
   S5 g(5);
   S3 m;
@@ -216,7 +216,7 @@ int main(int argc, char **argv) {
     foo();
   }
 #pragma omp parallel
-#pragma omp sections lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be lastprivate}}
+#pragma omp sections lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 1 {{const-qualified variable without mutable fields cannot be lastprivate}} expected-error 2 {{const-qualified variable cannot be lastprivate}}
   {
     foo();
   }
@@ -236,12 +236,12 @@ int main(int argc, char **argv) {
     foo();
   }
 #pragma omp parallel
-#pragma omp sections lastprivate(ca) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp sections lastprivate(ca) // expected-error {{const-qualified variable without mutable fields cannot be lastprivate}}
   {
     foo();
   }
 #pragma omp parallel
-#pragma omp sections lastprivate(da) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp sections lastprivate(da) // expected-error {{const-qualified variable cannot be lastprivate}}
   {
     foo();
   }
@@ -257,7 +257,7 @@ int main(int argc, char **argv) {
     foo();
   }
 #pragma omp parallel
-#pragma omp sections lastprivate(S2::S2sc) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp sections lastprivate(S2::S2sc) // expected-error {{const-qualified variable cannot be lastprivate}}
   {
     foo();
   }
diff --git a/test/OpenMP/simd_lastprivate_messages.cpp b/test/OpenMP/simd_lastprivate_messages.cpp
index 0af812889c..bd5a237a60 100644
--- a/test/OpenMP/simd_lastprivate_messages.cpp
+++ b/test/OpenMP/simd_lastprivate_messages.cpp
@@ -19,7 +19,7 @@ public:
   S2(S2 &s2) : a(s2.a) {}
   const S2 &operator=(const S2 &) const;
   static float S2s; // expected-note {{static data member is predetermined as shared}}
-  static const float S2sc; // expected-note {{static data member is predetermined as shared}}
+  static const float S2sc; // expected-note {{'S2sc' declared here}}
 };
 const float S2::S2sc = 0;
 const S2 b;
@@ -32,9 +32,9 @@ public:
   S3() : a(0) {}
   S3(S3 &s3) : a(s3.a) {}
 };
-const S3 c;         // expected-note {{global variable is predetermined as shared}}
-const S3 ca[5];     // expected-note {{global variable is predetermined as shared}}
-extern const int f; // expected-note {{global variable is predetermined as shared}}
+const S3 c;         // expected-note {{'c' defined here}}
+const S3 ca[5];     // expected-note {{'ca' defined here}}
+extern const int f; // expected-note {{'f' declared here}}
 class S4 {
   int a;
   S4();          // expected-note {{implicitly declared private here}}
@@ -130,8 +130,8 @@ int foomain(I argc, C **argv) {
 }
 
 int main(int argc, char **argv) {
-  const int d = 5;       // expected-note {{constant variable is predetermined as shared}}
-  const int da[5] = {0}; // expected-note {{constant variable is predetermined as shared}}
+  const int d = 5;       // expected-note {{'d' defined here}}
+  const int da[5] = {0}; // expected-note {{'da' defined here}}
   S4 e(4);
   S5 g(5);
   S3 m;
@@ -161,7 +161,7 @@ int main(int argc, char **argv) {
 #pragma omp simd lastprivate(S1) // expected-error {{'S1' does not refer to a value}}
   for (i = 0; i < argc; ++i)
     foo();
-#pragma omp simd lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be lastprivate}}
+#pragma omp simd lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 1 {{const-qualified variable without mutable fields cannot be lastprivate}} expected-error 2 {{const-qualified variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i)
     foo();
 #pragma omp simd lastprivate(argv[1]) // expected-error {{expected variable name}}
@@ -173,10 +173,10 @@ int main(int argc, char **argv) {
 #pragma omp simd lastprivate(ba)
   for (i = 0; i < argc; ++i)
     foo();
-#pragma omp simd lastprivate(ca) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp simd lastprivate(ca) // expected-error {{const-qualified variable without mutable fields cannot be lastprivate}}
   for (i = 0; i < argc; ++i)
     foo();
-#pragma omp simd lastprivate(da) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp simd lastprivate(da) // expected-error {{const-qualified variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i)
     foo();
   int xa;
@@ -186,7 +186,7 @@ int main(int argc, char **argv) {
 #pragma omp simd lastprivate(S2::S2s) // expected-error {{shared variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i)
     foo();
-#pragma omp simd lastprivate(S2::S2sc) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp simd lastprivate(S2::S2sc) // expected-error {{const-qualified variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i)
     foo();
 #pragma omp simd firstprivate(g) // expected-error {{unexpected OpenMP clause 'firstprivate' in directive '#pragma omp simd'}}
diff --git a/test/OpenMP/target_parallel_for_lastprivate_messages.cpp b/test/OpenMP/target_parallel_for_lastprivate_messages.cpp
index 0ff2c722f7..7aff164b50 100644
--- a/test/OpenMP/target_parallel_for_lastprivate_messages.cpp
+++ b/test/OpenMP/target_parallel_for_lastprivate_messages.cpp
@@ -20,7 +20,7 @@ public:
   S2 &operator=(const S2 &);
   const S2 &operator=(const S2 &) const;
   static float S2s; // expected-note {{static data member is predetermined as shared}}
-  static const float S2sc; // expected-note {{static data member is predetermined as shared}}
+  static const float S2sc; // expected-note {{'S2sc' declared here}}
 };
 const float S2::S2sc = 0;
 const S2 b;
@@ -33,9 +33,9 @@ public:
   S3() : a(0) {}
   S3(S3 &s3) : a(s3.a) {}
 };
-const S3 c;         // expected-note {{global variable is predetermined as shared}}
-const S3 ca[5];     // expected-note {{global variable is predetermined as shared}}
-extern const int f; // expected-note {{global variable is predetermined as shared}}
+const S3 c;         // expected-note {{'c' defined here}}
+const S3 ca[5];     // expected-note {{'ca' defined here}}
+extern const int f; // expected-note {{'f' declared here}}
 class S4 {
   int a;
   S4();             // expected-note 3 {{implicitly declared private here}}
@@ -136,8 +136,8 @@ using A::x;
 }
 
 int main(int argc, char **argv) {
-  const int d = 5;       // expected-note {{constant variable is predetermined as shared}}
-  const int da[5] = {0}; // expected-note {{constant variable is predetermined as shared}}
+  const int d = 5;       // expected-note {{'d' defined here}}
+  const int da[5] = {0}; // expected-note {{'da' defined here}}
   S4 e(4);
   S5 g(5);
   S3 m;
@@ -168,7 +168,7 @@ int main(int argc, char **argv) {
 #pragma omp target parallel for lastprivate(S1) // expected-error {{'S1' does not refer to a value}}
   for (i = 0; i < argc; ++i)
     foo();
-#pragma omp target parallel for lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be lastprivate}}
+#pragma omp target parallel for lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 1 {{const-qualified variable without mutable fields cannot be lastprivate}} expected-error 2 {{const-qualified variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i)
     foo();
 #pragma omp target parallel for lastprivate(argv[1]) // expected-error {{expected variable name}}
@@ -180,10 +180,10 @@ int main(int argc, char **argv) {
 #pragma omp target parallel for lastprivate(ba)
   for (i = 0; i < argc; ++i)
     foo();
-#pragma omp target parallel for lastprivate(ca) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp target parallel for lastprivate(ca) // expected-error {{const-qualified variable without mutable fields cannot be lastprivate}}
   for (i = 0; i < argc; ++i)
     foo();
-#pragma omp target parallel for lastprivate(da) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp target parallel for lastprivate(da) // expected-error {{const-qualified variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i)
     foo();
   int xa;
@@ -193,7 +193,7 @@ int main(int argc, char **argv) {
 #pragma omp target parallel for lastprivate(S2::S2s) // expected-error {{shared variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i)
     foo();
-#pragma omp target parallel for lastprivate(S2::S2sc) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp target parallel for lastprivate(S2::S2sc) // expected-error {{const-qualified variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i)
     foo();
 #pragma omp target parallel for safelen(5) // expected-error {{unexpected OpenMP clause 'safelen' in directive '#pragma omp target parallel for'}}
diff --git a/test/OpenMP/target_parallel_for_simd_lastprivate_messages.cpp b/test/OpenMP/target_parallel_for_simd_lastprivate_messages.cpp
index 7c2c23f9d7..1c4d853431 100644
--- a/test/OpenMP/target_parallel_for_simd_lastprivate_messages.cpp
+++ b/test/OpenMP/target_parallel_for_simd_lastprivate_messages.cpp
@@ -20,7 +20,7 @@ public:
   S2 &operator=(const S2 &);
   const S2 &operator=(const S2 &) const;
   static float S2s; // expected-note {{static data member is predetermined as shared}}
-  static const float S2sc; // expected-note {{static data member is predetermined as shared}}
+  static const float S2sc; // expected-note {{'S2sc' declared here}}
 };
 const float S2::S2sc = 0;
 const S2 b;
@@ -33,9 +33,9 @@ public:
   S3() : a(0) {}
   S3(S3 &s3) : a(s3.a) {}
 };
-const S3 c;         // expected-note {{global variable is predetermined as shared}}
-const S3 ca[5];     // expected-note {{global variable is predetermined as shared}}
-extern const int f; // expected-note {{global variable is predetermined as shared}}
+const S3 c;         // expected-note {{'c' defined here}}
+const S3 ca[5];     // expected-note {{'ca' defined here}}
+extern const int f; // expected-note {{'f' declared here}}
 class S4 {
   int a;
   S4();             // expected-note 3 {{implicitly declared private here}}
@@ -136,8 +136,8 @@ using A::x;
 }
 
 int main(int argc, char **argv) {
-  const int d = 5;       // expected-note {{constant variable is predetermined as shared}}
-  const int da[5] = {0}; // expected-note {{constant variable is predetermined as shared}}
+  const int d = 5;       // expected-note {{'d' defined here}}
+  const int da[5] = {0}; // expected-note {{'da' defined here}}
   S4 e(4);
   S5 g(5);
   S3 m;
@@ -168,7 +168,7 @@ int main(int argc, char **argv) {
 #pragma omp target parallel for simd lastprivate(S1) // expected-error {{'S1' does not refer to a value}}
   for (i = 0; i < argc; ++i)
     foo();
-#pragma omp target parallel for simd lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be lastprivate}}
+#pragma omp target parallel for simd lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 1 {{const-qualified variable without mutable fields cannot be lastprivate}} expected-error 2 {{const-qualified variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i)
     foo();
 #pragma omp target parallel for simd lastprivate(argv[1]) // expected-error {{expected variable name}}
@@ -180,10 +180,10 @@ int main(int argc, char **argv) {
 #pragma omp target parallel for simd lastprivate(ba)
   for (i = 0; i < argc; ++i)
     foo();
-#pragma omp target parallel for simd lastprivate(ca) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp target parallel for simd lastprivate(ca) // expected-error {{const-qualified variable without mutable fields cannot be lastprivate}}
   for (i = 0; i < argc; ++i)
     foo();
-#pragma omp target parallel for simd lastprivate(da) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp target parallel for simd lastprivate(da) // expected-error {{const-qualified variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i)
     foo();
   int xa;
@@ -193,7 +193,7 @@ int main(int argc, char **argv) {
 #pragma omp target parallel for simd lastprivate(S2::S2s) // expected-error {{shared variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i)
     foo();
-#pragma omp target parallel for simd lastprivate(S2::S2sc) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp target parallel for simd lastprivate(S2::S2sc) // expected-error {{const-qualified variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i)
     foo();
 #pragma omp target parallel for simd safelen(5) // OK
diff --git a/test/OpenMP/target_parallel_private_messages.cpp b/test/OpenMP/target_parallel_private_messages.cpp
index 34652d6cb3..de71c03ad4 100644
--- a/test/OpenMP/target_parallel_private_messages.cpp
+++ b/test/OpenMP/target_parallel_private_messages.cpp
@@ -22,9 +22,9 @@ class S3 {
 public:
   S3() : a(0) {}
 };
-const S3 c; // expected-note {{global variable is predetermined as shared}} expected-note 1 {{global variable is predetermined as shared}}
-const S3 ca[5]; // expected-note {{global variable is predetermined as shared}} expected-note 1 {{global variable is predetermined as shared}}
-extern const int f; // expected-note {{global variable is predetermined as shared}} expected-note 1 {{global variable is predetermined as shared}} 
+const S3 c; // expected-note 2 {{'c' defined here}}
+const S3 ca[5]; // expected-note 2 {{'ca' defined here}}
+extern const int f; // expected-note 2 {{'f' declared here}}
 
 int threadvar;
 #pragma omp threadprivate(threadvar) // expected-note {{defined as threadprivate or thread local}} expected-note 1 {{defined as threadprivate or thread local}}
@@ -56,8 +56,8 @@ S3 h;
 
 template 
 int foomain(I argc, C **argv) {
-  const I d = 5; // expected-note {{constant variable is predetermined as shared}}
-  const I da[5] = { 0 }; // expected-note {{constant variable is predetermined as shared}}
+  const I d = 5; // expected-note {{'d' defined here}}
+  const I da[5] = { 0 }; // expected-note {{'da' defined here}}
   D e(4);
   E g[] = {5, 6};
   I i;
@@ -82,15 +82,15 @@ int foomain(I argc, C **argv) {
 {}
 #pragma omp target parallel private(a, b) // expected-error {{private variable with incomplete type 'S1'}}
 {}
-#pragma omp target parallel private (a, b, c, d, f) // expected-error {{a private variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be private}}
+#pragma omp target parallel private (a, b, c, d, f) // expected-error {{a private variable with incomplete type 'S1'}} expected-error 1 {{const-qualified variable without mutable fields cannot be private}} expected-error 2 {{const-qualified variable cannot be private}}
 {}
 #pragma omp target parallel private(argv[1]) // expected-error {{expected variable name}}
 {}
 #pragma omp target parallel private(ba)
 {}
-#pragma omp target parallel private(ca) // expected-error {{shared variable cannot be private}}
+#pragma omp target parallel private(ca) // expected-error {{const-qualified variable without mutable fields cannot be private}}
 {}
-#pragma omp target parallel private(da) // expected-error {{shared variable cannot be private}}
+#pragma omp target parallel private(da) // expected-error {{const-qualified variable cannot be private}}
 {}
 #pragma omp target parallel private(S2::S2s) // expected-error {{shared variable cannot be private}}
 {}
@@ -143,8 +143,8 @@ void bar(S4 a[2]) {
 }
 
 int main(int argc, char **argv) {
-  const int d = 5; // expected-note {{constant variable is predetermined as shared}}
-  const int da[5] = { 0 }; // expected-note {{constant variable is predetermined as shared}}
+  const int d = 5; // expected-note {{'d' defined here}}
+  const int da[5] = { 0 }; // expected-note {{'da' defined here}}
   S4 e(4);
   S5 g[] = {5, 6};
   int i;
@@ -169,15 +169,15 @@ int main(int argc, char **argv) {
 {}
 #pragma omp target parallel private(a, b) // expected-error {{private variable with incomplete type 'S1'}}
 {}
-#pragma omp target parallel private (a, b, c, d, f) // expected-error {{a private variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be private}}
+#pragma omp target parallel private (a, b, c, d, f) // expected-error {{a private variable with incomplete type 'S1'}} expected-error 1 {{const-qualified variable without mutable fields cannot be private}} expected-error 2 {{const-qualified variable cannot be private}}
 {}
 #pragma omp target parallel private(argv[1]) // expected-error {{expected variable name}}
 {}
 #pragma omp target parallel private(ba)
 {}
-#pragma omp target parallel private(ca) // expected-error {{shared variable cannot be private}}
+#pragma omp target parallel private(ca) // expected-error {{const-qualified variable without mutable fields cannot be private}}
 {}
-#pragma omp target parallel private(da) // expected-error {{shared variable cannot be private}}
+#pragma omp target parallel private(da) // expected-error {{const-qualified variable cannot be private}}
 {}
 #pragma omp target parallel private(S2::S2s) // expected-error {{shared variable cannot be private}}
 {}
diff --git a/test/OpenMP/target_simd_lastprivate_messages.cpp b/test/OpenMP/target_simd_lastprivate_messages.cpp
index ae8bd0af7b..70a452f6a5 100644
--- a/test/OpenMP/target_simd_lastprivate_messages.cpp
+++ b/test/OpenMP/target_simd_lastprivate_messages.cpp
@@ -20,7 +20,7 @@ public:
   S2 &operator=(const S2 &);
   const S2 &operator=(const S2 &) const;
   static float S2s; // expected-note {{static data member is predetermined as shared}}
-  static const float S2sc; // expected-note {{static data member is predetermined as shared}}
+  static const float S2sc; // expected-note {{'S2sc' declared here}}
 };
 const float S2::S2sc = 0;
 const S2 b;
@@ -33,9 +33,9 @@ public:
   S3() : a(0) {}
   S3(S3 &s3) : a(s3.a) {}
 };
-const S3 c;         // expected-note {{global variable is predetermined as shared}}
-const S3 ca[5];     // expected-note {{global variable is predetermined as shared}}
-extern const int f; // expected-note {{global variable is predetermined as shared}}
+const S3 c;         // expected-note {{'c' defined here}}
+const S3 ca[5];     // expected-note {{'ca' defined here}}
+extern const int f; // expected-note {{'f' declared here}}
 class S4 {
   int a;
   S4();             // expected-note 3 {{implicitly declared private here}}
@@ -136,8 +136,8 @@ using A::x;
 }
 
 int main(int argc, char **argv) {
-  const int d = 5;       // expected-note {{constant variable is predetermined as shared}}
-  const int da[5] = {0}; // expected-note {{constant variable is predetermined as shared}}
+  const int d = 5;       // expected-note {{'d' defined here}}
+  const int da[5] = {0}; // expected-note {{'da' defined here}}
   S4 e(4);
   S5 g(5);
   S3 m;
@@ -168,7 +168,7 @@ int main(int argc, char **argv) {
 #pragma omp target simd lastprivate(S1) // expected-error {{'S1' does not refer to a value}}
   for (i = 0; i < argc; ++i)
     foo();
-#pragma omp target simd lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be lastprivate}}
+#pragma omp target simd lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 1 {{const-qualified variable without mutable fields cannot be lastprivate}} expected-error 2 {{const-qualified variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i)
     foo();
 #pragma omp target simd lastprivate(argv[1]) // expected-error {{expected variable name}}
@@ -180,10 +180,10 @@ int main(int argc, char **argv) {
 #pragma omp target simd lastprivate(ba)
   for (i = 0; i < argc; ++i)
     foo();
-#pragma omp target simd lastprivate(ca) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp target simd lastprivate(ca) // expected-error {{const-qualified variable without mutable fields cannot be lastprivate}}
   for (i = 0; i < argc; ++i)
     foo();
-#pragma omp target simd lastprivate(da) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp target simd lastprivate(da) // expected-error {{const-qualified variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i)
     foo();
   int xa;
@@ -193,7 +193,7 @@ int main(int argc, char **argv) {
 #pragma omp target simd lastprivate(S2::S2s) // expected-error {{shared variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i)
     foo();
-#pragma omp target simd lastprivate(S2::S2sc) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp target simd lastprivate(S2::S2sc) // expected-error {{const-qualified variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i)
     foo();
 #pragma omp target simd safelen(5) // OK
diff --git a/test/OpenMP/target_teams_distribute_lastprivate_messages.cpp b/test/OpenMP/target_teams_distribute_lastprivate_messages.cpp
index 0739846cee..0a2f5448ba 100644
--- a/test/OpenMP/target_teams_distribute_lastprivate_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_lastprivate_messages.cpp
@@ -20,7 +20,7 @@ public:
   const S2 &operator =(const S2&) const;
   S2 &operator =(const S2&);
   static float S2s; // expected-note {{static data member is predetermined as shared}}
-  static const float S2sc; // expected-note {{static data member is predetermined as shared}}
+  static const float S2sc; // expected-note {{'S2sc' declared here}}
 };
 const float S2::S2sc = 0;
 const S2 b;
@@ -33,9 +33,9 @@ public:
   S3() : a(0) {}
   S3(S3 &s3) : a(s3.a) {}
 };
-const S3 c;         // expected-note {{global variable is predetermined as shared}}
-const S3 ca[5];     // expected-note {{global variable is predetermined as shared}}
-extern const int f; // expected-note {{global variable is predetermined as shared}}
+const S3 c;         // expected-note {{'c' defined here}}
+const S3 ca[5];     // expected-note {{'ca' defined here}}
+extern const int f; // expected-note {{'f' declared here}}
 class S4 {
   int a;
   S4();             // expected-note 3 {{implicitly declared private here}}
@@ -136,8 +136,8 @@ using A::x;
 }
 
 int main(int argc, char **argv) {
-  const int d = 5;       // expected-note {{constant variable is predetermined as shared}}
-  const int da[5] = {0}; // expected-note {{constant variable is predetermined as shared}}
+  const int d = 5;       // expected-note {{'d' defined here}}
+  const int da[5] = {0}; // expected-note {{'da' defined here}}
   S4 e(4);
   S5 g(5);
   S3 m;
@@ -168,7 +168,7 @@ int main(int argc, char **argv) {
 #pragma omp target teams distribute lastprivate(S1) // expected-error {{'S1' does not refer to a value}}
   for (i = 0; i < argc; ++i) foo();
 
-#pragma omp target teams distribute lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be lastprivate}}
+#pragma omp target teams distribute lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 1 {{const-qualified variable without mutable fields cannot be lastprivate}} expected-error 2 {{const-qualified variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i) foo();
 
 #pragma omp target teams distribute lastprivate(argv[1]) // expected-error {{expected variable name}}
@@ -180,10 +180,10 @@ int main(int argc, char **argv) {
 #pragma omp target teams distribute lastprivate(ba)
   for (i = 0; i < argc; ++i) foo();
 
-#pragma omp target teams distribute lastprivate(ca) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp target teams distribute lastprivate(ca) // expected-error {{const-qualified variable without mutable fields cannot be lastprivate}}
   for (i = 0; i < argc; ++i) foo();
 
-#pragma omp target teams distribute lastprivate(da) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp target teams distribute lastprivate(da) // expected-error {{const-qualified variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i) foo();
 
   int xa;
@@ -193,7 +193,7 @@ int main(int argc, char **argv) {
 #pragma omp target teams distribute lastprivate(S2::S2s) // expected-error {{shared variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i) foo();
 
-#pragma omp target teams distribute lastprivate(S2::S2sc) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp target teams distribute lastprivate(S2::S2sc) // expected-error {{const-qualified variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i) foo();
 
 #pragma omp target teams distribute lastprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}}
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_lastprivate_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_lastprivate_messages.cpp
index b21b9118f9..3c5e815217 100644
--- a/test/OpenMP/target_teams_distribute_parallel_for_lastprivate_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_parallel_for_lastprivate_messages.cpp
@@ -20,7 +20,7 @@ public:
   const S2 &operator =(const S2&) const;
   S2 &operator =(const S2&);
   static float S2s; // expected-note {{static data member is predetermined as shared}}
-  static const float S2sc; // expected-note {{static data member is predetermined as shared}}
+  static const float S2sc; // expected-note {{'S2sc' declared here}}
 };
 const float S2::S2sc = 0;
 const S2 b;
@@ -33,9 +33,9 @@ public:
   S3() : a(0) {}
   S3(S3 &s3) : a(s3.a) {}
 };
-const S3 c;         // expected-note {{global variable is predetermined as shared}}
-const S3 ca[5];     // expected-note {{global variable is predetermined as shared}}
-extern const int f; // expected-note {{global variable is predetermined as shared}}
+const S3 c;         // expected-note {{'c' defined here}}
+const S3 ca[5];     // expected-note {{'ca' defined here}}
+extern const int f; // expected-note {{'f' declared here}}
 class S4 {
   int a;
   S4();             // expected-note 3 {{implicitly declared private here}}
@@ -136,8 +136,8 @@ using A::x;
 }
 
 int main(int argc, char **argv) {
-  const int d = 5;       // expected-note {{constant variable is predetermined as shared}}
-  const int da[5] = {0}; // expected-note {{constant variable is predetermined as shared}}
+  const int d = 5;       // expected-note {{'d' defined here}}
+  const int da[5] = {0}; // expected-note {{'da' defined here}}
   S4 e(4);
   S5 g(5);
   S3 m;
@@ -169,7 +169,7 @@ int main(int argc, char **argv) {
 #pragma omp target teams distribute parallel for lastprivate(S1) // expected-error {{'S1' does not refer to a value}}
   for (i = 0; i < argc; ++i) foo();
 
-#pragma omp target teams distribute parallel for lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be lastprivate}}
+#pragma omp target teams distribute parallel for lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 1 {{const-qualified variable without mutable fields cannot be lastprivate}} expected-error 2 {{const-qualified variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i) foo();
 
 #pragma omp target teams distribute parallel for lastprivate(argv[1]) // expected-error {{expected variable name}}
@@ -181,10 +181,10 @@ int main(int argc, char **argv) {
 #pragma omp target teams distribute parallel for lastprivate(ba)
   for (i = 0; i < argc; ++i) foo();
 
-#pragma omp target teams distribute parallel for lastprivate(ca) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp target teams distribute parallel for lastprivate(ca) // expected-error {{const-qualified variable without mutable fields cannot be lastprivate}}
   for (i = 0; i < argc; ++i) foo();
 
-#pragma omp target teams distribute parallel for lastprivate(da) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp target teams distribute parallel for lastprivate(da) // expected-error {{const-qualified variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i) foo();
 
   int xa;
@@ -194,7 +194,7 @@ int main(int argc, char **argv) {
 #pragma omp target teams distribute parallel for lastprivate(S2::S2s) // expected-error {{shared variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i) foo();
 
-#pragma omp target teams distribute parallel for lastprivate(S2::S2sc) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp target teams distribute parallel for lastprivate(S2::S2sc) // expected-error {{const-qualified variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i) foo();
 
 #pragma omp target teams distribute parallel for lastprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}}
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_private_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_private_messages.cpp
index 7750238e70..43b0304bb9 100644
--- a/test/OpenMP/target_teams_distribute_parallel_for_private_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_parallel_for_private_messages.cpp
@@ -24,9 +24,9 @@ class S3 {
 public:
   S3():a(0) { }
 };
-const S3 c; // expected-note {{predetermined as shared}}
-const S3 ca[5]; // expected-note {{predetermined as shared}}
-extern const int f;  // expected-note {{predetermined as shared}}
+const S3 c; // expected-note {{'c' defined here}}
+const S3 ca[5]; // expected-note {{'ca' defined here}}
+extern const int f;  // expected-note {{'f' declared here}}
 class S4 {
   int a;
   S4(); // expected-note {{implicitly declared private here}}
@@ -45,8 +45,8 @@ S3 h;
 
 
 int main(int argc, char **argv) {
-  const int d = 5;  // expected-note {{predetermined as shared}}
-  const int da[5] = { 0 }; // expected-note {{predetermined as shared}}
+  const int d = 5;  // expected-note {{'d' defined here}}
+  const int da[5] = { 0 }; // expected-note {{'da' defined here}}
   S4 e(4);
   S5 g(5);
   int i;
@@ -76,7 +76,7 @@ int main(int argc, char **argv) {
 #pragma omp target teams distribute parallel for private (S1) // expected-error {{'S1' does not refer to a value}}
   for (int k = 0; k < argc; ++k) ++k;
 
-#pragma omp target teams distribute parallel for private (a, b, c, d, f) // expected-error {{private variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be private}}
+#pragma omp target teams distribute parallel for private (a, b, c, d, f) // expected-error {{private variable with incomplete type 'S1'}} expected-error 1 {{const-qualified variable without mutable fields cannot be private}} expected-error 2 {{const-qualified variable cannot be private}}
   for (int k = 0; k < argc; ++k) ++k;
 
 #pragma omp target teams distribute parallel for private (argv[1]) // expected-error {{expected variable name}}
@@ -85,10 +85,10 @@ int main(int argc, char **argv) {
 #pragma omp target teams distribute parallel for private(ba)
   for (int k = 0; k < argc; ++k) ++k;
 
-#pragma omp target teams distribute parallel for private(ca) // expected-error {{shared variable cannot be private}}
+#pragma omp target teams distribute parallel for private(ca) // expected-error {{const-qualified variable without mutable fields cannot be private}}
   for (int k = 0; k < argc; ++k) ++k;
 
-#pragma omp target teams distribute parallel for private(da) // expected-error {{shared variable cannot be private}}
+#pragma omp target teams distribute parallel for private(da) // expected-error {{const-qualified variable cannot be private}}
   for (int k = 0; k < argc; ++k) ++k;
 
 #pragma omp target teams distribute parallel for private(S2::S2s) // expected-error {{shared variable cannot be private}}
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_simd_lastprivate_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_simd_lastprivate_messages.cpp
index b65c22ba8a..d1adbd0d39 100644
--- a/test/OpenMP/target_teams_distribute_parallel_for_simd_lastprivate_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_lastprivate_messages.cpp
@@ -20,7 +20,7 @@ public:
   const S2 &operator =(const S2&) const;
   S2 &operator =(const S2&);
   static float S2s; // expected-note {{static data member is predetermined as shared}}
-  static const float S2sc; // expected-note {{static data member is predetermined as shared}}
+  static const float S2sc; // expected-note {{'S2sc' declared here}}
 };
 const float S2::S2sc = 0;
 const S2 b;
@@ -33,9 +33,9 @@ public:
   S3() : a(0) {}
   S3(S3 &s3) : a(s3.a) {}
 };
-const S3 c;         // expected-note {{global variable is predetermined as shared}}
-const S3 ca[5];     // expected-note {{global variable is predetermined as shared}}
-extern const int f; // expected-note {{global variable is predetermined as shared}}
+const S3 c;         // expected-note {{'c' defined here}}
+const S3 ca[5];     // expected-note {{'ca' defined here}}
+extern const int f; // expected-note {{'f' declared here}}
 class S4 {
   int a;
   S4();             // expected-note 3 {{implicitly declared private here}}
@@ -136,8 +136,8 @@ using A::x;
 }
 
 int main(int argc, char **argv) {
-  const int d = 5;       // expected-note {{constant variable is predetermined as shared}}
-  const int da[5] = {0}; // expected-note {{constant variable is predetermined as shared}}
+  const int d = 5;       // expected-note {{'d' defined here}}
+  const int da[5] = {0}; // expected-note {{'da' defined here}}
   S4 e(4);
   S5 g(5);
   S3 m;
@@ -169,7 +169,7 @@ int main(int argc, char **argv) {
 #pragma omp target teams distribute parallel for simd lastprivate(S1) // expected-error {{'S1' does not refer to a value}}
   for (i = 0; i < argc; ++i) foo();
 
-#pragma omp target teams distribute parallel for simd lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be lastprivate}}
+#pragma omp target teams distribute parallel for simd lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 1 {{const-qualified variable without mutable fields cannot be lastprivate}} expected-error 2 {{const-qualified variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i) foo();
 
 #pragma omp target teams distribute parallel for simd lastprivate(argv[1]) // expected-error {{expected variable name}}
@@ -181,10 +181,10 @@ int main(int argc, char **argv) {
 #pragma omp target teams distribute parallel for simd lastprivate(ba)
   for (i = 0; i < argc; ++i) foo();
 
-#pragma omp target teams distribute parallel for simd lastprivate(ca) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp target teams distribute parallel for simd lastprivate(ca) // expected-error {{const-qualified variable without mutable fields cannot be lastprivate}}
   for (i = 0; i < argc; ++i) foo();
 
-#pragma omp target teams distribute parallel for simd lastprivate(da) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp target teams distribute parallel for simd lastprivate(da) // expected-error {{const-qualified variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i) foo();
 
   int xa;
@@ -194,7 +194,7 @@ int main(int argc, char **argv) {
 #pragma omp target teams distribute parallel for simd lastprivate(S2::S2s) // expected-error {{shared variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i) foo();
 
-#pragma omp target teams distribute parallel for simd lastprivate(S2::S2sc) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp target teams distribute parallel for simd lastprivate(S2::S2sc) // expected-error {{const-qualified variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i) foo();
 
 #pragma omp target teams distribute parallel for simd lastprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}}
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_simd_private_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_simd_private_messages.cpp
index f1a8e0bfc7..9cf810a9e9 100644
--- a/test/OpenMP/target_teams_distribute_parallel_for_simd_private_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_private_messages.cpp
@@ -24,9 +24,9 @@ class S3 {
 public:
   S3():a(0) { }
 };
-const S3 c; // expected-note {{predetermined as shared}}
-const S3 ca[5]; // expected-note {{predetermined as shared}}
-extern const int f;  // expected-note {{predetermined as shared}}
+const S3 c; // expected-note {{'c' defined here}}
+const S3 ca[5]; // expected-note {{'ca' defined here}}
+extern const int f;  // expected-note {{'f' declared here}}
 class S4 {
   int a;
   S4(); // expected-note {{implicitly declared private here}}
@@ -45,8 +45,8 @@ S3 h;
 
 
 int main(int argc, char **argv) {
-  const int d = 5;  // expected-note {{predetermined as shared}}
-  const int da[5] = { 0 }; // expected-note {{predetermined as shared}}
+  const int d = 5;  // expected-note {{'d' defined here}}
+  const int da[5] = { 0 }; // expected-note {{'da' defined here}}
   S4 e(4);
   S5 g(5);
   int i;
@@ -76,7 +76,7 @@ int main(int argc, char **argv) {
   #pragma omp target teams distribute parallel for simd private (S1) // expected-error {{'S1' does not refer to a value}}
   for (int k = 0; k < argc; ++k) ++k;
 
-  #pragma omp target teams distribute parallel for simd private (a, b, c, d, f) // expected-error {{private variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be private}}
+  #pragma omp target teams distribute parallel for simd private (a, b, c, d, f) // expected-error {{private variable with incomplete type 'S1'}} expected-error 1 {{const-qualified variable without mutable fields cannot be private}} expected-error 2 {{const-qualified variable cannot be private}}
   for (int k = 0; k < argc; ++k) ++k;
 
   #pragma omp target teams distribute parallel for simd private (argv[1]) // expected-error {{expected variable name}}
@@ -85,10 +85,10 @@ int main(int argc, char **argv) {
   #pragma omp target teams distribute parallel for simd private(ba)
   for (int k = 0; k < argc; ++k) ++k;
 
-  #pragma omp target teams distribute parallel for simd private(ca) // expected-error {{shared variable cannot be private}}
+  #pragma omp target teams distribute parallel for simd private(ca) // expected-error {{const-qualified variable without mutable fields cannot be private}}
   for (int k = 0; k < argc; ++k) ++k;
 
-  #pragma omp target teams distribute parallel for simd private(da) // expected-error {{shared variable cannot be private}}
+  #pragma omp target teams distribute parallel for simd private(da) // expected-error {{const-qualified variable cannot be private}}
   for (int k = 0; k < argc; ++k) ++k;
 
   #pragma omp target teams distribute parallel for simd private(S2::S2s) // expected-error {{shared variable cannot be private}}
diff --git a/test/OpenMP/target_teams_distribute_private_messages.cpp b/test/OpenMP/target_teams_distribute_private_messages.cpp
index df7b68919c..3d692a3f26 100644
--- a/test/OpenMP/target_teams_distribute_private_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_private_messages.cpp
@@ -24,9 +24,9 @@ class S3 {
 public:
   S3():a(0) { }
 };
-const S3 c; // expected-note {{predetermined as shared}}
-const S3 ca[5]; // expected-note {{predetermined as shared}}
-extern const int f;  // expected-note {{predetermined as shared}}
+const S3 c; // expected-note {{'c' defined here}}
+const S3 ca[5]; // expected-note {{'ca' defined here}}
+extern const int f;  // expected-note {{'f' declared here}}
 class S4 {
   int a;
   S4(); // expected-note {{implicitly declared private here}}
@@ -45,8 +45,8 @@ S3 h;
 
 
 int main(int argc, char **argv) {
-  const int d = 5;  // expected-note {{predetermined as shared}}
-  const int da[5] = { 0 }; // expected-note {{predetermined as shared}}
+  const int d = 5;  // expected-note {{'d' defined here}}
+  const int da[5] = { 0 }; // expected-note {{'da' defined here}}
   S4 e(4);
   S5 g(5);
   int i;
@@ -76,7 +76,7 @@ int main(int argc, char **argv) {
 #pragma omp target teams distribute private (S1) // expected-error {{'S1' does not refer to a value}}
   for (int k = 0; k < argc; ++k) ++k;
 
-#pragma omp target teams distribute private (a, b, c, d, f) // expected-error {{private variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be private}}
+#pragma omp target teams distribute private (a, b, c, d, f) // expected-error {{private variable with incomplete type 'S1'}} expected-error 1 {{const-qualified variable without mutable fields cannot be private}} expected-error 2 {{const-qualified variable cannot be private}}
   for (int k = 0; k < argc; ++k) ++k;
 
 #pragma omp target teams distribute private (argv[1]) // expected-error {{expected variable name}}
@@ -85,10 +85,10 @@ int main(int argc, char **argv) {
 #pragma omp target teams distribute private(ba)
   for (int k = 0; k < argc; ++k) ++k;
 
-#pragma omp target teams distribute private(ca) // expected-error {{shared variable cannot be private}}
+#pragma omp target teams distribute private(ca) // expected-error {{const-qualified variable without mutable fields cannot be private}}
   for (int k = 0; k < argc; ++k) ++k;
 
-#pragma omp target teams distribute private(da) // expected-error {{shared variable cannot be private}}
+#pragma omp target teams distribute private(da) // expected-error {{const-qualified variable cannot be private}}
   for (int k = 0; k < argc; ++k) ++k;
 
 #pragma omp target teams distribute private(S2::S2s) // expected-error {{shared variable cannot be private}}
diff --git a/test/OpenMP/target_teams_distribute_simd_lastprivate_messages.cpp b/test/OpenMP/target_teams_distribute_simd_lastprivate_messages.cpp
index 3a9abfb24a..4dcc9ea754 100644
--- a/test/OpenMP/target_teams_distribute_simd_lastprivate_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_simd_lastprivate_messages.cpp
@@ -20,7 +20,7 @@ public:
   const S2 &operator =(const S2&) const;
   S2 &operator =(const S2&);
   static float S2s; // expected-note {{static data member is predetermined as shared}}
-  static const float S2sc; // expected-note {{static data member is predetermined as shared}}
+  static const float S2sc; // expected-note {{'S2sc' declared here}}
 };
 const float S2::S2sc = 0;
 const S2 b;
@@ -33,9 +33,9 @@ public:
   S3() : a(0) {}
   S3(S3 &s3) : a(s3.a) {}
 };
-const S3 c;         // expected-note {{global variable is predetermined as shared}}
-const S3 ca[5];     // expected-note {{global variable is predetermined as shared}}
-extern const int f; // expected-note {{global variable is predetermined as shared}}
+const S3 c;         // expected-note {{'c' defined here}}
+const S3 ca[5];     // expected-note {{'ca' defined here}}
+extern const int f; // expected-note {{'f' declared here}}
 class S4 {
   int a;
   S4();             // expected-note 3 {{implicitly declared private here}}
@@ -136,8 +136,8 @@ using A::x;
 }
 
 int main(int argc, char **argv) {
-  const int d = 5;       // expected-note {{constant variable is predetermined as shared}}
-  const int da[5] = {0}; // expected-note {{constant variable is predetermined as shared}}
+  const int d = 5;       // expected-note {{'d' defined here}}
+  const int da[5] = {0}; // expected-note {{'da' defined here}}
   S4 e(4);
   S5 g(5);
   S3 m;
@@ -169,7 +169,7 @@ int main(int argc, char **argv) {
 #pragma omp target teams distribute simd lastprivate(S1) // expected-error {{'S1' does not refer to a value}}
   for (i = 0; i < argc; ++i) foo();
 
-#pragma omp target teams distribute simd lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be lastprivate}}
+#pragma omp target teams distribute simd lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 1 {{const-qualified variable without mutable fields cannot be lastprivate}} expected-error 2 {{const-qualified variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i) foo();
 
 #pragma omp target teams distribute simd lastprivate(argv[1]) // expected-error {{expected variable name}}
@@ -181,10 +181,10 @@ int main(int argc, char **argv) {
 #pragma omp target teams distribute simd lastprivate(ba)
   for (i = 0; i < argc; ++i) foo();
 
-#pragma omp target teams distribute simd lastprivate(ca) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp target teams distribute simd lastprivate(ca) // expected-error {{const-qualified variable without mutable fields cannot be lastprivate}}
   for (i = 0; i < argc; ++i) foo();
 
-#pragma omp target teams distribute simd lastprivate(da) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp target teams distribute simd lastprivate(da) // expected-error {{const-qualified variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i) foo();
 
   int xa;
@@ -194,7 +194,7 @@ int main(int argc, char **argv) {
 #pragma omp target teams distribute simd lastprivate(S2::S2s) // expected-error {{shared variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i) foo();
 
-#pragma omp target teams distribute simd lastprivate(S2::S2sc) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp target teams distribute simd lastprivate(S2::S2sc) // expected-error {{const-qualified variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i) foo();
 
 #pragma omp target teams distribute simd lastprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}}
diff --git a/test/OpenMP/target_teams_distribute_simd_private_messages.cpp b/test/OpenMP/target_teams_distribute_simd_private_messages.cpp
index 743ac160ce..eef86d229d 100644
--- a/test/OpenMP/target_teams_distribute_simd_private_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_simd_private_messages.cpp
@@ -24,9 +24,9 @@ class S3 {
 public:
   S3():a(0) { }
 };
-const S3 c; // expected-note {{predetermined as shared}}
-const S3 ca[5]; // expected-note {{predetermined as shared}}
-extern const int f;  // expected-note {{predetermined as shared}}
+const S3 c; // expected-note {{'c' defined here}}
+const S3 ca[5]; // expected-note {{'ca' defined here}}
+extern const int f;  // expected-note {{'f' declared here}}
 class S4 {
   int a;
   S4(); // expected-note {{implicitly declared private here}}
@@ -45,8 +45,8 @@ S3 h;
 
 
 int main(int argc, char **argv) {
-  const int d = 5;  // expected-note {{predetermined as shared}}
-  const int da[5] = { 0 }; // expected-note {{predetermined as shared}}
+  const int d = 5;  // expected-note {{'d' defined here}}
+  const int da[5] = { 0 }; // expected-note {{'da' defined here}}
   S4 e(4);
   S5 g(5);
   int i;
@@ -76,7 +76,7 @@ int main(int argc, char **argv) {
 #pragma omp target teams distribute simd private (S1) // expected-error {{'S1' does not refer to a value}}
   for (int k = 0; k < argc; ++k) ++k;
 
-#pragma omp target teams distribute simd private (a, b, c, d, f) // expected-error {{private variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be private}}
+#pragma omp target teams distribute simd private (a, b, c, d, f) // expected-error {{private variable with incomplete type 'S1'}} expected-error 1 {{const-qualified variable without mutable fields cannot be private}} expected-error 2 {{const-qualified variable cannot be private}}
   for (int k = 0; k < argc; ++k) ++k;
 
 #pragma omp target teams distribute simd private (argv[1]) // expected-error {{expected variable name}}
@@ -85,10 +85,10 @@ int main(int argc, char **argv) {
 #pragma omp target teams distribute simd private(ba)
   for (int k = 0; k < argc; ++k) ++k;
 
-#pragma omp target teams distribute simd private(ca) // expected-error {{shared variable cannot be private}}
+#pragma omp target teams distribute simd private(ca) // expected-error {{const-qualified variable without mutable fields cannot be private}}
   for (int k = 0; k < argc; ++k) ++k;
 
-#pragma omp target teams distribute simd private(da) // expected-error {{shared variable cannot be private}}
+#pragma omp target teams distribute simd private(da) // expected-error {{const-qualified variable cannot be private}}
   for (int k = 0; k < argc; ++k) ++k;
 
 #pragma omp target teams distribute simd private(S2::S2s) // expected-error {{shared variable cannot be private}}
diff --git a/test/OpenMP/target_teams_private_messages.cpp b/test/OpenMP/target_teams_private_messages.cpp
index 7ee509c8ac..ceb268f40a 100644
--- a/test/OpenMP/target_teams_private_messages.cpp
+++ b/test/OpenMP/target_teams_private_messages.cpp
@@ -24,9 +24,9 @@ class S3 {
 public:
   S3():a(0) { }
 };
-const S3 c; // expected-note {{global variable is predetermined as shared}}
-const S3 ca[5]; // expected-note {{global variable is predetermined as shared}}
-extern const int f; // expected-note {{global variable is predetermined as shared}}
+const S3 c; // expected-note {{'c' defined here}}
+const S3 ca[5]; // expected-note {{'ca' defined here}}
+extern const int f; // expected-note {{'f' declared here}}
 class S4 {
   int a;
   S4(); // expected-note {{implicitly declared private here}}
@@ -52,8 +52,8 @@ using A::x;
 }
 
 int main(int argc, char **argv) {
-  const int d = 5; // expected-note {{constant variable is predetermined as shared}}
-  const int da[5] = { 0 }; // expected-note {{constant variable is predetermined as shared}}
+  const int d = 5; // expected-note {{'d' defined here}}
+  const int da[5] = { 0 }; // expected-note {{'da' defined here}}
   S4 e(4);
   S5 g(5);
   int i;
@@ -74,15 +74,15 @@ int main(int argc, char **argv) {
   foo();
 #pragma omp target teams private (S1) // expected-error {{'S1' does not refer to a value}}
   foo();
-#pragma omp target teams private (a, b, c, d, f) // expected-error {{a private variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be private}}
+#pragma omp target teams private (a, b, c, d, f) // expected-error {{a private variable with incomplete type 'S1'}} expected-error 1 {{const-qualified variable without mutable fields cannot be private}} expected-error 2 {{const-qualified variable cannot be private}}
   foo();
 #pragma omp target teams private (argv[1]) // expected-error {{expected variable name}}
   foo();
 #pragma omp target teams private(ba)
   foo();
-#pragma omp target teams private(ca) // expected-error {{shared variable cannot be private}}
+#pragma omp target teams private(ca) // expected-error {{const-qualified variable without mutable fields cannot be private}}
   foo();
-#pragma omp target teams private(da) // expected-error {{shared variable cannot be private}}
+#pragma omp target teams private(da) // expected-error {{const-qualified variable cannot be private}}
   foo();
 #pragma omp target teams private(S2::S2s) // expected-error {{shared variable cannot be private}}
   foo();
diff --git a/test/OpenMP/task_private_messages.cpp b/test/OpenMP/task_private_messages.cpp
index 5663a436e4..2a3df509c2 100644
--- a/test/OpenMP/task_private_messages.cpp
+++ b/test/OpenMP/task_private_messages.cpp
@@ -26,9 +26,9 @@ class S3 {
 public:
   S3() : a(0) {}
 };
-const S3 c;         // expected-note {{global variable is predetermined as shared}}
-const S3 ca[5];     // expected-note {{global variable is predetermined as shared}}
-extern const int f; // expected-note {{global variable is predetermined as shared}}
+const S3 c;         // expected-note {{'c' defined here}}
+const S3 ca[5];     // expected-note {{'ca' defined here}}
+extern const int f; // expected-note {{'f' declared here}}
 class S4 {
   int a;
   S4(); // expected-note {{implicitly declared private here}}
@@ -61,8 +61,8 @@ using A::x;
 }
 
 int main(int argc, char **argv) {
-  const int d = 5;       // expected-note {{constant variable is predetermined as shared}}
-  const int da[5] = {0}; // expected-note {{constant variable is predetermined as shared}}
+  const int d = 5;       // expected-note {{'d' defined here}}
+  const int da[5] = {0}; // expected-note {{'da' defined here}}
   S4 e(4);
   S5 g(5);
   int i;
@@ -75,11 +75,11 @@ int main(int argc, char **argv) {
 #pragma omp task private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
 #pragma omp task private(argc argv)                    // expected-error {{expected ',' or ')' in 'private' clause}}
 #pragma omp task private(S1)                           // expected-error {{'S1' does not refer to a value}}
-#pragma omp task private(a, b, c, d, f)                // expected-error {{a private variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be private}}
+#pragma omp task private(a, b, c, d, f)                // expected-error {{a private variable with incomplete type 'S1'}} expected-error 1 {{const-qualified variable without mutable fields cannot be private}} expected-error 2 {{const-qualified variable cannot be private}}
 #pragma omp task private(argv[1])                      // expected-error {{expected variable name}}
 #pragma omp task private(ba)
-#pragma omp task private(ca)           // expected-error {{shared variable cannot be private}}
-#pragma omp task private(da)           // expected-error {{shared variable cannot be private}}
+#pragma omp task private(ca)           // expected-error {{const-qualified variable without mutable fields cannot be private}}
+#pragma omp task private(da)           // expected-error {{const-qualified variable cannot be private}}
 #pragma omp task private(S2::S2s)      // expected-error {{shared variable cannot be private}}
 #pragma omp task private(e, g)         // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}}
 #pragma omp task private(threadvar, B::x)    // expected-error 2 {{threadprivate or thread local variable cannot be private}}
diff --git a/test/OpenMP/taskloop_lastprivate_messages.cpp b/test/OpenMP/taskloop_lastprivate_messages.cpp
index 85aaa00c81..c46a1f0c4c 100644
--- a/test/OpenMP/taskloop_lastprivate_messages.cpp
+++ b/test/OpenMP/taskloop_lastprivate_messages.cpp
@@ -20,7 +20,7 @@ public:
   const S2 &operator =(const S2&) const;
   S2 &operator =(const S2&);
   static float S2s; // expected-note {{static data member is predetermined as shared}}
-  static const float S2sc; // expected-note {{static data member is predetermined as shared}}
+  static const float S2sc; // expected-note {{'S2sc' declared here}}
 };
 const float S2::S2sc = 0;
 const S2 b;
@@ -33,9 +33,9 @@ public:
   S3() : a(0) {}
   S3(S3 &s3) : a(s3.a) {}
 };
-const S3 c;         // expected-note {{global variable is predetermined as shared}}
-const S3 ca[5];     // expected-note {{global variable is predetermined as shared}}
-extern const int f; // expected-note {{global variable is predetermined as shared}}
+const S3 c;         // expected-note {{'c' defined here}}
+const S3 ca[5];     // expected-note {{'ca' defined here}}
+extern const int f; // expected-note {{'f' declared here}}
 class S4 {
   int a;
   S4();             // expected-note 3 {{implicitly declared private here}}
@@ -156,8 +156,8 @@ using A::x;
 }
 
 int main(int argc, char **argv) {
-  const int d = 5;       // expected-note {{constant variable is predetermined as shared}}
-  const int da[5] = {0}; // expected-note {{constant variable is predetermined as shared}}
+  const int d = 5;       // expected-note {{'d' defined here}}
+  const int da[5] = {0}; // expected-note {{'da' defined here}}
   S4 e(4);
   S5 g(5);
   S3 m;
@@ -197,7 +197,7 @@ int main(int argc, char **argv) {
   for (i = 0; i < argc; ++i)
     foo();
 #pragma omp parallel
-#pragma omp taskloop lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be lastprivate}}
+#pragma omp taskloop lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 1 {{const-qualified variable without mutable fields cannot be lastprivate}} expected-error 2 {{const-qualified variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i)
     foo();
 #pragma omp parallel
@@ -213,11 +213,11 @@ int main(int argc, char **argv) {
   for (i = 0; i < argc; ++i)
     foo();
 #pragma omp parallel
-#pragma omp taskloop lastprivate(ca) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp taskloop lastprivate(ca) // expected-error {{const-qualified variable without mutable fields cannot be lastprivate}}
   for (i = 0; i < argc; ++i)
     foo();
 #pragma omp parallel
-#pragma omp taskloop lastprivate(da) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp taskloop lastprivate(da) // expected-error {{const-qualified variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i)
     foo();
   int xa;
@@ -230,7 +230,7 @@ int main(int argc, char **argv) {
   for (i = 0; i < argc; ++i)
     foo();
 #pragma omp parallel
-#pragma omp taskloop lastprivate(S2::S2sc) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp taskloop lastprivate(S2::S2sc) // expected-error {{const-qualified variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i)
     foo();
 #pragma omp parallel
diff --git a/test/OpenMP/taskloop_simd_lastprivate_messages.cpp b/test/OpenMP/taskloop_simd_lastprivate_messages.cpp
index 8f418ff3b8..3ed65de247 100644
--- a/test/OpenMP/taskloop_simd_lastprivate_messages.cpp
+++ b/test/OpenMP/taskloop_simd_lastprivate_messages.cpp
@@ -20,7 +20,7 @@ public:
   const S2 &operator =(const S2&) const;
   S2 &operator =(const S2&);
   static float S2s; // expected-note {{static data member is predetermined as shared}}
-  static const float S2sc; // expected-note {{static data member is predetermined as shared}}
+  static const float S2sc; // expected-note {{'S2sc' declared here}}
 };
 const float S2::S2sc = 0;
 const S2 b;
@@ -33,9 +33,9 @@ public:
   S3() : a(0) {}
   S3(S3 &s3) : a(s3.a) {}
 };
-const S3 c;         // expected-note {{global variable is predetermined as shared}}
-const S3 ca[5];     // expected-note {{global variable is predetermined as shared}}
-extern const int f; // expected-note {{global variable is predetermined as shared}}
+const S3 c;         // expected-note {{'c' defined here}}
+const S3 ca[5];     // expected-note {{'ca' defined here}}
+extern const int f; // expected-note {{'f' declared here}}
 class S4 {
   int a;
   S4();             // expected-note 3 {{implicitly declared private here}}
@@ -156,8 +156,8 @@ using A::x;
 }
 
 int main(int argc, char **argv) {
-  const int d = 5;       // expected-note {{constant variable is predetermined as shared}}
-  const int da[5] = {0}; // expected-note {{constant variable is predetermined as shared}}
+  const int d = 5;       // expected-note {{'d' defined here}}
+  const int da[5] = {0}; // expected-note {{'da' defined here}}
   S4 e(4);
   S5 g(5);
   S3 m;
@@ -197,7 +197,7 @@ int main(int argc, char **argv) {
   for (i = 0; i < argc; ++i)
     foo();
 #pragma omp parallel
-#pragma omp taskloop simd lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be lastprivate}}
+#pragma omp taskloop simd lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 1 {{const-qualified variable without mutable fields cannot be lastprivate}} expected-error 2 {{const-qualified variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i)
     foo();
 #pragma omp parallel
@@ -213,11 +213,11 @@ int main(int argc, char **argv) {
   for (i = 0; i < argc; ++i)
     foo();
 #pragma omp parallel
-#pragma omp taskloop simd lastprivate(ca) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp taskloop simd lastprivate(ca) // expected-error {{const-qualified variable without mutable fields cannot be lastprivate}}
   for (i = 0; i < argc; ++i)
     foo();
 #pragma omp parallel
-#pragma omp taskloop simd lastprivate(da) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp taskloop simd lastprivate(da) // expected-error {{const-qualified variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i)
     foo();
   int xa;
@@ -230,7 +230,7 @@ int main(int argc, char **argv) {
   for (i = 0; i < argc; ++i)
     foo();
 #pragma omp parallel
-#pragma omp taskloop simd lastprivate(S2::S2sc) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp taskloop simd lastprivate(S2::S2sc) // expected-error {{const-qualified variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i)
     foo();
 #pragma omp parallel
diff --git a/test/OpenMP/teams_distribute_lastprivate_messages.cpp b/test/OpenMP/teams_distribute_lastprivate_messages.cpp
index d5e1a1c94c..a6440b7b6d 100644
--- a/test/OpenMP/teams_distribute_lastprivate_messages.cpp
+++ b/test/OpenMP/teams_distribute_lastprivate_messages.cpp
@@ -20,7 +20,7 @@ public:
   const S2 &operator =(const S2&) const;
   S2 &operator =(const S2&);
   static float S2s; // expected-note {{static data member is predetermined as shared}}
-  static const float S2sc; // expected-note {{static data member is predetermined as shared}}
+  static const float S2sc; // expected-note {{'S2sc' declared here}}
 };
 const float S2::S2sc = 0;
 const S2 b;
@@ -33,9 +33,9 @@ public:
   S3() : a(0) {}
   S3(S3 &s3) : a(s3.a) {}
 };
-const S3 c;         // expected-note {{global variable is predetermined as shared}}
-const S3 ca[5];     // expected-note {{global variable is predetermined as shared}}
-extern const int f; // expected-note {{global variable is predetermined as shared}}
+const S3 c;         // expected-note {{'c' defined here}}
+const S3 ca[5];     // expected-note {{'ca' defined here}}
+extern const int f; // expected-note {{'f' declared here}}
 class S4 {
   int a;
   S4();             // expected-note 3 {{implicitly declared private here}}
@@ -152,8 +152,8 @@ using A::x;
 }
 
 int main(int argc, char **argv) {
-  const int d = 5;       // expected-note {{constant variable is predetermined as shared}}
-  const int da[5] = {0}; // expected-note {{constant variable is predetermined as shared}}
+  const int d = 5;       // expected-note {{'d' defined here}}
+  const int da[5] = {0}; // expected-note {{'da' defined here}}
   S4 e(4);
   S5 g(5);
   S3 m;
@@ -193,7 +193,7 @@ int main(int argc, char **argv) {
   for (i = 0; i < argc; ++i) foo();
 
 #pragma omp target
-#pragma omp teams distribute lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be lastprivate}}
+#pragma omp teams distribute lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 1 {{const-qualified variable without mutable fields cannot be lastprivate}} expected-error 2 {{const-qualified variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i) foo();
 
 #pragma omp target
@@ -209,11 +209,11 @@ int main(int argc, char **argv) {
   for (i = 0; i < argc; ++i) foo();
 
 #pragma omp target
-#pragma omp teams distribute lastprivate(ca) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp teams distribute lastprivate(ca) // expected-error {{const-qualified variable without mutable fields cannot be lastprivate}}
   for (i = 0; i < argc; ++i) foo();
 
 #pragma omp target
-#pragma omp teams distribute lastprivate(da) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp teams distribute lastprivate(da) // expected-error {{const-qualified variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i) foo();
 
   int xa;
@@ -226,7 +226,7 @@ int main(int argc, char **argv) {
   for (i = 0; i < argc; ++i) foo();
 
 #pragma omp target
-#pragma omp teams distribute lastprivate(S2::S2sc) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp teams distribute lastprivate(S2::S2sc) // expected-error {{const-qualified variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i) foo();
 
 #pragma omp target
diff --git a/test/OpenMP/teams_distribute_parallel_for_lastprivate_messages.cpp b/test/OpenMP/teams_distribute_parallel_for_lastprivate_messages.cpp
index 97e9e4f822..14b7e8be2a 100644
--- a/test/OpenMP/teams_distribute_parallel_for_lastprivate_messages.cpp
+++ b/test/OpenMP/teams_distribute_parallel_for_lastprivate_messages.cpp
@@ -20,7 +20,7 @@ public:
   const S2 &operator =(const S2&) const;
   S2 &operator =(const S2&);
   static float S2s; // expected-note {{static data member is predetermined as shared}}
-  static const float S2sc; // expected-note {{static data member is predetermined as shared}}
+  static const float S2sc; // expected-note {{'S2sc' declared here}}
 };
 const float S2::S2sc = 0;
 const S2 b;
@@ -33,9 +33,9 @@ public:
   S3() : a(0) {}
   S3(S3 &s3) : a(s3.a) {}
 };
-const S3 c;         // expected-note {{global variable is predetermined as shared}}
-const S3 ca[5];     // expected-note {{global variable is predetermined as shared}}
-extern const int f; // expected-note {{global variable is predetermined as shared}}
+const S3 c;         // expected-note {{'c' defined here}}
+const S3 ca[5];     // expected-note {{'ca' defined here}}
+extern const int f; // expected-note {{'f' declared here}}
 class S4 {
   int a;
   S4();             // expected-note 3 {{implicitly declared private here}}
@@ -152,8 +152,8 @@ using A::x;
 }
 
 int main(int argc, char **argv) {
-  const int d = 5;       // expected-note {{constant variable is predetermined as shared}}
-  const int da[5] = {0}; // expected-note {{constant variable is predetermined as shared}}
+  const int d = 5;       // expected-note {{'d' defined here}}
+  const int da[5] = {0}; // expected-note {{'da' defined here}}
   S4 e(4);
   S5 g(5);
   S3 m;
@@ -193,7 +193,7 @@ int main(int argc, char **argv) {
   for (i = 0; i < argc; ++i) foo();
 
 #pragma omp target
-#pragma omp teams distribute parallel for lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be lastprivate}}
+#pragma omp teams distribute parallel for lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 1 {{const-qualified variable without mutable fields cannot be lastprivate}} expected-error 2 {{const-qualified variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i) foo();
 
 #pragma omp target
@@ -209,11 +209,11 @@ int main(int argc, char **argv) {
   for (i = 0; i < argc; ++i) foo();
 
 #pragma omp target
-#pragma omp teams distribute parallel for lastprivate(ca) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp teams distribute parallel for lastprivate(ca) // expected-error {{const-qualified variable without mutable fields cannot be lastprivate}}
   for (i = 0; i < argc; ++i) foo();
 
 #pragma omp target
-#pragma omp teams distribute parallel for lastprivate(da) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp teams distribute parallel for lastprivate(da) // expected-error {{const-qualified variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i) foo();
 
   int xa;
@@ -226,7 +226,7 @@ int main(int argc, char **argv) {
   for (i = 0; i < argc; ++i) foo();
 
 #pragma omp target
-#pragma omp teams distribute parallel for lastprivate(S2::S2sc) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp teams distribute parallel for lastprivate(S2::S2sc) // expected-error {{const-qualified variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i) foo();
 
 #pragma omp target
diff --git a/test/OpenMP/teams_distribute_parallel_for_private_messages.cpp b/test/OpenMP/teams_distribute_parallel_for_private_messages.cpp
index 5fda1a96e4..ba9e077437 100644
--- a/test/OpenMP/teams_distribute_parallel_for_private_messages.cpp
+++ b/test/OpenMP/teams_distribute_parallel_for_private_messages.cpp
@@ -24,9 +24,9 @@ class S3 {
 public:
   S3():a(0) { }
 };
-const S3 c; // expected-note {{predetermined as shared}}
-const S3 ca[5]; // expected-note {{predetermined as shared}}
-extern const int f;  // expected-note {{predetermined as shared}}
+const S3 c; // expected-note {{'c' defined here}}
+const S3 ca[5]; // expected-note {{'ca' defined here}}
+extern const int f;  // expected-note {{'f' declared here}}
 class S4 {
   int a;
   S4(); // expected-note {{implicitly declared private here}}
@@ -45,8 +45,8 @@ S3 h;
 
 
 int main(int argc, char **argv) {
-  const int d = 5;  // expected-note {{predetermined as shared}}
-  const int da[5] = { 0 }; // expected-note {{predetermined as shared}}
+  const int d = 5;  // expected-note {{'d' defined here}}
+  const int da[5] = { 0 }; // expected-note {{'da' defined here}}
   S4 e(4);
   S5 g(5);
   int i;
@@ -85,7 +85,7 @@ int main(int argc, char **argv) {
   for (int k = 0; k < argc; ++k) ++k;
 
   #pragma omp target
-  #pragma omp teams distribute parallel for private (a, b, c, d, f) // expected-error {{private variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be private}}
+  #pragma omp teams distribute parallel for private (a, b, c, d, f) // expected-error {{private variable with incomplete type 'S1'}} expected-error 1 {{const-qualified variable without mutable fields cannot be private}} expected-error 2 {{const-qualified variable cannot be private}}
   for (int k = 0; k < argc; ++k) ++k;
 
   #pragma omp target
@@ -97,11 +97,11 @@ int main(int argc, char **argv) {
   for (int k = 0; k < argc; ++k) ++k;
 
   #pragma omp target
-  #pragma omp teams distribute parallel for private(ca) // expected-error {{shared variable cannot be private}}
+  #pragma omp teams distribute parallel for private(ca) // expected-error {{const-qualified variable without mutable fields cannot be private}}
   for (int k = 0; k < argc; ++k) ++k;
 
   #pragma omp target
-  #pragma omp teams distribute parallel for private(da) // expected-error {{shared variable cannot be private}}
+  #pragma omp teams distribute parallel for private(da) // expected-error {{const-qualified variable cannot be private}}
   for (int k = 0; k < argc; ++k) ++k;
 
   #pragma omp target
diff --git a/test/OpenMP/teams_distribute_parallel_for_simd_lastprivate_messages.cpp b/test/OpenMP/teams_distribute_parallel_for_simd_lastprivate_messages.cpp
index 416d409acc..7e78d06e93 100644
--- a/test/OpenMP/teams_distribute_parallel_for_simd_lastprivate_messages.cpp
+++ b/test/OpenMP/teams_distribute_parallel_for_simd_lastprivate_messages.cpp
@@ -20,7 +20,7 @@ public:
   const S2 &operator =(const S2&) const;
   S2 &operator =(const S2&);
   static float S2s; // expected-note {{static data member is predetermined as shared}}
-  static const float S2sc; // expected-note {{static data member is predetermined as shared}}
+  static const float S2sc; // expected-note {{'S2sc' declared here}}
 };
 const float S2::S2sc = 0;
 const S2 b;
@@ -33,9 +33,9 @@ public:
   S3() : a(0) {}
   S3(S3 &s3) : a(s3.a) {}
 };
-const S3 c;         // expected-note {{global variable is predetermined as shared}}
-const S3 ca[5];     // expected-note {{global variable is predetermined as shared}}
-extern const int f; // expected-note {{global variable is predetermined as shared}}
+const S3 c;         // expected-note {{'c' defined here}}
+const S3 ca[5];     // expected-note {{'ca' defined here}}
+extern const int f; // expected-note {{'f' declared here}}
 class S4 {
   int a;
   S4();             // expected-note 3 {{implicitly declared private here}}
@@ -152,8 +152,8 @@ using A::x;
 }
 
 int main(int argc, char **argv) {
-  const int d = 5;       // expected-note {{constant variable is predetermined as shared}}
-  const int da[5] = {0}; // expected-note {{constant variable is predetermined as shared}}
+  const int d = 5;       // expected-note {{'d' defined here}}
+  const int da[5] = {0}; // expected-note {{'da' defined here}}
   S4 e(4);
   S5 g(5);
   S3 m;
@@ -193,7 +193,7 @@ int main(int argc, char **argv) {
   for (i = 0; i < argc; ++i) foo();
 
 #pragma omp target
-#pragma omp teams distribute parallel for simd lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be lastprivate}}
+#pragma omp teams distribute parallel for simd lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 1 {{const-qualified variable without mutable fields cannot be lastprivate}} expected-error 2 {{const-qualified variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i) foo();
 
 #pragma omp target
@@ -209,11 +209,11 @@ int main(int argc, char **argv) {
   for (i = 0; i < argc; ++i) foo();
 
 #pragma omp target
-#pragma omp teams distribute parallel for simd lastprivate(ca) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp teams distribute parallel for simd lastprivate(ca) // expected-error {{const-qualified variable without mutable fields cannot be lastprivate}}
   for (i = 0; i < argc; ++i) foo();
 
 #pragma omp target
-#pragma omp teams distribute parallel for simd lastprivate(da) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp teams distribute parallel for simd lastprivate(da) // expected-error {{const-qualified variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i) foo();
 
   int xa;
@@ -226,7 +226,7 @@ int main(int argc, char **argv) {
   for (i = 0; i < argc; ++i) foo();
 
 #pragma omp target
-#pragma omp teams distribute parallel for simd lastprivate(S2::S2sc) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp teams distribute parallel for simd lastprivate(S2::S2sc) // expected-error {{const-qualified variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i) foo();
 
 #pragma omp target
diff --git a/test/OpenMP/teams_distribute_parallel_for_simd_private_messages.cpp b/test/OpenMP/teams_distribute_parallel_for_simd_private_messages.cpp
index 50bf034891..7bbe4c2f23 100644
--- a/test/OpenMP/teams_distribute_parallel_for_simd_private_messages.cpp
+++ b/test/OpenMP/teams_distribute_parallel_for_simd_private_messages.cpp
@@ -24,9 +24,9 @@ class S3 {
 public:
   S3():a(0) { }
 };
-const S3 c; // expected-note {{predetermined as shared}}
-const S3 ca[5]; // expected-note {{predetermined as shared}}
-extern const int f;  // expected-note {{predetermined as shared}}
+const S3 c; // expected-note {{'c' defined here}}
+const S3 ca[5]; // expected-note {{'ca' defined here}}
+extern const int f;  // expected-note {{'f' declared here}}
 class S4 {
   int a;
   S4(); // expected-note {{implicitly declared private here}}
@@ -45,8 +45,8 @@ S3 h;
 
 
 int main(int argc, char **argv) {
-  const int d = 5;  // expected-note {{predetermined as shared}}
-  const int da[5] = { 0 }; // expected-note {{predetermined as shared}}
+  const int d = 5;  // expected-note {{'d' defined here}}
+  const int da[5] = { 0 }; // expected-note {{'da' defined here}}
   S4 e(4);
   S5 g(5);
   int i;
@@ -85,7 +85,7 @@ int main(int argc, char **argv) {
   for (int k = 0; k < argc; ++k) ++k;
 
   #pragma omp target
-  #pragma omp teams distribute parallel for simd private (a, b, c, d, f) // expected-error {{private variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be private}}
+  #pragma omp teams distribute parallel for simd private (a, b, c, d, f) // expected-error {{private variable with incomplete type 'S1'}} expected-error 1 {{const-qualified variable without mutable fields cannot be private}} expected-error 2 {{const-qualified variable cannot be private}}
   for (int k = 0; k < argc; ++k) ++k;
 
   #pragma omp target
@@ -97,11 +97,11 @@ int main(int argc, char **argv) {
   for (int k = 0; k < argc; ++k) ++k;
 
   #pragma omp target
-  #pragma omp teams distribute parallel for simd private(ca) // expected-error {{shared variable cannot be private}}
+  #pragma omp teams distribute parallel for simd private(ca) // expected-error {{const-qualified variable without mutable fields cannot be private}}
   for (int k = 0; k < argc; ++k) ++k;
 
   #pragma omp target
-  #pragma omp teams distribute parallel for simd private(da) // expected-error {{shared variable cannot be private}}
+  #pragma omp teams distribute parallel for simd private(da) // expected-error {{const-qualified variable cannot be private}}
   for (int k = 0; k < argc; ++k) ++k;
 
   #pragma omp target
diff --git a/test/OpenMP/teams_distribute_private_messages.cpp b/test/OpenMP/teams_distribute_private_messages.cpp
index 5fa002aada..c24504460e 100644
--- a/test/OpenMP/teams_distribute_private_messages.cpp
+++ b/test/OpenMP/teams_distribute_private_messages.cpp
@@ -24,9 +24,9 @@ class S3 {
 public:
   S3():a(0) { }
 };
-const S3 c; // expected-note {{predetermined as shared}}
-const S3 ca[5]; // expected-note {{predetermined as shared}}
-extern const int f;  // expected-note {{predetermined as shared}}
+const S3 c; // expected-note {{'c' defined here}}
+const S3 ca[5]; // expected-note {{'ca' defined here}}
+extern const int f;  // expected-note {{'f' declared here}}
 class S4 {
   int a;
   S4(); // expected-note {{implicitly declared private here}}
@@ -45,8 +45,8 @@ S3 h;
 
 
 int main(int argc, char **argv) {
-  const int d = 5;  // expected-note {{predetermined as shared}}
-  const int da[5] = { 0 }; // expected-note {{predetermined as shared}}
+  const int d = 5;  // expected-note {{'d' defined here}}
+  const int da[5] = { 0 }; // expected-note {{'da' defined here}}
   S4 e(4);
   S5 g(5);
   int i;
@@ -85,7 +85,7 @@ int main(int argc, char **argv) {
   for (int k = 0; k < argc; ++k) ++k;
 
   #pragma omp target
-  #pragma omp teams distribute private (a, b, c, d, f) // expected-error {{private variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be private}}
+  #pragma omp teams distribute private (a, b, c, d, f) // expected-error {{private variable with incomplete type 'S1'}} expected-error 1 {{const-qualified variable without mutable fields cannot be private}} expected-error 2 {{const-qualified variable cannot be private}}
   for (int k = 0; k < argc; ++k) ++k;
 
   #pragma omp target
@@ -97,11 +97,11 @@ int main(int argc, char **argv) {
   for (int k = 0; k < argc; ++k) ++k;
 
   #pragma omp target
-  #pragma omp teams distribute private(ca) // expected-error {{shared variable cannot be private}}
+  #pragma omp teams distribute private(ca) // expected-error {{const-qualified variable without mutable fields cannot be private}}
   for (int k = 0; k < argc; ++k) ++k;
 
   #pragma omp target
-  #pragma omp teams distribute private(da) // expected-error {{shared variable cannot be private}}
+  #pragma omp teams distribute private(da) // expected-error {{const-qualified variable cannot be private}}
   for (int k = 0; k < argc; ++k) ++k;
 
   #pragma omp target
diff --git a/test/OpenMP/teams_distribute_simd_lastprivate_messages.cpp b/test/OpenMP/teams_distribute_simd_lastprivate_messages.cpp
index 08605912d8..5e0806b687 100644
--- a/test/OpenMP/teams_distribute_simd_lastprivate_messages.cpp
+++ b/test/OpenMP/teams_distribute_simd_lastprivate_messages.cpp
@@ -20,7 +20,7 @@ public:
   const S2 &operator =(const S2&) const;
   S2 &operator =(const S2&);
   static float S2s; // expected-note {{static data member is predetermined as shared}}
-  static const float S2sc; // expected-note {{static data member is predetermined as shared}}
+  static const float S2sc; // expected-note {{'S2sc' declared here}}
 };
 const float S2::S2sc = 0;
 const S2 b;
@@ -33,9 +33,9 @@ public:
   S3() : a(0) {}
   S3(S3 &s3) : a(s3.a) {}
 };
-const S3 c;         // expected-note {{global variable is predetermined as shared}}
-const S3 ca[5];     // expected-note {{global variable is predetermined as shared}}
-extern const int f; // expected-note {{global variable is predetermined as shared}}
+const S3 c;         // expected-note {{'c' defined here}}
+const S3 ca[5];     // expected-note {{'ca' defined here}}
+extern const int f; // expected-note {{'f' declared here}}
 class S4 {
   int a;
   S4();             // expected-note 3 {{implicitly declared private here}}
@@ -152,8 +152,8 @@ using A::x;
 }
 
 int main(int argc, char **argv) {
-  const int d = 5;       // expected-note {{constant variable is predetermined as shared}}
-  const int da[5] = {0}; // expected-note {{constant variable is predetermined as shared}}
+  const int d = 5;       // expected-note {{'d' defined here}}
+  const int da[5] = {0}; // expected-note {{'da' defined here}}
   S4 e(4);
   S5 g(5);
   S3 m;
@@ -193,7 +193,7 @@ int main(int argc, char **argv) {
   for (i = 0; i < argc; ++i) foo();
 
 #pragma omp target
-#pragma omp teams distribute simd lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be lastprivate}}
+#pragma omp teams distribute simd lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 1 {{const-qualified variable without mutable fields cannot be lastprivate}} expected-error 2 {{const-qualified variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i) foo();
 
 #pragma omp target
@@ -209,11 +209,11 @@ int main(int argc, char **argv) {
   for (i = 0; i < argc; ++i) foo();
 
 #pragma omp target
-#pragma omp teams distribute simd lastprivate(ca) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp teams distribute simd lastprivate(ca) // expected-error {{const-qualified variable without mutable fields cannot be lastprivate}}
   for (i = 0; i < argc; ++i) foo();
 
 #pragma omp target
-#pragma omp teams distribute simd lastprivate(da) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp teams distribute simd lastprivate(da) // expected-error {{const-qualified variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i) foo();
 
   int xa;
@@ -226,7 +226,7 @@ int main(int argc, char **argv) {
   for (i = 0; i < argc; ++i) foo();
 
 #pragma omp target
-#pragma omp teams distribute simd lastprivate(S2::S2sc) // expected-error {{shared variable cannot be lastprivate}}
+#pragma omp teams distribute simd lastprivate(S2::S2sc) // expected-error {{const-qualified variable cannot be lastprivate}}
   for (i = 0; i < argc; ++i) foo();
 
 #pragma omp target
diff --git a/test/OpenMP/teams_distribute_simd_private_messages.cpp b/test/OpenMP/teams_distribute_simd_private_messages.cpp
index 94fb9098a7..f2485b36a0 100644
--- a/test/OpenMP/teams_distribute_simd_private_messages.cpp
+++ b/test/OpenMP/teams_distribute_simd_private_messages.cpp
@@ -24,9 +24,9 @@ class S3 {
 public:
   S3():a(0) { }
 };
-const S3 c; // expected-note {{predetermined as shared}}
-const S3 ca[5]; // expected-note {{predetermined as shared}}
-extern const int f;  // expected-note {{predetermined as shared}}
+const S3 c; // expected-note {{'c' defined here}}
+const S3 ca[5]; // expected-note {{'ca' defined here}}
+extern const int f;  // expected-note {{'f' declared here}}
 class S4 {
   int a;
   S4(); // expected-note {{implicitly declared private here}}
@@ -45,8 +45,8 @@ S3 h;
 
 
 int main(int argc, char **argv) {
-  const int d = 5;  // expected-note {{predetermined as shared}}
-  const int da[5] = { 0 }; // expected-note {{predetermined as shared}}
+  const int d = 5;  // expected-note {{'d' defined here}}
+  const int da[5] = { 0 }; // expected-note {{'da' defined here}}
   S4 e(4);
   S5 g(5);
   int i;
@@ -85,7 +85,7 @@ int main(int argc, char **argv) {
   for (int k = 0; k < argc; ++k) ++k;
 
   #pragma omp target
-  #pragma omp teams distribute simd private (a, b, c, d, f) // expected-error {{private variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be private}}
+  #pragma omp teams distribute simd private (a, b, c, d, f) // expected-error {{private variable with incomplete type 'S1'}} expected-error 1 {{const-qualified variable without mutable fields cannot be private}} expected-error 2 {{const-qualified variable cannot be private}}
   for (int k = 0; k < argc; ++k) ++k;
 
   #pragma omp target
@@ -97,11 +97,11 @@ int main(int argc, char **argv) {
   for (int k = 0; k < argc; ++k) ++k;
 
   #pragma omp target
-  #pragma omp teams distribute simd private(ca) // expected-error {{shared variable cannot be private}}
+  #pragma omp teams distribute simd private(ca) // expected-error {{const-qualified variable without mutable fields cannot be private}}
   for (int k = 0; k < argc; ++k) ++k;
 
   #pragma omp target
-  #pragma omp teams distribute simd private(da) // expected-error {{shared variable cannot be private}}
+  #pragma omp teams distribute simd private(da) // expected-error {{const-qualified variable cannot be private}}
   for (int k = 0; k < argc; ++k) ++k;
 
   #pragma omp target
diff --git a/test/OpenMP/teams_private_messages.cpp b/test/OpenMP/teams_private_messages.cpp
index 30c7a0abd6..4ad7a0de29 100644
--- a/test/OpenMP/teams_private_messages.cpp
+++ b/test/OpenMP/teams_private_messages.cpp
@@ -24,9 +24,9 @@ class S3 {
 public:
   S3():a(0) { }
 };
-const S3 c; // expected-note {{global variable is predetermined as shared}}
-const S3 ca[5]; // expected-note {{global variable is predetermined as shared}}
-extern const int f; // expected-note {{global variable is predetermined as shared}}
+const S3 c; // expected-note {{'c' defined here}}
+const S3 ca[5]; // expected-note {{'ca' defined here}}
+extern const int f; // expected-note {{'f' declared here}}
 class S4 {
   int a;
   S4(); // expected-note {{implicitly declared private here}}
@@ -52,8 +52,8 @@ using A::x;
 }
 
 int main(int argc, char **argv) {
-  const int d = 5; // expected-note {{constant variable is predetermined as shared}}
-  const int da[5] = { 0 }; // expected-note {{constant variable is predetermined as shared}}
+  const int d = 5; // expected-note {{'d' defined here}}
+  const int da[5] = { 0 }; // expected-note {{'da' defined here}}
   S4 e(4);
   S5 g(5);
   int i;
@@ -83,7 +83,7 @@ int main(int argc, char **argv) {
   #pragma omp teams private (S1) // expected-error {{'S1' does not refer to a value}}
   foo();
   #pragma omp target
-  #pragma omp teams private (a, b, c, d, f) // expected-error {{a private variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be private}}
+  #pragma omp teams private (a, b, c, d, f) // expected-error {{a private variable with incomplete type 'S1'}} expected-error 1 {{const-qualified variable without mutable fields cannot be private}} expected-error 2 {{const-qualified variable cannot be private}}
   foo();
   #pragma omp target
   #pragma omp teams private (argv[1]) // expected-error {{expected variable name}}
@@ -92,10 +92,10 @@ int main(int argc, char **argv) {
   #pragma omp teams private(ba)
   foo();
   #pragma omp target
-  #pragma omp teams private(ca) // expected-error {{shared variable cannot be private}}
+  #pragma omp teams private(ca) // expected-error {{const-qualified variable without mutable fields cannot be private}}
   foo();
   #pragma omp target
-  #pragma omp teams private(da) // expected-error {{shared variable cannot be private}}
+  #pragma omp teams private(da) // expected-error {{const-qualified variable cannot be private}}
   foo();
   #pragma omp target
   #pragma omp teams private(S2::S2s) // expected-error {{shared variable cannot be private}}
-- 
cgit v1.2.3


From 5b0be04e490e2b66c2abb51292e01112b6834ef4 Mon Sep 17 00:00:00 2001
From: "Joel E. Denny" 
Date: Fri, 4 Jan 2019 22:11:56 +0000
Subject: [OpenMP] Refactor const restriction for reductions

As discussed in D56113, this patch refactors the implementation of the
const restriction for reductions to reuse a function introduced by
D56113.  A side effect is that diagnostics sometimes now say
"variable" instead of "list item" when a list item is a variable.

Reviewed By: ABataev

Differential Revision: https://reviews.llvm.org/D56298

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350440 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/Basic/DiagnosticSemaKinds.td         |  4 +-
 lib/Sema/SemaOpenMP.cpp                            | 60 +++++++++++-----------
 .../distribute_parallel_for_reduction_messages.cpp | 28 +++++-----
 ...ribute_parallel_for_simd_reduction_messages.cpp | 28 +++++-----
 test/OpenMP/distribute_simd_reduction_messages.cpp | 28 +++++-----
 test/OpenMP/for_reduction_messages.cpp             | 28 +++++-----
 test/OpenMP/for_simd_reduction_messages.cpp        | 28 +++++-----
 test/OpenMP/parallel_for_reduction_messages.cpp    | 28 +++++-----
 .../parallel_for_simd_reduction_messages.cpp       | 28 +++++-----
 test/OpenMP/parallel_reduction_messages.cpp        | 28 +++++-----
 .../parallel_sections_reduction_messages.cpp       | 28 +++++-----
 test/OpenMP/sections_reduction_messages.cpp        | 28 +++++-----
 test/OpenMP/simd_reduction_messages.cpp            | 28 +++++-----
 .../target_parallel_for_reduction_messages.cpp     | 28 +++++-----
 ...target_parallel_for_simd_reduction_messages.cpp | 28 +++++-----
 test/OpenMP/target_parallel_reduction_messages.cpp | 28 +++++-----
 test/OpenMP/target_reduction_messages.cpp          | 28 +++++-----
 test/OpenMP/target_simd_reduction_messages.cpp     | 28 +++++-----
 ..._distribute_parallel_for_reduction_messages.cpp | 28 +++++-----
 ...ribute_parallel_for_simd_reduction_messages.cpp | 28 +++++-----
 .../target_teams_distribute_reduction_messages.cpp | 28 +++++-----
 ...et_teams_distribute_simd_reduction_messages.cpp | 28 +++++-----
 test/OpenMP/target_teams_reduction_messages.cpp    | 28 +++++-----
 test/OpenMP/task_in_reduction_message.cpp          | 28 +++++-----
 test/OpenMP/taskgroup_task_reduction_messages.cpp  | 28 +++++-----
 test/OpenMP/taskloop_in_reduction_messages.cpp     | 28 +++++-----
 test/OpenMP/taskloop_reduction_messages.cpp        | 28 +++++-----
 .../OpenMP/taskloop_simd_in_reduction_messages.cpp | 28 +++++-----
 test/OpenMP/taskloop_simd_reduction_messages.cpp   | 28 +++++-----
 ..._distribute_parallel_for_reduction_messages.cpp | 28 +++++-----
 ...ribute_parallel_for_simd_reduction_messages.cpp | 28 +++++-----
 .../OpenMP/teams_distribute_reduction_messages.cpp | 28 +++++-----
 .../teams_distribute_simd_reduction_messages.cpp   | 28 +++++-----
 test/OpenMP/teams_reduction_messages.cpp           | 28 +++++-----
 34 files changed, 480 insertions(+), 480 deletions(-)

diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index da0bb5d987..fb6cd24dba 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -8780,8 +8780,8 @@ def err_omp_const_variable : Error<
   "const-qualified variable cannot be %0">;
 def err_omp_const_not_mutable_variable : Error<
   "const-qualified variable without mutable fields cannot be %0">;
-def err_omp_const_reduction_list_item : Error<
-  "const-qualified list item cannot be reduction">;
+def err_omp_const_list_item : Error<
+  "const-qualified list item cannot be %0">;
 def err_omp_linear_incomplete_type : Error<
   "a linear variable with incomplete type %0">;
 def err_omp_linear_expected_int_or_ptr : Error<
diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp
index 7b702250b8..87d33c09e5 100644
--- a/lib/Sema/SemaOpenMP.cpp
+++ b/lib/Sema/SemaOpenMP.cpp
@@ -1080,14 +1080,16 @@ bool DSAStackTy::isOpenMPLocal(VarDecl *D, iterator Iter) const {
   return false;
 }
 
-static bool isConstNotMutableType(Sema &SemaRef, ValueDecl *D,
+static bool isConstNotMutableType(Sema &SemaRef, QualType Type,
+                                  bool AcceptIfMutable = true,
                                   bool *IsClassType = nullptr) {
   ASTContext &Context = SemaRef.getASTContext();
-  QualType Type = D->getType().getNonReferenceType().getCanonicalType();
+  Type = Type.getNonReferenceType().getCanonicalType();
   bool IsConstant = Type.isConstant(Context);
   Type = Context.getBaseElementType(Type);
-  const CXXRecordDecl *RD =
-      SemaRef.getLangOpts().CPlusPlus ? Type->getAsCXXRecordDecl() : nullptr;
+  const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus
+                                ? Type->getAsCXXRecordDecl()
+                                : nullptr;
   if (const auto *CTSD = dyn_cast_or_null(RD))
     if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate())
       RD = CTD->getTemplatedDecl();
@@ -1097,21 +1099,27 @@ static bool isConstNotMutableType(Sema &SemaRef, ValueDecl *D,
                          RD->hasDefinition() && RD->hasMutableFields());
 }
 
-static bool rejectConstNotMutableType(Sema &SemaRef, ValueDecl *D,
-                                      OpenMPClauseKind CKind,
-                                      SourceLocation ELoc) {
+static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D,
+                                      QualType Type, OpenMPClauseKind CKind,
+                                      SourceLocation ELoc,
+                                      bool AcceptIfMutable = true,
+                                      bool ListItemNotVar = false) {
   ASTContext &Context = SemaRef.getASTContext();
   bool IsClassType;
-  if (isConstNotMutableType(SemaRef, D, &IsClassType)) {
-    SemaRef.Diag(ELoc, IsClassType ? diag::err_omp_const_not_mutable_variable
-                                   : diag::err_omp_const_variable)
-        << getOpenMPClauseName(CKind);
-    VarDecl *VD = dyn_cast(D);
-    bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
-                             VarDecl::DeclarationOnly;
-    SemaRef.Diag(D->getLocation(),
-                 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
-        << D;
+  if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) {
+    unsigned Diag = ListItemNotVar
+                        ? diag::err_omp_const_list_item
+                        : IsClassType ? diag::err_omp_const_not_mutable_variable
+                                      : diag::err_omp_const_variable;
+    SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind);
+    if (!ListItemNotVar && D) {
+      const VarDecl *VD = dyn_cast(D);
+      bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
+                               VarDecl::DeclarationOnly;
+      SemaRef.Diag(D->getLocation(),
+                   IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+          << D;
+    }
     return true;
   }
   return false;
@@ -1221,7 +1229,7 @@ const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D,
     // in a Construct, C/C++, predetermined, p.6]
     //  Variables with const qualified type having no mutable member are
     //  shared.
-    if (isConstNotMutableType(SemaRef, D)) {
+    if (isConstNotMutableType(SemaRef, D->getType())) {
       // Variables with const-qualified type having no mutable member may be
       // listed in a firstprivate clause, even if they are static data members.
       DSAVarData DVarTemp = hasInnermostDSA(
@@ -9830,7 +9838,7 @@ OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef VarList,
     // OpenMP 3.1 [2.9.3.3, private clause, Restrictions]
     // A variable that appears in a private clause must not have a
     // const-qualified type unless it is of class type with a mutable member.
-    if (rejectConstNotMutableType(*this, D, OMPC_private, ELoc))
+    if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc))
       continue;
 
     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
@@ -10262,7 +10270,7 @@ OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef VarList,
     // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions]
     // A variable that appears in a lastprivate clause must not have a
     // const-qualified type unless it is of class type with a mutable member.
-    if (rejectConstNotMutableType(*this, D, OMPC_lastprivate, ELoc))
+    if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc))
       continue;
 
     OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
@@ -10974,17 +10982,9 @@ static bool actOnOMPReductionKindClause(
     // OpenMP [2.14.3.6, reduction clause, Restrictions]
     // A list item that appears in a reduction clause must not be
     // const-qualified.
-    if (Type.getNonReferenceType().isConstant(Context)) {
-      S.Diag(ELoc, diag::err_omp_const_reduction_list_item) << ERange;
-      if (!ASE && !OASE) {
-        bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
-                                 VarDecl::DeclarationOnly;
-        S.Diag(D->getLocation(),
-               IsDecl ? diag::note_previous_decl : diag::note_defined_here)
-            << D;
-      }
+    if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc,
+                                  /*AcceptIfMutable*/ false, ASE || OASE))
       continue;
-    }
 
     OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective();
     // OpenMP [2.9.3.6, Restrictions, C/C++, p.4]
diff --git a/test/OpenMP/distribute_parallel_for_reduction_messages.cpp b/test/OpenMP/distribute_parallel_for_reduction_messages.cpp
index c3159c7c5f..e6be867f15 100644
--- a/test/OpenMP/distribute_parallel_for_reduction_messages.cpp
+++ b/test/OpenMP/distribute_parallel_for_reduction_messages.cpp
@@ -160,12 +160,12 @@ T tmain(T argc) {
     foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute parallel for reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}} expected-warning 2 {{Non-trivial type 'S2' is mapped, only trivial types are guaranteed to be mapped correctly}} expected-warning 2 {{Non-trivial type 'S3' is mapped, only trivial types are guaranteed to be mapped correctly}}
+#pragma omp distribute parallel for reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}} expected-warning 2 {{Non-trivial type 'S2' is mapped, only trivial types are guaranteed to be mapped correctly}} expected-warning 2 {{Non-trivial type 'S3' is mapped, only trivial types are guaranteed to be mapped correctly}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute parallel for reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
+#pragma omp distribute parallel for reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp target
@@ -175,17 +175,17 @@ T tmain(T argc) {
     foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute parallel for reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp distribute parallel for reduction(+ : ba) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute parallel for reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp distribute parallel for reduction(* : ca) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute parallel for reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp distribute parallel for reduction(- : da) // expected-error {{const-qualified variable cannot be reduction}} expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp target
@@ -200,7 +200,7 @@ T tmain(T argc) {
     foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute parallel for reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp distribute parallel for reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp target
@@ -231,7 +231,7 @@ T tmain(T argc) {
     foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute parallel for reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}}
+#pragma omp distribute parallel for reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel shared(i)
@@ -344,12 +344,12 @@ int main(int argc, char **argv) {
     foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute parallel for reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}} expected-error {{incomplete type 'S1' where a complete type is required}} expected-warning {{Non-trivial type 'S2' is mapped, only trivial types are guaranteed to be mapped correctly}} expected-warning {{Non-trivial type 'S3' is mapped, only trivial types are guaranteed to be mapped correctly}}
+#pragma omp distribute parallel for reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}} expected-error {{incomplete type 'S1' where a complete type is required}} expected-warning {{Non-trivial type 'S2' is mapped, only trivial types are guaranteed to be mapped correctly}} expected-warning {{Non-trivial type 'S3' is mapped, only trivial types are guaranteed to be mapped correctly}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute parallel for reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{incomplete type 'S1' where a complete type is required}} expected-warning {{Non-trivial type 'S2' is mapped, only trivial types are guaranteed to be mapped correctly}} expected-warning {{Non-trivial type 'S3' is mapped, only trivial types are guaranteed to be mapped correctly}}
+#pragma omp distribute parallel for reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{incomplete type 'S1' where a complete type is required}} expected-warning {{Non-trivial type 'S2' is mapped, only trivial types are guaranteed to be mapped correctly}} expected-warning {{Non-trivial type 'S3' is mapped, only trivial types are guaranteed to be mapped correctly}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp target
@@ -359,17 +359,17 @@ int main(int argc, char **argv) {
     foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute parallel for reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}} expected-warning {{Non-trivial type 'const S2 [5]' is mapped, only trivial types are guaranteed to be mapped correctl}}
+#pragma omp distribute parallel for reduction(+ : ba) // expected-error {{const-qualified variable cannot be reduction}} expected-warning {{Non-trivial type 'const S2 [5]' is mapped, only trivial types are guaranteed to be mapped correctl}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute parallel for reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}} expected-warning {{Non-trivial type 'const S3 [5]' is mapped, only trivial types are guaranteed to be mapped correctly}}
+#pragma omp distribute parallel for reduction(* : ca) // expected-error {{const-qualified variable cannot be reduction}} expected-warning {{Non-trivial type 'const S3 [5]' is mapped, only trivial types are guaranteed to be mapped correctly}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute parallel for reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp distribute parallel for reduction(- : da) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp target
@@ -384,7 +384,7 @@ int main(int argc, char **argv) {
     foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute parallel for reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp distribute parallel for reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp target
@@ -420,7 +420,7 @@ int main(int argc, char **argv) {
     foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute parallel for reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp distribute parallel for reduction(+ : r) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel shared(i)
diff --git a/test/OpenMP/distribute_parallel_for_simd_reduction_messages.cpp b/test/OpenMP/distribute_parallel_for_simd_reduction_messages.cpp
index bcccf0bfdb..046cce59dd 100644
--- a/test/OpenMP/distribute_parallel_for_simd_reduction_messages.cpp
+++ b/test/OpenMP/distribute_parallel_for_simd_reduction_messages.cpp
@@ -160,12 +160,12 @@ T tmain(T argc) {
     foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute parallel for simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
+#pragma omp distribute parallel for simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute parallel for simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
+#pragma omp distribute parallel for simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp target
@@ -175,17 +175,17 @@ T tmain(T argc) {
     foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute parallel for simd reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp distribute parallel for simd reduction(+ : ba) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute parallel for simd reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp distribute parallel for simd reduction(* : ca) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute parallel for simd reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp distribute parallel for simd reduction(- : da) // expected-error {{const-qualified variable cannot be reduction}} expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp target
@@ -200,7 +200,7 @@ T tmain(T argc) {
     foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute parallel for simd reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp distribute parallel for simd reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp target
@@ -231,7 +231,7 @@ T tmain(T argc) {
     foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute parallel for simd reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}}
+#pragma omp distribute parallel for simd reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel shared(i)
@@ -344,12 +344,12 @@ int main(int argc, char **argv) {
     foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute parallel for simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}} expected-error {{incomplete type 'S1' where a complete type is required}}
+#pragma omp distribute parallel for simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}} expected-error {{incomplete type 'S1' where a complete type is required}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute parallel for simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{incomplete type 'S1' where a complete type is required}}
+#pragma omp distribute parallel for simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{incomplete type 'S1' where a complete type is required}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp target
@@ -359,17 +359,17 @@ int main(int argc, char **argv) {
     foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute parallel for simd reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp distribute parallel for simd reduction(+ : ba) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute parallel for simd reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp distribute parallel for simd reduction(* : ca) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute parallel for simd reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp distribute parallel for simd reduction(- : da) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp target
@@ -384,7 +384,7 @@ int main(int argc, char **argv) {
     foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute parallel for simd reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp distribute parallel for simd reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp target
@@ -420,7 +420,7 @@ int main(int argc, char **argv) {
     foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute parallel for simd reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp distribute parallel for simd reduction(+ : r) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel shared(i)
diff --git a/test/OpenMP/distribute_simd_reduction_messages.cpp b/test/OpenMP/distribute_simd_reduction_messages.cpp
index 56f43a3b6d..f960b18319 100644
--- a/test/OpenMP/distribute_simd_reduction_messages.cpp
+++ b/test/OpenMP/distribute_simd_reduction_messages.cpp
@@ -160,12 +160,12 @@ T tmain(T argc) {
     foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}} expected-warning 2 {{Non-trivial type 'S2' is mapped, only trivial types are guaranteed to be mapped correctly}} expected-warning 2 {{Non-trivial type 'S3' is mapped, only trivial types are guaranteed to be mapped correctly}}
+#pragma omp distribute simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}} expected-warning 2 {{Non-trivial type 'S2' is mapped, only trivial types are guaranteed to be mapped correctly}} expected-warning 2 {{Non-trivial type 'S3' is mapped, only trivial types are guaranteed to be mapped correctly}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
+#pragma omp distribute simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp target
@@ -175,17 +175,17 @@ T tmain(T argc) {
     foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute simd reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp distribute simd reduction(+ : ba) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute simd reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp distribute simd reduction(* : ca) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute simd reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp distribute simd reduction(- : da) // expected-error {{const-qualified variable cannot be reduction}} expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp target
@@ -200,7 +200,7 @@ T tmain(T argc) {
     foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute simd reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp distribute simd reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp target
@@ -231,7 +231,7 @@ T tmain(T argc) {
     foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute simd reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}}
+#pragma omp distribute simd reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel shared(i)
@@ -344,12 +344,12 @@ int main(int argc, char **argv) {
     foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}} expected-warning {{Non-trivial type 'S2' is mapped, only trivial types are guaranteed to be mapped correctly}} expected-warning {{Non-trivial type 'S3' is mapped, only trivial types are guaranteed to be mapped correctly}} expected-error {{incomplete type 'S1' where a complete type is required}}
+#pragma omp distribute simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}} expected-warning {{Non-trivial type 'S2' is mapped, only trivial types are guaranteed to be mapped correctly}} expected-warning {{Non-trivial type 'S3' is mapped, only trivial types are guaranteed to be mapped correctly}} expected-error {{incomplete type 'S1' where a complete type is required}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-warning {{Non-trivial type 'S2' is mapped, only trivial types are guaranteed to be mapped correctly}} expected-warning {{Non-trivial type 'S3' is mapped, only trivial types are guaranteed to be mapped correctly}} expected-error {{incomplete type 'S1' where a complete type is required}}
+#pragma omp distribute simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-warning {{Non-trivial type 'S2' is mapped, only trivial types are guaranteed to be mapped correctly}} expected-warning {{Non-trivial type 'S3' is mapped, only trivial types are guaranteed to be mapped correctly}} expected-error {{incomplete type 'S1' where a complete type is required}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp target
@@ -359,17 +359,17 @@ int main(int argc, char **argv) {
     foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute simd reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}} expected-warning {{Non-trivial type 'const S2 [5]' is mapped, only trivial types are guaranteed to be mapped correctly}}
+#pragma omp distribute simd reduction(+ : ba) // expected-error {{const-qualified variable cannot be reduction}} expected-warning {{Non-trivial type 'const S2 [5]' is mapped, only trivial types are guaranteed to be mapped correctly}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute simd reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}} expected-warning {{Non-trivial type 'const S3 [5]' is mapped, only trivial types are guaranteed to be mapped correctly}}
+#pragma omp distribute simd reduction(* : ca) // expected-error {{const-qualified variable cannot be reduction}} expected-warning {{Non-trivial type 'const S3 [5]' is mapped, only trivial types are guaranteed to be mapped correctly}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute simd reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp distribute simd reduction(- : da) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp target
@@ -384,7 +384,7 @@ int main(int argc, char **argv) {
     foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute simd reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp distribute simd reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp target
@@ -426,7 +426,7 @@ int main(int argc, char **argv) {
     foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute simd reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp distribute simd reduction(+ : r) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel shared(i)
diff --git a/test/OpenMP/for_reduction_messages.cpp b/test/OpenMP/for_reduction_messages.cpp
index 520097de66..f575ee463d 100644
--- a/test/OpenMP/for_reduction_messages.cpp
+++ b/test/OpenMP/for_reduction_messages.cpp
@@ -146,11 +146,11 @@ T tmain(T argc) {
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel
-#pragma omp for reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
+#pragma omp for reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel
-#pragma omp for reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
+#pragma omp for reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel
@@ -158,15 +158,15 @@ T tmain(T argc) {
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel
-#pragma omp for reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp for reduction(+ : ba) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel
-#pragma omp for reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp for reduction(* : ca) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel
-#pragma omp for reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp for reduction(- : da) // expected-error {{const-qualified variable cannot be reduction}} expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel
@@ -178,7 +178,7 @@ T tmain(T argc) {
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel
-#pragma omp for reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp for reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel
@@ -202,7 +202,7 @@ T tmain(T argc) {
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel
-#pragma omp for reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}}
+#pragma omp for reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel shared(i)
@@ -303,11 +303,11 @@ int main(int argc, char **argv) {
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel
-#pragma omp for reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
+#pragma omp for reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel
-#pragma omp for reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified list item cannot be reduction}}
+#pragma omp for reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel
@@ -315,15 +315,15 @@ int main(int argc, char **argv) {
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel
-#pragma omp for reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp for reduction(+ : ba) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel
-#pragma omp for reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp for reduction(* : ca) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel
-#pragma omp for reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp for reduction(- : da) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel
@@ -335,7 +335,7 @@ int main(int argc, char **argv) {
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel
-#pragma omp for reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp for reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel
@@ -367,7 +367,7 @@ int main(int argc, char **argv) {
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel
-#pragma omp for reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp for reduction(+ : r) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel shared(i)
diff --git a/test/OpenMP/for_simd_reduction_messages.cpp b/test/OpenMP/for_simd_reduction_messages.cpp
index 1f5578e611..12368efccf 100644
--- a/test/OpenMP/for_simd_reduction_messages.cpp
+++ b/test/OpenMP/for_simd_reduction_messages.cpp
@@ -145,11 +145,11 @@ T tmain(T argc) {
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel
-#pragma omp for simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
+#pragma omp for simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel
-#pragma omp for simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
+#pragma omp for simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel
@@ -157,15 +157,15 @@ T tmain(T argc) {
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel
-#pragma omp for simd reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp for simd reduction(+ : ba) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel
-#pragma omp for simd reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp for simd reduction(* : ca) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel
-#pragma omp for simd reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp for simd reduction(- : da) // expected-error {{const-qualified variable cannot be reduction}} expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel
@@ -177,7 +177,7 @@ T tmain(T argc) {
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel
-#pragma omp for simd reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp for simd reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel
@@ -201,7 +201,7 @@ T tmain(T argc) {
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel
-#pragma omp for simd reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}}
+#pragma omp for simd reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel shared(i)
@@ -294,11 +294,11 @@ int main(int argc, char **argv) {
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel
-#pragma omp for simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
+#pragma omp for simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel
-#pragma omp for simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified list item cannot be reduction}}
+#pragma omp for simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel
@@ -306,15 +306,15 @@ int main(int argc, char **argv) {
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel
-#pragma omp for simd reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp for simd reduction(+ : ba) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel
-#pragma omp for simd reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp for simd reduction(* : ca) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel
-#pragma omp for simd reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp for simd reduction(- : da) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel
@@ -326,7 +326,7 @@ int main(int argc, char **argv) {
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel
-#pragma omp for simd reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp for simd reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel
@@ -354,7 +354,7 @@ int main(int argc, char **argv) {
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel
-#pragma omp for simd reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp for simd reduction(+ : r) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel shared(i)
diff --git a/test/OpenMP/parallel_for_reduction_messages.cpp b/test/OpenMP/parallel_for_reduction_messages.cpp
index 5cfc2b9041..c44ee676d6 100644
--- a/test/OpenMP/parallel_for_reduction_messages.cpp
+++ b/test/OpenMP/parallel_for_reduction_messages.cpp
@@ -136,22 +136,22 @@ T tmain(T argc) {
 #pragma omp parallel for reduction(^ : T) // expected-error {{'T' does not refer to a value}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp parallel for reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
+#pragma omp parallel for reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp parallel for reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
+#pragma omp parallel for reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel for reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp parallel for reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp parallel for reduction(+ : ba) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp parallel for reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp parallel for reduction(* : ca) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp parallel for reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp parallel for reduction(- : da) // expected-error {{const-qualified variable cannot be reduction}} expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel for reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
@@ -160,7 +160,7 @@ T tmain(T argc) {
 #pragma omp parallel for reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp parallel for reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp parallel for reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel for reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
@@ -179,7 +179,7 @@ T tmain(T argc) {
 #pragma omp parallel for reduction(+ : p), reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 2 {{previously referenced here}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp parallel for reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}}
+#pragma omp parallel for reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel shared(i)
@@ -258,22 +258,22 @@ int main(int argc, char **argv) {
 #pragma omp parallel for reduction(^ : S1) // expected-error {{'S1' does not refer to a value}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp parallel for reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
+#pragma omp parallel for reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp parallel for reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified list item cannot be reduction}}
+#pragma omp parallel for reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel for reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp parallel for reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp parallel for reduction(+ : ba) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp parallel for reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp parallel for reduction(* : ca) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp parallel for reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp parallel for reduction(- : da) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel for reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
@@ -282,7 +282,7 @@ int main(int argc, char **argv) {
 #pragma omp parallel for reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp parallel for reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp parallel for reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel for reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
@@ -304,7 +304,7 @@ int main(int argc, char **argv) {
 #pragma omp parallel for reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp parallel for reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp parallel for reduction(+ : r) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel shared(i)
diff --git a/test/OpenMP/parallel_for_simd_reduction_messages.cpp b/test/OpenMP/parallel_for_simd_reduction_messages.cpp
index 32222ac5a5..5be42461f0 100644
--- a/test/OpenMP/parallel_for_simd_reduction_messages.cpp
+++ b/test/OpenMP/parallel_for_simd_reduction_messages.cpp
@@ -130,22 +130,22 @@ T tmain(T argc) {
 #pragma omp parallel for simd reduction(^ : T) // expected-error {{'T' does not refer to a value}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp parallel for simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
+#pragma omp parallel for simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp parallel for simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
+#pragma omp parallel for simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel for simd reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp parallel for simd reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp parallel for simd reduction(+ : ba) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp parallel for simd reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp parallel for simd reduction(* : ca) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp parallel for simd reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp parallel for simd reduction(- : da) // expected-error {{const-qualified variable cannot be reduction}} expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel for simd reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
@@ -154,7 +154,7 @@ T tmain(T argc) {
 #pragma omp parallel for simd reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp parallel for simd reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp parallel for simd reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel for simd reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
@@ -173,7 +173,7 @@ T tmain(T argc) {
 #pragma omp parallel for simd reduction(+ : p), reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 2 {{previously referenced here}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp parallel for simd reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}}
+#pragma omp parallel for simd reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel shared(i)
@@ -252,22 +252,22 @@ int main(int argc, char **argv) {
 #pragma omp parallel for simd reduction(^ : S1) // expected-error {{'S1' does not refer to a value}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp parallel for simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
+#pragma omp parallel for simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp parallel for simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified list item cannot be reduction}}
+#pragma omp parallel for simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel for simd reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp parallel for simd reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp parallel for simd reduction(+ : ba) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp parallel for simd reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp parallel for simd reduction(* : ca) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp parallel for simd reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp parallel for simd reduction(- : da) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel for simd reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
@@ -276,7 +276,7 @@ int main(int argc, char **argv) {
 #pragma omp parallel for simd reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp parallel for simd reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp parallel for simd reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel for simd reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
@@ -298,7 +298,7 @@ int main(int argc, char **argv) {
 #pragma omp parallel for simd reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp parallel for simd reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp parallel for simd reduction(+ : r) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel shared(i)
diff --git a/test/OpenMP/parallel_reduction_messages.cpp b/test/OpenMP/parallel_reduction_messages.cpp
index b3619bb9ad..f520d4a0fa 100644
--- a/test/OpenMP/parallel_reduction_messages.cpp
+++ b/test/OpenMP/parallel_reduction_messages.cpp
@@ -116,23 +116,23 @@ T tmain(T argc) {
   foo();
 #pragma omp parallel reduction(^ : T) // expected-error {{'T' does not refer to a value}}
   foo();
-#pragma omp parallel reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
+#pragma omp parallel reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
   foo();
-#pragma omp parallel reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
+#pragma omp parallel reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified variable cannot be reduction}}
   foo();
 #pragma omp parallel reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
   foo();
-#pragma omp parallel reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp parallel reduction(+ : ba) // expected-error {{const-qualified variable cannot be reduction}}
   foo();
-#pragma omp parallel reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp parallel reduction(* : ca) // expected-error {{const-qualified variable cannot be reduction}}
   foo();
-#pragma omp parallel reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp parallel reduction(- : da) // expected-error {{const-qualified variable cannot be reduction}} expected-error {{const-qualified variable cannot be reduction}}
   foo();
 #pragma omp parallel reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
   foo();
 #pragma omp parallel reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
   foo();
-#pragma omp parallel reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp parallel reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   foo();
 #pragma omp parallel reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
   foo();
@@ -145,7 +145,7 @@ T tmain(T argc) {
   foo();
 #pragma omp parallel reduction(+ : p), reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 2 {{previously referenced here}}
   foo();
-#pragma omp parallel reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}}
+#pragma omp parallel reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be reduction}}
   foo();
 #pragma omp parallel shared(i)
 #pragma omp parallel reduction(min : i)
@@ -211,23 +211,23 @@ int main(int argc, char **argv) {
   foo();
 #pragma omp parallel reduction(^ : S1) // expected-error {{'S1' does not refer to a value}}
   foo();
-#pragma omp parallel reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
+#pragma omp parallel reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
   foo();
-#pragma omp parallel reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified list item cannot be reduction}}
+#pragma omp parallel reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be reduction}}
   foo();
 #pragma omp parallel reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
   foo();
-#pragma omp parallel reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp parallel reduction(+ : ba) // expected-error {{const-qualified variable cannot be reduction}}
   foo();
-#pragma omp parallel reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp parallel reduction(* : ca) // expected-error {{const-qualified variable cannot be reduction}}
   foo();
-#pragma omp parallel reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp parallel reduction(- : da) // expected-error {{const-qualified variable cannot be reduction}}
   foo();
 #pragma omp parallel reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
   foo();
 #pragma omp parallel reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
   foo();
-#pragma omp parallel reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp parallel reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   foo();
 #pragma omp parallel reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{nvalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
   foo();
@@ -242,7 +242,7 @@ int main(int argc, char **argv) {
   foo();
 #pragma omp parallel reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}}
   foo();
-#pragma omp parallel reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp parallel reduction(+ : r) // expected-error {{const-qualified variable cannot be reduction}}
   foo();
 #pragma omp parallel shared(i)
 #pragma omp parallel reduction(min : i)
diff --git a/test/OpenMP/parallel_sections_reduction_messages.cpp b/test/OpenMP/parallel_sections_reduction_messages.cpp
index bbd3737de5..ae8384adf0 100644
--- a/test/OpenMP/parallel_sections_reduction_messages.cpp
+++ b/test/OpenMP/parallel_sections_reduction_messages.cpp
@@ -144,11 +144,11 @@ T tmain(T argc) {
   {
     foo();
   }
-#pragma omp parallel sections reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
+#pragma omp parallel sections reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
   {
     foo();
   }
-#pragma omp parallel sections reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
+#pragma omp parallel sections reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified variable cannot be reduction}}
   {
     foo();
   }
@@ -156,15 +156,15 @@ T tmain(T argc) {
   {
     foo();
   }
-#pragma omp parallel sections reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp parallel sections reduction(+ : ba) // expected-error {{const-qualified variable cannot be reduction}}
   {
     foo();
   }
-#pragma omp parallel sections reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp parallel sections reduction(* : ca) // expected-error {{const-qualified variable cannot be reduction}}
   {
     foo();
   }
-#pragma omp parallel sections reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp parallel sections reduction(- : da) // expected-error {{const-qualified variable cannot be reduction}} expected-error {{const-qualified variable cannot be reduction}}
   {
     foo();
   }
@@ -176,7 +176,7 @@ T tmain(T argc) {
   {
     foo();
   }
-#pragma omp parallel sections reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp parallel sections reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   {
     foo();
   }
@@ -201,7 +201,7 @@ T tmain(T argc) {
   {
     foo();
   }
-#pragma omp parallel sections reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}}
+#pragma omp parallel sections reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be reduction}}
   {
     foo();
   }
@@ -297,11 +297,11 @@ int main(int argc, char **argv) {
   {
     foo();
   }
-#pragma omp parallel sections reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
+#pragma omp parallel sections reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
   {
     foo();
   }
-#pragma omp parallel sections reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified list item cannot be reduction}}
+#pragma omp parallel sections reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be reduction}}
   {
     foo();
   }
@@ -309,15 +309,15 @@ int main(int argc, char **argv) {
   {
     foo();
   }
-#pragma omp parallel sections reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp parallel sections reduction(+ : ba) // expected-error {{const-qualified variable cannot be reduction}}
   {
     foo();
   }
-#pragma omp parallel sections reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp parallel sections reduction(* : ca) // expected-error {{const-qualified variable cannot be reduction}}
   {
     foo();
   }
-#pragma omp parallel sections reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp parallel sections reduction(- : da) // expected-error {{const-qualified variable cannot be reduction}}
   {
     foo();
   }
@@ -329,7 +329,7 @@ int main(int argc, char **argv) {
   {
     foo();
   }
-#pragma omp parallel sections reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp parallel sections reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   {
     foo();
   }
@@ -358,7 +358,7 @@ int main(int argc, char **argv) {
   {
     foo();
   }
-#pragma omp parallel sections reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp parallel sections reduction(+ : r) // expected-error {{const-qualified variable cannot be reduction}}
   {
     foo();
   }
diff --git a/test/OpenMP/sections_reduction_messages.cpp b/test/OpenMP/sections_reduction_messages.cpp
index bf302cf7b3..72a48c9c43 100644
--- a/test/OpenMP/sections_reduction_messages.cpp
+++ b/test/OpenMP/sections_reduction_messages.cpp
@@ -159,12 +159,12 @@ T tmain(T argc) {
     foo();
   }
 #pragma omp parallel
-#pragma omp sections reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
+#pragma omp sections reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
   {
     foo();
   }
 #pragma omp parallel
-#pragma omp sections reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
+#pragma omp sections reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified variable cannot be reduction}}
   {
     foo();
   }
@@ -174,17 +174,17 @@ T tmain(T argc) {
     foo();
   }
 #pragma omp parallel
-#pragma omp sections reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp sections reduction(+ : ba) // expected-error {{const-qualified variable cannot be reduction}}
   {
     foo();
   }
 #pragma omp parallel
-#pragma omp sections reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp sections reduction(* : ca) // expected-error {{const-qualified variable cannot be reduction}}
   {
     foo();
   }
 #pragma omp parallel
-#pragma omp sections reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp sections reduction(- : da) // expected-error {{const-qualified variable cannot be reduction}} expected-error {{const-qualified variable cannot be reduction}}
   {
     foo();
   }
@@ -199,7 +199,7 @@ T tmain(T argc) {
     foo();
   }
 #pragma omp parallel
-#pragma omp sections reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp sections reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   {
     foo();
   }
@@ -229,7 +229,7 @@ T tmain(T argc) {
     foo();
   }
 #pragma omp parallel
-#pragma omp sections reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}}
+#pragma omp sections reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be reduction}}
   {
     foo();
   }
@@ -339,12 +339,12 @@ int main(int argc, char **argv) {
     foo();
   }
 #pragma omp parallel
-#pragma omp sections reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
+#pragma omp sections reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
   {
     foo();
   }
 #pragma omp parallel
-#pragma omp sections reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified list item cannot be reduction}}
+#pragma omp sections reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be reduction}}
   {
     foo();
   }
@@ -354,17 +354,17 @@ int main(int argc, char **argv) {
     foo();
   }
 #pragma omp parallel
-#pragma omp sections reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp sections reduction(+ : ba) // expected-error {{const-qualified variable cannot be reduction}}
   {
     foo();
   }
 #pragma omp parallel
-#pragma omp sections reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp sections reduction(* : ca) // expected-error {{const-qualified variable cannot be reduction}}
   {
     foo();
   }
 #pragma omp parallel
-#pragma omp sections reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp sections reduction(- : da) // expected-error {{const-qualified variable cannot be reduction}}
   {
     foo();
   }
@@ -379,7 +379,7 @@ int main(int argc, char **argv) {
     foo();
   }
 #pragma omp parallel
-#pragma omp sections reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp sections reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   {
     foo();
   }
@@ -414,7 +414,7 @@ int main(int argc, char **argv) {
     foo();
   }
 #pragma omp parallel
-#pragma omp sections reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp sections reduction(+ : r) // expected-error {{const-qualified variable cannot be reduction}}
   {
     foo();
   }
diff --git a/test/OpenMP/simd_reduction_messages.cpp b/test/OpenMP/simd_reduction_messages.cpp
index 135a3ca71f..1602aeb40f 100644
--- a/test/OpenMP/simd_reduction_messages.cpp
+++ b/test/OpenMP/simd_reduction_messages.cpp
@@ -130,22 +130,22 @@ T tmain(T argc) {
 #pragma omp simd reduction(^ : T) // expected-error {{'T' does not refer to a value}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
+#pragma omp simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
+#pragma omp simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp simd reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp simd reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp simd reduction(+ : ba) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp simd reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp simd reduction(* : ca) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp simd reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp simd reduction(- : da) // expected-error {{const-qualified variable cannot be reduction}} expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp simd reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
@@ -154,7 +154,7 @@ T tmain(T argc) {
 #pragma omp simd reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp simd reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp simd reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp simd reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
@@ -176,7 +176,7 @@ T tmain(T argc) {
 #pragma omp simd reduction(+ : p), reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 2 {{previously referenced here}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp simd reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}}
+#pragma omp simd reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel shared(i)
@@ -255,22 +255,22 @@ int main(int argc, char **argv) {
 #pragma omp simd reduction(^ : S1) // expected-error {{'S1' does not refer to a value}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
+#pragma omp simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified list item cannot be reduction}}
+#pragma omp simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp simd reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp simd reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp simd reduction(+ : ba) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp simd reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp simd reduction(* : ca) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp simd reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp simd reduction(- : da) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp simd reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
@@ -279,7 +279,7 @@ int main(int argc, char **argv) {
 #pragma omp simd reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp simd reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp simd reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp simd reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
@@ -301,7 +301,7 @@ int main(int argc, char **argv) {
 #pragma omp simd reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp simd reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp simd reduction(+ : r) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel shared(i)
diff --git a/test/OpenMP/target_parallel_for_reduction_messages.cpp b/test/OpenMP/target_parallel_for_reduction_messages.cpp
index 5cc40e9b99..7cb55129e2 100644
--- a/test/OpenMP/target_parallel_for_reduction_messages.cpp
+++ b/test/OpenMP/target_parallel_for_reduction_messages.cpp
@@ -130,22 +130,22 @@ T tmain(T argc) {
 #pragma omp target parallel for reduction(^ : T) // expected-error {{'T' does not refer to a value}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp target parallel for reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
+#pragma omp target parallel for reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp target parallel for reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
+#pragma omp target parallel for reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp target parallel for reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp target parallel for reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target parallel for reduction(+ : ba) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp target parallel for reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target parallel for reduction(* : ca) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp target parallel for reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target parallel for reduction(- : da) // expected-error {{const-qualified variable cannot be reduction}} expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp target parallel for reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
@@ -154,7 +154,7 @@ T tmain(T argc) {
 #pragma omp target parallel for reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp target parallel for reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target parallel for reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp target parallel for reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
@@ -173,7 +173,7 @@ T tmain(T argc) {
 #pragma omp target parallel for reduction(+ : p), reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 2 {{previously referenced here}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp target parallel for reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}}
+#pragma omp target parallel for reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel shared(i)
@@ -252,22 +252,22 @@ int main(int argc, char **argv) {
 #pragma omp target parallel for reduction(^ : S1) // expected-error {{'S1' does not refer to a value}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp target parallel for reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
+#pragma omp target parallel for reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp target parallel for reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified list item cannot be reduction}}
+#pragma omp target parallel for reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp target parallel for reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp target parallel for reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target parallel for reduction(+ : ba) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp target parallel for reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target parallel for reduction(* : ca) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp target parallel for reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target parallel for reduction(- : da) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp target parallel for reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
@@ -276,7 +276,7 @@ int main(int argc, char **argv) {
 #pragma omp target parallel for reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp target parallel for reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target parallel for reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp target parallel for reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
@@ -298,7 +298,7 @@ int main(int argc, char **argv) {
 #pragma omp target parallel for reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp target parallel for reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target parallel for reduction(+ : r) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel shared(i)
diff --git a/test/OpenMP/target_parallel_for_simd_reduction_messages.cpp b/test/OpenMP/target_parallel_for_simd_reduction_messages.cpp
index 30aaf832d6..eb3d756dce 100644
--- a/test/OpenMP/target_parallel_for_simd_reduction_messages.cpp
+++ b/test/OpenMP/target_parallel_for_simd_reduction_messages.cpp
@@ -130,22 +130,22 @@ T tmain(T argc) {
 #pragma omp target parallel for simd reduction(^ : T) // expected-error {{'T' does not refer to a value}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp target parallel for simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
+#pragma omp target parallel for simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp target parallel for simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
+#pragma omp target parallel for simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp target parallel for simd reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp target parallel for simd reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target parallel for simd reduction(+ : ba) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp target parallel for simd reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target parallel for simd reduction(* : ca) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp target parallel for simd reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target parallel for simd reduction(- : da) // expected-error {{const-qualified variable cannot be reduction}} expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp target parallel for simd reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
@@ -154,7 +154,7 @@ T tmain(T argc) {
 #pragma omp target parallel for simd reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp target parallel for simd reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target parallel for simd reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp target parallel for simd reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
@@ -173,7 +173,7 @@ T tmain(T argc) {
 #pragma omp target parallel for simd reduction(+ : p), reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 2 {{previously referenced here}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp target parallel for simd reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}}
+#pragma omp target parallel for simd reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel shared(i)
@@ -252,22 +252,22 @@ int main(int argc, char **argv) {
 #pragma omp target parallel for simd reduction(^ : S1) // expected-error {{'S1' does not refer to a value}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp target parallel for simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
+#pragma omp target parallel for simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp target parallel for simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified list item cannot be reduction}}
+#pragma omp target parallel for simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp target parallel for simd reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp target parallel for simd reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target parallel for simd reduction(+ : ba) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp target parallel for simd reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target parallel for simd reduction(* : ca) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp target parallel for simd reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target parallel for simd reduction(- : da) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp target parallel for simd reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
@@ -276,7 +276,7 @@ int main(int argc, char **argv) {
 #pragma omp target parallel for simd reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp target parallel for simd reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target parallel for simd reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp target parallel for simd reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
@@ -298,7 +298,7 @@ int main(int argc, char **argv) {
 #pragma omp target parallel for simd reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp target parallel for simd reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target parallel for simd reduction(+ : r) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel shared(i)
diff --git a/test/OpenMP/target_parallel_reduction_messages.cpp b/test/OpenMP/target_parallel_reduction_messages.cpp
index 6ea08848d5..63a00caf92 100644
--- a/test/OpenMP/target_parallel_reduction_messages.cpp
+++ b/test/OpenMP/target_parallel_reduction_messages.cpp
@@ -116,23 +116,23 @@ T tmain(T argc) {
   foo();
 #pragma omp target parallel reduction(^ : T) // expected-error {{'T' does not refer to a value}}
   foo();
-#pragma omp target parallel reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
+#pragma omp target parallel reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
   foo();
-#pragma omp target parallel reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
+#pragma omp target parallel reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified variable cannot be reduction}}
   foo();
 #pragma omp target parallel reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
   foo();
-#pragma omp target parallel reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target parallel reduction(+ : ba) // expected-error {{const-qualified variable cannot be reduction}}
   foo();
-#pragma omp target parallel reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target parallel reduction(* : ca) // expected-error {{const-qualified variable cannot be reduction}}
   foo();
-#pragma omp target parallel reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target parallel reduction(- : da) // expected-error {{const-qualified variable cannot be reduction}} expected-error {{const-qualified variable cannot be reduction}}
   foo();
 #pragma omp target parallel reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
   foo();
 #pragma omp target parallel reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
   foo();
-#pragma omp target parallel reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target parallel reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   foo();
 #pragma omp target parallel reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
   foo();
@@ -145,7 +145,7 @@ T tmain(T argc) {
   foo();
 #pragma omp target parallel reduction(+ : p), reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 2 {{previously referenced here}}
   foo();
-#pragma omp target parallel reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}}
+#pragma omp target parallel reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be reduction}}
   foo();
 #pragma omp target parallel shared(i)
   foo();
@@ -214,23 +214,23 @@ int main(int argc, char **argv) {
   foo();
 #pragma omp target parallel reduction(^ : S1) // expected-error {{'S1' does not refer to a value}}
   foo();
-#pragma omp target parallel reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
+#pragma omp target parallel reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
   foo();
-#pragma omp target parallel reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified list item cannot be reduction}}
+#pragma omp target parallel reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be reduction}}
   foo();
 #pragma omp target parallel reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
   foo();
-#pragma omp target parallel reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target parallel reduction(+ : ba) // expected-error {{const-qualified variable cannot be reduction}}
   foo();
-#pragma omp target parallel reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target parallel reduction(* : ca) // expected-error {{const-qualified variable cannot be reduction}}
   foo();
-#pragma omp target parallel reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target parallel reduction(- : da) // expected-error {{const-qualified variable cannot be reduction}}
   foo();
 #pragma omp target parallel reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
   foo();
 #pragma omp target parallel reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
   foo();
-#pragma omp target parallel reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target parallel reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   foo();
 #pragma omp target parallel reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{nvalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
   foo();
@@ -245,7 +245,7 @@ int main(int argc, char **argv) {
   foo();
 #pragma omp target parallel reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}}
   foo();
-#pragma omp target parallel reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target parallel reduction(+ : r) // expected-error {{const-qualified variable cannot be reduction}}
   foo();
 #pragma omp target parallel shared(i)
   foo();
diff --git a/test/OpenMP/target_reduction_messages.cpp b/test/OpenMP/target_reduction_messages.cpp
index ff936b8c19..29a12aba85 100644
--- a/test/OpenMP/target_reduction_messages.cpp
+++ b/test/OpenMP/target_reduction_messages.cpp
@@ -116,23 +116,23 @@ T tmain(T argc) {
   foo();
 #pragma omp target reduction(^ : T) // expected-error {{'T' does not refer to a value}}
   foo();
-#pragma omp target reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
+#pragma omp target reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
   foo();
-#pragma omp target reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
+#pragma omp target reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified variable cannot be reduction}}
   foo();
 #pragma omp target reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
   foo();
-#pragma omp target reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target reduction(+ : ba) // expected-error {{const-qualified variable cannot be reduction}}
   foo();
-#pragma omp target reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target reduction(* : ca) // expected-error {{const-qualified variable cannot be reduction}}
   foo();
-#pragma omp target reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target reduction(- : da) // expected-error {{const-qualified variable cannot be reduction}} expected-error {{const-qualified variable cannot be reduction}}
   foo();
 #pragma omp target reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
   foo();
 #pragma omp target reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
   foo();
-#pragma omp target reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   foo();
 #pragma omp target reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
   foo();
@@ -145,7 +145,7 @@ T tmain(T argc) {
   foo();
 #pragma omp target reduction(+ : p), reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 2 {{previously referenced here}}
   foo();
-#pragma omp target reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}}
+#pragma omp target reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be reduction}}
   foo();
 #pragma omp parallel shared(i)
 #pragma omp target reduction(min : i)
@@ -211,23 +211,23 @@ int main(int argc, char **argv) {
   foo();
 #pragma omp target reduction(^ : S1) // expected-error {{'S1' does not refer to a value}}
   foo();
-#pragma omp target reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
+#pragma omp target reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
   foo();
-#pragma omp target reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified list item cannot be reduction}}
+#pragma omp target reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be reduction}}
   foo();
 #pragma omp target reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
   foo();
-#pragma omp target reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target reduction(+ : ba) // expected-error {{const-qualified variable cannot be reduction}}
   foo();
-#pragma omp target reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target reduction(* : ca) // expected-error {{const-qualified variable cannot be reduction}}
   foo();
-#pragma omp target reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target reduction(- : da) // expected-error {{const-qualified variable cannot be reduction}}
   foo();
 #pragma omp target reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
   foo();
 #pragma omp target reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
   foo();
-#pragma omp target reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   foo();
 #pragma omp target reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{nvalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
   foo();
@@ -242,7 +242,7 @@ int main(int argc, char **argv) {
   foo();
 #pragma omp target reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}}
   foo();
-#pragma omp target reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target reduction(+ : r) // expected-error {{const-qualified variable cannot be reduction}}
   foo();
 #pragma omp parallel shared(i)
 #pragma omp target reduction(min : i)
diff --git a/test/OpenMP/target_simd_reduction_messages.cpp b/test/OpenMP/target_simd_reduction_messages.cpp
index 299c81315a..cf6c9f6295 100644
--- a/test/OpenMP/target_simd_reduction_messages.cpp
+++ b/test/OpenMP/target_simd_reduction_messages.cpp
@@ -130,22 +130,22 @@ T tmain(T argc) {
 #pragma omp target simd reduction(^ : T) // expected-error {{'T' does not refer to a value}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp target simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
+#pragma omp target simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp target simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
+#pragma omp target simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp target simd reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp target simd reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target simd reduction(+ : ba) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp target simd reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target simd reduction(* : ca) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp target simd reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target simd reduction(- : da) // expected-error {{const-qualified variable cannot be reduction}} expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp target simd reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
@@ -154,7 +154,7 @@ T tmain(T argc) {
 #pragma omp target simd reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp target simd reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target simd reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp target simd reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
@@ -173,7 +173,7 @@ T tmain(T argc) {
 #pragma omp target simd reduction(+ : p), reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 2 {{previously referenced here}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp target simd reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}}
+#pragma omp target simd reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel shared(i)
@@ -252,22 +252,22 @@ int main(int argc, char **argv) {
 #pragma omp target simd reduction(^ : S1) // expected-error {{'S1' does not refer to a value}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp target simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
+#pragma omp target simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp target simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified list item cannot be reduction}}
+#pragma omp target simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp target simd reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp target simd reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target simd reduction(+ : ba) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp target simd reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target simd reduction(* : ca) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp target simd reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target simd reduction(- : da) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp target simd reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
@@ -276,7 +276,7 @@ int main(int argc, char **argv) {
 #pragma omp target simd reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp target simd reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target simd reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp target simd reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
@@ -298,7 +298,7 @@ int main(int argc, char **argv) {
 #pragma omp target simd reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp target simd reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target simd reduction(+ : r) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel shared(i)
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_reduction_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_reduction_messages.cpp
index 53c41b6bb0..33a0e37b86 100644
--- a/test/OpenMP/target_teams_distribute_parallel_for_reduction_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_parallel_for_reduction_messages.cpp
@@ -111,23 +111,23 @@ T tmain(T argc) {
   for (int j=0; j<100; j++) foo();
 #pragma omp target teams distribute parallel for reduction(^ : T) // expected-error {{'T' does not refer to a value}}
   for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute parallel for reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
+#pragma omp target teams distribute parallel for reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
   for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute parallel for reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
+#pragma omp target teams distribute parallel for reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target teams distribute parallel for reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
   for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute parallel for reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target teams distribute parallel for reduction(+ : ba) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute parallel for reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target teams distribute parallel for reduction(* : ca) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute parallel for reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target teams distribute parallel for reduction(- : da) // expected-error {{const-qualified variable cannot be reduction}} expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target teams distribute parallel for reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target teams distribute parallel for reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute parallel for reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target teams distribute parallel for reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target teams distribute parallel for reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
@@ -140,7 +140,7 @@ T tmain(T argc) {
   for (int j=0; j<100; j++) foo();
 #pragma omp target teams distribute parallel for reduction(+ : p), reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 2 {{previously referenced here}}
   for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute parallel for reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}}
+#pragma omp target teams distribute parallel for reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp parallel shared(i)
 #pragma omp parallel reduction(min : i)
@@ -198,23 +198,23 @@ int main(int argc, char **argv) {
   for (int j=0; j<100; j++) foo();
 #pragma omp target teams distribute parallel for reduction(^ : S1) // expected-error {{'S1' does not refer to a value}}
   for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute parallel for reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
+#pragma omp target teams distribute parallel for reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
   for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute parallel for reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified list item cannot be reduction}}
+#pragma omp target teams distribute parallel for reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target teams distribute parallel for reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
   for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute parallel for reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target teams distribute parallel for reduction(+ : ba) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute parallel for reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target teams distribute parallel for reduction(* : ca) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute parallel for reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target teams distribute parallel for reduction(- : da) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target teams distribute parallel for reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target teams distribute parallel for reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute parallel for reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target teams distribute parallel for reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target teams distribute parallel for reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
   for (int j=0; j<100; j++) foo();
@@ -229,7 +229,7 @@ int main(int argc, char **argv) {
   for (int j=0; j<100; j++) foo();
 #pragma omp target teams distribute parallel for reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}}
   for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute parallel for reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target teams distribute parallel for reduction(+ : r) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp parallel shared(i)
 #pragma omp parallel reduction(min : i)
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_simd_reduction_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_simd_reduction_messages.cpp
index 8cd4acd878..d3d9c60091 100644
--- a/test/OpenMP/target_teams_distribute_parallel_for_simd_reduction_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_reduction_messages.cpp
@@ -111,23 +111,23 @@ T tmain(T argc) {
   for (int j=0; j<100; j++) foo();
 #pragma omp target teams distribute parallel for simd reduction(^ : T) // expected-error {{'T' does not refer to a value}}
   for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute parallel for simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
+#pragma omp target teams distribute parallel for simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
   for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute parallel for simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
+#pragma omp target teams distribute parallel for simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target teams distribute parallel for simd reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
   for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute parallel for simd reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target teams distribute parallel for simd reduction(+ : ba) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute parallel for simd reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target teams distribute parallel for simd reduction(* : ca) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute parallel for simd reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target teams distribute parallel for simd reduction(- : da) // expected-error {{const-qualified variable cannot be reduction}} expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target teams distribute parallel for simd reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target teams distribute parallel for simd reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute parallel for simd reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target teams distribute parallel for simd reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target teams distribute parallel for simd reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
@@ -140,7 +140,7 @@ T tmain(T argc) {
   for (int j=0; j<100; j++) foo();
 #pragma omp target teams distribute parallel for simd reduction(+ : p), reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 2 {{previously referenced here}}
   for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute parallel for simd reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}}
+#pragma omp target teams distribute parallel for simd reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp parallel shared(i)
 #pragma omp parallel reduction(min : i)
@@ -198,23 +198,23 @@ int main(int argc, char **argv) {
   for (int j=0; j<100; j++) foo();
 #pragma omp target teams distribute parallel for simd reduction(^ : S1) // expected-error {{'S1' does not refer to a value}}
   for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute parallel for simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
+#pragma omp target teams distribute parallel for simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
   for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute parallel for simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified list item cannot be reduction}}
+#pragma omp target teams distribute parallel for simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target teams distribute parallel for simd reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
   for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute parallel for simd reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target teams distribute parallel for simd reduction(+ : ba) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute parallel for simd reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target teams distribute parallel for simd reduction(* : ca) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute parallel for simd reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target teams distribute parallel for simd reduction(- : da) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target teams distribute parallel for simd reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target teams distribute parallel for simd reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute parallel for simd reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target teams distribute parallel for simd reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target teams distribute parallel for simd reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
   for (int j=0; j<100; j++) foo();
@@ -229,7 +229,7 @@ int main(int argc, char **argv) {
   for (int j=0; j<100; j++) foo();
 #pragma omp target teams distribute parallel for simd reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}}
   for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute parallel for simd reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target teams distribute parallel for simd reduction(+ : r) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp parallel shared(i)
 #pragma omp parallel reduction(min : i)
diff --git a/test/OpenMP/target_teams_distribute_reduction_messages.cpp b/test/OpenMP/target_teams_distribute_reduction_messages.cpp
index 38878fc74c..6a9e6782f6 100644
--- a/test/OpenMP/target_teams_distribute_reduction_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_reduction_messages.cpp
@@ -116,23 +116,23 @@ T tmain(T argc) {
   for (int j=0; j<100; j++) foo();
 #pragma omp target teams distribute reduction(^ : T) // expected-error {{'T' does not refer to a value}}
   for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
+#pragma omp target teams distribute reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
   for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
+#pragma omp target teams distribute reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target teams distribute reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
   for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target teams distribute reduction(+ : ba) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target teams distribute reduction(* : ca) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target teams distribute reduction(- : da) // expected-error {{const-qualified variable cannot be reduction}} expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target teams distribute reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target teams distribute reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target teams distribute reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target teams distribute reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
@@ -145,7 +145,7 @@ T tmain(T argc) {
   for (int j=0; j<100; j++) foo();
 #pragma omp target teams distribute reduction(+ : p), reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 2 {{previously referenced here}}
   for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}}
+#pragma omp target teams distribute reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp parallel shared(i)
 #pragma omp parallel reduction(min : i)
@@ -203,23 +203,23 @@ int main(int argc, char **argv) {
   for (int j=0; j<100; j++) foo();
 #pragma omp target teams distribute reduction(^ : S1) // expected-error {{'S1' does not refer to a value}}
   for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
+#pragma omp target teams distribute reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
   for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified list item cannot be reduction}}
+#pragma omp target teams distribute reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target teams distribute reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
   for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target teams distribute reduction(+ : ba) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target teams distribute reduction(* : ca) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target teams distribute reduction(- : da) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target teams distribute reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target teams distribute reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target teams distribute reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target teams distribute reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
   for (int j=0; j<100; j++) foo();
@@ -234,7 +234,7 @@ int main(int argc, char **argv) {
   for (int j=0; j<100; j++) foo();
 #pragma omp target teams distribute reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}}
   for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target teams distribute reduction(+ : r) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp parallel shared(i)
 #pragma omp parallel reduction(min : i)
diff --git a/test/OpenMP/target_teams_distribute_simd_reduction_messages.cpp b/test/OpenMP/target_teams_distribute_simd_reduction_messages.cpp
index b77082b44a..1b4b3ed88c 100644
--- a/test/OpenMP/target_teams_distribute_simd_reduction_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_simd_reduction_messages.cpp
@@ -111,23 +111,23 @@ T tmain(T argc) {
   for (int j=0; j<100; j++) foo();
 #pragma omp target teams distribute simd reduction(^ : T) // expected-error {{'T' does not refer to a value}}
   for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
+#pragma omp target teams distribute simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
   for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
+#pragma omp target teams distribute simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target teams distribute simd reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
   for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute simd reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target teams distribute simd reduction(+ : ba) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute simd reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target teams distribute simd reduction(* : ca) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute simd reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target teams distribute simd reduction(- : da) // expected-error {{const-qualified variable cannot be reduction}} expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target teams distribute simd reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target teams distribute simd reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute simd reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target teams distribute simd reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target teams distribute simd reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
@@ -140,7 +140,7 @@ T tmain(T argc) {
   for (int j=0; j<100; j++) foo();
 #pragma omp target teams distribute simd reduction(+ : p), reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 2 {{previously referenced here}}
   for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute simd reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}}
+#pragma omp target teams distribute simd reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp parallel shared(i)
 #pragma omp parallel reduction(min : i)
@@ -198,23 +198,23 @@ int main(int argc, char **argv) {
   for (int j=0; j<100; j++) foo();
 #pragma omp target teams distribute simd reduction(^ : S1) // expected-error {{'S1' does not refer to a value}}
   for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
+#pragma omp target teams distribute simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
   for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified list item cannot be reduction}}
+#pragma omp target teams distribute simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target teams distribute simd reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
   for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute simd reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target teams distribute simd reduction(+ : ba) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute simd reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target teams distribute simd reduction(* : ca) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute simd reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target teams distribute simd reduction(- : da) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target teams distribute simd reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target teams distribute simd reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute simd reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target teams distribute simd reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target teams distribute simd reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
   for (int j=0; j<100; j++) foo();
@@ -229,7 +229,7 @@ int main(int argc, char **argv) {
   for (int j=0; j<100; j++) foo();
 #pragma omp target teams distribute simd reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}}
   for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute simd reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target teams distribute simd reduction(+ : r) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp parallel shared(i)
 #pragma omp parallel reduction(min : i)
diff --git a/test/OpenMP/target_teams_reduction_messages.cpp b/test/OpenMP/target_teams_reduction_messages.cpp
index c62f2c5844..1c3eacfef4 100644
--- a/test/OpenMP/target_teams_reduction_messages.cpp
+++ b/test/OpenMP/target_teams_reduction_messages.cpp
@@ -116,23 +116,23 @@ T tmain(T argc) {
   foo();
 #pragma omp target teams reduction(^ : T) // expected-error {{'T' does not refer to a value}}
   foo();
-#pragma omp target teams reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
+#pragma omp target teams reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
   foo();
-#pragma omp target teams reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
+#pragma omp target teams reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified variable cannot be reduction}}
   foo();
 #pragma omp target teams reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
   foo();
-#pragma omp target teams reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target teams reduction(+ : ba) // expected-error {{const-qualified variable cannot be reduction}}
   foo();
-#pragma omp target teams reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target teams reduction(* : ca) // expected-error {{const-qualified variable cannot be reduction}}
   foo();
-#pragma omp target teams reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target teams reduction(- : da) // expected-error {{const-qualified variable cannot be reduction}} expected-error {{const-qualified variable cannot be reduction}}
   foo();
 #pragma omp target teams reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
   foo();
 #pragma omp target teams reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
   foo();
-#pragma omp target teams reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target teams reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   foo();
 #pragma omp target teams reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
   foo();
@@ -145,7 +145,7 @@ T tmain(T argc) {
   foo();
 #pragma omp target teams reduction(+ : p), reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 2 {{previously referenced here}}
   foo();
-#pragma omp target teams reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}}
+#pragma omp target teams reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be reduction}}
   foo();
 #pragma omp parallel shared(i)
 #pragma omp parallel reduction(min : i)
@@ -213,23 +213,23 @@ int main(int argc, char **argv) {
   foo();
 #pragma omp target teams reduction(^ : S1) // expected-error {{'S1' does not refer to a value}}
   foo();
-#pragma omp target teams reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
+#pragma omp target teams reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
   foo();
-#pragma omp target teams reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified list item cannot be reduction}}
+#pragma omp target teams reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be reduction}}
   foo();
 #pragma omp target teams reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
   foo();
-#pragma omp target teams reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target teams reduction(+ : ba) // expected-error {{const-qualified variable cannot be reduction}}
   foo();
-#pragma omp target teams reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target teams reduction(* : ca) // expected-error {{const-qualified variable cannot be reduction}}
   foo();
-#pragma omp target teams reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target teams reduction(- : da) // expected-error {{const-qualified variable cannot be reduction}}
   foo();
 #pragma omp target teams reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
   foo();
 #pragma omp target teams reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
   foo();
-#pragma omp target teams reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target teams reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   foo();
 #pragma omp target teams reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
   foo();
@@ -244,7 +244,7 @@ int main(int argc, char **argv) {
   foo();
 #pragma omp target teams reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}}
   foo();
-#pragma omp target teams reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp target teams reduction(+ : r) // expected-error {{const-qualified variable cannot be reduction}}
   foo();
 #pragma omp parallel shared(i)
 #pragma omp parallel reduction(min : i)
diff --git a/test/OpenMP/task_in_reduction_message.cpp b/test/OpenMP/task_in_reduction_message.cpp
index d99d2e42d7..e9bde31ec9 100644
--- a/test/OpenMP/task_in_reduction_message.cpp
+++ b/test/OpenMP/task_in_reduction_message.cpp
@@ -154,23 +154,23 @@ T tmain(T argc) {
 #pragma omp task in_reduction(^ : T) // expected-error {{'T' does not refer to a value}}
   foo();
 #pragma omp taskgroup task_reduction(+:c)
-#pragma omp task in_reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}} expected-error 2 {{in_reduction variable must appear in a task_reduction clause}}
+#pragma omp task in_reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be in_reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}} expected-error 2 {{in_reduction variable must appear in a task_reduction clause}}
   foo();
-#pragma omp task in_reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'in_reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
+#pragma omp task in_reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'in_reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified variable cannot be in_reduction}}
   foo();
 #pragma omp task in_reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
   foo();
-#pragma omp task in_reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp task in_reduction(+ : ba) // expected-error {{const-qualified variable cannot be in_reduction}}
   foo();
-#pragma omp task in_reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp task in_reduction(* : ca) // expected-error {{const-qualified variable cannot be in_reduction}}
   foo();
-#pragma omp task in_reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp task in_reduction(- : da) // expected-error {{const-qualified variable cannot be in_reduction}} expected-error {{const-qualified variable cannot be in_reduction}}
   foo();
 #pragma omp task in_reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} expected-error {{in_reduction variable must appear in a task_reduction clause}}
   foo();
 #pragma omp task in_reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
   foo();
-#pragma omp task in_reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp task in_reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be in_reduction}}
   foo();
 #pragma omp taskgroup task_reduction(+:k)
 #pragma omp task in_reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
@@ -183,7 +183,7 @@ T tmain(T argc) {
 #pragma omp taskgroup task_reduction(+:p)
 #pragma omp task in_reduction(+ : p), in_reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'in_reduction' clause}} expected-note 2 {{previously referenced here}}
   foo();
-#pragma omp task in_reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}}
+#pragma omp task in_reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be in_reduction}}
   foo();
 #pragma omp parallel shared(i)
 #pragma omp parallel reduction(min : i)
@@ -258,23 +258,23 @@ int main(int argc, char **argv) {
 #pragma omp task in_reduction(^ : S1) // expected-error {{'S1' does not refer to a value}}
   foo();
 #pragma omp taskgroup task_reduction(+:c)
-#pragma omp task in_reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}} expected-error {{in_reduction variable must appear in a task_reduction clause}}
+#pragma omp task in_reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be in_reduction}} expected-error {{'operator+' is a private member of 'S2'}} expected-error {{in_reduction variable must appear in a task_reduction clause}}
   foo();
-#pragma omp task in_reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'in_reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified list item cannot be reduction}}
+#pragma omp task in_reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'in_reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be in_reduction}}
   foo();
 #pragma omp task in_reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
   foo();
-#pragma omp task in_reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp task in_reduction(+ : ba) // expected-error {{const-qualified variable cannot be in_reduction}}
   foo();
-#pragma omp task in_reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp task in_reduction(* : ca) // expected-error {{const-qualified variable cannot be in_reduction}}
   foo();
-#pragma omp task in_reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp task in_reduction(- : da) // expected-error {{const-qualified variable cannot be in_reduction}}
   foo();
 #pragma omp task in_reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
   foo();
 #pragma omp task in_reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
   foo();
-#pragma omp task in_reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp task in_reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be in_reduction}}
   foo();
 #pragma omp task in_reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{nvalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
   foo();
@@ -289,7 +289,7 @@ int main(int argc, char **argv) {
 #pragma omp taskgroup task_reduction(+:p)
 #pragma omp task in_reduction(+ : p), in_reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'in_reduction' clause}} expected-note {{previously referenced here}}
   foo();
-#pragma omp task in_reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp task in_reduction(+ : r) // expected-error {{const-qualified variable cannot be in_reduction}}
   foo();
 #pragma omp parallel shared(i)
 #pragma omp parallel reduction(min : i)
diff --git a/test/OpenMP/taskgroup_task_reduction_messages.cpp b/test/OpenMP/taskgroup_task_reduction_messages.cpp
index 59ff2190bb..56abe2abe6 100644
--- a/test/OpenMP/taskgroup_task_reduction_messages.cpp
+++ b/test/OpenMP/taskgroup_task_reduction_messages.cpp
@@ -116,23 +116,23 @@ T tmain(T argc) {
   foo();
 #pragma omp taskgroup task_reduction(^ : T) // expected-error {{'T' does not refer to a value}}
   foo();
-#pragma omp taskgroup task_reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
+#pragma omp taskgroup task_reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be task_reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
   foo();
-#pragma omp taskgroup task_reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'task_reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
+#pragma omp taskgroup task_reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'task_reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified variable cannot be task_reduction}}
   foo();
 #pragma omp taskgroup task_reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
   foo();
-#pragma omp taskgroup task_reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp taskgroup task_reduction(+ : ba) // expected-error {{const-qualified variable cannot be task_reduction}}
   foo();
-#pragma omp taskgroup task_reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp taskgroup task_reduction(* : ca) // expected-error {{const-qualified variable cannot be task_reduction}}
   foo();
-#pragma omp taskgroup task_reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp taskgroup task_reduction(- : da) // expected-error {{const-qualified variable cannot be task_reduction}} expected-error {{const-qualified variable cannot be task_reduction}}
   foo();
 #pragma omp taskgroup task_reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
   foo();
 #pragma omp taskgroup task_reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
   foo();
-#pragma omp taskgroup task_reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp taskgroup task_reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be task_reduction}}
   foo();
 #pragma omp taskgroup task_reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
   foo();
@@ -143,7 +143,7 @@ T tmain(T argc) {
   foo();
 #pragma omp taskgroup task_reduction(+ : p), task_reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'task_reduction' clause}} expected-note 2 {{previously referenced here}}
   foo();
-#pragma omp taskgroup task_reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}}
+#pragma omp taskgroup task_reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be task_reduction}}
   foo();
 #pragma omp parallel shared(i)
 #pragma omp parallel reduction(min : i)
@@ -209,23 +209,23 @@ int main(int argc, char **argv) {
   foo();
 #pragma omp taskgroup task_reduction(^ : S1) // expected-error {{'S1' does not refer to a value}}
   foo();
-#pragma omp taskgroup task_reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
+#pragma omp taskgroup task_reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be task_reduction}} expected-error {{'operator+' is a private member of 'S2'}}
   foo();
-#pragma omp taskgroup task_reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'task_reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified list item cannot be reduction}}
+#pragma omp taskgroup task_reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'task_reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be task_reduction}}
   foo();
 #pragma omp taskgroup task_reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
   foo();
-#pragma omp taskgroup task_reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp taskgroup task_reduction(+ : ba) // expected-error {{const-qualified variable cannot be task_reduction}}
   foo();
-#pragma omp taskgroup task_reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp taskgroup task_reduction(* : ca) // expected-error {{const-qualified variable cannot be task_reduction}}
   foo();
-#pragma omp taskgroup task_reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp taskgroup task_reduction(- : da) // expected-error {{const-qualified variable cannot be task_reduction}}
   foo();
 #pragma omp taskgroup task_reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
   foo();
 #pragma omp taskgroup task_reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
   foo();
-#pragma omp taskgroup task_reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp taskgroup task_reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be task_reduction}}
   foo();
 #pragma omp taskgroup task_reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{nvalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
   foo();
@@ -238,7 +238,7 @@ int main(int argc, char **argv) {
   foo();
 #pragma omp taskgroup task_reduction(+ : p), task_reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'task_reduction' clause}} expected-note {{previously referenced here}}
   foo();
-#pragma omp taskgroup task_reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp taskgroup task_reduction(+ : r) // expected-error {{const-qualified variable cannot be task_reduction}}
   foo();
 #pragma omp parallel shared(i)
 #pragma omp parallel reduction(min : i)
diff --git a/test/OpenMP/taskloop_in_reduction_messages.cpp b/test/OpenMP/taskloop_in_reduction_messages.cpp
index dc19bac907..177217888e 100644
--- a/test/OpenMP/taskloop_in_reduction_messages.cpp
+++ b/test/OpenMP/taskloop_in_reduction_messages.cpp
@@ -171,22 +171,22 @@ T tmain(T argc) {
   for (int i = 0; i < 10; ++i)
   foo();
 #pragma omp taskgroup task_reduction(+:c)
-#pragma omp taskloop in_reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}} expected-error 2 {{in_reduction variable must appear in a task_reduction clause}}
+#pragma omp taskloop in_reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be in_reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}} expected-error 2 {{in_reduction variable must appear in a task_reduction clause}}
   for (int i = 0; i < 10; ++i)
   foo();
-#pragma omp taskloop in_reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'in_reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
+#pragma omp taskloop in_reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'in_reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified variable cannot be in_reduction}}
   for (int i = 0; i < 10; ++i)
   foo();
 #pragma omp taskloop in_reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
   for (int i = 0; i < 10; ++i)
   foo();
-#pragma omp taskloop in_reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp taskloop in_reduction(+ : ba) // expected-error {{const-qualified variable cannot be in_reduction}}
   for (int i = 0; i < 10; ++i)
   foo();
-#pragma omp taskloop in_reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp taskloop in_reduction(* : ca) // expected-error {{const-qualified variable cannot be in_reduction}}
   for (int i = 0; i < 10; ++i)
   foo();
-#pragma omp taskloop in_reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp taskloop in_reduction(- : da) // expected-error {{const-qualified variable cannot be in_reduction}} expected-error {{const-qualified variable cannot be in_reduction}}
   for (int i = 0; i < 10; ++i)
   foo();
 #pragma omp taskloop in_reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} expected-error {{in_reduction variable must appear in a task_reduction clause}}
@@ -195,7 +195,7 @@ T tmain(T argc) {
 #pragma omp taskloop in_reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
   foo();
-#pragma omp taskloop in_reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp taskloop in_reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be in_reduction}}
   for (int i = 0; i < 10; ++i)
   foo();
 #pragma omp taskgroup task_reduction(+:k)
@@ -213,7 +213,7 @@ T tmain(T argc) {
 #pragma omp taskloop in_reduction(+ : p), in_reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'in_reduction' clause}} expected-note 2 {{previously referenced here}}
   for (int i = 0; i < 10; ++i)
   foo();
-#pragma omp taskloop in_reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}}
+#pragma omp taskloop in_reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be in_reduction}}
   for (int i = 0; i < 10; ++i)
   foo();
 #pragma omp parallel shared(i)
@@ -306,22 +306,22 @@ int main(int argc, char **argv) {
   for (int i = 0; i < 10; ++i)
   foo();
 #pragma omp taskgroup task_reduction(+:c)
-#pragma omp taskloop in_reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}} expected-error {{in_reduction variable must appear in a task_reduction clause}}
+#pragma omp taskloop in_reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be in_reduction}} expected-error {{'operator+' is a private member of 'S2'}} expected-error {{in_reduction variable must appear in a task_reduction clause}}
   for (int i = 0; i < 10; ++i)
   foo();
-#pragma omp taskloop in_reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'in_reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified list item cannot be reduction}}
+#pragma omp taskloop in_reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'in_reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be in_reduction}}
   for (int i = 0; i < 10; ++i)
   foo();
 #pragma omp taskloop in_reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
   for (int i = 0; i < 10; ++i)
   foo();
-#pragma omp taskloop in_reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp taskloop in_reduction(+ : ba) // expected-error {{const-qualified variable cannot be in_reduction}}
   for (int i = 0; i < 10; ++i)
   foo();
-#pragma omp taskloop in_reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp taskloop in_reduction(* : ca) // expected-error {{const-qualified variable cannot be in_reduction}}
   for (int i = 0; i < 10; ++i)
   foo();
-#pragma omp taskloop in_reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp taskloop in_reduction(- : da) // expected-error {{const-qualified variable cannot be in_reduction}}
   for (int i = 0; i < 10; ++i)
   foo();
 #pragma omp taskloop in_reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
@@ -330,7 +330,7 @@ int main(int argc, char **argv) {
 #pragma omp taskloop in_reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
   foo();
-#pragma omp taskloop in_reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp taskloop in_reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be in_reduction}}
   for (int i = 0; i < 10; ++i)
   foo();
 #pragma omp taskloop in_reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{nvalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
@@ -351,7 +351,7 @@ int main(int argc, char **argv) {
 #pragma omp taskloop in_reduction(+ : p), in_reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'in_reduction' clause}} expected-note {{previously referenced here}}
   for (int i = 0; i < 10; ++i)
   foo();
-#pragma omp taskloop in_reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp taskloop in_reduction(+ : r) // expected-error {{const-qualified variable cannot be in_reduction}}
   for (int i = 0; i < 10; ++i)
   foo();
 #pragma omp parallel shared(i)
diff --git a/test/OpenMP/taskloop_reduction_messages.cpp b/test/OpenMP/taskloop_reduction_messages.cpp
index c83a8b30c5..4794c7a2d0 100644
--- a/test/OpenMP/taskloop_reduction_messages.cpp
+++ b/test/OpenMP/taskloop_reduction_messages.cpp
@@ -139,22 +139,22 @@ T tmain(T argc) {
 #pragma omp taskloop reduction(^ : T) // expected-error {{'T' does not refer to a value}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp taskloop reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
+#pragma omp taskloop reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp taskloop reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
+#pragma omp taskloop reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp taskloop reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp taskloop reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp taskloop reduction(+ : ba) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp taskloop reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp taskloop reduction(* : ca) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp taskloop reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp taskloop reduction(- : da) // expected-error {{const-qualified variable cannot be reduction}} expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp taskloop reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
@@ -163,7 +163,7 @@ T tmain(T argc) {
 #pragma omp taskloop reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp taskloop reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp taskloop reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp taskloop reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
@@ -182,7 +182,7 @@ T tmain(T argc) {
 #pragma omp taskloop reduction(+ : p), reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 2 {{previously referenced here}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp taskloop reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}}
+#pragma omp taskloop reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel shared(i)
@@ -261,22 +261,22 @@ int main(int argc, char **argv) {
 #pragma omp taskloop reduction(^ : S1) // expected-error {{'S1' does not refer to a value}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp taskloop reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
+#pragma omp taskloop reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp taskloop reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified list item cannot be reduction}}
+#pragma omp taskloop reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp taskloop reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp taskloop reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp taskloop reduction(+ : ba) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp taskloop reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp taskloop reduction(* : ca) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp taskloop reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp taskloop reduction(- : da) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp taskloop reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
@@ -285,7 +285,7 @@ int main(int argc, char **argv) {
 #pragma omp taskloop reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp taskloop reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp taskloop reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp taskloop reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
@@ -307,7 +307,7 @@ int main(int argc, char **argv) {
 #pragma omp taskloop reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp taskloop reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp taskloop reduction(+ : r) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel shared(i)
diff --git a/test/OpenMP/taskloop_simd_in_reduction_messages.cpp b/test/OpenMP/taskloop_simd_in_reduction_messages.cpp
index ee3d093766..5fa976b229 100644
--- a/test/OpenMP/taskloop_simd_in_reduction_messages.cpp
+++ b/test/OpenMP/taskloop_simd_in_reduction_messages.cpp
@@ -171,22 +171,22 @@ T tmain(T argc) {
   for (int i = 0; i < 10; ++i)
   foo();
 #pragma omp taskgroup task_reduction(+:c)
-#pragma omp taskloop simd in_reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}} expected-error 2 {{in_reduction variable must appear in a task_reduction clause}}
+#pragma omp taskloop simd in_reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be in_reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}} expected-error 2 {{in_reduction variable must appear in a task_reduction clause}}
   for (int i = 0; i < 10; ++i)
   foo();
-#pragma omp taskloop simd in_reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'in_reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
+#pragma omp taskloop simd in_reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'in_reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified variable cannot be in_reduction}}
   for (int i = 0; i < 10; ++i)
   foo();
 #pragma omp taskloop simd in_reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
   for (int i = 0; i < 10; ++i)
   foo();
-#pragma omp taskloop simd in_reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp taskloop simd in_reduction(+ : ba) // expected-error {{const-qualified variable cannot be in_reduction}}
   for (int i = 0; i < 10; ++i)
   foo();
-#pragma omp taskloop simd in_reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp taskloop simd in_reduction(* : ca) // expected-error {{const-qualified variable cannot be in_reduction}}
   for (int i = 0; i < 10; ++i)
   foo();
-#pragma omp taskloop simd in_reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp taskloop simd in_reduction(- : da) // expected-error {{const-qualified variable cannot be in_reduction}} expected-error {{const-qualified variable cannot be in_reduction}}
   for (int i = 0; i < 10; ++i)
   foo();
 #pragma omp taskloop simd in_reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} expected-error {{in_reduction variable must appear in a task_reduction clause}}
@@ -195,7 +195,7 @@ T tmain(T argc) {
 #pragma omp taskloop simd in_reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
   foo();
-#pragma omp taskloop simd in_reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp taskloop simd in_reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be in_reduction}}
   for (int i = 0; i < 10; ++i)
   foo();
 #pragma omp taskgroup task_reduction(+:k)
@@ -213,7 +213,7 @@ T tmain(T argc) {
 #pragma omp taskloop simd in_reduction(+ : p), in_reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'in_reduction' clause}} expected-note 2 {{previously referenced here}}
   for (int i = 0; i < 10; ++i)
   foo();
-#pragma omp taskloop simd in_reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}}
+#pragma omp taskloop simd in_reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be in_reduction}}
   for (int i = 0; i < 10; ++i)
   foo();
 #pragma omp parallel shared(i)
@@ -306,22 +306,22 @@ int main(int argc, char **argv) {
   for (int i = 0; i < 10; ++i)
   foo();
 #pragma omp taskgroup task_reduction(+:c)
-#pragma omp taskloop simd in_reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}} expected-error {{in_reduction variable must appear in a task_reduction clause}}
+#pragma omp taskloop simd in_reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be in_reduction}} expected-error {{'operator+' is a private member of 'S2'}} expected-error {{in_reduction variable must appear in a task_reduction clause}}
   for (int i = 0; i < 10; ++i)
   foo();
-#pragma omp taskloop simd in_reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'in_reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified list item cannot be reduction}}
+#pragma omp taskloop simd in_reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'in_reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be in_reduction}}
   for (int i = 0; i < 10; ++i)
   foo();
 #pragma omp taskloop simd in_reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
   for (int i = 0; i < 10; ++i)
   foo();
-#pragma omp taskloop simd in_reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp taskloop simd in_reduction(+ : ba) // expected-error {{const-qualified variable cannot be in_reduction}}
   for (int i = 0; i < 10; ++i)
   foo();
-#pragma omp taskloop simd in_reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp taskloop simd in_reduction(* : ca) // expected-error {{const-qualified variable cannot be in_reduction}}
   for (int i = 0; i < 10; ++i)
   foo();
-#pragma omp taskloop simd in_reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp taskloop simd in_reduction(- : da) // expected-error {{const-qualified variable cannot be in_reduction}}
   for (int i = 0; i < 10; ++i)
   foo();
 #pragma omp taskloop simd in_reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
@@ -330,7 +330,7 @@ int main(int argc, char **argv) {
 #pragma omp taskloop simd in_reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
   foo();
-#pragma omp taskloop simd in_reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp taskloop simd in_reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be in_reduction}}
   for (int i = 0; i < 10; ++i)
   foo();
 #pragma omp taskloop simd in_reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{nvalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
@@ -351,7 +351,7 @@ int main(int argc, char **argv) {
 #pragma omp taskloop simd in_reduction(+ : p), in_reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'in_reduction' clause}} expected-note {{previously referenced here}}
   for (int i = 0; i < 10; ++i)
   foo();
-#pragma omp taskloop simd in_reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp taskloop simd in_reduction(+ : r) // expected-error {{const-qualified variable cannot be in_reduction}}
   for (int i = 0; i < 10; ++i)
   foo();
 #pragma omp parallel shared(i)
diff --git a/test/OpenMP/taskloop_simd_reduction_messages.cpp b/test/OpenMP/taskloop_simd_reduction_messages.cpp
index 10ee5ce8c8..fb279e28b8 100644
--- a/test/OpenMP/taskloop_simd_reduction_messages.cpp
+++ b/test/OpenMP/taskloop_simd_reduction_messages.cpp
@@ -139,22 +139,22 @@ T tmain(T argc) {
 #pragma omp taskloop simd reduction(^ : T) // expected-error {{'T' does not refer to a value}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp taskloop simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
+#pragma omp taskloop simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp taskloop simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
+#pragma omp taskloop simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp taskloop simd reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp taskloop simd reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp taskloop simd reduction(+ : ba) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp taskloop simd reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp taskloop simd reduction(* : ca) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp taskloop simd reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp taskloop simd reduction(- : da) // expected-error {{const-qualified variable cannot be reduction}} expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp taskloop simd reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
@@ -163,7 +163,7 @@ T tmain(T argc) {
 #pragma omp taskloop simd reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp taskloop simd reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp taskloop simd reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp taskloop simd reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
@@ -182,7 +182,7 @@ T tmain(T argc) {
 #pragma omp taskloop simd reduction(+ : p), reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 2 {{previously referenced here}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp taskloop simd reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}}
+#pragma omp taskloop simd reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel shared(i)
@@ -261,22 +261,22 @@ int main(int argc, char **argv) {
 #pragma omp taskloop simd reduction(^ : S1) // expected-error {{'S1' does not refer to a value}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp taskloop simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
+#pragma omp taskloop simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp taskloop simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified list item cannot be reduction}}
+#pragma omp taskloop simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp taskloop simd reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp taskloop simd reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp taskloop simd reduction(+ : ba) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp taskloop simd reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp taskloop simd reduction(* : ca) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp taskloop simd reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp taskloop simd reduction(- : da) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp taskloop simd reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
@@ -285,7 +285,7 @@ int main(int argc, char **argv) {
 #pragma omp taskloop simd reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp taskloop simd reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp taskloop simd reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp taskloop simd reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
@@ -307,7 +307,7 @@ int main(int argc, char **argv) {
 #pragma omp taskloop simd reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}}
   for (int i = 0; i < 10; ++i)
     foo();
-#pragma omp taskloop simd reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp taskloop simd reduction(+ : r) // expected-error {{const-qualified variable cannot be reduction}}
   for (int i = 0; i < 10; ++i)
     foo();
 #pragma omp parallel shared(i)
diff --git a/test/OpenMP/teams_distribute_parallel_for_reduction_messages.cpp b/test/OpenMP/teams_distribute_parallel_for_reduction_messages.cpp
index 31a91a862f..5eb69fd00b 100644
--- a/test/OpenMP/teams_distribute_parallel_for_reduction_messages.cpp
+++ b/test/OpenMP/teams_distribute_parallel_for_reduction_messages.cpp
@@ -125,22 +125,22 @@ T tmain(T argc) {
 #pragma omp teams distribute parallel for reduction(^ : T) // expected-error {{'T' does not refer to a value}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
-#pragma omp teams distribute parallel for reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
+#pragma omp teams distribute parallel for reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
-#pragma omp teams distribute parallel for reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
+#pragma omp teams distribute parallel for reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
 #pragma omp teams distribute parallel for reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
-#pragma omp teams distribute parallel for reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp teams distribute parallel for reduction(+ : ba) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
-#pragma omp teams distribute parallel for reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp teams distribute parallel for reduction(* : ca) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
-#pragma omp teams distribute parallel for reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp teams distribute parallel for reduction(- : da) // expected-error {{const-qualified variable cannot be reduction}} expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
 #pragma omp teams distribute parallel for reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
@@ -149,7 +149,7 @@ T tmain(T argc) {
 #pragma omp teams distribute parallel for reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
-#pragma omp teams distribute parallel for reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp teams distribute parallel for reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
 #pragma omp teams distribute parallel for reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
@@ -168,7 +168,7 @@ T tmain(T argc) {
 #pragma omp teams distribute parallel for reduction(+ : p), reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 2 {{previously referenced here}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
-#pragma omp teams distribute parallel for reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}}
+#pragma omp teams distribute parallel for reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp parallel shared(i)
 #pragma omp parallel reduction(min : i)
@@ -242,22 +242,22 @@ int main(int argc, char **argv) {
 #pragma omp teams distribute parallel for reduction(^ : S1) // expected-error {{'S1' does not refer to a value}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
-#pragma omp teams distribute parallel for reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
+#pragma omp teams distribute parallel for reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
-#pragma omp teams distribute parallel for reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified list item cannot be reduction}}
+#pragma omp teams distribute parallel for reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
 #pragma omp teams distribute parallel for reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
-#pragma omp teams distribute parallel for reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp teams distribute parallel for reduction(+ : ba) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
-#pragma omp teams distribute parallel for reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp teams distribute parallel for reduction(* : ca) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
-#pragma omp teams distribute parallel for reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp teams distribute parallel for reduction(- : da) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
 #pragma omp teams distribute parallel for reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
@@ -266,7 +266,7 @@ int main(int argc, char **argv) {
 #pragma omp teams distribute parallel for reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
-#pragma omp teams distribute parallel for reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp teams distribute parallel for reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
 #pragma omp teams distribute parallel for reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
@@ -288,7 +288,7 @@ int main(int argc, char **argv) {
 #pragma omp teams distribute parallel for reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
-#pragma omp teams distribute parallel for reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp teams distribute parallel for reduction(+ : r) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp parallel shared(i)
 #pragma omp parallel reduction(min : i)
diff --git a/test/OpenMP/teams_distribute_parallel_for_simd_reduction_messages.cpp b/test/OpenMP/teams_distribute_parallel_for_simd_reduction_messages.cpp
index a17ffe392b..9f203063f1 100644
--- a/test/OpenMP/teams_distribute_parallel_for_simd_reduction_messages.cpp
+++ b/test/OpenMP/teams_distribute_parallel_for_simd_reduction_messages.cpp
@@ -125,22 +125,22 @@ T tmain(T argc) {
 #pragma omp teams distribute parallel for simd reduction(^ : T) // expected-error {{'T' does not refer to a value}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
-#pragma omp teams distribute parallel for simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
+#pragma omp teams distribute parallel for simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
-#pragma omp teams distribute parallel for simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
+#pragma omp teams distribute parallel for simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
 #pragma omp teams distribute parallel for simd reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
-#pragma omp teams distribute parallel for simd reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp teams distribute parallel for simd reduction(+ : ba) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
-#pragma omp teams distribute parallel for simd reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp teams distribute parallel for simd reduction(* : ca) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
-#pragma omp teams distribute parallel for simd reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp teams distribute parallel for simd reduction(- : da) // expected-error {{const-qualified variable cannot be reduction}} expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
 #pragma omp teams distribute parallel for simd reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
@@ -149,7 +149,7 @@ T tmain(T argc) {
 #pragma omp teams distribute parallel for simd reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
-#pragma omp teams distribute parallel for simd reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp teams distribute parallel for simd reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
 #pragma omp teams distribute parallel for simd reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
@@ -168,7 +168,7 @@ T tmain(T argc) {
 #pragma omp teams distribute parallel for simd reduction(+ : p), reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 2 {{previously referenced here}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
-#pragma omp teams distribute parallel for simd reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}}
+#pragma omp teams distribute parallel for simd reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp parallel shared(i)
 #pragma omp parallel reduction(min : i)
@@ -242,22 +242,22 @@ int main(int argc, char **argv) {
 #pragma omp teams distribute parallel for simd reduction(^ : S1) // expected-error {{'S1' does not refer to a value}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
-#pragma omp teams distribute parallel for simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
+#pragma omp teams distribute parallel for simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
-#pragma omp teams distribute parallel for simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified list item cannot be reduction}}
+#pragma omp teams distribute parallel for simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
 #pragma omp teams distribute parallel for simd reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
-#pragma omp teams distribute parallel for simd reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp teams distribute parallel for simd reduction(+ : ba) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
-#pragma omp teams distribute parallel for simd reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp teams distribute parallel for simd reduction(* : ca) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
-#pragma omp teams distribute parallel for simd reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp teams distribute parallel for simd reduction(- : da) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
 #pragma omp teams distribute parallel for simd reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
@@ -266,7 +266,7 @@ int main(int argc, char **argv) {
 #pragma omp teams distribute parallel for simd reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
-#pragma omp teams distribute parallel for simd reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp teams distribute parallel for simd reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
 #pragma omp teams distribute parallel for simd reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
@@ -288,7 +288,7 @@ int main(int argc, char **argv) {
 #pragma omp teams distribute parallel for simd reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
-#pragma omp teams distribute parallel for simd reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp teams distribute parallel for simd reduction(+ : r) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp parallel shared(i)
 #pragma omp parallel reduction(min : i)
diff --git a/test/OpenMP/teams_distribute_reduction_messages.cpp b/test/OpenMP/teams_distribute_reduction_messages.cpp
index 4b9d6e51b2..f83dda6809 100644
--- a/test/OpenMP/teams_distribute_reduction_messages.cpp
+++ b/test/OpenMP/teams_distribute_reduction_messages.cpp
@@ -131,22 +131,22 @@ T tmain(T argc) {
 #pragma omp teams distribute reduction(^ : T) // expected-error {{'T' does not refer to a value}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
-#pragma omp teams distribute reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
+#pragma omp teams distribute reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
-#pragma omp teams distribute reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
+#pragma omp teams distribute reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
 #pragma omp teams distribute reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
-#pragma omp teams distribute reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp teams distribute reduction(+ : ba) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
-#pragma omp teams distribute reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp teams distribute reduction(* : ca) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
-#pragma omp teams distribute reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp teams distribute reduction(- : da) // expected-error {{const-qualified variable cannot be reduction}} expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
 #pragma omp teams distribute reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
@@ -155,7 +155,7 @@ T tmain(T argc) {
 #pragma omp teams distribute reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
-#pragma omp teams distribute reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp teams distribute reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
 #pragma omp teams distribute reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
@@ -174,7 +174,7 @@ T tmain(T argc) {
 #pragma omp teams distribute reduction(+ : p), reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 2 {{previously referenced here}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
-#pragma omp teams distribute reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}}
+#pragma omp teams distribute reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp parallel shared(i)
 #pragma omp parallel reduction(min : i)
@@ -248,22 +248,22 @@ int main(int argc, char **argv) {
 #pragma omp teams distribute reduction(^ : S1) // expected-error {{'S1' does not refer to a value}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
-#pragma omp teams distribute reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
+#pragma omp teams distribute reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
-#pragma omp teams distribute reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified list item cannot be reduction}}
+#pragma omp teams distribute reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
 #pragma omp teams distribute reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
-#pragma omp teams distribute reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp teams distribute reduction(+ : ba) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
-#pragma omp teams distribute reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp teams distribute reduction(* : ca) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
-#pragma omp teams distribute reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp teams distribute reduction(- : da) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
 #pragma omp teams distribute reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
@@ -272,7 +272,7 @@ int main(int argc, char **argv) {
 #pragma omp teams distribute reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
-#pragma omp teams distribute reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp teams distribute reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
 #pragma omp teams distribute reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
@@ -294,7 +294,7 @@ int main(int argc, char **argv) {
 #pragma omp teams distribute reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
-#pragma omp teams distribute reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp teams distribute reduction(+ : r) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp parallel shared(i)
 #pragma omp parallel reduction(min : i)
diff --git a/test/OpenMP/teams_distribute_simd_reduction_messages.cpp b/test/OpenMP/teams_distribute_simd_reduction_messages.cpp
index 49b45b7bc6..e590d3616d 100644
--- a/test/OpenMP/teams_distribute_simd_reduction_messages.cpp
+++ b/test/OpenMP/teams_distribute_simd_reduction_messages.cpp
@@ -125,22 +125,22 @@ T tmain(T argc) {
 #pragma omp teams distribute simd reduction(^ : T) // expected-error {{'T' does not refer to a value}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
-#pragma omp teams distribute simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
+#pragma omp teams distribute simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
-#pragma omp teams distribute simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
+#pragma omp teams distribute simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
 #pragma omp teams distribute simd reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
-#pragma omp teams distribute simd reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp teams distribute simd reduction(+ : ba) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
-#pragma omp teams distribute simd reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp teams distribute simd reduction(* : ca) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
-#pragma omp teams distribute simd reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp teams distribute simd reduction(- : da) // expected-error {{const-qualified variable cannot be reduction}} expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
 #pragma omp teams distribute simd reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
@@ -149,7 +149,7 @@ T tmain(T argc) {
 #pragma omp teams distribute simd reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
-#pragma omp teams distribute simd reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp teams distribute simd reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
 #pragma omp teams distribute simd reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
@@ -168,7 +168,7 @@ T tmain(T argc) {
 #pragma omp teams distribute simd reduction(+ : p), reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 2 {{previously referenced here}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
-#pragma omp teams distribute simd reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}}
+#pragma omp teams distribute simd reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp parallel shared(i)
 #pragma omp parallel reduction(min : i)
@@ -242,22 +242,22 @@ int main(int argc, char **argv) {
 #pragma omp teams distribute simd reduction(^ : S1) // expected-error {{'S1' does not refer to a value}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
-#pragma omp teams distribute simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
+#pragma omp teams distribute simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
-#pragma omp teams distribute simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified list item cannot be reduction}}
+#pragma omp teams distribute simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
 #pragma omp teams distribute simd reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
-#pragma omp teams distribute simd reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp teams distribute simd reduction(+ : ba) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
-#pragma omp teams distribute simd reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp teams distribute simd reduction(* : ca) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
-#pragma omp teams distribute simd reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp teams distribute simd reduction(- : da) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
 #pragma omp teams distribute simd reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
@@ -266,7 +266,7 @@ int main(int argc, char **argv) {
 #pragma omp teams distribute simd reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
-#pragma omp teams distribute simd reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp teams distribute simd reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
 #pragma omp teams distribute simd reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
@@ -288,7 +288,7 @@ int main(int argc, char **argv) {
 #pragma omp teams distribute simd reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}}
   for (int j=0; j<100; j++) foo();
 #pragma omp target
-#pragma omp teams distribute simd reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp teams distribute simd reduction(+ : r) // expected-error {{const-qualified variable cannot be reduction}}
   for (int j=0; j<100; j++) foo();
 #pragma omp parallel shared(i)
 #pragma omp parallel reduction(min : i)
diff --git a/test/OpenMP/teams_reduction_messages.cpp b/test/OpenMP/teams_reduction_messages.cpp
index 94a47436c1..37f58f8b17 100644
--- a/test/OpenMP/teams_reduction_messages.cpp
+++ b/test/OpenMP/teams_reduction_messages.cpp
@@ -131,22 +131,22 @@ T tmain(T argc) {
 #pragma omp teams reduction(^ : T) // expected-error {{'T' does not refer to a value}}
   foo();
 #pragma omp target
-#pragma omp teams reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
+#pragma omp teams reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
   foo();
 #pragma omp target
-#pragma omp teams reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
+#pragma omp teams reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified variable cannot be reduction}}
   foo();
 #pragma omp target
 #pragma omp teams reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
   foo();
 #pragma omp target
-#pragma omp teams reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp teams reduction(+ : ba) // expected-error {{const-qualified variable cannot be reduction}}
   foo();
 #pragma omp target
-#pragma omp teams reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp teams reduction(* : ca) // expected-error {{const-qualified variable cannot be reduction}}
   foo();
 #pragma omp target
-#pragma omp teams reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp teams reduction(- : da) // expected-error {{const-qualified variable cannot be reduction}} expected-error {{const-qualified variable cannot be reduction}}
   foo();
 #pragma omp target
 #pragma omp teams reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
@@ -155,7 +155,7 @@ T tmain(T argc) {
 #pragma omp teams reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
   foo();
 #pragma omp target
-#pragma omp teams reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp teams reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   foo();
 #pragma omp target
 #pragma omp teams reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
@@ -174,7 +174,7 @@ T tmain(T argc) {
 #pragma omp teams reduction(+ : p), reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 2 {{previously referenced here}}
   foo();
 #pragma omp target
-#pragma omp teams reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}}
+#pragma omp teams reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be reduction}}
   foo();
 #pragma omp parallel shared(i)
 #pragma omp parallel reduction(min : i)
@@ -261,22 +261,22 @@ int main(int argc, char **argv) {
 #pragma omp teams reduction(^ : S1) // expected-error {{'S1' does not refer to a value}}
   foo();
 #pragma omp target
-#pragma omp teams reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
+#pragma omp teams reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
   foo();
 #pragma omp target
-#pragma omp teams reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified list item cannot be reduction}}
+#pragma omp teams reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be reduction}}
   foo();
 #pragma omp target
 #pragma omp teams reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
   foo();
 #pragma omp target
-#pragma omp teams reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp teams reduction(+ : ba) // expected-error {{const-qualified variable cannot be reduction}}
   foo();
 #pragma omp target
-#pragma omp teams reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp teams reduction(* : ca) // expected-error {{const-qualified variable cannot be reduction}}
   foo();
 #pragma omp target
-#pragma omp teams reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp teams reduction(- : da) // expected-error {{const-qualified variable cannot be reduction}}
   foo();
 #pragma omp target
 #pragma omp teams reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
@@ -285,7 +285,7 @@ int main(int argc, char **argv) {
 #pragma omp teams reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
   foo();
 #pragma omp target
-#pragma omp teams reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp teams reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
   foo();
 #pragma omp target
 #pragma omp teams reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
@@ -307,7 +307,7 @@ int main(int argc, char **argv) {
 #pragma omp teams reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}}
   foo();
 #pragma omp target
-#pragma omp teams reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}}
+#pragma omp teams reduction(+ : r) // expected-error {{const-qualified variable cannot be reduction}}
   foo();
 #pragma omp parallel shared(i)
 #pragma omp parallel reduction(min : i)
-- 
cgit v1.2.3


From 3bd81ff22212f694b92736739bfcaccd86da737c Mon Sep 17 00:00:00 2001
From: "Joel E. Denny" 
Date: Fri, 4 Jan 2019 22:12:13 +0000
Subject: [OpenMP] Refactor const restriction for linear

As discussed in D56113, this patch refactors the implementation of the
const restriction for linear to reuse a function introduced by D56113.
A side effect is that, if a variable has mutable members, this
diagnostic is now skipped, and the diagnostic for the variable not
being an integer or pointer is reported instead.

Reviewed By: ABataev

Differential Revision: https://reviews.llvm.org/D56299

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350441 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/Sema/SemaOpenMP.cpp                                | 18 +++++-------------
 .../distribute_parallel_for_simd_linear_messages.cpp   |  4 ++--
 test/OpenMP/distribute_simd_linear_messages.cpp        |  4 ++--
 test/OpenMP/for_linear_messages.cpp                    |  4 ++--
 test/OpenMP/for_simd_linear_messages.cpp               |  4 ++--
 test/OpenMP/parallel_for_linear_messages.cpp           |  4 ++--
 test/OpenMP/parallel_for_simd_linear_messages.cpp      |  4 ++--
 test/OpenMP/simd_linear_messages.cpp                   |  4 ++--
 test/OpenMP/target_parallel_for_linear_messages.cpp    |  4 ++--
 .../target_parallel_for_simd_linear_messages.cpp       |  4 ++--
 test/OpenMP/target_simd_linear_messages.cpp            |  4 ++--
 ...ms_distribute_parallel_for_simd_linear_messages.cpp |  4 ++--
 .../target_teams_distribute_simd_linear_messages.cpp   |  4 ++--
 test/OpenMP/taskloop_simd_linear_messages.cpp          |  4 ++--
 ...ms_distribute_parallel_for_simd_linear_messages.cpp |  4 ++--
 test/OpenMP/teams_distribute_simd_linear_messages.cpp  |  4 ++--
 16 files changed, 35 insertions(+), 43 deletions(-)

diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp
index 87d33c09e5..eac5f64e6e 100644
--- a/lib/Sema/SemaOpenMP.cpp
+++ b/lib/Sema/SemaOpenMP.cpp
@@ -11531,20 +11531,12 @@ bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc,
   }
   Type = Type.getNonReferenceType();
 
-  // A list item must not be const-qualified.
-  if (Type.isConstant(Context)) {
-    Diag(ELoc, diag::err_omp_const_variable)
-        << getOpenMPClauseName(OMPC_linear);
-    if (D) {
-      bool IsDecl =
-          !VD ||
-          VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
-      Diag(D->getLocation(),
-           IsDecl ? diag::note_previous_decl : diag::note_defined_here)
-          << D;
-    }
+  // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
+  // A variable that is privatized must not have a const-qualified type
+  // unless it is of class type with a mutable member. This restriction does
+  // not apply to the firstprivate clause.
+  if (rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc))
     return true;
-  }
 
   // A list item must be of integral or pointer type.
   Type = Type.getUnqualifiedType().getCanonicalType();
diff --git a/test/OpenMP/distribute_parallel_for_simd_linear_messages.cpp b/test/OpenMP/distribute_parallel_for_simd_linear_messages.cpp
index ad236ecda4..6fb5944d2c 100644
--- a/test/OpenMP/distribute_parallel_for_simd_linear_messages.cpp
+++ b/test/OpenMP/distribute_parallel_for_simd_linear_messages.cpp
@@ -189,7 +189,7 @@ template int foomain(I argc, C **argv) {
 
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute parallel for simd linear (a, b:B::ib) // expected-error {{linear variable with incomplete type 'S1'}} expected-error {{const-qualified variable cannot be linear}}
+#pragma omp distribute parallel for simd linear (a, b:B::ib) // expected-error {{linear variable with incomplete type 'S1'}} expected-error {{argument of a linear clause should be of integral or pointer type, not 'S2'}}
   for (int k = 0; k < argc; ++k) ++k;
 
 #pragma omp target
@@ -294,7 +294,7 @@ int main(int argc, char **argv) {
 
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute parallel for simd linear (a, b) // expected-error {{linear variable with incomplete type 'S1'}} expected-error {{const-qualified variable cannot be linear}} expected-error {{incomplete type 'S1' where a complete type is required}}
+#pragma omp distribute parallel for simd linear (a, b) // expected-error {{linear variable with incomplete type 'S1'}} expected-error {{argument of a linear clause should be of integral or pointer type, not 'S2'}} expected-error {{incomplete type 'S1' where a complete type is required}}
   for (int k = 0; k < argc; ++k) ++k;
 
 #pragma omp target
diff --git a/test/OpenMP/distribute_simd_linear_messages.cpp b/test/OpenMP/distribute_simd_linear_messages.cpp
index f9af5dd94f..631b43a120 100644
--- a/test/OpenMP/distribute_simd_linear_messages.cpp
+++ b/test/OpenMP/distribute_simd_linear_messages.cpp
@@ -189,7 +189,7 @@ template int foomain(I argc, C **argv) {
 
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute simd linear (a, b:B::ib) // expected-error {{linear variable with incomplete type 'S1'}} expected-error {{const-qualified variable cannot be linear}}
+#pragma omp distribute simd linear (a, b:B::ib) // expected-error {{linear variable with incomplete type 'S1'}} expected-error {{argument of a linear clause should be of integral or pointer type, not 'S2'}}
   for (int k = 0; k < argc; ++k) ++k;
 
 #pragma omp target
@@ -283,7 +283,7 @@ int main(int argc, char **argv) {
 
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute simd linear (a, b) // expected-error {{linear variable with incomplete type 'S1'}} expected-error {{const-qualified variable cannot be linear}} expected-warning {{Non-trivial type 'const S2' is mapped, only trivial types are guaranteed to be mapped correctly}} expected-error {{incomplete type 'S1' where a complete type is required}}
+#pragma omp distribute simd linear (a, b) // expected-error {{linear variable with incomplete type 'S1'}} expected-error {{argument of a linear clause should be of integral or pointer type, not 'S2'}} expected-warning {{Non-trivial type 'const S2' is mapped, only trivial types are guaranteed to be mapped correctly}} expected-error {{incomplete type 'S1' where a complete type is required}}
   for (int k = 0; k < argc; ++k) ++k;
 
 #pragma omp target
diff --git a/test/OpenMP/for_linear_messages.cpp b/test/OpenMP/for_linear_messages.cpp
index 622cd4a8a3..f35e5343c3 100644
--- a/test/OpenMP/for_linear_messages.cpp
+++ b/test/OpenMP/for_linear_messages.cpp
@@ -122,7 +122,7 @@ template int foomain(I argc, C **argv) {
   #pragma omp for linear (S1) // expected-error {{'S1' does not refer to a value}}
   for (int k = 0; k < argc; ++k) ++k;
   // expected-error@+2 {{linear variable with incomplete type 'S1'}}
-  // expected-error@+1 {{const-qualified variable cannot be linear}}
+  // expected-error@+1 {{argument of a linear clause should be of integral or pointer type, not 'S2'}}
   #pragma omp for linear (a, b:B::ib)
   for (int k = 0; k < argc; ++k) ++k;
   #pragma omp for linear (argv[1]) // expected-error {{expected variable name}}
@@ -188,7 +188,7 @@ int main(int argc, char **argv) {
   #pragma omp for linear (S1) // expected-error {{'S1' does not refer to a value}}
   for (int k = 0; k < argc; ++k) ++k;
   // expected-error@+2 {{linear variable with incomplete type 'S1'}}
-  // expected-error@+1 {{const-qualified variable cannot be linear}}
+  // expected-error@+1 {{argument of a linear clause should be of integral or pointer type, not 'S2'}}
   #pragma omp for linear(a, b)
   for (int k = 0; k < argc; ++k) ++k;
   #pragma omp for linear (argv[1]) // expected-error {{expected variable name}}
diff --git a/test/OpenMP/for_simd_linear_messages.cpp b/test/OpenMP/for_simd_linear_messages.cpp
index ff522e7b7e..a87b1ab115 100644
--- a/test/OpenMP/for_simd_linear_messages.cpp
+++ b/test/OpenMP/for_simd_linear_messages.cpp
@@ -122,7 +122,7 @@ template int foomain(I argc, C **argv) {
   #pragma omp for simd linear (S1) // expected-error {{'S1' does not refer to a value}}
   for (int k = 0; k < argc; ++k) ++k;
   // expected-error@+2 {{linear variable with incomplete type 'S1'}}
-  // expected-error@+1 {{const-qualified variable cannot be linear}}
+  // expected-error@+1 {{argument of a linear clause should be of integral or pointer type, not 'S2'}}
   #pragma omp for simd linear (a, b:B::ib)
   for (int k = 0; k < argc; ++k) ++k;
   #pragma omp for simd linear (argv[1]) // expected-error {{expected variable name}}
@@ -186,7 +186,7 @@ int main(int argc, char **argv) {
   #pragma omp for simd linear (S1) // expected-error {{'S1' does not refer to a value}}
   for (int k = 0; k < argc; ++k) ++k;
   // expected-error@+2 {{linear variable with incomplete type 'S1'}}
-  // expected-error@+1 {{const-qualified variable cannot be linear}}
+  // expected-error@+1 {{argument of a linear clause should be of integral or pointer type, not 'S2'}}
   #pragma omp for simd linear (a, b) 
   for (int k = 0; k < argc; ++k) ++k;
   #pragma omp for simd linear (argv[1]) // expected-error {{expected variable name}}
diff --git a/test/OpenMP/parallel_for_linear_messages.cpp b/test/OpenMP/parallel_for_linear_messages.cpp
index 080add692c..6596814de6 100644
--- a/test/OpenMP/parallel_for_linear_messages.cpp
+++ b/test/OpenMP/parallel_for_linear_messages.cpp
@@ -146,7 +146,7 @@ int foomain(I argc, C **argv) {
   for (int k = 0; k < argc; ++k)
     ++k;
 // expected-error@+2 {{linear variable with incomplete type 'S1'}}
-// expected-error@+1 {{const-qualified variable cannot be linear}}
+// expected-error@+1 {{argument of a linear clause should be of integral or pointer type, not 'S2'}}
 #pragma omp parallel for linear(a, b : B::ib)
   for (int k = 0; k < argc; ++k)
     ++k;
@@ -231,7 +231,7 @@ int main(int argc, char **argv) {
   for (int k = 0; k < argc; ++k)
     ++k;
 // expected-error@+2 {{linear variable with incomplete type 'S1'}}
-// expected-error@+1 {{const-qualified variable cannot be linear}}
+// expected-error@+1 {{argument of a linear clause should be of integral or pointer type, not 'S2'}}
 #pragma omp parallel for linear(a, b)
   for (int k = 0; k < argc; ++k)
     ++k;
diff --git a/test/OpenMP/parallel_for_simd_linear_messages.cpp b/test/OpenMP/parallel_for_simd_linear_messages.cpp
index a6bcf64806..792978e631 100644
--- a/test/OpenMP/parallel_for_simd_linear_messages.cpp
+++ b/test/OpenMP/parallel_for_simd_linear_messages.cpp
@@ -122,7 +122,7 @@ template int foomain(I argc, C **argv) {
   #pragma omp parallel for simd linear (S1) // expected-error {{'S1' does not refer to a value}}
   for (int k = 0; k < argc; ++k) ++k;
   // expected-error@+2 {{linear variable with incomplete type 'S1'}}
-  // expected-error@+1 {{const-qualified variable cannot be linear}}
+  // expected-error@+1 {{argument of a linear clause should be of integral or pointer type, not 'S2'}}
   #pragma omp parallel for simd linear (a, b:B::ib)
   for (int k = 0; k < argc; ++k) ++k;
   #pragma omp parallel for simd linear (argv[1]) // expected-error {{expected variable name}}
@@ -186,7 +186,7 @@ int main(int argc, char **argv) {
   #pragma omp parallel for simd linear (S1) // expected-error {{'S1' does not refer to a value}}
   for (int k = 0; k < argc; ++k) ++k;
   // expected-error@+2 {{linear variable with incomplete type 'S1'}}
-  // expected-error@+1 {{const-qualified variable cannot be linear}}
+  // expected-error@+1 {{argument of a linear clause should be of integral or pointer type, not 'S2'}}
   #pragma omp parallel for simd linear (a, b) 
   for (int k = 0; k < argc; ++k) ++k;
   #pragma omp parallel for simd linear (argv[1]) // expected-error {{expected variable name}}
diff --git a/test/OpenMP/simd_linear_messages.cpp b/test/OpenMP/simd_linear_messages.cpp
index aad0d18d42..3a72ed26fc 100644
--- a/test/OpenMP/simd_linear_messages.cpp
+++ b/test/OpenMP/simd_linear_messages.cpp
@@ -132,7 +132,7 @@ template int foomain(I argc, C **argv) {
   #pragma omp simd linear (S1) // expected-error {{'S1' does not refer to a value}}
   for (int k = 0; k < argc; ++k) ++k;
   // expected-error@+2 {{linear variable with incomplete type 'S1'}}
-  // expected-error@+1 {{const-qualified variable cannot be linear}}
+  // expected-error@+1 {{argument of a linear clause should be of integral or pointer type, not 'S2'}}
   #pragma omp simd linear (val(a, b):B::ib)
   for (int k = 0; k < argc; ++k) ++k;
   #pragma omp simd linear (argv[1]) // expected-error {{expected variable name}}
@@ -221,7 +221,7 @@ int main(int argc, char **argv) {
   #pragma omp simd linear (S1) // expected-error {{'S1' does not refer to a value}}
   for (int k = 0; k < argc; ++k) ++k;
   // expected-error@+2 {{linear variable with incomplete type 'S1'}}
-  // expected-error@+1 {{const-qualified variable cannot be linear}}
+  // expected-error@+1 {{argument of a linear clause should be of integral or pointer type, not 'S2'}}
   #pragma omp simd linear(a, b)
   for (int k = 0; k < argc; ++k) ++k;
   #pragma omp simd linear (argv[1]) // expected-error {{expected variable name}}
diff --git a/test/OpenMP/target_parallel_for_linear_messages.cpp b/test/OpenMP/target_parallel_for_linear_messages.cpp
index b7224b538f..79890c414a 100644
--- a/test/OpenMP/target_parallel_for_linear_messages.cpp
+++ b/test/OpenMP/target_parallel_for_linear_messages.cpp
@@ -146,7 +146,7 @@ int foomain(I argc, C **argv) {
   for (int k = 0; k < argc; ++k)
     ++k;
 // expected-error@+2 {{linear variable with incomplete type 'S1'}}
-// expected-error@+1 {{const-qualified variable cannot be linear}}
+// expected-error@+1 {{argument of a linear clause should be of integral or pointer type, not 'S2'}}
 #pragma omp target parallel for linear(a, b : B::ib)
   for (int k = 0; k < argc; ++k)
     ++k;
@@ -231,7 +231,7 @@ int main(int argc, char **argv) {
   for (int k = 0; k < argc; ++k)
     ++k;
 // expected-error@+2 {{linear variable with incomplete type 'S1'}}
-// expected-error@+1 {{const-qualified variable cannot be linear}}
+// expected-error@+1 {{argument of a linear clause should be of integral or pointer type, not 'S2'}}
 #pragma omp target parallel for linear(a, b)
   for (int k = 0; k < argc; ++k)
     ++k;
diff --git a/test/OpenMP/target_parallel_for_simd_linear_messages.cpp b/test/OpenMP/target_parallel_for_simd_linear_messages.cpp
index 40fd052df2..166cd2bc0b 100644
--- a/test/OpenMP/target_parallel_for_simd_linear_messages.cpp
+++ b/test/OpenMP/target_parallel_for_simd_linear_messages.cpp
@@ -146,7 +146,7 @@ int foomain(I argc, C **argv) {
   for (int k = 0; k < argc; ++k)
     ++k;
 // expected-error@+2 {{linear variable with incomplete type 'S1'}}
-// expected-error@+1 {{const-qualified variable cannot be linear}}
+// expected-error@+1 {{argument of a linear clause should be of integral or pointer type, not 'S2'}}
 #pragma omp target parallel for simd linear(a, b : B::ib)
   for (int k = 0; k < argc; ++k)
     ++k;
@@ -231,7 +231,7 @@ int main(int argc, char **argv) {
   for (int k = 0; k < argc; ++k)
     ++k;
 // expected-error@+2 {{linear variable with incomplete type 'S1'}}
-// expected-error@+1 {{const-qualified variable cannot be linear}}
+// expected-error@+1 {{argument of a linear clause should be of integral or pointer type, not 'S2'}}
 #pragma omp target parallel for simd linear(a, b)
   for (int k = 0; k < argc; ++k)
     ++k;
diff --git a/test/OpenMP/target_simd_linear_messages.cpp b/test/OpenMP/target_simd_linear_messages.cpp
index 6a094b8651..d19409f280 100644
--- a/test/OpenMP/target_simd_linear_messages.cpp
+++ b/test/OpenMP/target_simd_linear_messages.cpp
@@ -146,7 +146,7 @@ int foomain(I argc, C **argv) {
   for (int k = 0; k < argc; ++k)
     ++k;
 // expected-error@+2 {{linear variable with incomplete type 'S1'}}
-// expected-error@+1 {{const-qualified variable cannot be linear}}
+// expected-error@+1 {{argument of a linear clause should be of integral or pointer type, not 'S2'}}
 #pragma omp target simd linear(a, b : B::ib)
   for (int k = 0; k < argc; ++k)
     ++k;
@@ -231,7 +231,7 @@ int main(int argc, char **argv) {
   for (int k = 0; k < argc; ++k)
     ++k;
 // expected-error@+2 {{linear variable with incomplete type 'S1'}}
-// expected-error@+1 {{const-qualified variable cannot be linear}}
+// expected-error@+1 {{argument of a linear clause should be of integral or pointer type, not 'S2'}}
 #pragma omp target simd linear(a, b)
   for (int k = 0; k < argc; ++k)
     ++k;
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_simd_linear_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_simd_linear_messages.cpp
index 3013480d6e..372a976087 100644
--- a/test/OpenMP/target_teams_distribute_parallel_for_simd_linear_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_linear_messages.cpp
@@ -148,7 +148,7 @@ template int foomain(I argc, C **argv) {
 #pragma omp target teams distribute parallel for simd linear (S1) // expected-error {{'S1' does not refer to a value}}
   for (int k = 0; k < argc; ++k) ++k;
 
-#pragma omp target teams distribute parallel for simd linear (a, b:B::ib) // expected-error {{linear variable with incomplete type 'S1'}} expected-error {{const-qualified variable cannot be linear}}
+#pragma omp target teams distribute parallel for simd linear (a, b:B::ib) // expected-error {{linear variable with incomplete type 'S1'}} expected-error {{argument of a linear clause should be of integral or pointer type, not 'S2'}}
   for (int k = 0; k < argc; ++k) ++k;
 
 #pragma omp target teams distribute parallel for simd linear (argv[1]) // expected-error {{expected variable name}}
@@ -216,7 +216,7 @@ int main(int argc, char **argv) {
   for (int k = 0; k < argc; ++k) ++k;
 
 
-#pragma omp target teams distribute parallel for simd linear (a, b) // expected-error {{linear variable with incomplete type 'S1'}} expected-error {{const-qualified variable cannot be linear}}
+#pragma omp target teams distribute parallel for simd linear (a, b) // expected-error {{linear variable with incomplete type 'S1'}} expected-error {{argument of a linear clause should be of integral or pointer type, not 'S2'}}
   for (int k = 0; k < argc; ++k) ++k;
 
 #pragma omp target teams distribute parallel for simd linear (argv[1]) // expected-error {{expected variable name}}
diff --git a/test/OpenMP/target_teams_distribute_simd_linear_messages.cpp b/test/OpenMP/target_teams_distribute_simd_linear_messages.cpp
index 5bcd77da9e..c353242bc1 100644
--- a/test/OpenMP/target_teams_distribute_simd_linear_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_simd_linear_messages.cpp
@@ -148,7 +148,7 @@ template int foomain(I argc, C **argv) {
 #pragma omp target teams distribute simd linear (S1) // expected-error {{'S1' does not refer to a value}}
   for (int k = 0; k < argc; ++k) ++k;
 
-#pragma omp target teams distribute simd linear (a, b:B::ib) // expected-error {{linear variable with incomplete type 'S1'}} expected-error {{const-qualified variable cannot be linear}}
+#pragma omp target teams distribute simd linear (a, b:B::ib) // expected-error {{linear variable with incomplete type 'S1'}} expected-error {{argument of a linear clause should be of integral or pointer type, not 'S2'}}
   for (int k = 0; k < argc; ++k) ++k;
 
 #pragma omp target teams distribute simd linear (argv[1]) // expected-error {{expected variable name}}
@@ -216,7 +216,7 @@ int main(int argc, char **argv) {
   for (int k = 0; k < argc; ++k) ++k;
 
 
-#pragma omp target teams distribute simd linear (a, b) // expected-error {{linear variable with incomplete type 'S1'}} expected-error {{const-qualified variable cannot be linear}}
+#pragma omp target teams distribute simd linear (a, b) // expected-error {{linear variable with incomplete type 'S1'}} expected-error {{argument of a linear clause should be of integral or pointer type, not 'S2'}}
   for (int k = 0; k < argc; ++k) ++k;
 
 #pragma omp target teams distribute simd linear (argv[1]) // expected-error {{expected variable name}}
diff --git a/test/OpenMP/taskloop_simd_linear_messages.cpp b/test/OpenMP/taskloop_simd_linear_messages.cpp
index 2aea6a041f..645026c9fa 100644
--- a/test/OpenMP/taskloop_simd_linear_messages.cpp
+++ b/test/OpenMP/taskloop_simd_linear_messages.cpp
@@ -132,7 +132,7 @@ template int foomain(I argc, C **argv) {
   #pragma omp taskloop simd linear (S1) // expected-error {{'S1' does not refer to a value}}
   for (int k = 0; k < argc; ++k) ++k;
   // expected-error@+2 {{linear variable with incomplete type 'S1'}}
-  // expected-error@+1 {{const-qualified variable cannot be linear}}
+  // expected-error@+1 {{argument of a linear clause should be of integral or pointer type, not 'S2'}}
   #pragma omp taskloop simd linear (val(a, b):B::ib)
   for (int k = 0; k < argc; ++k) ++k;
   #pragma omp taskloop simd linear (argv[1]) // expected-error {{expected variable name}}
@@ -221,7 +221,7 @@ int main(int argc, char **argv) {
   #pragma omp taskloop simd linear (S1) // expected-error {{'S1' does not refer to a value}}
   for (int k = 0; k < argc; ++k) ++k;
   // expected-error@+2 {{linear variable with incomplete type 'S1'}}
-  // expected-error@+1 {{const-qualified variable cannot be linear}}
+  // expected-error@+1 {{argument of a linear clause should be of integral or pointer type, not 'S2'}}
   #pragma omp taskloop simd linear(a, b)
   for (int k = 0; k < argc; ++k) ++k;
   #pragma omp taskloop simd linear (argv[1]) // expected-error {{expected variable name}}
diff --git a/test/OpenMP/teams_distribute_parallel_for_simd_linear_messages.cpp b/test/OpenMP/teams_distribute_parallel_for_simd_linear_messages.cpp
index e60f2c9dbc..c6fb77b496 100644
--- a/test/OpenMP/teams_distribute_parallel_for_simd_linear_messages.cpp
+++ b/test/OpenMP/teams_distribute_parallel_for_simd_linear_messages.cpp
@@ -169,7 +169,7 @@ template int foomain(I argc, C **argv) {
   for (int k = 0; k < argc; ++k) ++k;
 
 #pragma omp target
-#pragma omp teams distribute parallel for simd linear (a, b:B::ib) // expected-error {{linear variable with incomplete type 'S1'}} expected-error {{const-qualified variable cannot be linear}}
+#pragma omp teams distribute parallel for simd linear (a, b:B::ib) // expected-error {{linear variable with incomplete type 'S1'}} expected-error {{argument of a linear clause should be of integral or pointer type, not 'S2'}}
   for (int k = 0; k < argc; ++k) ++k;
 
 #pragma omp target
@@ -250,7 +250,7 @@ int main(int argc, char **argv) {
 
 
 #pragma omp target
-#pragma omp teams distribute parallel for simd linear (a, b) // expected-error {{linear variable with incomplete type 'S1'}} expected-error {{const-qualified variable cannot be linear}}
+#pragma omp teams distribute parallel for simd linear (a, b) // expected-error {{linear variable with incomplete type 'S1'}} expected-error {{argument of a linear clause should be of integral or pointer type, not 'S2'}}
   for (int k = 0; k < argc; ++k) ++k;
 
 #pragma omp target
diff --git a/test/OpenMP/teams_distribute_simd_linear_messages.cpp b/test/OpenMP/teams_distribute_simd_linear_messages.cpp
index a3984b98da..8548e3dcc0 100644
--- a/test/OpenMP/teams_distribute_simd_linear_messages.cpp
+++ b/test/OpenMP/teams_distribute_simd_linear_messages.cpp
@@ -169,7 +169,7 @@ template int foomain(I argc, C **argv) {
   for (int k = 0; k < argc; ++k) ++k;
 
 #pragma omp target
-#pragma omp teams distribute simd linear (a, b:B::ib) // expected-error {{linear variable with incomplete type 'S1'}} expected-error {{const-qualified variable cannot be linear}}
+#pragma omp teams distribute simd linear (a, b:B::ib) // expected-error {{linear variable with incomplete type 'S1'}} expected-error {{argument of a linear clause should be of integral or pointer type, not 'S2'}}
   for (int k = 0; k < argc; ++k) ++k;
 
 #pragma omp target
@@ -250,7 +250,7 @@ int main(int argc, char **argv) {
 
 
 #pragma omp target
-#pragma omp teams distribute simd linear (a, b) // expected-error {{linear variable with incomplete type 'S1'}} expected-error {{const-qualified variable cannot be linear}}
+#pragma omp teams distribute simd linear (a, b) // expected-error {{linear variable with incomplete type 'S1'}} expected-error {{argument of a linear clause should be of integral or pointer type, not 'S2'}}
   for (int k = 0; k < argc; ++k) ++k;
 
 #pragma omp target
-- 
cgit v1.2.3


From 6cb22f178c14c7b52595f53d51c661e36afa090f Mon Sep 17 00:00:00 2001
From: Nico Weber 
Date: Sat, 5 Jan 2019 01:10:20 +0000
Subject: Move -add-plugin validation after -load was executed.

Moves the code added in r350340 around a bit, to hopefully make the existing
plugin tests pass when clang is built with examples enabled.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350451 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/Frontend/CompilerInvocation.cpp | 15 +--------------
 lib/Frontend/FrontendAction.cpp     | 18 ++++++++++++++++++
 2 files changed, 19 insertions(+), 14 deletions(-)

diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index 00083bd622..04105f0980 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -1666,20 +1666,7 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
     Opts.ProgramAction = frontend::PluginAction;
     Opts.ActionName = A->getValue();
   }
-  for (const std::string &Arg : Args.getAllArgValues(OPT_add_plugin)) {
-    bool Found = false;
-    for (FrontendPluginRegistry::iterator it = FrontendPluginRegistry::begin(),
-                                          ie = FrontendPluginRegistry::end();
-         it != ie; ++it) {
-      if (it->getName() == Arg)
-        Found = true;
-    }
-    if (!Found) {
-      Diags.Report(diag::err_fe_invalid_plugin_name) << Arg;
-      continue;
-    }
-    Opts.AddPluginActions.push_back(Arg);
-  }
+  Opts.AddPluginActions = Args.getAllArgValues(OPT_add_plugin);
   for (const auto *AA : Args.filtered(OPT_plugin_arg))
     Opts.PluginArgs[AA->getValue(0)].emplace_back(AA->getValue(1));
 
diff --git a/lib/Frontend/FrontendAction.cpp b/lib/Frontend/FrontendAction.cpp
index 83152bd353..a1866e48cc 100644
--- a/lib/Frontend/FrontendAction.cpp
+++ b/lib/Frontend/FrontendAction.cpp
@@ -156,6 +156,24 @@ FrontendAction::CreateWrappedASTConsumer(CompilerInstance &CI,
   if (FrontendPluginRegistry::begin() == FrontendPluginRegistry::end())
     return Consumer;
 
+  // Validate -add-plugin args.
+  bool FoundAllPlugins = true;
+  for (const std::string &Arg : CI.getFrontendOpts().AddPluginActions) {
+    bool Found = false;
+    for (FrontendPluginRegistry::iterator it = FrontendPluginRegistry::begin(),
+                                          ie = FrontendPluginRegistry::end();
+         it != ie; ++it) {
+      if (it->getName() == Arg)
+        Found = true;
+    }
+    if (!Found) {
+      CI.getDiagnostics().Report(diag::err_fe_invalid_plugin_name) << Arg;
+      FoundAllPlugins = false;
+    }
+  }
+  if (!FoundAllPlugins)
+    return nullptr;
+
   // If this is a code completion run, avoid invoking the plugin consumers
   if (CI.hasCodeCompletionConsumer())
     return Consumer;
-- 
cgit v1.2.3


From 938b369b755291219699f57dd3f0b1c7e86711a6 Mon Sep 17 00:00:00 2001
From: Nico Weber 
Date: Sat, 5 Jan 2019 01:19:14 +0000
Subject: Let new test from r350340 still pass even after r350451.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350453 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/Frontend/FrontendAction.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/lib/Frontend/FrontendAction.cpp b/lib/Frontend/FrontendAction.cpp
index a1866e48cc..f5226380b4 100644
--- a/lib/Frontend/FrontendAction.cpp
+++ b/lib/Frontend/FrontendAction.cpp
@@ -152,10 +152,6 @@ FrontendAction::CreateWrappedASTConsumer(CompilerInstance &CI,
   if (!Consumer)
     return nullptr;
 
-  // If there are no registered plugins we don't need to wrap the consumer
-  if (FrontendPluginRegistry::begin() == FrontendPluginRegistry::end())
-    return Consumer;
-
   // Validate -add-plugin args.
   bool FoundAllPlugins = true;
   for (const std::string &Arg : CI.getFrontendOpts().AddPluginActions) {
@@ -174,6 +170,10 @@ FrontendAction::CreateWrappedASTConsumer(CompilerInstance &CI,
   if (!FoundAllPlugins)
     return nullptr;
 
+  // If there are no registered plugins we don't need to wrap the consumer
+  if (FrontendPluginRegistry::begin() == FrontendPluginRegistry::end())
+    return Consumer;
+
   // If this is a code completion run, avoid invoking the plugin consumers
   if (CI.hasCodeCompletionConsumer())
     return Consumer;
-- 
cgit v1.2.3


From 0cdb85449b3c696dd25400baef6750eec154566a Mon Sep 17 00:00:00 2001
From: Petr Hosek 
Date: Sat, 5 Jan 2019 07:57:38 +0000
Subject: [CMake][Fuchsia] Enable --build-id linker flag by default

This enables passing --build-id to linker by default.

Differential Revision: https://reviews.llvm.org/D56348

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350459 91177308-0d34-0410-b5e6-96231b3b80d8
---
 cmake/caches/Fuchsia-stage2.cmake | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/cmake/caches/Fuchsia-stage2.cmake b/cmake/caches/Fuchsia-stage2.cmake
index 9413c79dc3..c4daee1b76 100644
--- a/cmake/caches/Fuchsia-stage2.cmake
+++ b/cmake/caches/Fuchsia-stage2.cmake
@@ -14,6 +14,8 @@ set(LLVM_ENABLE_ZLIB ON CACHE BOOL "")
 set(LLVM_EXTERNALIZE_DEBUGINFO ON CACHE BOOL "")
 set(CLANG_PLUGIN_SUPPORT OFF CACHE BOOL "")
 
+set(ENABLE_LINKER_BUILD_ID ON CACHE BOOL "")
+
 set(LLVM_ENABLE_LTO ON CACHE BOOL "")
 if(NOT APPLE)
   set(LLVM_ENABLE_LLD ON CACHE BOOL "")
-- 
cgit v1.2.3


From 264e7d838aaef3e915f2d80001572d1f2ab4ebd9 Mon Sep 17 00:00:00 2001
From: Petr Hosek 
Date: Sat, 5 Jan 2019 07:57:46 +0000
Subject: [CMake][Fuchsia] Enable x86 relaxation by default

This enables x86 relaxation by default. This depends on a linker new
enough to support the new reloc types but since we default to lld we
don't worry about host system linkers that might be too old to support
the new reloc types.

Differential Revision: https://reviews.llvm.org/D56349

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350460 91177308-0d34-0410-b5e6-96231b3b80d8
---
 cmake/caches/Fuchsia-stage2.cmake | 1 +
 1 file changed, 1 insertion(+)

diff --git a/cmake/caches/Fuchsia-stage2.cmake b/cmake/caches/Fuchsia-stage2.cmake
index c4daee1b76..3d9b08da44 100644
--- a/cmake/caches/Fuchsia-stage2.cmake
+++ b/cmake/caches/Fuchsia-stage2.cmake
@@ -15,6 +15,7 @@ set(LLVM_EXTERNALIZE_DEBUGINFO ON CACHE BOOL "")
 set(CLANG_PLUGIN_SUPPORT OFF CACHE BOOL "")
 
 set(ENABLE_LINKER_BUILD_ID ON CACHE BOOL "")
+set(ENABLE_X86_RELAX_RELOCATIONS ON CACHE BOOL "")
 
 set(LLVM_ENABLE_LTO ON CACHE BOOL "")
 if(NOT APPLE)
-- 
cgit v1.2.3


From 0da4016acab85eaae8b07d807cfcf35028d6e4d0 Mon Sep 17 00:00:00 2001
From: Petr Hosek 
Date: Sat, 5 Jan 2019 07:57:53 +0000
Subject: [CMake][Fuchsia] Enable experimental new pass manager by default

This change enableds experimental new pass manager.

Differential Revision: https://reviews.llvm.org/D56350

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350461 91177308-0d34-0410-b5e6-96231b3b80d8
---
 cmake/caches/Fuchsia-stage2.cmake | 1 +
 1 file changed, 1 insertion(+)

diff --git a/cmake/caches/Fuchsia-stage2.cmake b/cmake/caches/Fuchsia-stage2.cmake
index 3d9b08da44..ef991b1f8a 100644
--- a/cmake/caches/Fuchsia-stage2.cmake
+++ b/cmake/caches/Fuchsia-stage2.cmake
@@ -16,6 +16,7 @@ set(CLANG_PLUGIN_SUPPORT OFF CACHE BOOL "")
 
 set(ENABLE_LINKER_BUILD_ID ON CACHE BOOL "")
 set(ENABLE_X86_RELAX_RELOCATIONS ON CACHE BOOL "")
+set(ENABLE_EXPERIMENTAL_NEW_PASS_MANAGER ON CACHE BOOL "")
 
 set(LLVM_ENABLE_LTO ON CACHE BOOL "")
 if(NOT APPLE)
-- 
cgit v1.2.3


From f098e402487681b6d371d8a5c731b320412d8435 Mon Sep 17 00:00:00 2001
From: Serge Guelton 
Date: Sat, 5 Jan 2019 12:07:36 +0000
Subject: [python] Make the collections import future-proof

On Python 3.7 the old code raises a warning:

	DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working
    	class ArgumentsIterator(collections.Sequence):

On Python 3.8 it wouldn't work anymore.

Commited on behalf of Jakub Stasiak.

Differential Revision: https://reviews.llvm.org/D56341

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350467 91177308-0d34-0410-b5e6-96231b3b80d8
---
 bindings/python/clang/cindex.py | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/bindings/python/clang/cindex.py b/bindings/python/clang/cindex.py
index 54514b8dae..8b23ae90b9 100644
--- a/bindings/python/clang/cindex.py
+++ b/bindings/python/clang/cindex.py
@@ -64,7 +64,6 @@ from __future__ import absolute_import, division, print_function
 # o implement additional SourceLocation, SourceRange, and File methods.
 
 from ctypes import *
-import collections
 
 import clang.enumerations
 
@@ -123,6 +122,14 @@ elif sys.version_info[0] == 2:
     def b(x):
         return x
 
+# Importing ABC-s directly from collections is deprecated since Python 3.7,
+# will stop working in Python 3.8.
+# See: https://docs.python.org/dev/whatsnew/3.7.html#id3
+if sys.version_info[:2] >= (3, 7):
+    from collections import abc as collections_abc
+else:
+    import collections as collections_abc
+
 # We only support PathLike objects on Python version with os.fspath present
 # to be consistent with the Python standard library. On older Python versions
 # we only support strings and we have dummy fspath to just pass them through.
@@ -2181,7 +2188,7 @@ class Type(Structure):
         The returned object is iterable and indexable. Each item in the
         container is a Type instance.
         """
-        class ArgumentsIterator(collections.Sequence):
+        class ArgumentsIterator(collections_abc.Sequence):
             def __init__(self, parent):
                 self.parent = parent
                 self.length = None
-- 
cgit v1.2.3


From 310a23fc9ae245bdedfe69f9ed0ab749717d50f2 Mon Sep 17 00:00:00 2001
From: Mike Spertus 
Date: Sat, 5 Jan 2019 17:01:34 +0000
Subject: Improve MSVC type visualizations

Display TypeBits in a single line.
Fix bit rot in template visualizations
Rudimentary support for deduced types



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350470 91177308-0d34-0410-b5e6-96231b3b80d8
---
 utils/ClangVisualizers/clang.natvis | 54 ++++++++++++++++++++++++++++++++-----
 1 file changed, 47 insertions(+), 7 deletions(-)

diff --git a/utils/ClangVisualizers/clang.natvis b/utils/ClangVisualizers/clang.natvis
index 24c4715cca..a581a0d068 100644
--- a/utils/ClangVisualizers/clang.natvis
+++ b/utils/ClangVisualizers/clang.natvis
@@ -34,16 +34,37 @@ For later versions of Visual Studio, no setup is required-->
     {*(clang::RecordType *)this,view(cpp)}
     {*(clang::FunctionProtoType *)this}
     {*(clang::TemplateSpecializationType *)this}
+    {*(clang::DeducedTemplateSpecializationType *)this}
     {*(clang::InjectedClassNameType *)this}
     {*(clang::PackExpansionType *)this}
     {*(clang::LocInfoType *)this}
     {*this,view(poly)}
     No visualizer yet for {(clang::Type::TypeClass)TypeBits.TC,en}Type 
+    Dependent
+    
+    InstantiationDependent
+    
+    VariablyModified
+    
+    ContainsUnexpandedParameterPack
+    
+    CachedLinkage: {(clang::Linkage)TypeBits.CachedLinkage,en} CachedLocalOrUnnamed
+    CachedLinkage: {(clang::Linkage)TypeBits.CachedLinkage,en}
+    
+    FromAST
+    
+    
+      No TypeBits set beyond TypeClass
+    
+    
+    {*this, view(Dependent)}{*this, view(InstantiationDependent)}{*this, view(VariablyModified)}
+    {*this, view(ContainsUnexpandedParameterPack)}{*this, view(Cache)}{*this, view(FromAST)}
     {*this,view(cmn)}  {{{*this,view(poly)}}}
     
       (clang::Type::TypeClass)TypeBits.TC
-      TypeBits
+      *this,view(flags)
       CanonicalType
+      CanonicalType.Value.Value == this
       *(clang::BuiltinType *)this
       *(clang::PointerType *)this
       *(clang::LValueReferenceType *)this
@@ -54,6 +75,7 @@ For later versions of Visual Studio, no setup is required-->
       (clang::RecordType *)this
       (clang::FunctionProtoType *)this
       (clang::TemplateSpecializationType *)this
+      (clang::DeducedTemplateSpecializationType *)this
       (clang::InjectedClassNameType *)this
       (clang::PackExpansionType *)this
       (clang::LocInfoType *)this
@@ -125,7 +147,13 @@ For later versions of Visual Studio, no setup is required-->
     {*this,view(TorC)} {*this,view(MaybeEllipses)}{Name,view(cpp)} 
   
   
-    template{*TemplateParams} {*TemplatedDecl};
+    template{TemplateParams,view(deref)} {*TemplatedDecl};
+  
+  
+    {Storage,view(deref)}
+    
+      Storage
+    
   
   
     {Name,view(cpp)}
@@ -136,11 +164,11 @@ For later versions of Visual Studio, no setup is required-->
     
     {*this,view(implicit)}
     {*this,view(modifiers)}{Name,view(cpp)}
-    {*this,view(modifiers)}struct {Name,view(cpp)}
-    {*this,view(modifiers)}interface {Name,view(cpp)}
-    {*this,view(modifiers)}union {Name,view(cpp)}
-    {*this,view(modifiers)}class {Name,view(cpp)}
-    {*this,view(modifiers)}enum {Name,view(cpp)}
+    {*this,view(modifiers)}struct {Name,view(cpp)}
+    {*this,view(modifiers)}interface {Name,view(cpp)}
+    {*this,view(modifiers)}union {Name,view(cpp)}
+    {*this,view(modifiers)}class {Name,view(cpp)}
+    {*this,view(modifiers)}enum {Name,view(cpp)}
     
       (clang::DeclContext *)this
     
@@ -381,6 +409,18 @@ For later versions of Visual Studio, no setup is required-->
       
     
   
+  
+    
+      (CanonicalType.Value.Value != this) || TypeBits.Dependent
+      *(clang::Type *)this,view(cmn)
+    
+  
+  
+    {Template}
+    
+      *(clang::DeducedType *)this
+    
+  
   
     {((llvm::StringMapEntry<clang::IdentifierInfo *>*)Entry)+1,sb}
     
-- 
cgit v1.2.3


From 270a7924028186360e10a9e606b5978ae3f179b7 Mon Sep 17 00:00:00 2001
From: Saleem Abdulrasool 
Date: Sat, 5 Jan 2019 18:39:32 +0000
Subject: CodeGen: switch iteration to range based for loop (NFC)

Change a loop to range based instead while working on cleaning up some
modules autolinking issues on Linux.  NFC.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350472 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/CodeGen/CodeGenModule.cpp | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index b398f98024..b9466fe87c 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -1746,16 +1746,14 @@ void CodeGenModule::EmitModuleLinkOptions() {
     bool AnyChildren = false;
 
     // Visit the submodules of this module.
-    for (clang::Module::submodule_iterator Sub = Mod->submodule_begin(),
-                                        SubEnd = Mod->submodule_end();
-         Sub != SubEnd; ++Sub) {
+    for (const auto &SM : Mod->submodules()) {
       // Skip explicit children; they need to be explicitly imported to be
       // linked against.
-      if ((*Sub)->IsExplicit)
+      if (SM->IsExplicit)
         continue;
 
-      if (Visited.insert(*Sub).second) {
-        Stack.push_back(*Sub);
+      if (Visited.insert(SM).second) {
+        Stack.push_back(SM);
         AnyChildren = true;
       }
     }
-- 
cgit v1.2.3


From 4159746b2cb2077a5a10b1ba65d8c865d35f6bd3 Mon Sep 17 00:00:00 2001
From: Saleem Abdulrasool 
Date: Sat, 5 Jan 2019 19:27:12 +0000
Subject: CodeGen: fix autolink emission on ELF

The autolinking extension for ELF uses a slightly different format for
encoding the autolink information compared to COFF and MachO.  Account
for this in the CGM to ensure that we do not assert when emitting
assembly or an object file.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350476 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/CodeGen/CodeGenModule.cpp | 20 +++++++++++++++-----
 test/Modules/autolink.m       |  4 ++--
 2 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index b9466fe87c..54190493f0 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -1692,6 +1692,8 @@ static void addLinkOptionsPostorder(CodeGenModule &CGM, Module *Mod,
   // Add linker options to link against the libraries/frameworks
   // described by this module.
   llvm::LLVMContext &Context = CGM.getLLVMContext();
+  bool IsELF = CGM.getTarget().getTriple().isOSBinFormatELF();
+  bool IsPS4 = CGM.getTarget().getTriple().isPS4();
 
   // For modules that use export_as for linking, use that module
   // name instead.
@@ -1711,11 +1713,19 @@ static void addLinkOptionsPostorder(CodeGenModule &CGM, Module *Mod,
     }
 
     // Link against a library.
-    llvm::SmallString<24> Opt;
-    CGM.getTargetCodeGenInfo().getDependentLibraryOption(
-      Mod->LinkLibraries[I-1].Library, Opt);
-    auto *OptString = llvm::MDString::get(Context, Opt);
-    Metadata.push_back(llvm::MDNode::get(Context, OptString));
+    if (IsELF && !IsPS4) {
+      llvm::Metadata *Args[2] = {
+          llvm::MDString::get(Context, "lib"),
+          llvm::MDString::get(Context, Mod->LinkLibraries[I - 1].Library),
+      };
+      Metadata.push_back(llvm::MDNode::get(Context, Args));
+    } else {
+      llvm::SmallString<24> Opt;
+      CGM.getTargetCodeGenInfo().getDependentLibraryOption(
+          Mod->LinkLibraries[I - 1].Library, Opt);
+      auto *OptString = llvm::MDString::get(Context, Opt);
+      Metadata.push_back(llvm::MDNode::get(Context, OptString));
+    }
   }
 }
 
diff --git a/test/Modules/autolink.m b/test/Modules/autolink.m
index 6aee0e11b1..f15472692d 100644
--- a/test/Modules/autolink.m
+++ b/test/Modules/autolink.m
@@ -37,9 +37,9 @@ int use_autolink_sub3() {
 // NOTE: "autolink_sub" is intentionally not linked.
 
 // CHECK: !llvm.linker.options = !{![[AUTOLINK_PCH:[0-9]+]], ![[AUTOLINK_FRAMEWORK:[0-9]+]], ![[AUTOLINK:[0-9]+]], ![[DEPENDSONMODULE:[0-9]+]], ![[MODULE:[0-9]+]], ![[NOUMBRELLA:[0-9]+]]}
-// CHECK: ![[AUTOLINK_PCH]] = !{!"{{(\\01|-l|/DEFAULTLIB:)}}autolink_from_pch{{(\.lib)?}}"}
+// CHECK: ![[AUTOLINK_PCH]] = !{!"{{(\\01|-l|/DEFAULTLIB:|lib", !")}}autolink_from_pch{{(\.lib)?}}"}
 // CHECK: ![[AUTOLINK_FRAMEWORK]] = !{!"-framework", !"autolink_framework"}
-// CHECK: ![[AUTOLINK]] = !{!"{{(\\01|-l|/DEFAULTLIB:)}}autolink{{(\.lib)?}}"}
+// CHECK: ![[AUTOLINK]] = !{!"{{(\\01|-l|/DEFAULTLIB:|lib", !")}}autolink{{(\.lib)?}}"}
 // CHECK: ![[DEPENDSONMODULE]] = !{!"-framework", !"DependsOnModule"}
 // CHECK: ![[MODULE]] = !{!"-framework", !"Module"}
 // CHECK: ![[NOUMBRELLA]] = !{!"-framework", !"NoUmbrella"}
-- 
cgit v1.2.3


From 98c2cb159c1d4b54ebe0862467665ef10f2b586d Mon Sep 17 00:00:00 2001
From: Mike Spertus 
Date: Sat, 5 Jan 2019 23:15:30 +0000
Subject: Fix MSVC Visualization for TemplateTypeParmType and
 TemplateTypeParmDecl

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350482 91177308-0d34-0410-b5e6-96231b3b80d8
---
 utils/ClangVisualizers/clang.natvis | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/utils/ClangVisualizers/clang.natvis b/utils/ClangVisualizers/clang.natvis
index a581a0d068..dad00c5618 100644
--- a/utils/ClangVisualizers/clang.natvis
+++ b/utils/ClangVisualizers/clang.natvis
@@ -57,14 +57,13 @@ For later versions of Visual Studio, no setup is required-->
       No TypeBits set beyond TypeClass
     
     
-    {*this, view(Dependent)}{*this, view(InstantiationDependent)}{*this, view(VariablyModified)}
-    {*this, view(ContainsUnexpandedParameterPack)}{*this, view(Cache)}{*this, view(FromAST)}
+{*this, view(Dependent)}{*this, view(InstantiationDependent)}{*this, view(VariablyModified)}
+{*this, view(ContainsUnexpandedParameterPack)}{*this, view(Cache)}{*this, view(FromAST)}
     {*this,view(cmn)}  {{{*this,view(poly)}}}
     
       (clang::Type::TypeClass)TypeBits.TC
       *this,view(flags)
       CanonicalType
-      CanonicalType.Value.Value == this
       *(clang::BuiltinType *)this
       *(clang::PointerType *)this
       *(clang::LValueReferenceType *)this
@@ -142,8 +141,9 @@ For later versions of Visual Studio, no setup is required-->
   
     typename
     class
-    ...
-    
+    (not yet known if parameter pack) 
+    ...
+    
     {*this,view(TorC)} {*this,view(MaybeEllipses)}{Name,view(cpp)} 
   
   
@@ -227,8 +227,10 @@ For later versions of Visual Studio, no setup is required-->
     
   
   
-    {*TTPDecl,view(cpp)}
-    {*TTPDecl}
+    Non-canonical: {*TTPDecl}
+    Canonical: {CanTTPTInfo}
+    
+    
   
   
     {*Decl,view(cpp)}
@@ -261,6 +263,7 @@ For later versions of Visual Studio, no setup is required-->
     {" ",sb}volatile restrict
     {" ",sb}const volatile restrict
     Cannot visualize non-fast qualifiers
+    Null
     {*((clang::ExtQualsTypeCommonBase *)(((uintptr_t)Value.Value) & ~(uintptr_t)((1 << 4) - 1)))->BaseType}{*this,view(fastQuals)}
     
       *this,view(fastQuals)
-- 
cgit v1.2.3


From 53e3c74f8e4c55f5122bdd1cab090fd21daa9ce2 Mon Sep 17 00:00:00 2001
From: Petr Hosek 
Date: Sat, 5 Jan 2019 23:45:31 +0000
Subject: Revert "[CMake][Fuchsia] Enable experimental new pass manager by
 default"

This reverts commit r350461 as it causes many of the Clang tests to fail.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350484 91177308-0d34-0410-b5e6-96231b3b80d8
---
 cmake/caches/Fuchsia-stage2.cmake | 1 -
 1 file changed, 1 deletion(-)

diff --git a/cmake/caches/Fuchsia-stage2.cmake b/cmake/caches/Fuchsia-stage2.cmake
index ef991b1f8a..3d9b08da44 100644
--- a/cmake/caches/Fuchsia-stage2.cmake
+++ b/cmake/caches/Fuchsia-stage2.cmake
@@ -16,7 +16,6 @@ set(CLANG_PLUGIN_SUPPORT OFF CACHE BOOL "")
 
 set(ENABLE_LINKER_BUILD_ID ON CACHE BOOL "")
 set(ENABLE_X86_RELAX_RELOCATIONS ON CACHE BOOL "")
-set(ENABLE_EXPERIMENTAL_NEW_PASS_MANAGER ON CACHE BOOL "")
 
 set(LLVM_ENABLE_LTO ON CACHE BOOL "")
 if(NOT APPLE)
-- 
cgit v1.2.3


From ace6bcb7b9f4114b051d3c70d0f3f92c4099959f Mon Sep 17 00:00:00 2001
From: Petr Hosek 
Date: Sun, 6 Jan 2019 04:14:51 +0000
Subject: [CMake][Fuchsia] Enable build ID, relaxations for first stage

We want these to be used for the second stage compiler as well.

Differential Revision: https://reviews.llvm.org/D56359

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350486 91177308-0d34-0410-b5e6-96231b3b80d8
---
 cmake/caches/Fuchsia.cmake | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/cmake/caches/Fuchsia.cmake b/cmake/caches/Fuchsia.cmake
index cc3baa294d..2ac30de6ba 100644
--- a/cmake/caches/Fuchsia.cmake
+++ b/cmake/caches/Fuchsia.cmake
@@ -14,6 +14,9 @@ set(LLVM_ENABLE_ZLIB OFF CACHE BOOL "")
 set(CLANG_INCLUDE_TESTS OFF CACHE BOOL "")
 set(CLANG_PLUGIN_SUPPORT OFF CACHE BOOL "")
 
+set(ENABLE_LINKER_BUILD_ID ON CACHE BOOL "")
+set(ENABLE_X86_RELAX_RELOCATIONS ON CACHE BOOL "")
+
 set(LLVM_ENABLE_ASSERTIONS ON CACHE BOOL "")
 set(CMAKE_BUILD_TYPE Release CACHE STRING "")
 
-- 
cgit v1.2.3


From 6d5c059076455da0429f6ba4f11d3185c65ef362 Mon Sep 17 00:00:00 2001
From: Mike Spertus 
Date: Sun, 6 Jan 2019 04:58:48 +0000
Subject: Have MSVC Visualizer for DeducedTemplateSpecializationType show both
 the original template and deduced specialization

Now appears in the Autos window something like

- MyType	DeducedTemplateSpecializationType  {struct Y}
|- Template	template struct Y;
|- Deduced As	struct Y
|- isDeduced	true	bool
|- TypeClass	DeducedTemplateSpecialization (36)
|- Flags	No TypeBits set beyond TypeClass
|- Canonical	RecordType  {struct Y}

Also changed QualType visualization to auto-expand the BaseType



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350487 91177308-0d34-0410-b5e6-96231b3b80d8
---
 utils/ClangVisualizers/clang.natvis | 37 ++++++++++++++++++++++++-------------
 1 file changed, 24 insertions(+), 13 deletions(-)

diff --git a/utils/ClangVisualizers/clang.natvis b/utils/ClangVisualizers/clang.natvis
index dad00c5618..17556f9cab 100644
--- a/utils/ClangVisualizers/clang.natvis
+++ b/utils/ClangVisualizers/clang.natvis
@@ -40,16 +40,16 @@ For later versions of Visual Studio, no setup is required-->
     {*(clang::LocInfoType *)this}
     {*this,view(poly)}
     No visualizer yet for {(clang::Type::TypeClass)TypeBits.TC,en}Type 
-    Dependent
+    Dependent{" ",sb}
     
-    InstantiationDependent
+    InstantiationDependent{" ",sb}
     
-    VariablyModified
+    VariablyModified{" ",sb}
     
-    ContainsUnexpandedParameterPack
+    ContainsUnexpandedParameterPack{" ",sb}
     
     CachedLinkage: {(clang::Linkage)TypeBits.CachedLinkage,en} CachedLocalOrUnnamed
-    CachedLinkage: {(clang::Linkage)TypeBits.CachedLinkage,en}
+    CachedLinkage: {(clang::Linkage)TypeBits.CachedLinkage,en}{" ",sb}
     
     FromAST
     
@@ -162,13 +162,13 @@ For later versions of Visual Studio, no setup is required-->
   
     implicit{" ",sb}
     
-    {*this,view(implicit)}
+    {*this,view(implicit)nd}
     {*this,view(modifiers)}{Name,view(cpp)}
-    {*this,view(modifiers)}struct {Name,view(cpp)}
-    {*this,view(modifiers)}interface {Name,view(cpp)}
-    {*this,view(modifiers)}union {Name,view(cpp)}
-    {*this,view(modifiers)}class {Name,view(cpp)}
-    {*this,view(modifiers)}enum {Name,view(cpp)}
+    {*this,view(modifiers)nd}struct {Name,view(cpp)}
+    {*this,view(modifiers)nd}interface {Name,view(cpp)}
+    {*this,view(modifiers)nd}union {Name,view(cpp)}
+    {*this,view(modifiers)nd}class {Name,view(cpp)}
+    {*this,view(modifiers)nd}enum {Name,view(cpp)}
     
       (clang::DeclContext *)this
     
@@ -227,6 +227,7 @@ For later versions of Visual Studio, no setup is required-->
     
   
   
+    {*TTPDecl}
     Non-canonical: {*TTPDecl}
     Canonical: {CanTTPTInfo}
     
@@ -267,7 +268,7 @@ For later versions of Visual Studio, no setup is required-->
     {*((clang::ExtQualsTypeCommonBase *)(((uintptr_t)Value.Value) & ~(uintptr_t)((1 << 4) - 1)))->BaseType}{*this,view(fastQuals)}
     
       *this,view(fastQuals)
-      *((clang::ExtQualsTypeCommonBase *)(((uintptr_t)Value.Value) & ~(uintptr_t)((1 << 4) - 1)))->BaseType
+      *((clang::ExtQualsTypeCommonBase *)(((uintptr_t)Value.Value) & ~(uintptr_t)((1 << 4) - 1)))->BaseType
     
   
   
@@ -419,9 +420,20 @@ For later versions of Visual Studio, no setup is required-->
     
   
   
+    {CanonicalType,view(cpp)}
     {Template}
     
+      Template
+      CanonicalType,view(cpp)
       *(clang::DeducedType *)this
+      Template
+    
+  
+  
+    {*(CXXRecordDecl *)this,nd}{*TemplateArgs}
+    
+      (CXXRecordDecl *)this,nd
+      TemplateArgs
     
   
   
@@ -532,7 +544,6 @@ For later versions of Visual Studio, no setup is required-->
           
         
       
-      *(clang::Type *)this, view(cmn)
     
   
   
-- 
cgit v1.2.3


From 9474014cc9cd2c1ed6ede59304f4b976c69b72a9 Mon Sep 17 00:00:00 2001
From: Petr Hosek 
Date: Sun, 6 Jan 2019 08:23:56 +0000
Subject: [CMake] Use hidden visibility for static libc++ in Fuchsia

This is enables the use of libc++ in contexts such as device drivers.

Differential Revision: https://reviews.llvm.org/D55405

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350491 91177308-0d34-0410-b5e6-96231b3b80d8
---
 cmake/caches/Fuchsia-stage2.cmake | 1 +
 1 file changed, 1 insertion(+)

diff --git a/cmake/caches/Fuchsia-stage2.cmake b/cmake/caches/Fuchsia-stage2.cmake
index 3d9b08da44..5dccd1f9fb 100644
--- a/cmake/caches/Fuchsia-stage2.cmake
+++ b/cmake/caches/Fuchsia-stage2.cmake
@@ -119,6 +119,7 @@ if(FUCHSIA_SDK)
     set(RUNTIMES_${target}-fuchsia_LIBCXX_USE_COMPILER_RT ON CACHE BOOL "")
     set(RUNTIMES_${target}-fuchsia_LIBCXX_ENABLE_STATIC_ABI_LIBRARY ON CACHE BOOL "")
     set(RUNTIMES_${target}-fuchsia_LIBCXX_STATICALLY_LINK_ABI_IN_SHARED_LIBRARY OFF CACHE BOOL "")
+    set(RUNTIMES_${target}-fuchsia_LIBCXX_HERMETIC_STATIC_LIBRARY ON CACHE BOOL "")
     set(RUNTIMES_${target}-fuchsia_LIBCXX_ABI_VERSION 2 CACHE STRING "")
   endforeach()
 
-- 
cgit v1.2.3


From 4b88e5a18e030f104e3816616adf9eb1962001e5 Mon Sep 17 00:00:00 2001
From: Nico Weber 
Date: Sun, 6 Jan 2019 15:57:18 +0000
Subject: Fix bug in test found by the diagnostic added in r350340.

I meant to commit this change in 350341 but failed to do so (since it's
in test/CodeGenCXX, not in test/Frontend).


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350495 91177308-0d34-0410-b5e6-96231b3b80d8
---
 test/CodeGenCXX/debug-info-class-limited-plugin.test | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/test/CodeGenCXX/debug-info-class-limited-plugin.test b/test/CodeGenCXX/debug-info-class-limited-plugin.test
index 533c2f6b16..17248d5743 100644
--- a/test/CodeGenCXX/debug-info-class-limited-plugin.test
+++ b/test/CodeGenCXX/debug-info-class-limited-plugin.test
@@ -1,2 +1,2 @@
-RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -o - -load %llvmshlibdir/PrintFunctionNames%pluginext -add-plugin print-function-names %S/Inputs/debug-info-class-limited.cpp 2>&1 | FileCheck %S/Inputs/debug-info-class-limited.cpp
+RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -o - -load %llvmshlibdir/PrintFunctionNames%pluginext -add-plugin print-fns %S/Inputs/debug-info-class-limited.cpp 2>&1 | FileCheck %S/Inputs/debug-info-class-limited.cpp
 REQUIRES: plugins, examples
-- 
cgit v1.2.3


From 1a1eb1e55e1bccc461ae696bc445541f6fef3cd0 Mon Sep 17 00:00:00 2001
From: Brian Gesiak 
Date: Mon, 7 Jan 2019 03:25:59 +0000
Subject: [SemaCXX] Fix ICE for unexpanded parameter pack

Summary:
The documentation for RecursiveASTVisitor::TraverseDecl states that the
Decl being traversed may be null. In fact, this is the case when a
CXXCatchStmt with no exception decl is traversed. Because the visitor
for diagnosing unexpanded parameter packs does not check for null, it
ends up crashing when it attempts to call the Decl::isParameterPack
method on a null Decl pointer.

Add a null check to prevent an ICE, and a test case that would crash
otherwise. Also, because the test requires C++ exceptions and C++14,
change the test parameters for the entire test file. (Alternatively, I
thought about adding a new test file, but went with this approach for my
own convenience.)

Co-authored-by: Andreas Molzer 
Co-authored-by: Mara Bos 

Reviewers: rsmith

Reviewed By: rsmith

Subscribers: cfe-commits

Differential Revision: https://reviews.llvm.org/D56271

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350501 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/Sema/SemaTemplateVariadic.cpp | 2 +-
 test/SemaCXX/alias-template.cpp   | 6 +++++-
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/lib/Sema/SemaTemplateVariadic.cpp b/lib/Sema/SemaTemplateVariadic.cpp
index 3338cec5eb..0e7fc20d24 100644
--- a/lib/Sema/SemaTemplateVariadic.cpp
+++ b/lib/Sema/SemaTemplateVariadic.cpp
@@ -164,7 +164,7 @@ namespace {
       // A function parameter pack is a pack expansion, so cannot contain
       // an unexpanded parameter pack. Likewise for a template parameter
       // pack that contains any references to other packs.
-      if (D->isParameterPack())
+      if (D && D->isParameterPack())
         return true;
 
       return inherited::TraverseDecl(D);
diff --git a/test/SemaCXX/alias-template.cpp b/test/SemaCXX/alias-template.cpp
index f2ba04df78..0a92b9dd96 100644
--- a/test/SemaCXX/alias-template.cpp
+++ b/test/SemaCXX/alias-template.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -verify -std=c++11 %s
+// RUN: %clang_cc1 -verify -std=c++14 -fcxx-exceptions %s
 
 namespace RedeclAliasTypedef {
   template using T = int;
@@ -189,3 +189,7 @@ int sfinae_me() { return 0; } // expected-note{{candidate template ignored: subs
 
 int g = sfinae_me(); // expected-error{{no matching function for call to 'sfinae_me'}}
 }
+
+namespace NullExceptionDecl {
+template auto get = []() { try { } catch(...) {}; return I; }; // expected-error{{initializer contains unexpanded parameter pack 'I'}}
+}
-- 
cgit v1.2.3


From 02db2fa1a919655cb54a160131c3ca6a3fa215b5 Mon Sep 17 00:00:00 2001
From: Richard Smith 
Date: Mon, 7 Jan 2019 06:00:46 +0000
Subject: DR674, PR38883, PR40238: Qualified friend lookup should look for a
 template specialization if there is no matching non-template function.

This exposed a couple of related bugs:
 - we would sometimes substitute into a friend template instead of a
   suitable non-friend declaration; this would now crash because we'd
   decide the specialization of the friend is a redeclaration of itself
 - ADL failed to properly handle the case where an invisible local
   extern declaration redeclares an invisible friend

Both are fixed herein: in particular, we now never make invisible
friends or local extern declarations visible to name lookup unless
they are the only declaration of the entity. (We already mostly did
this for local extern declarations.)

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350505 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/Basic/DiagnosticSemaKinds.td |  4 +--
 include/clang/Sema/Sema.h                  |  6 ++---
 lib/AST/DeclBase.cpp                       |  6 +++++
 lib/Sema/SemaDecl.cpp                      | 17 +++++-------
 lib/Sema/SemaDeclCXX.cpp                   | 23 +++-------------
 lib/Sema/SemaLookup.cpp                    | 43 ++++++++++++------------------
 lib/Sema/SemaOverload.cpp                  | 29 ++++++++++++++++++++
 lib/Sema/SemaTemplate.cpp                  | 25 ++++++++++++++---
 test/CXX/class.access/class.friend/p1.cpp  |  5 ++--
 test/CXX/class.access/class.friend/p11.cpp | 11 +++-----
 test/CXX/class/class.friend/p1.cpp         |  4 +--
 test/CXX/drs/dr1xx.cpp                     |  5 ++--
 test/CXX/drs/dr5xx.cpp                     |  8 +++---
 test/CXX/drs/dr6xx.cpp                     | 42 ++++++++++++++++++++++++-----
 test/SemaCXX/cxx1y-deduced-return-type.cpp |  8 +++---
 test/SemaCXX/friend.cpp                    | 38 +++++++++++++++++++-------
 www/cxx_dr_status.html                     |  2 +-
 17 files changed, 169 insertions(+), 107 deletions(-)

diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index fb6cd24dba..c54fbc8b4c 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1298,8 +1298,8 @@ def ext_unelaborated_friend_type : ExtWarn<
 def warn_cxx98_compat_unelaborated_friend_type : Warning<
   "befriending %1 without '%select{struct|interface|union|class|enum}0' "
   "keyword is incompatible with C++98">, InGroup, DefaultIgnore;
-def err_qualified_friend_not_found : Error<
-  "no function named %0 with type %1 was found in the specified scope">;
+def err_qualified_friend_no_match : Error<
+  "friend declaration of %0 does not match any declaration in %1">;
 def err_introducing_special_friend : Error<
   "%plural{[0,2]:must use a qualified name when declaring|3:cannot declare}0"
   " a %select{constructor|destructor|conversion operator|deduction guide}0 "
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index 92bebcae7c..ab87704a40 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -6356,9 +6356,9 @@ public:
                     const TemplateArgumentListInfo &ExplicitTemplateArgs,
                                                     LookupResult &Previous);
 
-  bool CheckFunctionTemplateSpecialization(FunctionDecl *FD,
-                         TemplateArgumentListInfo *ExplicitTemplateArgs,
-                                           LookupResult &Previous);
+  bool CheckFunctionTemplateSpecialization(
+      FunctionDecl *FD, TemplateArgumentListInfo *ExplicitTemplateArgs,
+      LookupResult &Previous, bool QualifiedFriend = false);
   bool CheckMemberSpecialization(NamedDecl *Member, LookupResult &Previous);
   void CompleteMemberSpecialization(NamedDecl *Member, LookupResult &Previous);
 
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp
index 66dfa53314..b83082e9eb 100644
--- a/lib/AST/DeclBase.cpp
+++ b/lib/AST/DeclBase.cpp
@@ -1405,6 +1405,12 @@ static bool shouldBeHidden(NamedDecl *D) {
       D->isTemplateParameter())
     return true;
 
+  // Skip friends and local extern declarations unless they're the first
+  // declaration of the entity.
+  if ((D->isLocalExternDecl() || D->getFriendObjectKind()) &&
+      D != D->getCanonicalDecl())
+    return true;
+
   // Skip template specializations.
   // FIXME: This feels like a hack. Should DeclarationName support
   // template-ids, or is there a better way to keep specializations
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 40b0ed3779..f607873a73 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -5518,15 +5518,8 @@ NamedDecl *Sema::HandleDeclarator(Scope *S, Declarator &D,
 
   // If this has an identifier and is not a function template specialization,
   // add it to the scope stack.
-  if (New->getDeclName() && AddToScope) {
-    // Only make a locally-scoped extern declaration visible if it is the first
-    // declaration of this entity. Qualified lookup for such an entity should
-    // only find this declaration if there is no visible declaration of it.
-    bool AddToContext = !D.isRedeclaration() || !New->isLocalExternDecl();
-    PushOnScopeChains(New, S, AddToContext);
-    if (!AddToContext)
-      CurContext->addHiddenDecl(New);
-  }
+  if (New->getDeclName() && AddToScope)
+    PushOnScopeChains(New, S);
 
   if (isInOpenMPDeclareTargetContext())
     checkDeclIsAllowedInOpenMPTarget(nullptr, New);
@@ -7728,8 +7721,10 @@ static NamedDecl *DiagnoseInvalidRedeclaration(
   SmallVector, 1> NearMatches;
   TypoCorrection Correction;
   bool IsDefinition = ExtraArgs.D.isFunctionDefinition();
-  unsigned DiagMsg = IsLocalFriend ? diag::err_no_matching_local_friend
-                                   : diag::err_member_decl_does_not_match;
+  unsigned DiagMsg =
+    IsLocalFriend ? diag::err_no_matching_local_friend :
+    NewFD->getFriendObjectKind() ? diag::err_qualified_friend_no_match :
+    diag::err_member_decl_does_not_match;
   LookupResult Prev(SemaRef, Name, NewFD->getLocation(),
                     IsLocalFriend ? Sema::LookupLocalFriendName
                                   : Sema::LookupOrdinaryName,
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 2b380bf0dc..50d01f309b 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -14414,25 +14414,6 @@ NamedDecl *Sema::ActOnFriendFunctionDecl(Scope *S, Declarator &D,
 
     LookupQualifiedName(Previous, DC);
 
-    // Ignore things found implicitly in the wrong scope.
-    // TODO: better diagnostics for this case.  Suggesting the right
-    // qualified scope would be nice...
-    LookupResult::Filter F = Previous.makeFilter();
-    while (F.hasNext()) {
-      NamedDecl *D = F.next();
-      if (!DC->InEnclosingNamespaceSetOf(
-              D->getDeclContext()->getRedeclContext()))
-        F.erase();
-    }
-    F.done();
-
-    if (Previous.empty()) {
-      D.setInvalidType();
-      Diag(Loc, diag::err_qualified_friend_not_found)
-          << Name << TInfo->getType();
-      return nullptr;
-    }
-
     // C++ [class.friend]p1: A friend of a class is a function or
     //   class that is not a member of the class . . .
     if (DC->Equals(CurContext))
@@ -14446,6 +14427,10 @@ NamedDecl *Sema::ActOnFriendFunctionDecl(Scope *S, Declarator &D,
       //   A function can be defined in a friend declaration of a class if and
       //   only if the class is a non-local class (9.8), the function name is
       //   unqualified, and the function has namespace scope.
+      //
+      // FIXME: We should only do this if the scope specifier names the
+      // innermost enclosing namespace; otherwise the fixit changes the
+      // meaning of the code.
       SemaDiagnosticBuilder DB
         = Diag(SS.getRange().getBegin(), diag::err_qualified_friend_def);
 
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp
index a8a3651c5d..effccc2f3d 100644
--- a/lib/Sema/SemaLookup.cpp
+++ b/lib/Sema/SemaLookup.cpp
@@ -3337,38 +3337,29 @@ void Sema::ArgumentDependentLookup(DeclarationName Name, SourceLocation Loc,
           !isa(Underlying))
         continue;
 
-      if (!isVisible(D)) {
-        D = findAcceptableDecl(
-            *this, D, (Decl::IDNS_Ordinary | Decl::IDNS_OrdinaryFriend));
-        if (!D)
-          continue;
-        if (auto *USD = dyn_cast(D))
-          Underlying = USD->getTargetDecl();
-      }
-
-      // If the only declaration here is an ordinary friend, consider
-      // it only if it was declared in an associated classes.
-      if ((D->getIdentifierNamespace() & Decl::IDNS_Ordinary) == 0) {
-        // If it's neither ordinarily visible nor a friend, we can't find it.
-        if ((D->getIdentifierNamespace() & Decl::IDNS_OrdinaryFriend) == 0)
-          continue;
-
-        bool DeclaredInAssociatedClass = false;
-        for (Decl *DI = D; DI; DI = DI->getPreviousDecl()) {
-          DeclContext *LexDC = DI->getLexicalDeclContext();
-          if (isa(LexDC) &&
-              AssociatedClasses.count(cast(LexDC)) &&
-              isVisible(cast(DI))) {
-            DeclaredInAssociatedClass = true;
+      // The declaration is visible to argument-dependent lookup if either
+      // it's ordinarily visible or declared as a friend in an associated
+      // class.
+      bool Visible = false;
+      for (D = D->getMostRecentDecl(); D;
+           D = cast_or_null(D->getPreviousDecl())) {
+        if (D->getIdentifierNamespace() & Decl::IDNS_Ordinary) {
+          if (isVisible(D)) {
+            Visible = true;
+            break;
+          }
+        } else if (D->getFriendObjectKind()) {
+          auto *RD = cast(D->getLexicalDeclContext());
+          if (AssociatedClasses.count(RD) && isVisible(D)) {
+            Visible = true;
             break;
           }
         }
-        if (!DeclaredInAssociatedClass)
-          continue;
       }
 
       // FIXME: Preserve D as the FoundDecl.
-      Result.insert(Underlying);
+      if (Visible)
+        Result.insert(Underlying);
     }
   }
 }
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 257eef435f..172116e30c 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -1041,6 +1041,35 @@ Sema::CheckOverload(Scope *S, FunctionDecl *New, const LookupResult &Old,
     }
   }
 
+  // C++ [temp.friend]p1:
+  //   For a friend function declaration that is not a template declaration:
+  //    -- if the name of the friend is a qualified or unqualified template-id,
+  //       [...], otherwise
+  //    -- if the name of the friend is a qualified-id and a matching
+  //       non-template function is found in the specified class or namespace,
+  //       the friend declaration refers to that function, otherwise,
+  //    -- if the name of the friend is a qualified-id and a matching function
+  //       template is found in the specified class or namespace, the friend
+  //       declaration refers to the deduced specialization of that function
+  //       template, otherwise
+  //    -- the name shall be an unqualified-id [...]
+  // If we get here for a qualified friend declaration, we've just reached the
+  // third bullet. If the type of the friend is dependent, skip this lookup
+  // until instantiation.
+  if (New->getFriendObjectKind() && New->getQualifier() &&
+      !New->getType()->isDependentType()) {
+    LookupResult TemplateSpecResult(LookupResult::Temporary, Old);
+    TemplateSpecResult.addAllDecls(Old);
+    if (CheckFunctionTemplateSpecialization(New, nullptr, TemplateSpecResult,
+                                            /*QualifiedFriend*/true)) {
+      New->setInvalidDecl();
+      return Ovl_Overload;
+    }
+
+    Match = TemplateSpecResult.getAsSingle();
+    return Ovl_Match;
+  }
+
   return Ovl_Overload;
 }
 
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index 8485ecd3a3..35935f994c 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -8104,9 +8104,13 @@ Sema::CheckDependentFunctionTemplateSpecialization(FunctionDecl *FD,
 ///
 /// \param Previous the set of declarations that may be specialized by
 /// this function specialization.
+///
+/// \param QualifiedFriend whether this is a lookup for a qualified friend
+/// declaration with no explicit template argument list that might be
+/// befriending a function template specialization.
 bool Sema::CheckFunctionTemplateSpecialization(
     FunctionDecl *FD, TemplateArgumentListInfo *ExplicitTemplateArgs,
-    LookupResult &Previous) {
+    LookupResult &Previous, bool QualifiedFriend) {
   // The set of function template specializations that could match this
   // explicit function template specialization.
   UnresolvedSet<8> Candidates;
@@ -8193,10 +8197,25 @@ bool Sema::CheckFunctionTemplateSpecialization(
     }
   }
 
+  // For a qualified friend declaration (with no explicit marker to indicate
+  // that a template specialization was intended), note all (template and
+  // non-template) candidates.
+  if (QualifiedFriend && Candidates.empty()) {
+    Diag(FD->getLocation(), diag::err_qualified_friend_no_match)
+        << FD->getDeclName() << FDLookupContext;
+    // FIXME: We should form a single candidate list and diagnose all
+    // candidates at once, to get proper sorting and limiting.
+    for (auto *OldND : Previous) {
+      if (auto *OldFD = dyn_cast(OldND->getUnderlyingDecl()))
+        NoteOverloadCandidate(OldND, OldFD, FD->getType(), false);
+    }
+    FailedCandidates.NoteCandidates(*this, FD->getLocation());
+    return true;
+  }
+
   // Find the most specialized function template.
   UnresolvedSetIterator Result = getMostSpecialized(
-      Candidates.begin(), Candidates.end(), FailedCandidates,
-      FD->getLocation(),
+      Candidates.begin(), Candidates.end(), FailedCandidates, FD->getLocation(),
       PDiag(diag::err_function_template_spec_no_match) << FD->getDeclName(),
       PDiag(diag::err_function_template_spec_ambiguous)
           << FD->getDeclName() << (ExplicitTemplateArgs != nullptr),
diff --git a/test/CXX/class.access/class.friend/p1.cpp b/test/CXX/class.access/class.friend/p1.cpp
index b6a1bcdab9..b335b0a8c8 100644
--- a/test/CXX/class.access/class.friend/p1.cpp
+++ b/test/CXX/class.access/class.friend/p1.cpp
@@ -11,12 +11,11 @@
 //   friends members of the befriending class.
 
 struct S { static void f(); }; // expected-note 2 {{'S' declared here}}
-S* g() { return 0; }
+S* g() { return 0; } // expected-note 2 {{'g' declared here}}
 
 struct X {
   friend struct S;
-  friend S* g(); // expected-note 2 {{'g' declared here}}
-  // FIXME: The above two notes would be better attached to line 11.
+  friend S* g();
 };
 
 void test1() {
diff --git a/test/CXX/class.access/class.friend/p11.cpp b/test/CXX/class.access/class.friend/p11.cpp
index 0d25c59c9b..0deead19a0 100644
--- a/test/CXX/class.access/class.friend/p11.cpp
+++ b/test/CXX/class.access/class.friend/p11.cpp
@@ -19,17 +19,16 @@ namespace test1 {
 }
 
 namespace test2 {
-  void bar(); // expected-note {{'::test2::bar' declared here}}
+  void bar(); // expected-note 3{{'::test2::bar' declared here}}
 
-  void foo() { // expected-note {{'::test2::foo' declared here}}
+  void foo() { // expected-note 2{{'::test2::foo' declared here}}
     struct S1 {
       friend void foo(); // expected-error {{no matching function 'foo' found in local scope; did you mean '::test2::foo'?}}
     };
 
     void foo(); // expected-note {{local declaration nearly matches}}
     struct S2 {
-      friend void foo(); // expected-note{{'::test2::foo' declared here}}
-      // TODO: the above note should go on line 24
+      friend void foo();
     };
 
     {
@@ -47,8 +46,6 @@ namespace test2 {
 
     struct S4 {
       friend void bar(); // expected-error {{no matching function 'bar' found in local scope; did you mean '::test2::bar'?}}
-      // expected-note@-1 {{'::test2::bar' declared here}}
-      // TODO: the above note should go on line 22
     };
 
     { void bar(); }
@@ -81,8 +78,6 @@ namespace test2 {
     struct S9 {
       struct Inner {
         friend void baz(); // expected-error {{no matching function 'baz' found in local scope; did you mean 'bar'?}}
-        // expected-note@-1 {{'::test2::bar' declared here}}
-        // TODO: the above note should go on line 22
       };
     };
 
diff --git a/test/CXX/class/class.friend/p1.cpp b/test/CXX/class/class.friend/p1.cpp
index 037fc3dadb..08498c0733 100644
--- a/test/CXX/class/class.friend/p1.cpp
+++ b/test/CXX/class/class.friend/p1.cpp
@@ -51,9 +51,9 @@ class A {
   friend class A::AInner; // this is okay as an extension
   friend class AInner; // okay, refers to ::AInner
 
-  friend void Derived::missing_member(); // expected-error {{no function named 'missing_member' with type 'void ()' was found in the specified scope}}
+  friend void Derived::missing_member(); // expected-error {{friend declaration of 'missing_member' does not match any declaration in 'Derived'}}
 
-  friend void Derived::base_member(); // expected-error {{no function named 'base_member' with type 'void ()' was found in the specified scope}}
+  friend void Derived::base_member(); // expected-error {{friend declaration of 'base_member' does not match any declaration in 'Derived'}}
 
   friend int Base::typedeffed_member(); // okay: should look through typedef
 
diff --git a/test/CXX/drs/dr1xx.cpp b/test/CXX/drs/dr1xx.cpp
index a92501128b..26ab67d54d 100644
--- a/test/CXX/drs/dr1xx.cpp
+++ b/test/CXX/drs/dr1xx.cpp
@@ -401,13 +401,12 @@ namespace dr136 { // dr136: 3.4
   extern "C" void k(int, int, int, int); // expected-note {{previous declaration is here}}
   namespace NSA {
   struct A {
-    friend void dr136::k(int, int, int, int = 0); // expected-error {{friend declaration specifying a default argument must be the only declaration}} \
-                                                  // expected-note {{previous declaration is here}}
+    friend void dr136::k(int, int, int, int = 0); // expected-error {{friend declaration specifying a default argument must be the only declaration}}
   };
   }
   namespace NSB {
   struct A {
-    friend void dr136::k(int, int, int = 0, int); // expected-error {{friend declaration specifying a default argument must be the only declaration}}
+    friend void dr136::k(int, int, int = 0, int); // expected-error {{missing default argument on parameter}}
   };
   }
   struct B {
diff --git a/test/CXX/drs/dr5xx.cpp b/test/CXX/drs/dr5xx.cpp
index c20a873fc1..2099612e23 100644
--- a/test/CXX/drs/dr5xx.cpp
+++ b/test/CXX/drs/dr5xx.cpp
@@ -740,17 +740,17 @@ namespace dr573 { // dr573: no
 
 namespace dr574 { // dr574: yes
   struct A {
-    A &operator=(const A&) const; // expected-note {{does not match because it is const}}
+    A &operator=(const A&) const; // expected-note {{different qualifiers}}
   };
   struct B {
-    B &operator=(const B&) volatile; // expected-note {{nearly matches}}
+    B &operator=(const B&) volatile; // expected-note {{different qualifiers}}
   };
 #if __cplusplus >= 201103L
   struct C {
-    C &operator=(const C&) &; // expected-note {{not viable}} expected-note {{nearly matches}} expected-note {{here}}
+    C &operator=(const C&) &; // expected-note {{not viable}} expected-note {{candidate}} expected-note {{here}}
   };
   struct D {
-    D &operator=(const D&) &&; // expected-note {{not viable}} expected-note {{nearly matches}} expected-note {{here}}
+    D &operator=(const D&) &&; // expected-note {{not viable}} expected-note {{candidate}} expected-note {{here}}
   };
   void test(C c, D d) {
     c = c;
diff --git a/test/CXX/drs/dr6xx.cpp b/test/CXX/drs/dr6xx.cpp
index f4eccfead2..b4247b2260 100644
--- a/test/CXX/drs/dr6xx.cpp
+++ b/test/CXX/drs/dr6xx.cpp
@@ -839,7 +839,7 @@ namespace dr673 { // dr673: yes
   F *f; // expected-error {{unknown type name}}
 }
 
-namespace dr674 { // dr674: no
+namespace dr674 { // dr674: 8
   template int f(T);
 
   int g(int);
@@ -849,22 +849,50 @@ namespace dr674 { // dr674: no
   template int h(T);
 
   class X {
-    // FIXME: This should deduce dr674::f.
-    friend int dr674::f(int); // expected-error {{does not match any}}
+    friend int dr674::f(int);
     friend int dr674::g(int);
     friend int dr674::h<>(int);
-    int n;
+    int n; // expected-note 2{{private}}
   };
 
   template int f(T) { return X().n; }
   int g(int) { return X().n; }
-  template int g(T) { return X().n; }
-  int h(int) { return X().n; }
+  template int g(T) { return X().n; } // expected-error {{private}}
+  int h(int) { return X().n; } // expected-error {{private}}
   template int h(T) { return X().n; }
 
   template int f(int);
-  template int g(int);
+  template int g(int); // expected-note {{in instantiation of}}
   template int h(int);
+
+
+  struct Y {
+    template int f(T);
+
+    int g(int);
+    template int g(T);
+
+    int h(int);
+    template int h(T);
+  };
+
+  class Z {
+    friend int Y::f(int);
+    friend int Y::g(int);
+    friend int Y::h<>(int);
+    int n; // expected-note 2{{private}}
+  };
+
+  template int Y::f(T) { return Z().n; }
+  int Y::g(int) { return Z().n; }
+  template int Y::g(T) { return Z().n; } // expected-error {{private}}
+  int Y::h(int) { return Z().n; } // expected-error {{private}}
+  template int Y::h(T) { return Z().n; }
+
+  // FIXME: Should the <> be required here?
+  template int Y::f<>(int);
+  template int Y::g<>(int); // expected-note {{in instantiation of}}
+  template int Y::h<>(int);
 }
 
 namespace dr675 { // dr675: dup 739
diff --git a/test/SemaCXX/cxx1y-deduced-return-type.cpp b/test/SemaCXX/cxx1y-deduced-return-type.cpp
index 5daba67bc5..fafc6ead73 100644
--- a/test/SemaCXX/cxx1y-deduced-return-type.cpp
+++ b/test/SemaCXX/cxx1y-deduced-return-type.cpp
@@ -565,7 +565,7 @@ namespace PR33222 {
     static auto f1();
     static auto f2();
 
-    template static decltype(auto) g0(T x) { return x.n; } // FIXME (PR38883): expected-error {{private}}
+    template static decltype(auto) g0(T x) { return x.n; }
     template static decltype(auto) g1(T);
     template static decltype(auto) g2(T);
   };
@@ -574,8 +574,6 @@ namespace PR33222 {
     friend auto f1();
     friend auto f2();
 
-    // FIXME (PR38883): This friend declaration doesn't actually work, because
-    // we fail to look up the named function properly during instantiation.
     friend decltype(auto) g0<>(A);
     template friend decltype(auto) g1(T);
     template friend decltype(auto) g2(T);
@@ -589,7 +587,7 @@ namespace PR33222 {
     template friend decltype(auto) X::g1(T_);
     template friend decltype(auto) X::g2(T_);
 
-    int n; // FIXME: expected-note {{here}}
+    int n;
   };
 
   auto f1() { return A().n; }
@@ -600,7 +598,7 @@ namespace PR33222 {
 
   A ai;
   int k1 = g0(ai);
-  int k2 = X::g0(ai); // FIXME: expected-note {{in instantiation of}}
+  int k2 = X::g0(ai);
 
   int k3 = g1(ai);
   int k4 = X::g1(ai);
diff --git a/test/SemaCXX/friend.cpp b/test/SemaCXX/friend.cpp
index 61e96922f6..822b1de39a 100644
--- a/test/SemaCXX/friend.cpp
+++ b/test/SemaCXX/friend.cpp
@@ -162,7 +162,7 @@ namespace test9 {
   class C {
   };
   struct A {
-    friend void C::f(int, int, int) {}  // expected-error {{no function named 'f' with type 'void (int, int, int)' was found in the specified scope}}
+    friend void C::f(int, int, int) {}  // expected-error {{friend function definition cannot be qualified with 'C::'}}
   };
 }
 
@@ -230,6 +230,10 @@ namespace test10 {
     friend void f10_d(X);
   };
 
+  struct W {
+    friend void f10_d(W);
+  };
+
   void g(X x, Y y, Z z) {
     f10_d(); // expected-error {{undeclared identifier}}
     ::test10::f10_d(); // expected-error {{no member named 'f10_d'}}
@@ -245,14 +249,13 @@ namespace test10 {
     ::test10::f10_d(z); // expected-error {{no type named 'f10_d'}}
   }
 
-  void local_externs(X x, Y y) {
-    extern void f10_d();
-    extern void f10_d(X);
+  void local_externs(W w, X x, Y y) {
+    extern void f10_d(); // expected-note {{candidate}}
+    extern void f10_d(X); // expected-note {{candidate}}
     f10_d();
     f10_d(x);
-    // FIXME: This lookup should fail, because the local extern declaration
-    // should suppress ADL.
     f10_d(y);
+    f10_d(w); // expected-error {{no matching}}
     {
       int f10_d;
       f10_d(); // expected-error {{not a function}}
@@ -402,12 +405,27 @@ namespace PR33222 {
   };
   Y yf; // expected-note {{instantiation}}
 
-  int h();
+  int h(); // expected-note {{previous}}
   template struct Z {
-    // FIXME: The note here should point at the non-friend declaration, not the
-    // instantiation in Z.
-    friend T h(); // expected-error {{return type}} expected-note {{previous}}
+    friend T h(); // expected-error {{return type}}
   };
   Z zi;
   Z zf; // expected-note {{instantiation}}
 }
+
+namespace qualified_friend_no_match {
+  void f(int); // expected-note {{type mismatch at 1st parameter}}
+  template void f(T*); // expected-note {{could not match 'type-parameter-0-0 *' against 'double'}}
+  struct X {
+    friend void qualified_friend_no_match::f(double); // expected-error {{friend declaration of 'f' does not match any declaration in namespace 'qualified_friend_no_match'}}
+    friend void qualified_friend_no_match::g(); // expected-error {{friend declaration of 'g' does not match any declaration in namespace 'qualified_friend_no_match'}}
+  };
+
+  struct Y {
+    void f(int); // expected-note {{type mismatch at 1st parameter}}
+    template void f(T*); // expected-note {{could not match 'type-parameter-0-0 *' against 'double'}}
+  };
+  struct Z {
+    friend void Y::f(double); // expected-error {{friend declaration of 'f' does not match any declaration in 'qualified_friend_no_match::Y'}}
+  };
+}
diff --git a/www/cxx_dr_status.html b/www/cxx_dr_status.html
index 460978260f..b3165c7f17 100755
--- a/www/cxx_dr_status.html
+++ b/www/cxx_dr_status.html
@@ -4087,7 +4087,7 @@ and POD class
     674
     C++11
     “matching specialization” for a friend declaration
-    No
+    SVN
   
   
     675
-- 
cgit v1.2.3


From ebdd117a2308d58b31404cbd02877c70772f0cec Mon Sep 17 00:00:00 2001
From: Craig Topper 
Date: Mon, 7 Jan 2019 06:01:58 +0000
Subject: [X86] Update VBMI2 vshld/vshrd tests to use an immediate that doesn't
 require a modulo.

Planning to replace these with funnel shift intrinsics which would mask out the extra bits. This will help minimize test diffs.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350506 91177308-0d34-0410-b5e6-96231b3b80d8
---
 test/CodeGen/avx512vbmi2-builtins.c   | 22 +++++++++----------
 test/CodeGen/avx512vlvbmi2-builtins.c | 40 +++++++++++++++++------------------
 2 files changed, 31 insertions(+), 31 deletions(-)

diff --git a/test/CodeGen/avx512vbmi2-builtins.c b/test/CodeGen/avx512vbmi2-builtins.c
index db4abdba45..a29203027d 100644
--- a/test/CodeGen/avx512vbmi2-builtins.c
+++ b/test/CodeGen/avx512vbmi2-builtins.c
@@ -90,7 +90,7 @@ __m512i test_mm512_mask_shldi_epi64(__m512i __S, __mmask8 __U, __m512i __A, __m5
   // CHECK-LABEL: @test_mm512_mask_shldi_epi64
   // CHECK: @llvm.x86.avx512.vpshld.q.512
   // CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}}
-  return _mm512_mask_shldi_epi64(__S, __U, __A, __B, 127);
+  return _mm512_mask_shldi_epi64(__S, __U, __A, __B, 47);
 }
 
 __m512i test_mm512_maskz_shldi_epi64(__mmask8 __U, __m512i __A, __m512i __B) {
@@ -110,14 +110,14 @@ __m512i test_mm512_mask_shldi_epi32(__m512i __S, __mmask16 __U, __m512i __A, __m
   // CHECK-LABEL: @test_mm512_mask_shldi_epi32
   // CHECK: @llvm.x86.avx512.vpshld.d.512
   // CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}}
-  return _mm512_mask_shldi_epi32(__S, __U, __A, __B, 127);
+  return _mm512_mask_shldi_epi32(__S, __U, __A, __B, 7);
 }
 
 __m512i test_mm512_maskz_shldi_epi32(__mmask16 __U, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_maskz_shldi_epi32
   // CHECK: @llvm.x86.avx512.vpshld.d.512
   // CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}}
-  return _mm512_maskz_shldi_epi32(__U, __A, __B, 63);
+  return _mm512_maskz_shldi_epi32(__U, __A, __B, 15);
 }
 
 __m512i test_mm512_shldi_epi32(__m512i __A, __m512i __B) {
@@ -130,27 +130,27 @@ __m512i test_mm512_mask_shldi_epi16(__m512i __S, __mmask32 __U, __m512i __A, __m
   // CHECK-LABEL: @test_mm512_mask_shldi_epi16
   // CHECK: @llvm.x86.avx512.vpshld.w.512
   // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}}
-  return _mm512_mask_shldi_epi16(__S, __U, __A, __B, 127);
+  return _mm512_mask_shldi_epi16(__S, __U, __A, __B, 3);
 }
 
 __m512i test_mm512_maskz_shldi_epi16(__mmask32 __U, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_maskz_shldi_epi16
   // CHECK: @llvm.x86.avx512.vpshld.w.512
   // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}}
-  return _mm512_maskz_shldi_epi16(__U, __A, __B, 63);
+  return _mm512_maskz_shldi_epi16(__U, __A, __B, 7);
 }
 
 __m512i test_mm512_shldi_epi16(__m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_shldi_epi16
   // CHECK: @llvm.x86.avx512.vpshld.w.512
-  return _mm512_shldi_epi16(__A, __B, 31);
+  return _mm512_shldi_epi16(__A, __B, 15);
 }
 
 __m512i test_mm512_mask_shrdi_epi64(__m512i __S, __mmask8 __U, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_mask_shrdi_epi64
   // CHECK: @llvm.x86.avx512.vpshrd.q.512
   // CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}}
-  return _mm512_mask_shrdi_epi64(__S, __U, __A, __B, 127);
+  return _mm512_mask_shrdi_epi64(__S, __U, __A, __B, 47);
 }
 
 __m512i test_mm512_maskz_shrdi_epi64(__mmask8 __U, __m512i __A, __m512i __B) {
@@ -170,14 +170,14 @@ __m512i test_mm512_mask_shrdi_epi32(__m512i __S, __mmask16 __U, __m512i __A, __m
   // CHECK-LABEL: @test_mm512_mask_shrdi_epi32
   // CHECK: @llvm.x86.avx512.vpshrd.d.512
   // CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}}
-  return _mm512_mask_shrdi_epi32(__S, __U, __A, __B, 127);
+  return _mm512_mask_shrdi_epi32(__S, __U, __A, __B, 7);
 }
 
 __m512i test_mm512_maskz_shrdi_epi32(__mmask16 __U, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_maskz_shrdi_epi32
   // CHECK: @llvm.x86.avx512.vpshrd.d.512
   // CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}}
-  return _mm512_maskz_shrdi_epi32(__U, __A, __B, 63);
+  return _mm512_maskz_shrdi_epi32(__U, __A, __B, 15);
 }
 
 __m512i test_mm512_shrdi_epi32(__m512i __A, __m512i __B) {
@@ -190,14 +190,14 @@ __m512i test_mm512_mask_shrdi_epi16(__m512i __S, __mmask32 __U, __m512i __A, __m
   // CHECK-LABEL: @test_mm512_mask_shrdi_epi16
   // CHECK: @llvm.x86.avx512.vpshrd.w.512
   // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}}
-  return _mm512_mask_shrdi_epi16(__S, __U, __A, __B, 127);
+  return _mm512_mask_shrdi_epi16(__S, __U, __A, __B, 3);
 }
 
 __m512i test_mm512_maskz_shrdi_epi16(__mmask32 __U, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_maskz_shrdi_epi16
   // CHECK: @llvm.x86.avx512.vpshrd.w.512
   // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}}
-  return _mm512_maskz_shrdi_epi16(__U, __A, __B, 63);
+  return _mm512_maskz_shrdi_epi16(__U, __A, __B, 15);
 }
 
 __m512i test_mm512_shrdi_epi16(__m512i __A, __m512i __B) {
diff --git a/test/CodeGen/avx512vlvbmi2-builtins.c b/test/CodeGen/avx512vlvbmi2-builtins.c
index aceb97616d..53b58400bc 100644
--- a/test/CodeGen/avx512vlvbmi2-builtins.c
+++ b/test/CodeGen/avx512vlvbmi2-builtins.c
@@ -174,7 +174,7 @@ __m256i test_mm256_mask_shldi_epi64(__m256i __S, __mmask8 __U, __m256i __A, __m2
   // CHECK-LABEL: @test_mm256_mask_shldi_epi64
   // CHECK: @llvm.x86.avx512.vpshld.q.256
   // CHECK: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}}
-  return _mm256_mask_shldi_epi64(__S, __U, __A, __B, 127);
+  return _mm256_mask_shldi_epi64(__S, __U, __A, __B, 47);
 }
 
 __m256i test_mm256_maskz_shldi_epi64(__mmask8 __U, __m256i __A, __m256i __B) {
@@ -194,7 +194,7 @@ __m128i test_mm_mask_shldi_epi64(__m128i __S, __mmask8 __U, __m128i __A, __m128i
   // CHECK-LABEL: @test_mm_mask_shldi_epi64
   // CHECK: @llvm.x86.avx512.vpshld.q.128
   // CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}}
-  return _mm_mask_shldi_epi64(__S, __U, __A, __B, 127);
+  return _mm_mask_shldi_epi64(__S, __U, __A, __B, 47);
 }
 
 __m128i test_mm_maskz_shldi_epi64(__mmask8 __U, __m128i __A, __m128i __B) {
@@ -214,14 +214,14 @@ __m256i test_mm256_mask_shldi_epi32(__m256i __S, __mmask8 __U, __m256i __A, __m2
   // CHECK-LABEL: @test_mm256_mask_shldi_epi32
   // CHECK: @llvm.x86.avx512.vpshld.d.256
   // CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}}
-  return _mm256_mask_shldi_epi32(__S, __U, __A, __B, 127);
+  return _mm256_mask_shldi_epi32(__S, __U, __A, __B, 7);
 }
 
 __m256i test_mm256_maskz_shldi_epi32(__mmask8 __U, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_maskz_shldi_epi32
   // CHECK: @llvm.x86.avx512.vpshld.d.256
   // CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}}
-  return _mm256_maskz_shldi_epi32(__U, __A, __B, 63);
+  return _mm256_maskz_shldi_epi32(__U, __A, __B, 15);
 }
 
 __m256i test_mm256_shldi_epi32(__m256i __A, __m256i __B) {
@@ -234,14 +234,14 @@ __m128i test_mm_mask_shldi_epi32(__m128i __S, __mmask8 __U, __m128i __A, __m128i
   // CHECK-LABEL: @test_mm_mask_shldi_epi32
   // CHECK: @llvm.x86.avx512.vpshld.d.128
   // CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
-  return _mm_mask_shldi_epi32(__S, __U, __A, __B, 127);
+  return _mm_mask_shldi_epi32(__S, __U, __A, __B, 7);
 }
 
 __m128i test_mm_maskz_shldi_epi32(__mmask8 __U, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_maskz_shldi_epi32
   // CHECK: @llvm.x86.avx512.vpshld.d.128
   // CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
-  return _mm_maskz_shldi_epi32(__U, __A, __B, 63);
+  return _mm_maskz_shldi_epi32(__U, __A, __B, 15);
 }
 
 __m128i test_mm_shldi_epi32(__m128i __A, __m128i __B) {
@@ -254,14 +254,14 @@ __m256i test_mm256_mask_shldi_epi16(__m256i __S, __mmask16 __U, __m256i __A, __m
   // CHECK-LABEL: @test_mm256_mask_shldi_epi16
   // CHECK: @llvm.x86.avx512.vpshld.w.256
   // CHECK: select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}}
-  return _mm256_mask_shldi_epi16(__S, __U, __A, __B, 127);
+  return _mm256_mask_shldi_epi16(__S, __U, __A, __B, 3);
 }
 
 __m256i test_mm256_maskz_shldi_epi16(__mmask16 __U, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_maskz_shldi_epi16
   // CHECK: @llvm.x86.avx512.vpshld.w.256
   // CHECK: select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}}
-  return _mm256_maskz_shldi_epi16(__U, __A, __B, 63);
+  return _mm256_maskz_shldi_epi16(__U, __A, __B, 7);
 }
 
 __m256i test_mm256_shldi_epi16(__m256i __A, __m256i __B) {
@@ -274,14 +274,14 @@ __m128i test_mm_mask_shldi_epi16(__m128i __S, __mmask8 __U, __m128i __A, __m128i
   // CHECK-LABEL: @test_mm_mask_shldi_epi16
   // CHECK: @llvm.x86.avx512.vpshld.w.128
   // CHECK: select <8 x i1> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}
-  return _mm_mask_shldi_epi16(__S, __U, __A, __B, 127);
+  return _mm_mask_shldi_epi16(__S, __U, __A, __B, 3);
 }
 
 __m128i test_mm_maskz_shldi_epi16(__mmask8 __U, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_maskz_shldi_epi16
   // CHECK: @llvm.x86.avx512.vpshld.w.128
   // CHECK: select <8 x i1> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}
-  return _mm_maskz_shldi_epi16(__U, __A, __B, 63);
+  return _mm_maskz_shldi_epi16(__U, __A, __B, 7);
 }
 
 __m128i test_mm_shldi_epi16(__m128i __A, __m128i __B) {
@@ -294,7 +294,7 @@ __m256i test_mm256_mask_shrdi_epi64(__m256i __S, __mmask8 __U, __m256i __A, __m2
   // CHECK-LABEL: @test_mm256_mask_shrdi_epi64
   // CHECK: @llvm.x86.avx512.vpshrd.q.256
   // CHECK: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}}
-  return _mm256_mask_shrdi_epi64(__S, __U, __A, __B, 127);
+  return _mm256_mask_shrdi_epi64(__S, __U, __A, __B, 47);
 }
 
 __m256i test_mm256_maskz_shrdi_epi64(__mmask8 __U, __m256i __A, __m256i __B) {
@@ -314,7 +314,7 @@ __m128i test_mm_mask_shrdi_epi64(__m128i __S, __mmask8 __U, __m128i __A, __m128i
   // CHECK-LABEL: @test_mm_mask_shrdi_epi64
   // CHECK: @llvm.x86.avx512.vpshrd.q.128
   // CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}}
-  return _mm_mask_shrdi_epi64(__S, __U, __A, __B, 127);
+  return _mm_mask_shrdi_epi64(__S, __U, __A, __B, 47);
 }
 
 __m128i test_mm_maskz_shrdi_epi64(__mmask8 __U, __m128i __A, __m128i __B) {
@@ -334,14 +334,14 @@ __m256i test_mm256_mask_shrdi_epi32(__m256i __S, __mmask8 __U, __m256i __A, __m2
   // CHECK-LABEL: @test_mm256_mask_shrdi_epi32
   // CHECK: @llvm.x86.avx512.vpshrd.d.256
   // CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}}
-  return _mm256_mask_shrdi_epi32(__S, __U, __A, __B, 127);
+  return _mm256_mask_shrdi_epi32(__S, __U, __A, __B, 7);
 }
 
 __m256i test_mm256_maskz_shrdi_epi32(__mmask8 __U, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_maskz_shrdi_epi32
   // CHECK: @llvm.x86.avx512.vpshrd.d.256
   // CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}}
-  return _mm256_maskz_shrdi_epi32(__U, __A, __B, 63);
+  return _mm256_maskz_shrdi_epi32(__U, __A, __B, 15);
 }
 
 __m256i test_mm256_shrdi_epi32(__m256i __A, __m256i __B) {
@@ -354,14 +354,14 @@ __m128i test_mm_mask_shrdi_epi32(__m128i __S, __mmask8 __U, __m128i __A, __m128i
   // CHECK-LABEL: @test_mm_mask_shrdi_epi32
   // CHECK: @llvm.x86.avx512.vpshrd.d.128
   // CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
-  return _mm_mask_shrdi_epi32(__S, __U, __A, __B, 127);
+  return _mm_mask_shrdi_epi32(__S, __U, __A, __B, 7);
 }
 
 __m128i test_mm_maskz_shrdi_epi32(__mmask8 __U, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_maskz_shrdi_epi32
   // CHECK: @llvm.x86.avx512.vpshrd.d.128
   // CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
-  return _mm_maskz_shrdi_epi32(__U, __A, __B, 63);
+  return _mm_maskz_shrdi_epi32(__U, __A, __B, 15);
 }
 
 __m128i test_mm_shrdi_epi32(__m128i __A, __m128i __B) {
@@ -374,14 +374,14 @@ __m256i test_mm256_mask_shrdi_epi16(__m256i __S, __mmask16 __U, __m256i __A, __m
   // CHECK-LABEL: @test_mm256_mask_shrdi_epi16
   // CHECK: @llvm.x86.avx512.vpshrd.w.256
   // CHECK: select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}}
-  return _mm256_mask_shrdi_epi16(__S, __U, __A, __B, 127);
+  return _mm256_mask_shrdi_epi16(__S, __U, __A, __B, 3);
 }
 
 __m256i test_mm256_maskz_shrdi_epi16(__mmask16 __U, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_maskz_shrdi_epi16
   // CHECK: @llvm.x86.avx512.vpshrd.w.256
   // CHECK: select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}}
-  return _mm256_maskz_shrdi_epi16(__U, __A, __B, 63);
+  return _mm256_maskz_shrdi_epi16(__U, __A, __B, 7);
 }
 
 __m256i test_mm256_shrdi_epi16(__m256i __A, __m256i __B) {
@@ -394,14 +394,14 @@ __m128i test_mm_mask_shrdi_epi16(__m128i __S, __mmask8 __U, __m128i __A, __m128i
   // CHECK-LABEL: @test_mm_mask_shrdi_epi16
   // CHECK: @llvm.x86.avx512.vpshrd.w.128
   // CHECK: select <8 x i1> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}
-  return _mm_mask_shrdi_epi16(__S, __U, __A, __B, 127);
+  return _mm_mask_shrdi_epi16(__S, __U, __A, __B, 3);
 }
 
 __m128i test_mm_maskz_shrdi_epi16(__mmask8 __U, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_maskz_shrdi_epi16
   // CHECK: @llvm.x86.avx512.vpshrd.w.128
   // CHECK: select <8 x i1> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}
-  return _mm_maskz_shrdi_epi16(__U, __A, __B, 63);
+  return _mm_maskz_shrdi_epi16(__U, __A, __B, 7);
 }
 
 __m128i test_mm_shrdi_epi16(__m128i __A, __m128i __B) {
-- 
cgit v1.2.3


From 84ee269c66965015f9e39a4b1005c81d1b174677 Mon Sep 17 00:00:00 2001
From: Martin Probst 
Date: Mon, 7 Jan 2019 13:12:50 +0000
Subject: clang-format: [JS] support goog.requireType.

Summary:
It's a new primitive for importing symbols, and should be treated like
the (previously handled) `goog.require` and `goog.forwardDeclare`.

Reviewers: krasimir

Subscribers: cfe-commits

Differential Revision: https://reviews.llvm.org/D56385

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350516 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/Format/TokenAnnotator.cpp     | 1 +
 unittests/Format/FormatTestJS.cpp | 2 ++
 2 files changed, 3 insertions(+)

diff --git a/lib/Format/TokenAnnotator.cpp b/lib/Format/TokenAnnotator.cpp
index a04f2e672b..24c2f998c3 100644
--- a/lib/Format/TokenAnnotator.cpp
+++ b/lib/Format/TokenAnnotator.cpp
@@ -1123,6 +1123,7 @@ private:
            (Tok.Next->Next->TokenText == "module" ||
             Tok.Next->Next->TokenText == "provide" ||
             Tok.Next->Next->TokenText == "require" ||
+            Tok.Next->Next->TokenText == "requireType" ||
             Tok.Next->Next->TokenText == "forwardDeclare") &&
            Tok.Next->Next->Next && Tok.Next->Next->Next->is(tok::l_paren);
   }
diff --git a/unittests/Format/FormatTestJS.cpp b/unittests/Format/FormatTestJS.cpp
index a14724f85e..67b99ba146 100644
--- a/unittests/Format/FormatTestJS.cpp
+++ b/unittests/Format/FormatTestJS.cpp
@@ -600,6 +600,8 @@ TEST_F(FormatTestJS, GoogModules) {
                getGoogleJSStyleWithColumns(40));
   verifyFormat("var long = goog.require('this.is.really.absurdly.long');",
                getGoogleJSStyleWithColumns(40));
+  verifyFormat("const X = goog.requireType('this.is.really.absurdly.long');",
+               getGoogleJSStyleWithColumns(40));
   verifyFormat("goog.forwardDeclare('this.is.really.absurdly.long');",
                getGoogleJSStyleWithColumns(40));
 
-- 
cgit v1.2.3


From 550f5b09756692e2f47cb2d54b42ee9436b91c8d Mon Sep 17 00:00:00 2001
From: Bruno Ricci 
Date: Mon, 7 Jan 2019 13:39:26 +0000
Subject: [AST][NFC] Pack OpaqueValueExpr

Use the newly available space in the bit-fields of Stmt.
This saves 1 pointer per OpaqueValueExpr. NFC.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350519 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/AST/Expr.h            | 15 +++++++--------
 include/clang/AST/Stmt.h            |  5 ++++-
 lib/Serialization/ASTReaderStmt.cpp |  2 +-
 3 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index 025ef0642a..1c757b5330 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -945,7 +945,6 @@ public:
 class OpaqueValueExpr : public Expr {
   friend class ASTStmtReader;
   Expr *SourceExpr;
-  SourceLocation Loc;
 
 public:
   OpaqueValueExpr(SourceLocation Loc, QualType T, ExprValueKind VK,
@@ -959,8 +958,9 @@ public:
            T->isInstantiationDependentType() ||
            (SourceExpr && SourceExpr->isInstantiationDependent()),
            false),
-      SourceExpr(SourceExpr), Loc(Loc) {
+      SourceExpr(SourceExpr) {
     setIsUnique(false);
+    OpaqueValueExprBits.Loc = Loc;
   }
 
   /// Given an expression which invokes a copy constructor --- i.e.  a
@@ -969,20 +969,19 @@ public:
   static const OpaqueValueExpr *findInCopyConstruct(const Expr *expr);
 
   explicit OpaqueValueExpr(EmptyShell Empty)
-    : Expr(OpaqueValueExprClass, Empty) { }
+    : Expr(OpaqueValueExprClass, Empty) {}
 
   /// Retrieve the location of this expression.
-  SourceLocation getLocation() const { return Loc; }
+  SourceLocation getLocation() const { return OpaqueValueExprBits.Loc; }
 
   SourceLocation getBeginLoc() const LLVM_READONLY {
-    return SourceExpr ? SourceExpr->getBeginLoc() : Loc;
+    return SourceExpr ? SourceExpr->getBeginLoc() : getLocation();
   }
   SourceLocation getEndLoc() const LLVM_READONLY {
-    return SourceExpr ? SourceExpr->getEndLoc() : Loc;
+    return SourceExpr ? SourceExpr->getEndLoc() : getLocation();
   }
   SourceLocation getExprLoc() const LLVM_READONLY {
-    if (SourceExpr) return SourceExpr->getExprLoc();
-    return Loc;
+    return SourceExpr ? SourceExpr->getExprLoc() : getLocation();
   }
 
   child_range children() {
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index 9d8a297487..c83af51626 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -706,13 +706,16 @@ protected:
   //===--- Clang Extensions bitfields classes ---===//
 
   class OpaqueValueExprBitfields {
+    friend class ASTStmtReader;
     friend class OpaqueValueExpr;
 
     unsigned : NumExprBits;
 
-    /// The OVE is a unique semantic reference to its source expressio if this
+    /// The OVE is a unique semantic reference to its source expression if this
     /// bit is set to true.
     unsigned IsUnique : 1;
+
+    SourceLocation Loc;
   };
 
   union {
diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp
index 83b4fcd1d9..f2c623eb6b 100644
--- a/lib/Serialization/ASTReaderStmt.cpp
+++ b/lib/Serialization/ASTReaderStmt.cpp
@@ -1773,7 +1773,7 @@ void ASTStmtReader::VisitCXXFoldExpr(CXXFoldExpr *E) {
 void ASTStmtReader::VisitOpaqueValueExpr(OpaqueValueExpr *E) {
   VisitExpr(E);
   E->SourceExpr = Record.readSubExpr();
-  E->Loc = ReadSourceLocation();
+  E->OpaqueValueExprBits.Loc = ReadSourceLocation();
   E->setIsUnique(Record.readInt());
 }
 
-- 
cgit v1.2.3


From 1aa1a6f871aca22a9dcca8fef4fb49b41cfd3582 Mon Sep 17 00:00:00 2001
From: Gabor Marton 
Date: Mon, 7 Jan 2019 14:05:19 +0000
Subject: [CTU] Make loadExternalAST return with non nullptr on success

Summary:
In loadExternalAST we return with either an error or with a valid
ASTUnit pointer which should not be a nullptr.
This prevents in the call site any superfluous check for being a nullptr.

Reviewers: xazax.hun, a_sidorin, Szelethus, balazske

Subscribers: rnkovacs, dkrupp, gamesh411, cfe-commits

Differential Revision: https://reviews.llvm.org/D55280

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350521 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/CrossTU/CrossTranslationUnit.h | 5 +++--
 lib/CrossTU/CrossTranslationUnit.cpp         | 6 +++---
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/include/clang/CrossTU/CrossTranslationUnit.h b/include/clang/CrossTU/CrossTranslationUnit.h
index a5cec7e05e..9b36fe653b 100644
--- a/include/clang/CrossTU/CrossTranslationUnit.h
+++ b/include/clang/CrossTU/CrossTranslationUnit.h
@@ -130,8 +130,9 @@ public:
   /// \p IndexName. In case the declaration is found in the index the
   /// corresponding AST file will be loaded.
   ///
-  /// \return Returns an ASTUnit that contains the definition of the looked up
-  /// function.
+  /// \return Returns a pointer to the ASTUnit that contains the definition of
+  /// the looked up function or an Error.
+  /// The returned pointer is never a nullptr.
   ///
   /// Note that the AST files should also be in the \p CrossTUDir.
   llvm::Expected loadExternalAST(StringRef LookupName,
diff --git a/lib/CrossTU/CrossTranslationUnit.cpp b/lib/CrossTU/CrossTranslationUnit.cpp
index 6ee329c2b5..915b5246c9 100644
--- a/lib/CrossTU/CrossTranslationUnit.cpp
+++ b/lib/CrossTU/CrossTranslationUnit.cpp
@@ -208,9 +208,6 @@ CrossTranslationUnitContext::getCrossTUDefinition(const FunctionDecl *FD,
   if (!ASTUnitOrError)
     return ASTUnitOrError.takeError();
   ASTUnit *Unit = *ASTUnitOrError;
-  if (!Unit)
-    return llvm::make_error(
-        index_error_code::failed_to_get_external_ast);
   assert(&Unit->getFileManager() ==
          &Unit->getASTContext().getSourceManager().getFileManager());
 
@@ -324,6 +321,9 @@ llvm::Expected CrossTranslationUnitContext::loadExternalAST(
   } else {
     Unit = FnUnitCacheEntry->second;
   }
+  if (!Unit)
+    return llvm::make_error(
+        index_error_code::failed_to_get_external_ast);
   return Unit;
 }
 
-- 
cgit v1.2.3


From d21770300d16818ce8bd7c5ebbfb79ef323bc5f7 Mon Sep 17 00:00:00 2001
From: Hyrum Wright 
Date: Mon, 7 Jan 2019 14:14:36 +0000
Subject: [clang] Add AST matcher for initializer list members

Summary:
Much like hasArg for various call expressions, this allows LibTooling users to
match against a member of an initializer list.

This is currently being used as part of the abseil-duration-scale clang-tidy
check.

Differential Revision: https://reviews.llvm.org/D56090


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350523 91177308-0d34-0410-b5e6-96231b3b80d8
---
 docs/LibASTMatchersReference.html                  | 11 ++++++++++-
 include/clang/ASTMatchers/ASTMatchers.h            | 13 +++++++++++++
 lib/ASTMatchers/Dynamic/Registry.cpp               |  1 +
 unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp | 12 ++++++++++++
 4 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/docs/LibASTMatchersReference.html b/docs/LibASTMatchersReference.html
index 27cb00b6bd..2af0a7c9e3 100644
--- a/docs/LibASTMatchersReference.html
+++ b/docs/LibASTMatchersReference.html
@@ -718,7 +718,7 @@ Example matches a || b
 
 
 Matcher<Stmt>blockExprMatcher<BlockExpr>...
-
MAtches a reference to a block.
+
Matches a reference to a block.
 
 Example: matches "^{}":
   void f() { ^{}(); }
@@ -5866,6 +5866,15 @@ FIXME: Unit test this matcher
 
+Matcher<InitListExpr>hasInitunsigned N, ast_matchers::Matcher<Expr> InnerMatcher +
Matches the n'th item of an initializer list expression.
+
+Example matches y.
+    (matcher = initListExpr(hasInit(0, expr())))
+  int x{y}.
+
+ + Matcher<InitListExpr>hasSyntacticFormMatcher<Expr> InnerMatcher
Matches the syntactic form of init list expressions
 (if expression have it).
diff --git a/include/clang/ASTMatchers/ASTMatchers.h b/include/clang/ASTMatchers/ASTMatchers.h
index 7e35f0667a..5cdb964a92 100644
--- a/include/clang/ASTMatchers/ASTMatchers.h
+++ b/include/clang/ASTMatchers/ASTMatchers.h
@@ -3514,6 +3514,19 @@ AST_POLYMORPHIC_MATCHER_P2(hasArgument,
               *Node.getArg(N)->IgnoreParenImpCasts(), Finder, Builder));
 }
 
+/// Matches the n'th item of an initializer list expression.
+///
+/// Example matches y.
+///     (matcher = initListExpr(hasInit(0, expr())))
+/// \code
+///   int x{y}.
+/// \endcode
+AST_MATCHER_P2(InitListExpr, hasInit, unsigned, N,
+               ast_matchers::internal::Matcher, InnerMatcher) {
+  return N < Node.getNumInits() &&
+          InnerMatcher.matches(*Node.getInit(N), Finder, Builder);
+}
+
 /// Matches declaration statements that contain a specific number of
 /// declarations.
 ///
diff --git a/lib/ASTMatchers/Dynamic/Registry.cpp b/lib/ASTMatchers/Dynamic/Registry.cpp
index 0bef326ca5..e6e4846796 100644
--- a/lib/ASTMatchers/Dynamic/Registry.cpp
+++ b/lib/ASTMatchers/Dynamic/Registry.cpp
@@ -273,6 +273,7 @@ RegistryMaps::RegistryMaps() {
   REGISTER_MATCHER(hasInClassInitializer);
   REGISTER_MATCHER(hasIncrement);
   REGISTER_MATCHER(hasIndex);
+  REGISTER_MATCHER(hasInit);
   REGISTER_MATCHER(hasInitializer);
   REGISTER_MATCHER(hasKeywordSelector);
   REGISTER_MATCHER(hasLHS);
diff --git a/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp b/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
index d1f9495432..fb17d100c5 100644
--- a/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ b/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
@@ -2255,6 +2255,18 @@ TEST(IsAssignmentOperator, Basic) {
       notMatches("void x() { int a; if(a == 0) return; }", BinAsgmtOperator));
 }
 
+TEST(HasInit, Basic) {
+  EXPECT_TRUE(
+    matches("int x{0};",
+            initListExpr(hasInit(0, expr()))));
+  EXPECT_FALSE(
+    matches("int x{0};",
+            initListExpr(hasInit(1, expr()))));
+  EXPECT_FALSE(
+    matches("int x;",
+            initListExpr(hasInit(0, expr()))));
+}
+
 TEST(Matcher, isMain) {
   EXPECT_TRUE(
     matches("int main() {}", functionDecl(isMain())));
-- 
cgit v1.2.3


From 4d27dbbf8ec35d8c58f80938a8383da37e9f3800 Mon Sep 17 00:00:00 2001
From: Bruno Ricci 
Date: Mon, 7 Jan 2019 14:27:04 +0000
Subject: [AST][NFC] Pack DependentScopeDeclRefExpr and
 CXXUnresolvedConstructExpr

Use the newly available space in the bit-fields of Stmt.
This saves 1 pointer per DependentScopeDeclRefExpr/CXXUnresolvedConstructExpr.

Additionally rename "TypeSourceInfo *Type;" to "TypeSourceInfo *TSI;"
as was done in D56022 (r350003) (but this is an internal detail anyway),
and clang-format both classes. NFC.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350525 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/AST/ExprCXX.h         |  93 +++++++++++++++---------------
 include/clang/AST/Stmt.h            |  24 ++++++++
 lib/AST/ExprCXX.cpp                 | 110 +++++++++++++++++-------------------
 lib/Serialization/ASTReaderStmt.cpp |   2 +-
 lib/Serialization/ASTWriterStmt.cpp |   4 +-
 5 files changed, 123 insertions(+), 110 deletions(-)

diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index 3f22d8e9c5..f7d5d13637 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -2936,6 +2936,10 @@ class DependentScopeDeclRefExpr final
       private llvm::TrailingObjects {
+  friend class ASTStmtReader;
+  friend class ASTStmtWriter;
+  friend TrailingObjects;
+
   /// The nested-name-specifier that qualifies this unresolved
   /// declaration name.
   NestedNameSpecifierLoc QualifierLoc;
@@ -2943,32 +2947,26 @@ class DependentScopeDeclRefExpr final
   /// The name of the entity we will be referencing.
   DeclarationNameInfo NameInfo;
 
-  /// Whether the name includes info for explicit template
-  /// keyword and arguments.
-  bool HasTemplateKWAndArgsInfo;
-
-  DependentScopeDeclRefExpr(QualType T,
-                            NestedNameSpecifierLoc QualifierLoc,
+  DependentScopeDeclRefExpr(QualType Ty, NestedNameSpecifierLoc QualifierLoc,
                             SourceLocation TemplateKWLoc,
                             const DeclarationNameInfo &NameInfo,
                             const TemplateArgumentListInfo *Args);
 
   size_t numTrailingObjects(OverloadToken) const {
-    return HasTemplateKWAndArgsInfo ? 1 : 0;
+    return hasTemplateKWAndArgsInfo();
   }
 
-public:
-  friend class ASTStmtReader;
-  friend class ASTStmtWriter;
-  friend TrailingObjects;
+  bool hasTemplateKWAndArgsInfo() const {
+    return DependentScopeDeclRefExprBits.HasTemplateKWAndArgsInfo;
+  }
 
-  static DependentScopeDeclRefExpr *Create(const ASTContext &C,
-                                           NestedNameSpecifierLoc QualifierLoc,
-                                           SourceLocation TemplateKWLoc,
-                                           const DeclarationNameInfo &NameInfo,
-                              const TemplateArgumentListInfo *TemplateArgs);
+public:
+  static DependentScopeDeclRefExpr *
+  Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc,
+         SourceLocation TemplateKWLoc, const DeclarationNameInfo &NameInfo,
+         const TemplateArgumentListInfo *TemplateArgs);
 
-  static DependentScopeDeclRefExpr *CreateEmpty(const ASTContext &C,
+  static DependentScopeDeclRefExpr *CreateEmpty(const ASTContext &Context,
                                                 bool HasTemplateKWAndArgsInfo,
                                                 unsigned NumTemplateArgs);
 
@@ -2996,21 +2994,24 @@ public:
   /// Retrieve the location of the template keyword preceding
   /// this name, if any.
   SourceLocation getTemplateKeywordLoc() const {
-    if (!HasTemplateKWAndArgsInfo) return SourceLocation();
+    if (!hasTemplateKWAndArgsInfo())
+      return SourceLocation();
     return getTrailingObjects()->TemplateKWLoc;
   }
 
   /// Retrieve the location of the left angle bracket starting the
   /// explicit template argument list following the name, if any.
   SourceLocation getLAngleLoc() const {
-    if (!HasTemplateKWAndArgsInfo) return SourceLocation();
+    if (!hasTemplateKWAndArgsInfo())
+      return SourceLocation();
     return getTrailingObjects()->LAngleLoc;
   }
 
   /// Retrieve the location of the right angle bracket ending the
   /// explicit template argument list following the name, if any.
   SourceLocation getRAngleLoc() const {
-    if (!HasTemplateKWAndArgsInfo) return SourceLocation();
+    if (!hasTemplateKWAndArgsInfo())
+      return SourceLocation();
     return getTrailingObjects()->RAngleLoc;
   }
 
@@ -3164,7 +3165,7 @@ class CXXUnresolvedConstructExpr final
   friend TrailingObjects;
 
   /// The type being constructed.
-  TypeSourceInfo *Type = nullptr;
+  TypeSourceInfo *TSI;
 
   /// The location of the left parentheses ('(').
   SourceLocation LParenLoc;
@@ -3172,34 +3173,31 @@ class CXXUnresolvedConstructExpr final
   /// The location of the right parentheses (')').
   SourceLocation RParenLoc;
 
-  /// The number of arguments used to construct the type.
-  unsigned NumArgs;
-
-  CXXUnresolvedConstructExpr(TypeSourceInfo *Type,
-                             SourceLocation LParenLoc,
-                             ArrayRef Args,
-                             SourceLocation RParenLoc);
+  CXXUnresolvedConstructExpr(TypeSourceInfo *TSI, SourceLocation LParenLoc,
+                             ArrayRef Args, SourceLocation RParenLoc);
 
   CXXUnresolvedConstructExpr(EmptyShell Empty, unsigned NumArgs)
-      : Expr(CXXUnresolvedConstructExprClass, Empty), NumArgs(NumArgs) {}
+      : Expr(CXXUnresolvedConstructExprClass, Empty) {
+    CXXUnresolvedConstructExprBits.NumArgs = NumArgs;
+  }
 
 public:
-  static CXXUnresolvedConstructExpr *Create(const ASTContext &C,
+  static CXXUnresolvedConstructExpr *Create(const ASTContext &Context,
                                             TypeSourceInfo *Type,
                                             SourceLocation LParenLoc,
-                                            ArrayRef Args,
+                                            ArrayRef Args,
                                             SourceLocation RParenLoc);
 
-  static CXXUnresolvedConstructExpr *CreateEmpty(const ASTContext &C,
+  static CXXUnresolvedConstructExpr *CreateEmpty(const ASTContext &Context,
                                                  unsigned NumArgs);
 
   /// Retrieve the type that is being constructed, as specified
   /// in the source code.
-  QualType getTypeAsWritten() const { return Type->getType(); }
+  QualType getTypeAsWritten() const { return TSI->getType(); }
 
   /// Retrieve the type source information for the type being
   /// constructed.
-  TypeSourceInfo *getTypeSourceInfo() const { return Type; }
+  TypeSourceInfo *getTypeSourceInfo() const { return TSI; }
 
   /// Retrieve the location of the left parentheses ('(') that
   /// precedes the argument list.
@@ -3217,46 +3215,43 @@ public:
   bool isListInitialization() const { return LParenLoc.isInvalid(); }
 
   /// Retrieve the number of arguments.
-  unsigned arg_size() const { return NumArgs; }
+  unsigned arg_size() const { return CXXUnresolvedConstructExprBits.NumArgs; }
 
   using arg_iterator = Expr **;
   using arg_range = llvm::iterator_range;
 
   arg_iterator arg_begin() { return getTrailingObjects(); }
-  arg_iterator arg_end() { return arg_begin() + NumArgs; }
+  arg_iterator arg_end() { return arg_begin() + arg_size(); }
   arg_range arguments() { return arg_range(arg_begin(), arg_end()); }
 
   using const_arg_iterator = const Expr* const *;
   using const_arg_range = llvm::iterator_range;
 
   const_arg_iterator arg_begin() const { return getTrailingObjects(); }
-  const_arg_iterator arg_end() const {
-    return arg_begin() + NumArgs;
-  }
+  const_arg_iterator arg_end() const { return arg_begin() + arg_size(); }
   const_arg_range arguments() const {
     return const_arg_range(arg_begin(), arg_end());
   }
 
   Expr *getArg(unsigned I) {
-    assert(I < NumArgs && "Argument index out-of-range");
-    return *(arg_begin() + I);
+    assert(I < arg_size() && "Argument index out-of-range");
+    return arg_begin()[I];
   }
 
   const Expr *getArg(unsigned I) const {
-    assert(I < NumArgs && "Argument index out-of-range");
-    return *(arg_begin() + I);
+    assert(I < arg_size() && "Argument index out-of-range");
+    return arg_begin()[I];
   }
 
   void setArg(unsigned I, Expr *E) {
-    assert(I < NumArgs && "Argument index out-of-range");
-    *(arg_begin() + I) = E;
+    assert(I < arg_size() && "Argument index out-of-range");
+    arg_begin()[I] = E;
   }
 
   SourceLocation getBeginLoc() const LLVM_READONLY;
-
   SourceLocation getEndLoc() const LLVM_READONLY {
-    if (!RParenLoc.isValid() && NumArgs > 0)
-      return getArg(NumArgs - 1)->getEndLoc();
+    if (!RParenLoc.isValid() && arg_size() > 0)
+      return getArg(arg_size() - 1)->getEndLoc();
     return RParenLoc;
   }
 
@@ -3267,7 +3262,7 @@ public:
   // Iterators
   child_range children() {
     auto **begin = reinterpret_cast(arg_begin());
-    return child_range(begin, begin + NumArgs);
+    return child_range(begin, begin + arg_size());
   }
 };
 
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index c83af51626..4515d527a9 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -655,6 +655,18 @@ protected:
     unsigned NumArgs : 32 - 8 - 1 - NumExprBits;
   };
 
+  class DependentScopeDeclRefExprBitfields {
+    friend class ASTStmtReader;
+    friend class ASTStmtWriter;
+    friend class DependentScopeDeclRefExpr;
+
+    unsigned : NumExprBits;
+
+    /// Whether the name includes info for explicit template
+    /// keyword and arguments.
+    unsigned HasTemplateKWAndArgsInfo : 1;
+  };
+
   class CXXConstructExprBitfields {
     friend class ASTStmtReader;
     friend class CXXConstructExpr;
@@ -683,6 +695,16 @@ protected:
     unsigned NumObjects : 32 - 1 - NumExprBits;
   };
 
+  class CXXUnresolvedConstructExprBitfields {
+    friend class ASTStmtReader;
+    friend class CXXUnresolvedConstructExpr;
+
+    unsigned : NumExprBits;
+
+    /// The number of arguments used to construct the type.
+    unsigned NumArgs;
+  };
+
   //===--- C++ Coroutines TS bitfields classes ---===//
 
   class CoawaitExprBitfields {
@@ -765,8 +787,10 @@ protected:
     CXXDefaultInitExprBitfields CXXDefaultInitExprBits;
     CXXDeleteExprBitfields CXXDeleteExprBits;
     TypeTraitExprBitfields TypeTraitExprBits;
+    DependentScopeDeclRefExprBitfields DependentScopeDeclRefExprBits;
     CXXConstructExprBitfields CXXConstructExprBits;
     ExprWithCleanupsBitfields ExprWithCleanupsBits;
+    CXXUnresolvedConstructExprBitfields CXXUnresolvedConstructExprBits;
 
     // C++ Coroutines TS expressions
     CoawaitExprBitfields CoawaitBits;
diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp
index 83af29a638..7aa80c0392 100644
--- a/lib/AST/ExprCXX.cpp
+++ b/lib/AST/ExprCXX.cpp
@@ -385,23 +385,22 @@ CXXRecordDecl *OverloadExpr::getNamingClass() const {
 }
 
 // DependentScopeDeclRefExpr
-DependentScopeDeclRefExpr::DependentScopeDeclRefExpr(QualType T,
-                            NestedNameSpecifierLoc QualifierLoc,
-                            SourceLocation TemplateKWLoc,
-                            const DeclarationNameInfo &NameInfo,
-                            const TemplateArgumentListInfo *Args)
-  : Expr(DependentScopeDeclRefExprClass, T, VK_LValue, OK_Ordinary,
-         true, true,
-         (NameInfo.isInstantiationDependent() ||
-          (QualifierLoc &&
-           QualifierLoc.getNestedNameSpecifier()->isInstantiationDependent())),
-         (NameInfo.containsUnexpandedParameterPack() ||
-          (QualifierLoc &&
-           QualifierLoc.getNestedNameSpecifier()
-                            ->containsUnexpandedParameterPack()))),
-    QualifierLoc(QualifierLoc), NameInfo(NameInfo),
-    HasTemplateKWAndArgsInfo(Args != nullptr || TemplateKWLoc.isValid())
-{
+DependentScopeDeclRefExpr::DependentScopeDeclRefExpr(
+    QualType Ty, NestedNameSpecifierLoc QualifierLoc,
+    SourceLocation TemplateKWLoc, const DeclarationNameInfo &NameInfo,
+    const TemplateArgumentListInfo *Args)
+    : Expr(
+          DependentScopeDeclRefExprClass, Ty, VK_LValue, OK_Ordinary, true,
+          true,
+          (NameInfo.isInstantiationDependent() ||
+           (QualifierLoc &&
+            QualifierLoc.getNestedNameSpecifier()->isInstantiationDependent())),
+          (NameInfo.containsUnexpandedParameterPack() ||
+           (QualifierLoc && QualifierLoc.getNestedNameSpecifier()
+                                ->containsUnexpandedParameterPack()))),
+      QualifierLoc(QualifierLoc), NameInfo(NameInfo) {
+  DependentScopeDeclRefExprBits.HasTemplateKWAndArgsInfo =
+      (Args != nullptr) || TemplateKWLoc.isValid();
   if (Args) {
     bool Dependent = true;
     bool InstantiationDependent = true;
@@ -417,36 +416,34 @@ DependentScopeDeclRefExpr::DependentScopeDeclRefExpr(QualType T,
   }
 }
 
-DependentScopeDeclRefExpr *
-DependentScopeDeclRefExpr::Create(const ASTContext &C,
-                                  NestedNameSpecifierLoc QualifierLoc,
-                                  SourceLocation TemplateKWLoc,
-                                  const DeclarationNameInfo &NameInfo,
-                                  const TemplateArgumentListInfo *Args) {
+DependentScopeDeclRefExpr *DependentScopeDeclRefExpr::Create(
+    const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc,
+    SourceLocation TemplateKWLoc, const DeclarationNameInfo &NameInfo,
+    const TemplateArgumentListInfo *Args) {
   assert(QualifierLoc && "should be created for dependent qualifiers");
   bool HasTemplateKWAndArgsInfo = Args || TemplateKWLoc.isValid();
   std::size_t Size =
       totalSizeToAlloc(
           HasTemplateKWAndArgsInfo, Args ? Args->size() : 0);
-  void *Mem = C.Allocate(Size);
-  return new (Mem) DependentScopeDeclRefExpr(C.DependentTy, QualifierLoc,
+  void *Mem = Context.Allocate(Size);
+  return new (Mem) DependentScopeDeclRefExpr(Context.DependentTy, QualifierLoc,
                                              TemplateKWLoc, NameInfo, Args);
 }
 
 DependentScopeDeclRefExpr *
-DependentScopeDeclRefExpr::CreateEmpty(const ASTContext &C,
+DependentScopeDeclRefExpr::CreateEmpty(const ASTContext &Context,
                                        bool HasTemplateKWAndArgsInfo,
                                        unsigned NumTemplateArgs) {
   assert(NumTemplateArgs == 0 || HasTemplateKWAndArgsInfo);
   std::size_t Size =
       totalSizeToAlloc(
           HasTemplateKWAndArgsInfo, NumTemplateArgs);
-  void *Mem = C.Allocate(Size);
-  auto *E =
-      new (Mem) DependentScopeDeclRefExpr(QualType(), NestedNameSpecifierLoc(),
-                                          SourceLocation(),
-                                          DeclarationNameInfo(), nullptr);
-  E->HasTemplateKWAndArgsInfo = HasTemplateKWAndArgsInfo;
+  void *Mem = Context.Allocate(Size);
+  auto *E = new (Mem) DependentScopeDeclRefExpr(
+      QualType(), NestedNameSpecifierLoc(), SourceLocation(),
+      DeclarationNameInfo(), nullptr);
+  E->DependentScopeDeclRefExprBits.HasTemplateKWAndArgsInfo =
+      HasTemplateKWAndArgsInfo;
   return E;
 }
 
@@ -1216,22 +1213,22 @@ ExprWithCleanups *ExprWithCleanups::Create(const ASTContext &C,
   return new (buffer) ExprWithCleanups(empty, numObjects);
 }
 
-CXXUnresolvedConstructExpr::CXXUnresolvedConstructExpr(TypeSourceInfo *Type,
-                                                 SourceLocation LParenLoc,
-                                                 ArrayRef Args,
-                                                 SourceLocation RParenLoc)
+CXXUnresolvedConstructExpr::CXXUnresolvedConstructExpr(TypeSourceInfo *TSI,
+                                                       SourceLocation LParenLoc,
+                                                       ArrayRef Args,
+                                                       SourceLocation RParenLoc)
     : Expr(CXXUnresolvedConstructExprClass,
-           Type->getType().getNonReferenceType(),
-           (Type->getType()->isLValueReferenceType()
+           TSI->getType().getNonReferenceType(),
+           (TSI->getType()->isLValueReferenceType()
                 ? VK_LValue
-                : Type->getType()->isRValueReferenceType() ? VK_XValue
-                                                           : VK_RValue),
+                : TSI->getType()->isRValueReferenceType() ? VK_XValue
+                                                          : VK_RValue),
            OK_Ordinary,
-           Type->getType()->isDependentType() ||
-               Type->getType()->getContainedDeducedType(),
-           true, true, Type->getType()->containsUnexpandedParameterPack()),
-      Type(Type), LParenLoc(LParenLoc), RParenLoc(RParenLoc),
-      NumArgs(Args.size()) {
+           TSI->getType()->isDependentType() ||
+               TSI->getType()->getContainedDeducedType(),
+           true, true, TSI->getType()->containsUnexpandedParameterPack()),
+      TSI(TSI), LParenLoc(LParenLoc), RParenLoc(RParenLoc) {
+  CXXUnresolvedConstructExprBits.NumArgs = Args.size();
   auto **StoredArgs = getTrailingObjects();
   for (unsigned I = 0; I != Args.size(); ++I) {
     if (Args[I]->containsUnexpandedParameterPack())
@@ -1241,25 +1238,22 @@ CXXUnresolvedConstructExpr::CXXUnresolvedConstructExpr(TypeSourceInfo *Type,
   }
 }
 
-CXXUnresolvedConstructExpr *
-CXXUnresolvedConstructExpr::Create(const ASTContext &C,
-                                   TypeSourceInfo *Type,
-                                   SourceLocation LParenLoc,
-                                   ArrayRef Args,
-                                   SourceLocation RParenLoc) {
-  void *Mem = C.Allocate(totalSizeToAlloc(Args.size()));
-  return new (Mem) CXXUnresolvedConstructExpr(Type, LParenLoc, Args, RParenLoc);
+CXXUnresolvedConstructExpr *CXXUnresolvedConstructExpr::Create(
+    const ASTContext &Context, TypeSourceInfo *TSI, SourceLocation LParenLoc,
+    ArrayRef Args, SourceLocation RParenLoc) {
+  void *Mem = Context.Allocate(totalSizeToAlloc(Args.size()));
+  return new (Mem) CXXUnresolvedConstructExpr(TSI, LParenLoc, Args, RParenLoc);
 }
 
 CXXUnresolvedConstructExpr *
-CXXUnresolvedConstructExpr::CreateEmpty(const ASTContext &C, unsigned NumArgs) {
-  Stmt::EmptyShell Empty;
-  void *Mem = C.Allocate(totalSizeToAlloc(NumArgs));
-  return new (Mem) CXXUnresolvedConstructExpr(Empty, NumArgs);
+CXXUnresolvedConstructExpr::CreateEmpty(const ASTContext &Context,
+                                        unsigned NumArgs) {
+  void *Mem = Context.Allocate(totalSizeToAlloc(NumArgs));
+  return new (Mem) CXXUnresolvedConstructExpr(EmptyShell(), NumArgs);
 }
 
 SourceLocation CXXUnresolvedConstructExpr::getBeginLoc() const {
-  return Type->getTypeLoc().getBeginLoc();
+  return TSI->getTypeLoc().getBeginLoc();
 }
 
 CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr(
diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp
index f2c623eb6b..e789e20f57 100644
--- a/lib/Serialization/ASTReaderStmt.cpp
+++ b/lib/Serialization/ASTReaderStmt.cpp
@@ -1612,7 +1612,7 @@ ASTStmtReader::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E) {
   Record.skipInts(1);
   for (unsigned I = 0, N = E->arg_size(); I != N; ++I)
     E->setArg(I, Record.readSubExpr());
-  E->Type = GetTypeSourceInfo();
+  E->TSI = GetTypeSourceInfo();
   E->setLParenLoc(ReadSourceLocation());
   E->setRParenLoc(ReadSourceLocation());
 }
diff --git a/lib/Serialization/ASTWriterStmt.cpp b/lib/Serialization/ASTWriterStmt.cpp
index f0e1e10b5e..26a01706dc 100644
--- a/lib/Serialization/ASTWriterStmt.cpp
+++ b/lib/Serialization/ASTWriterStmt.cpp
@@ -1583,8 +1583,8 @@ ASTStmtWriter::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
   // Don't emit anything here, HasTemplateKWAndArgsInfo must be
   // emitted first.
 
-  Record.push_back(E->HasTemplateKWAndArgsInfo);
-  if (E->HasTemplateKWAndArgsInfo) {
+  Record.push_back(E->DependentScopeDeclRefExprBits.HasTemplateKWAndArgsInfo);
+  if (E->DependentScopeDeclRefExprBits.HasTemplateKWAndArgsInfo) {
     const ASTTemplateKWAndArgsInfo &ArgInfo =
         *E->getTrailingObjects();
     Record.push_back(ArgInfo.NumTemplateArgs);
-- 
cgit v1.2.3


From 7eadfa4ba2821e7394224da7023128dc9b36eebd Mon Sep 17 00:00:00 2001
From: Bruno Ricci 
Date: Mon, 7 Jan 2019 15:04:45 +0000
Subject: [AST] Store some data of CXXNewExpr as trailing objects

Store the optional array size expression, optional initialization expression
and optional placement new arguments in a trailing array. Additionally store
the range for the parenthesized type-id in a trailing object if needed since
in the vast majority of cases the type is not parenthesized (not a single new
expression in the translation unit of SemaDecl.cpp has a parenthesized type-id).

This saves 2 pointers per CXXNewExpr in all cases, and 2 pointers + 8 bytes
per CXXNewExpr in the common case where the type is not parenthesized.

Differential Revision: https://reviews.llvm.org/D56134

Reviewed By: rjmccall



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350527 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/AST/ExprCXX.h         | 189 +++++++++++++++++++++---------------
 include/clang/AST/Stmt.h            |  34 +++++++
 lib/AST/ASTImporter.cpp             |   2 +-
 lib/AST/ExprCXX.cpp                 | 144 +++++++++++++++++----------
 lib/CodeGen/CGExprCXX.cpp           |   4 +-
 lib/Sema/SemaExprCXX.cpp            |  10 +-
 lib/Serialization/ASTReaderStmt.cpp |  42 +++++---
 lib/Serialization/ASTWriterStmt.cpp |  19 ++--
 8 files changed, 288 insertions(+), 156 deletions(-)

diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index f7d5d13637..5155b6095e 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -1933,54 +1933,56 @@ public:
 
 /// Represents a new-expression for memory allocation and constructor
 /// calls, e.g: "new CXXNewExpr(foo)".
-class CXXNewExpr : public Expr {
+class CXXNewExpr final
+    : public Expr,
+      private llvm::TrailingObjects {
   friend class ASTStmtReader;
   friend class ASTStmtWriter;
-
-  /// Contains an optional array size expression, an optional initialization
-  /// expression, and any number of optional placement arguments, in that order.
-  Stmt **SubExprs = nullptr;
+  friend TrailingObjects;
 
   /// Points to the allocation function used.
   FunctionDecl *OperatorNew;
 
-  /// Points to the deallocation function used in case of error. May be
-  /// null.
+  /// Points to the deallocation function used in case of error. May be null.
   FunctionDecl *OperatorDelete;
 
   /// The allocated type-source information, as written in the source.
   TypeSourceInfo *AllocatedTypeInfo;
 
-  /// If the allocated type was expressed as a parenthesized type-id,
-  /// the source range covering the parenthesized type-id.
-  SourceRange TypeIdParens;
-
   /// Range of the entire new expression.
   SourceRange Range;
 
   /// Source-range of a paren-delimited initializer.
   SourceRange DirectInitRange;
 
-  /// Was the usage ::new, i.e. is the global new to be used?
-  unsigned GlobalNew : 1;
-
-  /// Do we allocate an array? If so, the first SubExpr is the size expression.
-  unsigned Array : 1;
-
-  /// Should the alignment be passed to the allocation function?
-  unsigned PassAlignment : 1;
-
-  /// If this is an array allocation, does the usual deallocation
-  /// function for the allocated type want to know the allocated size?
-  unsigned UsualArrayDeleteWantsSize : 1;
+  // CXXNewExpr is followed by several optional trailing objects.
+  // They are in order:
+  //
+  // * An optional "Stmt *" for the array size expression.
+  //    Present if and ony if isArray().
+  //
+  // * An optional "Stmt *" for the init expression.
+  //    Present if and only if hasInitializer().
+  //
+  // * An array of getNumPlacementArgs() "Stmt *" for the placement new
+  //   arguments, if any.
+  //
+  // * An optional SourceRange for the range covering the parenthesized type-id
+  //    if the allocated type was expressed as a parenthesized type-id.
+  //    Present if and only if isParenTypeId().
+  unsigned arraySizeOffset() const { return 0; }
+  unsigned initExprOffset() const { return arraySizeOffset() + isArray(); }
+  unsigned placementNewArgsOffset() const {
+    return initExprOffset() + hasInitializer();
+  }
 
-  /// The number of placement new arguments.
-  unsigned NumPlacementArgs : 26;
+  unsigned numTrailingObjects(OverloadToken) const {
+    return isArray() + hasInitializer() + getNumPlacementArgs();
+  }
 
-  /// What kind of initializer do we have? Could be none, parens, or braces.
-  /// In storage, we distinguish between "none, and no initializer expr", and
-  /// "none, but an implicit initializer expr".
-  unsigned StoredInitializationStyle : 2;
+  unsigned numTrailingObjects(OverloadToken) const {
+    return isParenTypeId();
+  }
 
 public:
   enum InitializationStyle {
@@ -1994,18 +1996,35 @@ public:
     ListInit
   };
 
-  CXXNewExpr(const ASTContext &C, bool globalNew, FunctionDecl *operatorNew,
-             FunctionDecl *operatorDelete, bool PassAlignment,
-             bool usualArrayDeleteWantsSize, ArrayRef placementArgs,
-             SourceRange typeIdParens, Expr *arraySize,
-             InitializationStyle initializationStyle, Expr *initializer,
-             QualType ty, TypeSourceInfo *AllocatedTypeInfo,
-             SourceRange Range, SourceRange directInitRange);
-  explicit CXXNewExpr(EmptyShell Shell)
-      : Expr(CXXNewExprClass, Shell) {}
+private:
+  /// Build a c++ new expression.
+  CXXNewExpr(bool IsGlobalNew, FunctionDecl *OperatorNew,
+             FunctionDecl *OperatorDelete, bool ShouldPassAlignment,
+             bool UsualArrayDeleteWantsSize, ArrayRef PlacementArgs,
+             SourceRange TypeIdParens, Expr *ArraySize,
+             InitializationStyle InitializationStyle, Expr *Initializer,
+             QualType Ty, TypeSourceInfo *AllocatedTypeInfo, SourceRange Range,
+             SourceRange DirectInitRange);
+
+  /// Build an empty c++ new expression.
+  CXXNewExpr(EmptyShell Empty, bool IsArray, unsigned NumPlacementArgs,
+             bool IsParenTypeId);
 
-  void AllocateArgsArray(const ASTContext &C, bool isArray,
-                         unsigned numPlaceArgs, bool hasInitializer);
+public:
+  /// Create a c++ new expression.
+  static CXXNewExpr *
+  Create(const ASTContext &Ctx, bool IsGlobalNew, FunctionDecl *OperatorNew,
+         FunctionDecl *OperatorDelete, bool ShouldPassAlignment,
+         bool UsualArrayDeleteWantsSize, ArrayRef PlacementArgs,
+         SourceRange TypeIdParens, Expr *ArraySize,
+         InitializationStyle InitializationStyle, Expr *Initializer,
+         QualType Ty, TypeSourceInfo *AllocatedTypeInfo, SourceRange Range,
+         SourceRange DirectInitRange);
+
+  /// Create an empty c++ new expression.
+  static CXXNewExpr *CreateEmpty(const ASTContext &Ctx, bool IsArray,
+                                 bool HasInit, unsigned NumPlacementArgs,
+                                 bool IsParenTypeId);
 
   QualType getAllocatedType() const {
     assert(getType()->isPointerType());
@@ -2031,58 +2050,74 @@ public:
   /// has a non-throwing exception-specification.  The '03 rule is
   /// identical except that the definition of a non-throwing
   /// exception specification is just "is it throw()?".
-  bool shouldNullCheckAllocation(const ASTContext &Ctx) const;
+  bool shouldNullCheckAllocation() const;
 
   FunctionDecl *getOperatorNew() const { return OperatorNew; }
   void setOperatorNew(FunctionDecl *D) { OperatorNew = D; }
   FunctionDecl *getOperatorDelete() const { return OperatorDelete; }
   void setOperatorDelete(FunctionDecl *D) { OperatorDelete = D; }
 
-  bool isArray() const { return Array; }
+  bool isArray() const { return CXXNewExprBits.IsArray; }
 
   Expr *getArraySize() {
-    return Array ? cast(SubExprs[0]) : nullptr;
+    return isArray()
+               ? cast(getTrailingObjects()[arraySizeOffset()])
+               : nullptr;
   }
   const Expr *getArraySize() const {
-    return Array ? cast(SubExprs[0]) : nullptr;
+    return isArray()
+               ? cast(getTrailingObjects()[arraySizeOffset()])
+               : nullptr;
   }
 
-  unsigned getNumPlacementArgs() const { return NumPlacementArgs; }
+  unsigned getNumPlacementArgs() const {
+    return CXXNewExprBits.NumPlacementArgs;
+  }
 
   Expr **getPlacementArgs() {
-    return reinterpret_cast(SubExprs + Array + hasInitializer());
+    return reinterpret_cast(getTrailingObjects() +
+                                     placementNewArgsOffset());
   }
 
-  Expr *getPlacementArg(unsigned i) {
-    assert(i < NumPlacementArgs && "Index out of range");
-    return getPlacementArgs()[i];
+  Expr *getPlacementArg(unsigned I) {
+    assert((I < getNumPlacementArgs()) && "Index out of range!");
+    return getPlacementArgs()[I];
   }
-  const Expr *getPlacementArg(unsigned i) const {
-    assert(i < NumPlacementArgs && "Index out of range");
-    return const_cast(this)->getPlacementArg(i);
+  const Expr *getPlacementArg(unsigned I) const {
+    return const_cast(this)->getPlacementArg(I);
   }
 
-  bool isParenTypeId() const { return TypeIdParens.isValid(); }
-  SourceRange getTypeIdParens() const { return TypeIdParens; }
+  bool isParenTypeId() const { return CXXNewExprBits.IsParenTypeId; }
+  SourceRange getTypeIdParens() const {
+    return isParenTypeId() ? getTrailingObjects()[0]
+                           : SourceRange();
+  }
 
-  bool isGlobalNew() const { return GlobalNew; }
+  bool isGlobalNew() const { return CXXNewExprBits.IsGlobalNew; }
 
   /// Whether this new-expression has any initializer at all.
-  bool hasInitializer() const { return StoredInitializationStyle > 0; }
+  bool hasInitializer() const {
+    return CXXNewExprBits.StoredInitializationStyle > 0;
+  }
 
   /// The kind of initializer this new-expression has.
   InitializationStyle getInitializationStyle() const {
-    if (StoredInitializationStyle == 0)
+    if (CXXNewExprBits.StoredInitializationStyle == 0)
       return NoInit;
-    return static_cast(StoredInitializationStyle-1);
+    return static_cast(
+        CXXNewExprBits.StoredInitializationStyle - 1);
   }
 
   /// The initializer of this new-expression.
   Expr *getInitializer() {
-    return hasInitializer() ? cast(SubExprs[Array]) : nullptr;
+    return hasInitializer()
+               ? cast(getTrailingObjects()[initExprOffset()])
+               : nullptr;
   }
   const Expr *getInitializer() const {
-    return hasInitializer() ? cast(SubExprs[Array]) : nullptr;
+    return hasInitializer()
+               ? cast(getTrailingObjects()[initExprOffset()])
+               : nullptr;
   }
 
   /// Returns the CXXConstructExpr from this new-expression, or null.
@@ -2092,15 +2127,13 @@ public:
 
   /// Indicates whether the required alignment should be implicitly passed to
   /// the allocation function.
-  bool passAlignment() const {
-    return PassAlignment;
-  }
+  bool passAlignment() const { return CXXNewExprBits.ShouldPassAlignment; }
 
   /// Answers whether the usual array deallocation function for the
   /// allocated type expects the size of the allocation as a
   /// parameter.
   bool doesUsualArrayDeleteWantSize() const {
-    return UsualArrayDeleteWantsSize;
+    return CXXNewExprBits.UsualArrayDeleteWantsSize;
   }
 
   using arg_iterator = ExprIterator;
@@ -2115,47 +2148,43 @@ public:
   }
 
   arg_iterator placement_arg_begin() {
-    return SubExprs + Array + hasInitializer();
+    return getTrailingObjects() + placementNewArgsOffset();
   }
   arg_iterator placement_arg_end() {
-    return SubExprs + Array + hasInitializer() + getNumPlacementArgs();
+    return placement_arg_begin() + getNumPlacementArgs();
   }
   const_arg_iterator placement_arg_begin() const {
-    return SubExprs + Array + hasInitializer();
+    return getTrailingObjects() + placementNewArgsOffset();
   }
   const_arg_iterator placement_arg_end() const {
-    return SubExprs + Array + hasInitializer() + getNumPlacementArgs();
+    return placement_arg_begin() + getNumPlacementArgs();
   }
 
   using raw_arg_iterator = Stmt **;
 
-  raw_arg_iterator raw_arg_begin() { return SubExprs; }
+  raw_arg_iterator raw_arg_begin() { return getTrailingObjects(); }
   raw_arg_iterator raw_arg_end() {
-    return SubExprs + Array + hasInitializer() + getNumPlacementArgs();
+    return raw_arg_begin() + numTrailingObjects(OverloadToken());
+  }
+  const_arg_iterator raw_arg_begin() const {
+    return getTrailingObjects();
   }
-  const_arg_iterator raw_arg_begin() const { return SubExprs; }
   const_arg_iterator raw_arg_end() const {
-    return SubExprs + Array + hasInitializer() + getNumPlacementArgs();
+    return raw_arg_begin() + numTrailingObjects(OverloadToken());
   }
 
   SourceLocation getBeginLoc() const { return Range.getBegin(); }
   SourceLocation getEndLoc() const { return Range.getEnd(); }
 
   SourceRange getDirectInitRange() const { return DirectInitRange; }
-
-  SourceRange getSourceRange() const LLVM_READONLY {
-    return Range;
-  }
-
+  SourceRange getSourceRange() const { return Range; }
 
   static bool classof(const Stmt *T) {
     return T->getStmtClass() == CXXNewExprClass;
   }
 
   // Iterators
-  child_range children() {
-    return child_range(raw_arg_begin(), raw_arg_end());
-  }
+  child_range children() { return child_range(raw_arg_begin(), raw_arg_end()); }
 };
 
 /// Represents a \c delete expression for memory deallocation and
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index 4515d527a9..2f94faee2c 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -612,6 +612,39 @@ protected:
     SourceLocation Loc;
   };
 
+  class CXXNewExprBitfields {
+    friend class ASTStmtReader;
+    friend class ASTStmtWriter;
+    friend class CXXNewExpr;
+
+    unsigned : NumExprBits;
+
+    /// Was the usage ::new, i.e. is the global new to be used?
+    unsigned IsGlobalNew : 1;
+
+    /// Do we allocate an array? If so, the first trailing "Stmt *" is the
+    /// size expression.
+    unsigned IsArray : 1;
+
+    /// Should the alignment be passed to the allocation function?
+    unsigned ShouldPassAlignment : 1;
+
+    /// If this is an array allocation, does the usual deallocation
+    /// function for the allocated type want to know the allocated size?
+    unsigned UsualArrayDeleteWantsSize : 1;
+
+    /// What kind of initializer do we have? Could be none, parens, or braces.
+    /// In storage, we distinguish between "none, and no initializer expr", and
+    /// "none, but an implicit initializer expr".
+    unsigned StoredInitializationStyle : 2;
+
+    /// True if the allocated type was expressed as a parenthesized type-id.
+    unsigned IsParenTypeId : 1;
+
+    /// The number of placement new arguments.
+    unsigned NumPlacementArgs;
+  };
+
   class CXXDeleteExprBitfields {
     friend class ASTStmtReader;
     friend class CXXDeleteExpr;
@@ -785,6 +818,7 @@ protected:
     CXXThrowExprBitfields CXXThrowExprBits;
     CXXDefaultArgExprBitfields CXXDefaultArgExprBits;
     CXXDefaultInitExprBitfields CXXDefaultInitExprBits;
+    CXXNewExprBitfields CXXNewExprBits;
     CXXDeleteExprBitfields CXXDeleteExprBits;
     TypeTraitExprBitfields TypeTraitExprBits;
     DependentScopeDeclRefExprBitfields DependentScopeDeclRefExprBits;
diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp
index 251d078635..44832557e9 100644
--- a/lib/AST/ASTImporter.cpp
+++ b/lib/AST/ASTImporter.cpp
@@ -6910,7 +6910,7 @@ ExpectedStmt ASTNodeImporter::VisitCXXNewExpr(CXXNewExpr *E) {
       ImportContainerChecked(E->placement_arguments(), ToPlacementArgs))
     return std::move(Err);
 
-  return new (Importer.getToContext()) CXXNewExpr(
+  return CXXNewExpr::Create(
       Importer.getToContext(), E->isGlobalNew(), ToOperatorNew,
       ToOperatorDelete, E->passAlignment(), E->doesUsualArrayDeleteWantSize(),
       ToPlacementArgs, ToTypeIdParens, ToArraySize, E->getInitializationStyle(),
diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp
index 7aa80c0392..4eb3d333bc 100644
--- a/lib/AST/ExprCXX.cpp
+++ b/lib/AST/ExprCXX.cpp
@@ -94,83 +94,127 @@ SourceLocation CXXScalarValueInitExpr::getBeginLoc() const {
 }
 
 // CXXNewExpr
-CXXNewExpr::CXXNewExpr(const ASTContext &C, bool globalNew,
-                       FunctionDecl *operatorNew, FunctionDecl *operatorDelete,
-                       bool PassAlignment, bool usualArrayDeleteWantsSize,
-                       ArrayRef placementArgs,
-                       SourceRange typeIdParens, Expr *arraySize,
-                       InitializationStyle initializationStyle,
-                       Expr *initializer, QualType ty,
-                       TypeSourceInfo *allocatedTypeInfo,
-                       SourceRange Range, SourceRange directInitRange)
-    : Expr(CXXNewExprClass, ty, VK_RValue, OK_Ordinary, ty->isDependentType(),
-           ty->isDependentType(), ty->isInstantiationDependentType(),
-           ty->containsUnexpandedParameterPack()),
-      OperatorNew(operatorNew), OperatorDelete(operatorDelete),
-      AllocatedTypeInfo(allocatedTypeInfo), TypeIdParens(typeIdParens),
-      Range(Range), DirectInitRange(directInitRange), GlobalNew(globalNew),
-      PassAlignment(PassAlignment),
-      UsualArrayDeleteWantsSize(usualArrayDeleteWantsSize) {
-  assert((initializer != nullptr || initializationStyle == NoInit) &&
-         "Only NoInit can have no initializer.");
-  StoredInitializationStyle = initializer ? initializationStyle + 1 : 0;
-  AllocateArgsArray(C, arraySize != nullptr, placementArgs.size(),
-                    initializer != nullptr);
-  unsigned i = 0;
-  if (Array) {
-    if (arraySize->isInstantiationDependent())
+CXXNewExpr::CXXNewExpr(bool IsGlobalNew, FunctionDecl *OperatorNew,
+                       FunctionDecl *OperatorDelete, bool ShouldPassAlignment,
+                       bool UsualArrayDeleteWantsSize,
+                       ArrayRef PlacementArgs, SourceRange TypeIdParens,
+                       Expr *ArraySize, InitializationStyle InitializationStyle,
+                       Expr *Initializer, QualType Ty,
+                       TypeSourceInfo *AllocatedTypeInfo, SourceRange Range,
+                       SourceRange DirectInitRange)
+    : Expr(CXXNewExprClass, Ty, VK_RValue, OK_Ordinary, Ty->isDependentType(),
+           Ty->isDependentType(), Ty->isInstantiationDependentType(),
+           Ty->containsUnexpandedParameterPack()),
+      OperatorNew(OperatorNew), OperatorDelete(OperatorDelete),
+      AllocatedTypeInfo(AllocatedTypeInfo), Range(Range),
+      DirectInitRange(DirectInitRange) {
+
+  assert((Initializer != nullptr || InitializationStyle == NoInit) &&
+         "Only NoInit can have no initializer!");
+
+  CXXNewExprBits.IsGlobalNew = IsGlobalNew;
+  CXXNewExprBits.IsArray = ArraySize != nullptr;
+  CXXNewExprBits.ShouldPassAlignment = ShouldPassAlignment;
+  CXXNewExprBits.UsualArrayDeleteWantsSize = UsualArrayDeleteWantsSize;
+  CXXNewExprBits.StoredInitializationStyle =
+      Initializer ? InitializationStyle + 1 : 0;
+  bool IsParenTypeId = TypeIdParens.isValid();
+  CXXNewExprBits.IsParenTypeId = IsParenTypeId;
+  CXXNewExprBits.NumPlacementArgs = PlacementArgs.size();
+
+  if (ArraySize) {
+    if (ArraySize->isInstantiationDependent())
       ExprBits.InstantiationDependent = true;
-
-    if (arraySize->containsUnexpandedParameterPack())
+    if (ArraySize->containsUnexpandedParameterPack())
       ExprBits.ContainsUnexpandedParameterPack = true;
 
-    SubExprs[i++] = arraySize;
+    getTrailingObjects()[arraySizeOffset()] = ArraySize;
   }
 
-  if (initializer) {
-    if (initializer->isInstantiationDependent())
+  if (Initializer) {
+    if (Initializer->isInstantiationDependent())
       ExprBits.InstantiationDependent = true;
-
-    if (initializer->containsUnexpandedParameterPack())
+    if (Initializer->containsUnexpandedParameterPack())
       ExprBits.ContainsUnexpandedParameterPack = true;
 
-    SubExprs[i++] = initializer;
+    getTrailingObjects()[initExprOffset()] = Initializer;
   }
 
-  for (unsigned j = 0; j != placementArgs.size(); ++j) {
-    if (placementArgs[j]->isInstantiationDependent())
+  for (unsigned I = 0; I != PlacementArgs.size(); ++I) {
+    if (PlacementArgs[I]->isInstantiationDependent())
       ExprBits.InstantiationDependent = true;
-    if (placementArgs[j]->containsUnexpandedParameterPack())
+    if (PlacementArgs[I]->containsUnexpandedParameterPack())
       ExprBits.ContainsUnexpandedParameterPack = true;
 
-    SubExprs[i++] = placementArgs[j];
+    getTrailingObjects()[placementNewArgsOffset() + I] =
+        PlacementArgs[I];
   }
 
+  if (IsParenTypeId)
+    getTrailingObjects()[0] = TypeIdParens;
+
   switch (getInitializationStyle()) {
   case CallInit:
-    this->Range.setEnd(DirectInitRange.getEnd()); break;
+    this->Range.setEnd(DirectInitRange.getEnd());
+    break;
   case ListInit:
-    this->Range.setEnd(getInitializer()->getSourceRange().getEnd()); break;
+    this->Range.setEnd(getInitializer()->getSourceRange().getEnd());
+    break;
   default:
-    if (TypeIdParens.isValid())
+    if (IsParenTypeId)
       this->Range.setEnd(TypeIdParens.getEnd());
     break;
   }
 }
 
-void CXXNewExpr::AllocateArgsArray(const ASTContext &C, bool isArray,
-                                   unsigned numPlaceArgs, bool hasInitializer){
-  assert(SubExprs == nullptr && "SubExprs already allocated");
-  Array = isArray;
-  NumPlacementArgs = numPlaceArgs;
+CXXNewExpr::CXXNewExpr(EmptyShell Empty, bool IsArray,
+                       unsigned NumPlacementArgs, bool IsParenTypeId)
+    : Expr(CXXNewExprClass, Empty) {
+  CXXNewExprBits.IsArray = IsArray;
+  CXXNewExprBits.NumPlacementArgs = NumPlacementArgs;
+  CXXNewExprBits.IsParenTypeId = IsParenTypeId;
+}
+
+CXXNewExpr *
+CXXNewExpr::Create(const ASTContext &Ctx, bool IsGlobalNew,
+                   FunctionDecl *OperatorNew, FunctionDecl *OperatorDelete,
+                   bool ShouldPassAlignment, bool UsualArrayDeleteWantsSize,
+                   ArrayRef PlacementArgs, SourceRange TypeIdParens,
+                   Expr *ArraySize, InitializationStyle InitializationStyle,
+                   Expr *Initializer, QualType Ty,
+                   TypeSourceInfo *AllocatedTypeInfo, SourceRange Range,
+                   SourceRange DirectInitRange) {
+  bool IsArray = ArraySize != nullptr;
+  bool HasInit = Initializer != nullptr;
+  unsigned NumPlacementArgs = PlacementArgs.size();
+  bool IsParenTypeId = TypeIdParens.isValid();
+  void *Mem =
+      Ctx.Allocate(totalSizeToAlloc(
+                       IsArray + HasInit + NumPlacementArgs, IsParenTypeId),
+                   alignof(CXXNewExpr));
+  return new (Mem)
+      CXXNewExpr(IsGlobalNew, OperatorNew, OperatorDelete, ShouldPassAlignment,
+                 UsualArrayDeleteWantsSize, PlacementArgs, TypeIdParens,
+                 ArraySize, InitializationStyle, Initializer, Ty,
+                 AllocatedTypeInfo, Range, DirectInitRange);
+}
 
-  unsigned TotalSize = Array + hasInitializer + NumPlacementArgs;
-  SubExprs = new (C) Stmt*[TotalSize];
+CXXNewExpr *CXXNewExpr::CreateEmpty(const ASTContext &Ctx, bool IsArray,
+                                    bool HasInit, unsigned NumPlacementArgs,
+                                    bool IsParenTypeId) {
+  void *Mem =
+      Ctx.Allocate(totalSizeToAlloc(
+                       IsArray + HasInit + NumPlacementArgs, IsParenTypeId),
+                   alignof(CXXNewExpr));
+  return new (Mem)
+      CXXNewExpr(EmptyShell(), IsArray, NumPlacementArgs, IsParenTypeId);
 }
 
-bool CXXNewExpr::shouldNullCheckAllocation(const ASTContext &Ctx) const {
-  return getOperatorNew()->getType()->castAs()
-                                          ->isNothrow() &&
+bool CXXNewExpr::shouldNullCheckAllocation() const {
+  return getOperatorNew()
+             ->getType()
+             ->castAs()
+             ->isNothrow() &&
          !getOperatorNew()->isReservedGlobalPlacementOperator();
 }
 
diff --git a/lib/CodeGen/CGExprCXX.cpp b/lib/CodeGen/CGExprCXX.cpp
index 2e0d4ca767..fabbb4ca54 100644
--- a/lib/CodeGen/CGExprCXX.cpp
+++ b/lib/CodeGen/CGExprCXX.cpp
@@ -1657,8 +1657,8 @@ llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) {
   // function is allowed to return null (because it has a non-throwing
   // exception spec or is the reserved placement new) and we have an
   // interesting initializer.
-  bool nullCheck = E->shouldNullCheckAllocation(getContext()) &&
-    (!allocType.isPODType(getContext()) || E->hasInitializer());
+  bool nullCheck = E->shouldNullCheckAllocation() &&
+                   (!allocType.isPODType(getContext()) || E->hasInitializer());
 
   llvm::BasicBlock *nullCheckBB = nullptr;
   llvm::BasicBlock *contBB = nullptr;
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index 1c210d332e..e963058b73 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -2179,11 +2179,11 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,
     }
   }
 
-  return new (Context)
-      CXXNewExpr(Context, UseGlobal, OperatorNew, OperatorDelete, PassAlignment,
-                 UsualArrayDeleteWantsSize, PlacementArgs, TypeIdParens,
-                 ArraySize, initStyle, Initializer, ResultType, AllocTypeInfo,
-                 Range, DirectInitRange);
+  return CXXNewExpr::Create(Context, UseGlobal, OperatorNew, OperatorDelete,
+                            PassAlignment, UsualArrayDeleteWantsSize,
+                            PlacementArgs, TypeIdParens, ArraySize, initStyle,
+                            Initializer, ResultType, AllocTypeInfo, Range,
+                            DirectInitRange);
 }
 
 /// Checks that a type is suitable as the allocated type
diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp
index e789e20f57..80b987a662 100644
--- a/lib/Serialization/ASTReaderStmt.cpp
+++ b/lib/Serialization/ASTReaderStmt.cpp
@@ -1507,25 +1507,38 @@ void ASTStmtReader::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
 
 void ASTStmtReader::VisitCXXNewExpr(CXXNewExpr *E) {
   VisitExpr(E);
-  E->GlobalNew = Record.readInt();
-  bool isArray = Record.readInt();
-  E->PassAlignment = Record.readInt();
-  E->UsualArrayDeleteWantsSize = Record.readInt();
+
+  bool IsArray = Record.readInt();
+  bool HasInit = Record.readInt();
   unsigned NumPlacementArgs = Record.readInt();
-  E->StoredInitializationStyle = Record.readInt();
+  bool IsParenTypeId = Record.readInt();
+
+  E->CXXNewExprBits.IsGlobalNew = Record.readInt();
+  E->CXXNewExprBits.ShouldPassAlignment = Record.readInt();
+  E->CXXNewExprBits.UsualArrayDeleteWantsSize = Record.readInt();
+  E->CXXNewExprBits.StoredInitializationStyle = Record.readInt();
+
+  assert((IsArray == E->isArray()) && "Wrong IsArray!");
+  assert((HasInit == E->hasInitializer()) && "Wrong HasInit!");
+  assert((NumPlacementArgs == E->getNumPlacementArgs()) &&
+         "Wrong NumPlacementArgs!");
+  assert((IsParenTypeId == E->isParenTypeId()) && "Wrong IsParenTypeId!");
+  (void)IsArray;
+  (void)HasInit;
+  (void)NumPlacementArgs;
+
   E->setOperatorNew(ReadDeclAs());
   E->setOperatorDelete(ReadDeclAs());
   E->AllocatedTypeInfo = GetTypeSourceInfo();
-  E->TypeIdParens = ReadSourceRange();
+  if (IsParenTypeId)
+    E->getTrailingObjects()[0] = ReadSourceRange();
   E->Range = ReadSourceRange();
   E->DirectInitRange = ReadSourceRange();
 
-  E->AllocateArgsArray(Record.getContext(), isArray, NumPlacementArgs,
-                       E->StoredInitializationStyle != 0);
-
   // Install all the subexpressions.
-  for (CXXNewExpr::raw_arg_iterator I = E->raw_arg_begin(),e = E->raw_arg_end();
-       I != e; ++I)
+  for (CXXNewExpr::raw_arg_iterator I = E->raw_arg_begin(),
+                                    N = E->raw_arg_end();
+       I != N; ++I)
     *I = Record.readSubStmt();
 }
 
@@ -3189,7 +3202,12 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
       break;
 
     case EXPR_CXX_NEW:
-      S = new (Context) CXXNewExpr(Empty);
+      S = CXXNewExpr::CreateEmpty(
+          Context,
+          /*IsArray=*/Record[ASTStmtReader::NumExprFields],
+          /*HasInit=*/Record[ASTStmtReader::NumExprFields + 1],
+          /*NumPlacementArgs=*/Record[ASTStmtReader::NumExprFields + 2],
+          /*IsParenTypeId=*/Record[ASTStmtReader::NumExprFields + 3]);
       break;
 
     case EXPR_CXX_DELETE:
diff --git a/lib/Serialization/ASTWriterStmt.cpp b/lib/Serialization/ASTWriterStmt.cpp
index 26a01706dc..14c3b3278e 100644
--- a/lib/Serialization/ASTWriterStmt.cpp
+++ b/lib/Serialization/ASTWriterStmt.cpp
@@ -1483,20 +1483,27 @@ void ASTStmtWriter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
 
 void ASTStmtWriter::VisitCXXNewExpr(CXXNewExpr *E) {
   VisitExpr(E);
-  Record.push_back(E->isGlobalNew());
+
   Record.push_back(E->isArray());
+  Record.push_back(E->hasInitializer());
+  Record.push_back(E->getNumPlacementArgs());
+  Record.push_back(E->isParenTypeId());
+
+  Record.push_back(E->isGlobalNew());
   Record.push_back(E->passAlignment());
   Record.push_back(E->doesUsualArrayDeleteWantSize());
-  Record.push_back(E->getNumPlacementArgs());
-  Record.push_back(E->StoredInitializationStyle);
+  Record.push_back(E->CXXNewExprBits.StoredInitializationStyle);
+
   Record.AddDeclRef(E->getOperatorNew());
   Record.AddDeclRef(E->getOperatorDelete());
   Record.AddTypeSourceInfo(E->getAllocatedTypeSourceInfo());
-  Record.AddSourceRange(E->getTypeIdParens());
+  if (E->isParenTypeId())
+    Record.AddSourceRange(E->getTypeIdParens());
   Record.AddSourceRange(E->getSourceRange());
   Record.AddSourceRange(E->getDirectInitRange());
-  for (CXXNewExpr::arg_iterator I = E->raw_arg_begin(), e = E->raw_arg_end();
-       I != e; ++I)
+
+  for (CXXNewExpr::arg_iterator I = E->raw_arg_begin(), N = E->raw_arg_end();
+       I != N; ++I)
     Record.AddStmt(*I);
 
   Code = serialization::EXPR_CXX_NEW;
-- 
cgit v1.2.3


From 20cee7d894a7a9e28901ba02906b2a36967bca07 Mon Sep 17 00:00:00 2001
From: Rafael Stahl 
Date: Mon, 7 Jan 2019 15:07:01 +0000
Subject: [analyzer] Pass the correct loc Expr from VisitIncDecOp to evalStore

Summary: The LocationE parameter of evalStore is documented as "The location expression that is stored to". When storing from an increment / decrement operator this was not satisfied. In user code this causes an inconsistency between the SVal and Stmt parameters of checkLocation.

Reviewers: NoQ, dcoughlin, george.karpenkov

Reviewed By: NoQ

Subscribers: xazax.hun, baloghadamsoftware, szepet, a.sidorin, mikhail.ramalho, Szelethus, donat.nagy, dkrupp, cfe-commits

Differential Revision: https://reviews.llvm.org/D55701

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350528 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/StaticAnalyzer/Core/ExprEngineC.cpp            |  4 +-
 .../StaticAnalyzer/RegisterCustomCheckersTest.cpp  | 55 +++++++++++++++-------
 2 files changed, 41 insertions(+), 18 deletions(-)

diff --git a/lib/StaticAnalyzer/Core/ExprEngineC.cpp b/lib/StaticAnalyzer/Core/ExprEngineC.cpp
index 7d47cf4f33..b980628878 100644
--- a/lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -1052,7 +1052,7 @@ void ExprEngine::VisitIncrementDecrementOperator(const UnaryOperator* U,
       // Perform the store, so that the uninitialized value detection happens.
       Bldr.takeNodes(*I);
       ExplodedNodeSet Dst3;
-      evalStore(Dst3, U, U, *I, state, loc, V2_untested);
+      evalStore(Dst3, U, Ex, *I, state, loc, V2_untested);
       Bldr.addNodes(Dst3);
 
       continue;
@@ -1120,7 +1120,7 @@ void ExprEngine::VisitIncrementDecrementOperator(const UnaryOperator* U,
     // Perform the store.
     Bldr.takeNodes(*I);
     ExplodedNodeSet Dst3;
-    evalStore(Dst3, U, U, *I, state, loc, Result);
+    evalStore(Dst3, U, Ex, *I, state, loc, Result);
     Bldr.addNodes(Dst3);
   }
   Dst.insert(Dst2);
diff --git a/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp b/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp
index 0dbf3ae451..568a719e33 100644
--- a/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp
+++ b/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp
@@ -21,16 +21,7 @@ namespace clang {
 namespace ento {
 namespace {
 
-class CustomChecker : public Checker {
-public:
-  void checkASTCodeBody(const Decl *D, AnalysisManager &Mgr,
-                        BugReporter &BR) const {
-    BR.EmitBasicReport(D, this, "Custom diagnostic", categories::LogicError,
-                       "Custom diagnostic description",
-                       PathDiagnosticLocation(D, Mgr.getSourceManager()), {});
-  }
-};
-
+template 
 class TestAction : public ASTFrontendAction {
   class DiagConsumer : public PathDiagnosticConsumer {
     llvm::raw_ostream &Output;
@@ -59,23 +50,55 @@ public:
     Compiler.getAnalyzerOpts()->CheckersControlList = {
         {"custom.CustomChecker", true}};
     AnalysisConsumer->AddCheckerRegistrationFn([](CheckerRegistry &Registry) {
-      Registry.addChecker("custom.CustomChecker", "Description",
-                                         "");
+      Registry.addChecker("custom.CustomChecker", "Description", "");
     });
     return std::move(AnalysisConsumer);
   }
 };
 
+template 
+bool runCheckerOnCode(const std::string &Code, std::string &Diags) {
+  llvm::raw_string_ostream OS(Diags);
+  return tooling::runToolOnCode(new TestAction(OS), Code);
+}
+template 
+bool runCheckerOnCode(const std::string &Code) {
+  std::string Diags;
+  return runCheckerOnCode(Code, Diags);
+}
+
+
+class CustomChecker : public Checker {
+public:
+  void checkASTCodeBody(const Decl *D, AnalysisManager &Mgr,
+                        BugReporter &BR) const {
+    BR.EmitBasicReport(D, this, "Custom diagnostic", categories::LogicError,
+                       "Custom diagnostic description",
+                       PathDiagnosticLocation(D, Mgr.getSourceManager()), {});
+  }
+};
 
 TEST(RegisterCustomCheckers, RegisterChecker) {
   std::string Diags;
-  {
-    llvm::raw_string_ostream OS(Diags);
-    EXPECT_TRUE(tooling::runToolOnCode(new TestAction(OS), "void f() {;}"));
-  }
+  EXPECT_TRUE(runCheckerOnCode("void f() {;}", Diags));
   EXPECT_EQ(Diags, "custom.CustomChecker:Custom diagnostic description");
 }
 
+class LocIncDecChecker : public Checker {
+public:
+  void checkLocation(SVal Loc, bool IsLoad, const Stmt *S,
+                     CheckerContext &C) const {
+    auto UnaryOp = dyn_cast(S);
+    if (UnaryOp && !IsLoad)
+      EXPECT_FALSE(UnaryOp->isIncrementOp());
+  }
+};
+
+TEST(RegisterCustomCheckers, CheckLocationIncDec) {
+  EXPECT_TRUE(
+      runCheckerOnCode("void f() { int *p; (*p)++; }"));
+}
+
 }
 }
 }
-- 
cgit v1.2.3


From 585feb7fd5e393b20bc15fb162f3d05945af2705 Mon Sep 17 00:00:00 2001
From: Benjamin Kramer 
Date: Mon, 7 Jan 2019 15:22:08 +0000
Subject: [Sema] Fix unused variable warning in Release builds

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350529 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/Sema/SemaDeclCXX.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 50d01f309b..4ab220fd03 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -14294,8 +14294,7 @@ NamedDecl *Sema::ActOnFriendFunctionDecl(Scope *S, Declarator &D,
 
   CXXScopeSpec &SS = D.getCXXScopeSpec();
   DeclarationNameInfo NameInfo = GetNameForDeclarator(D);
-  DeclarationName Name = NameInfo.getName();
-  assert(Name);
+  assert(NameInfo.getName());
 
   // Check for unexpanded parameter packs.
   if (DiagnoseUnexpandedParameterPack(Loc, TInfo, UPPC_FriendDeclaration) ||
-- 
cgit v1.2.3


From 90bf1904ce50911eeb6e20f8c6cde3e91ac6eff1 Mon Sep 17 00:00:00 2001
From: Alexey Bataev 
Date: Mon, 7 Jan 2019 15:45:09 +0000
Subject: [OPENMP][NVPTX]Reduce number of barriers in reductions.

After the fix for the syncthreads we don't need to generate extra
barriers for the parallel reductions.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350530 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp                    | 7 -------
 test/OpenMP/nvptx_target_parallel_reduction_codegen.cpp | 4 ----
 test/OpenMP/nvptx_teams_reduction_codegen.cpp           | 1 -
 3 files changed, 12 deletions(-)

diff --git a/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp b/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp
index 21911c96f3..403aefbef9 100644
--- a/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp
+++ b/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp
@@ -3124,7 +3124,6 @@ static void emitReductionListCopy(
 ///     sync
 ///     if (I am the first warp)
 ///       Copy smem[thread_id] to my local D
-///     sync
 static llvm::Value *emitInterWarpCopyFunction(CodeGenModule &CGM,
                                               ArrayRef Privates,
                                               QualType ReductionArrayTy,
@@ -3337,12 +3336,6 @@ static llvm::Value *emitInterWarpCopyFunction(CodeGenModule &CGM,
 
       CGF.EmitBlock(W0MergeBB);
 
-      // While warp 0 copies values from transfer medium, all other warps must
-      // wait.
-      // kmpc_barrier.
-      CGM.getOpenMPRuntime().emitBarrierCall(CGF, Loc, OMPD_unknown,
-                                             /*EmitChecks=*/false,
-                                             /*ForceSimpleCall=*/true);
       if (NumIters > 1) {
         Cnt = Bld.CreateNSWAdd(Cnt, llvm::ConstantInt::get(CGM.IntTy, /*V=*/1));
         CGF.EmitStoreOfScalar(Cnt, CntAddr, /*Volatile=*/false, C.IntTy);
diff --git a/test/OpenMP/nvptx_target_parallel_reduction_codegen.cpp b/test/OpenMP/nvptx_target_parallel_reduction_codegen.cpp
index 4f06f33e68..c23f275bd1 100644
--- a/test/OpenMP/nvptx_target_parallel_reduction_codegen.cpp
+++ b/test/OpenMP/nvptx_target_parallel_reduction_codegen.cpp
@@ -231,7 +231,6 @@ int bar(int n){
   // CHECK: br label {{%?}}[[READ_CONT]]
   //
   // CHECK: [[READ_CONT]]
-  // CHECK: call void @__kmpc_barrier(%struct.ident_t* @
   // CHECK: [[NEXT:%.+]] = add nsw i32 [[CNT]], 1
   // CHECK: store i32 [[NEXT]], i32* [[CNT_ADDR]],
   // CHECK: br label
@@ -468,7 +467,6 @@ int bar(int n){
   //
   // CHECK: [[READ_CONT]]
   // CHECK: call void @__kmpc_barrier(%struct.ident_t* @
-  // CHECK: call void @__kmpc_barrier(%struct.ident_t* @
   // CHECK: [[IS_WARP_MASTER:%.+]] = icmp eq i32 [[LANEID]], 0
   // CHECK: br i1 [[IS_WARP_MASTER]], label {{%?}}[[DO_COPY:.+]], label {{%?}}[[COPY_ELSE:.+]]
   //
@@ -507,7 +505,6 @@ int bar(int n){
   // CHECK: br label {{%?}}[[READ_CONT]]
   //
   // CHECK: [[READ_CONT]]
-  // CHECK: call void @__kmpc_barrier(%struct.ident_t* @
   // CHECK: ret
 
 
@@ -823,7 +820,6 @@ int bar(int n){
   // CHECK: br label {{%?}}[[READ_CONT]]
   //
   // CHECK: [[READ_CONT]]
-  // CHECK: call void @__kmpc_barrier(%struct.ident_t* @
   // CHECK: ret
 
 #endif
diff --git a/test/OpenMP/nvptx_teams_reduction_codegen.cpp b/test/OpenMP/nvptx_teams_reduction_codegen.cpp
index b0246e2ee8..0de25295a7 100644
--- a/test/OpenMP/nvptx_teams_reduction_codegen.cpp
+++ b/test/OpenMP/nvptx_teams_reduction_codegen.cpp
@@ -473,7 +473,6 @@ int bar(int n){
   // CHECK: br label {{%?}}[[READ_CONT]]
   //
   // CHECK: [[READ_CONT]]
-  // CHECK: call void @__kmpc_barrier(%struct.ident_t* @
   // CHECK: ret
 
 #endif
-- 
cgit v1.2.3


From d1e81632f3a6b3551bbfebf74efc2946329a5473 Mon Sep 17 00:00:00 2001
From: Craig Topper 
Date: Mon, 7 Jan 2019 19:10:22 +0000
Subject: [X86] Use funnel shift intrinsics for the VBMI2 vshld/vshrd builtins.

Differential Revision: https://reviews.llvm.org/D56365

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350555 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/Basic/BuiltinsX86.def   |  56 +++---
 lib/CodeGen/CGBuiltin.cpp             |  46 +++++
 lib/Headers/avx512vbmi2intrin.h       | 158 +++++++----------
 lib/Headers/avx512vlvbmi2intrin.h     | 312 ++++++++++++++--------------------
 test/CodeGen/avx512vbmi2-builtins.c   |  84 +++++----
 test/CodeGen/avx512vlvbmi2-builtins.c | 168 ++++++++++--------
 6 files changed, 407 insertions(+), 417 deletions(-)

diff --git a/include/clang/Basic/BuiltinsX86.def b/include/clang/Basic/BuiltinsX86.def
index d97ec58916..ccb5cd04d2 100644
--- a/include/clang/Basic/BuiltinsX86.def
+++ b/include/clang/Basic/BuiltinsX86.def
@@ -1256,43 +1256,25 @@ TARGET_BUILTIN(__builtin_ia32_vpshldw128, "V8sV8sV8sIi", "ncV:128:", "avx512vl,a
 TARGET_BUILTIN(__builtin_ia32_vpshldw256, "V16sV16sV16sIi", "ncV:256:", "avx512vl,avx512vbmi2")
 TARGET_BUILTIN(__builtin_ia32_vpshldw512, "V32sV32sV32sIi", "ncV:512:", "avx512vbmi2")
 
-TARGET_BUILTIN(__builtin_ia32_vpshldvd128_mask, "V4iV4iV4iV4iUc", "ncV:128:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvd256_mask, "V8iV8iV8iV8iUc", "ncV:256:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvd512_mask, "V16iV16iV16iV16iUs", "ncV:512:", "avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "ncV:128:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "ncV:256:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "ncV:512:", "avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvw128_mask, "V8sV8sV8sV8sUc", "ncV:128:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvw256_mask, "V16sV16sV16sV16sUs", "ncV:256:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvw512_mask, "V32sV32sV32sV32sUi", "ncV:512:", "avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvd128_maskz, "V4iV4iV4iV4iUc", "ncV:128:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvd256_maskz, "V8iV8iV8iV8iUc", "ncV:256:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvd512_maskz, "V16iV16iV16iV16iUs", "ncV:512:", "avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvq128_maskz, "V2LLiV2LLiV2LLiV2LLiUc", "ncV:128:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvq256_maskz, "V4LLiV4LLiV4LLiV4LLiUc", "ncV:256:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvq512_maskz, "V8LLiV8LLiV8LLiV8LLiUc", "ncV:512:", "avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvw128_maskz, "V8sV8sV8sV8sUc", "ncV:128:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvw256_maskz, "V16sV16sV16sV16sUs", "ncV:256:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvw512_maskz, "V32sV32sV32sV32sUi", "ncV:512:", "avx512vbmi2")
-
-TARGET_BUILTIN(__builtin_ia32_vpshrdvd128_mask, "V4iV4iV4iV4iUc", "ncV:128:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvd256_mask, "V8iV8iV8iV8iUc", "ncV:256:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvd512_mask, "V16iV16iV16iV16iUs", "ncV:512:", "avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "ncV:128:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "ncV:256:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "ncV:512:", "avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvw128_mask, "V8sV8sV8sV8sUc", "ncV:128:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvw256_mask, "V16sV16sV16sV16sUs", "ncV:256:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvw512_mask, "V32sV32sV32sV32sUi", "ncV:512:", "avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvd128_maskz, "V4iV4iV4iV4iUc", "ncV:128:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvd256_maskz, "V8iV8iV8iV8iUc", "ncV:256:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvd512_maskz, "V16iV16iV16iV16iUs", "ncV:512:", "avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvq128_maskz, "V2LLiV2LLiV2LLiV2LLiUc", "ncV:128:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvq256_maskz, "V4LLiV4LLiV4LLiV4LLiUc", "ncV:256:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvq512_maskz, "V8LLiV8LLiV8LLiV8LLiUc", "ncV:512:", "avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvw128_maskz, "V8sV8sV8sV8sUc", "ncV:128:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvw256_maskz, "V16sV16sV16sV16sUs", "ncV:256:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvw512_maskz, "V32sV32sV32sV32sUi", "ncV:512:", "avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvd128, "V4iV4iV4iV4i", "ncV:128:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvd256, "V8iV8iV8iV8i", "ncV:256:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvd512, "V16iV16iV16iV16i", "ncV:512:", "avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvq128, "V2LLiV2LLiV2LLiV2LLi", "ncV:128:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvq256, "V4LLiV4LLiV4LLiV4LLi", "ncV:256:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvq512, "V8LLiV8LLiV8LLiV8LLi", "ncV:512:", "avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvw128, "V8sV8sV8sV8s", "ncV:128:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvw256, "V16sV16sV16sV16s", "ncV:256:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvw512, "V32sV32sV32sV32s", "ncV:512:", "avx512vbmi2")
+
+TARGET_BUILTIN(__builtin_ia32_vpshrdvd128, "V4iV4iV4iV4i", "ncV:128:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdvd256, "V8iV8iV8iV8i", "ncV:256:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdvd512, "V16iV16iV16iV16i", "ncV:512:", "avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdvq128, "V2LLiV2LLiV2LLiV2LLi", "ncV:128:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdvq256, "V4LLiV4LLiV4LLiV4LLi", "ncV:256:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdvq512, "V8LLiV8LLiV8LLiV8LLi", "ncV:512:", "avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdvw128, "V8sV8sV8sV8s", "ncV:128:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdvw256, "V16sV16sV16sV16s", "ncV:256:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdvw512, "V32sV32sV32sV32s", "ncV:512:", "avx512vbmi2")
 
 TARGET_BUILTIN(__builtin_ia32_vpshrdd128, "V4iV4iV4iIi", "ncV:128:", "avx512vl,avx512vbmi2")
 TARGET_BUILTIN(__builtin_ia32_vpshrdd256, "V8iV8iV8iIi", "ncV:256:", "avx512vl,avx512vbmi2")
diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp
index 93484f82c3..ca7b4691ff 100644
--- a/lib/CodeGen/CGBuiltin.cpp
+++ b/lib/CodeGen/CGBuiltin.cpp
@@ -10999,6 +10999,52 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID,
   case X86::BI__builtin_ia32_pternlogq256_maskz:
     return EmitX86Ternlog(*this, /*ZeroMask*/true, Ops);
 
+  case X86::BI__builtin_ia32_vpshldd128:
+  case X86::BI__builtin_ia32_vpshldd256:
+  case X86::BI__builtin_ia32_vpshldd512:
+  case X86::BI__builtin_ia32_vpshldq128:
+  case X86::BI__builtin_ia32_vpshldq256:
+  case X86::BI__builtin_ia32_vpshldq512:
+  case X86::BI__builtin_ia32_vpshldw128:
+  case X86::BI__builtin_ia32_vpshldw256:
+  case X86::BI__builtin_ia32_vpshldw512:
+    return EmitX86FunnelShift(*this, Ops[0], Ops[1], Ops[2], false);
+
+  case X86::BI__builtin_ia32_vpshrdd128:
+  case X86::BI__builtin_ia32_vpshrdd256:
+  case X86::BI__builtin_ia32_vpshrdd512:
+  case X86::BI__builtin_ia32_vpshrdq128:
+  case X86::BI__builtin_ia32_vpshrdq256:
+  case X86::BI__builtin_ia32_vpshrdq512:
+  case X86::BI__builtin_ia32_vpshrdw128:
+  case X86::BI__builtin_ia32_vpshrdw256:
+  case X86::BI__builtin_ia32_vpshrdw512:
+    // Ops 0 and 1 are swapped.
+    return EmitX86FunnelShift(*this, Ops[1], Ops[0], Ops[2], true);
+
+  case X86::BI__builtin_ia32_vpshldvd128:
+  case X86::BI__builtin_ia32_vpshldvd256:
+  case X86::BI__builtin_ia32_vpshldvd512:
+  case X86::BI__builtin_ia32_vpshldvq128:
+  case X86::BI__builtin_ia32_vpshldvq256:
+  case X86::BI__builtin_ia32_vpshldvq512:
+  case X86::BI__builtin_ia32_vpshldvw128:
+  case X86::BI__builtin_ia32_vpshldvw256:
+  case X86::BI__builtin_ia32_vpshldvw512:
+    return EmitX86FunnelShift(*this, Ops[0], Ops[1], Ops[2], false);
+
+  case X86::BI__builtin_ia32_vpshrdvd128:
+  case X86::BI__builtin_ia32_vpshrdvd256:
+  case X86::BI__builtin_ia32_vpshrdvd512:
+  case X86::BI__builtin_ia32_vpshrdvq128:
+  case X86::BI__builtin_ia32_vpshrdvq256:
+  case X86::BI__builtin_ia32_vpshrdvq512:
+  case X86::BI__builtin_ia32_vpshrdvw128:
+  case X86::BI__builtin_ia32_vpshrdvw256:
+  case X86::BI__builtin_ia32_vpshrdvw512:
+    // Ops 0 and 1 are swapped.
+    return EmitX86FunnelShift(*this, Ops[1], Ops[0], Ops[2], true);
+
   // 3DNow!
   case X86::BI__builtin_ia32_pswapdsf:
   case X86::BI__builtin_ia32_pswapdsi: {
diff --git a/lib/Headers/avx512vbmi2intrin.h b/lib/Headers/avx512vbmi2intrin.h
index d2a58094fd..5324252429 100644
--- a/lib/Headers/avx512vbmi2intrin.h
+++ b/lib/Headers/avx512vbmi2intrin.h
@@ -227,167 +227,141 @@ _mm512_maskz_expandloadu_epi8(__mmask64 __U, void const *__P)
                                    (__v32hi)_mm512_setzero_si512())
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_mask_shldv_epi64(__m512i __S, __mmask8 __U, __m512i __A, __m512i __B)
+_mm512_shldv_epi64(__m512i __A, __m512i __B, __m512i __C)
 {
-  return (__m512i) __builtin_ia32_vpshldvq512_mask ((__v8di) __S,
-              (__v8di) __A,
-              (__v8di) __B,
-              __U);
+  return (__m512i)__builtin_ia32_vpshldvq512((__v8di)__A, (__v8di)__B,
+                                             (__v8di)__C);
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_maskz_shldv_epi64(__mmask8 __U, __m512i __S, __m512i __A, __m512i __B)
+_mm512_mask_shldv_epi64(__m512i __A, __mmask8 __U, __m512i __B, __m512i __C)
 {
-  return (__m512i) __builtin_ia32_vpshldvq512_maskz ((__v8di) __S,
-              (__v8di) __A,
-              (__v8di) __B,
-              __U);
+  return (__m512i)__builtin_ia32_selectq_512(__U,
+                                      (__v8di)_mm512_shldv_epi64(__A, __B, __C),
+                                      (__v8di)__A);
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_shldv_epi64(__m512i __S, __m512i __A, __m512i __B)
+_mm512_maskz_shldv_epi64(__mmask8 __U, __m512i __A, __m512i __B, __m512i __C)
 {
-  return (__m512i) __builtin_ia32_vpshldvq512_mask ((__v8di) __S,
-              (__v8di) __A,
-              (__v8di) __B,
-              (__mmask8) -1);
+  return (__m512i)__builtin_ia32_selectq_512(__U,
+                                      (__v8di)_mm512_shldv_epi64(__A, __B, __C),
+                                      (__v8di)_mm512_setzero_si512());
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_mask_shldv_epi32(__m512i __S, __mmask16 __U, __m512i __A, __m512i __B)
+_mm512_shldv_epi32(__m512i __A, __m512i __B, __m512i __C)
 {
-  return (__m512i) __builtin_ia32_vpshldvd512_mask ((__v16si) __S,
-              (__v16si) __A,
-              (__v16si) __B,
-              __U);
+  return (__m512i)__builtin_ia32_vpshldvd512((__v16si)__A, (__v16si)__B,
+                                             (__v16si)__C);
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_maskz_shldv_epi32(__mmask16 __U, __m512i __S, __m512i __A, __m512i __B)
+_mm512_mask_shldv_epi32(__m512i __A, __mmask16 __U, __m512i __B, __m512i __C)
 {
-  return (__m512i) __builtin_ia32_vpshldvd512_maskz ((__v16si) __S,
-              (__v16si) __A,
-              (__v16si) __B,
-              __U);
+  return (__m512i)__builtin_ia32_selectd_512(__U,
+                                     (__v16si)_mm512_shldv_epi32(__A, __B, __C),
+                                     (__v16si)__A);
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_shldv_epi32(__m512i __S, __m512i __A, __m512i __B)
+_mm512_maskz_shldv_epi32(__mmask16 __U, __m512i __A, __m512i __B, __m512i __C)
 {
-  return (__m512i) __builtin_ia32_vpshldvd512_mask ((__v16si) __S,
-              (__v16si) __A,
-              (__v16si) __B,
-              (__mmask16) -1);
+  return (__m512i)__builtin_ia32_selectd_512(__U,
+                                     (__v16si)_mm512_shldv_epi32(__A, __B, __C),
+                                     (__v16si)_mm512_setzero_si512());
 }
 
-
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_mask_shldv_epi16(__m512i __S, __mmask32 __U, __m512i __A, __m512i __B)
+_mm512_shldv_epi16(__m512i __A, __m512i __B, __m512i __C)
 {
-  return (__m512i) __builtin_ia32_vpshldvw512_mask ((__v32hi) __S,
-              (__v32hi) __A,
-              (__v32hi) __B,
-              __U);
+  return (__m512i)__builtin_ia32_vpshldvw512((__v32hi)__A, (__v32hi)__B,
+                                             (__v32hi)__C);
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_maskz_shldv_epi16(__mmask32 __U, __m512i __S, __m512i __A, __m512i __B)
+_mm512_mask_shldv_epi16(__m512i __A, __mmask32 __U, __m512i __B, __m512i __C)
 {
-  return (__m512i) __builtin_ia32_vpshldvw512_maskz ((__v32hi) __S,
-              (__v32hi) __A,
-              (__v32hi) __B,
-              __U);
+  return (__m512i)__builtin_ia32_selectw_512(__U,
+                                     (__v32hi)_mm512_shldv_epi16(__A, __B, __C),
+                                     (__v32hi)__A);
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_shldv_epi16(__m512i __S, __m512i __A, __m512i __B)
+_mm512_maskz_shldv_epi16(__mmask32 __U, __m512i __A, __m512i __B, __m512i __C)
 {
-  return (__m512i) __builtin_ia32_vpshldvw512_mask ((__v32hi) __S,
-              (__v32hi) __A,
-              (__v32hi) __B,
-              (__mmask32) -1);
+  return (__m512i)__builtin_ia32_selectw_512(__U,
+                                     (__v32hi)_mm512_shldv_epi16(__A, __B, __C),
+                                     (__v32hi)_mm512_setzero_si512());
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_mask_shrdv_epi64(__m512i __S, __mmask8 __U, __m512i __A, __m512i __B)
+_mm512_shrdv_epi64(__m512i __A, __m512i __B, __m512i __C)
 {
-  return (__m512i) __builtin_ia32_vpshrdvq512_mask ((__v8di) __S,
-              (__v8di) __A,
-              (__v8di) __B,
-              __U);
+  return (__m512i)__builtin_ia32_vpshrdvq512((__v8di)__A, (__v8di)__B,
+                                             (__v8di)__C);
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_maskz_shrdv_epi64(__mmask8 __U, __m512i __S, __m512i __A, __m512i __B)
+_mm512_mask_shrdv_epi64(__m512i __A, __mmask8 __U, __m512i __B, __m512i __C)
 {
-  return (__m512i) __builtin_ia32_vpshrdvq512_maskz ((__v8di) __S,
-              (__v8di) __A,
-              (__v8di) __B,
-              __U);
+  return (__m512i)__builtin_ia32_selectq_512(__U,
+                                      (__v8di)_mm512_shrdv_epi64(__A, __B, __C),
+                                      (__v8di)__A);
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_shrdv_epi64(__m512i __S, __m512i __A, __m512i __B)
+_mm512_maskz_shrdv_epi64(__mmask8 __U, __m512i __A, __m512i __B, __m512i __C)
 {
-  return (__m512i) __builtin_ia32_vpshrdvq512_mask ((__v8di) __S,
-              (__v8di) __A,
-              (__v8di) __B,
-              (__mmask8) -1);
+  return (__m512i)__builtin_ia32_selectq_512(__U,
+                                      (__v8di)_mm512_shrdv_epi64(__A, __B, __C),
+                                      (__v8di)_mm512_setzero_si512());
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_mask_shrdv_epi32(__m512i __S, __mmask16 __U, __m512i __A, __m512i __B)
+_mm512_shrdv_epi32(__m512i __A, __m512i __B, __m512i __C)
 {
-  return (__m512i) __builtin_ia32_vpshrdvd512_mask ((__v16si) __S,
-              (__v16si) __A,
-              (__v16si) __B,
-              __U);
+  return (__m512i)__builtin_ia32_vpshrdvd512((__v16si)__A, (__v16si)__B,
+                                             (__v16si)__C);
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_maskz_shrdv_epi32(__mmask16 __U, __m512i __S, __m512i __A, __m512i __B)
+_mm512_mask_shrdv_epi32(__m512i __A, __mmask16 __U, __m512i __B, __m512i __C)
 {
-  return (__m512i) __builtin_ia32_vpshrdvd512_maskz ((__v16si) __S,
-              (__v16si) __A,
-              (__v16si) __B,
-              __U);
+  return (__m512i) __builtin_ia32_selectd_512(__U,
+                                     (__v16si)_mm512_shrdv_epi32(__A, __B, __C),
+                                     (__v16si)__A);
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_shrdv_epi32(__m512i __S, __m512i __A, __m512i __B)
+_mm512_maskz_shrdv_epi32(__mmask16 __U, __m512i __A, __m512i __B, __m512i __C)
 {
-  return (__m512i) __builtin_ia32_vpshrdvd512_mask ((__v16si) __S,
-              (__v16si) __A,
-              (__v16si) __B,
-              (__mmask16) -1);
+  return (__m512i) __builtin_ia32_selectd_512(__U,
+                                     (__v16si)_mm512_shrdv_epi32(__A, __B, __C),
+                                     (__v16si)_mm512_setzero_si512());
 }
 
-
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_mask_shrdv_epi16(__m512i __S, __mmask32 __U, __m512i __A, __m512i __B)
+_mm512_shrdv_epi16(__m512i __A, __m512i __B, __m512i __C)
 {
-  return (__m512i) __builtin_ia32_vpshrdvw512_mask ((__v32hi) __S,
-              (__v32hi) __A,
-              (__v32hi) __B,
-              __U);
+  return (__m512i)__builtin_ia32_vpshrdvw512((__v32hi)__A, (__v32hi)__B,
+                                             (__v32hi)__C);
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_maskz_shrdv_epi16(__mmask32 __U, __m512i __S, __m512i __A, __m512i __B)
+_mm512_mask_shrdv_epi16(__m512i __A, __mmask32 __U, __m512i __B, __m512i __C)
 {
-  return (__m512i) __builtin_ia32_vpshrdvw512_maskz ((__v32hi) __S,
-              (__v32hi) __A,
-              (__v32hi) __B,
-              __U);
+  return (__m512i)__builtin_ia32_selectw_512(__U,
+                                     (__v32hi)_mm512_shrdv_epi16(__A, __B, __C),
+                                     (__v32hi)__A);
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_shrdv_epi16(__m512i __S, __m512i __A, __m512i __B)
+_mm512_maskz_shrdv_epi16(__mmask32 __U, __m512i __A, __m512i __B, __m512i __C)
 {
-  return (__m512i) __builtin_ia32_vpshrdvw512_mask ((__v32hi) __S,
-              (__v32hi) __A,
-              (__v32hi) __B,
-              (__mmask32) -1);
+  return (__m512i)__builtin_ia32_selectw_512(__U,
+                                     (__v32hi)_mm512_shrdv_epi16(__A, __B, __C),
+                                     (__v32hi)_mm512_setzero_si512());
 }
 
 
diff --git a/lib/Headers/avx512vlvbmi2intrin.h b/lib/Headers/avx512vlvbmi2intrin.h
index baaf565463..632d14fb55 100644
--- a/lib/Headers/avx512vlvbmi2intrin.h
+++ b/lib/Headers/avx512vlvbmi2intrin.h
@@ -421,327 +421,279 @@ _mm256_maskz_expandloadu_epi8(__mmask32 __U, void const *__P)
                                       (__v8hi)_mm_setzero_si128())
 
 static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_mask_shldv_epi64(__m256i __S, __mmask8 __U, __m256i __A, __m256i __B)
+_mm256_shldv_epi64(__m256i __A, __m256i __B, __m256i __C)
 {
-  return (__m256i) __builtin_ia32_vpshldvq256_mask ((__v4di) __S,
-              (__v4di) __A,
-              (__v4di) __B,
-              __U);
+  return (__m256i)__builtin_ia32_vpshldvq256((__v4di)__A, (__v4di)__B,
+                                             (__v4di)__C);
 }
 
 static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_maskz_shldv_epi64(__mmask8 __U, __m256i __S, __m256i __A, __m256i __B)
+_mm256_mask_shldv_epi64(__m256i __A, __mmask8 __U, __m256i __B, __m256i __C)
 {
-  return (__m256i) __builtin_ia32_vpshldvq256_maskz ((__v4di) __S,
-              (__v4di) __A,
-              (__v4di) __B,
-              __U);
+  return (__m256i)__builtin_ia32_selectq_256(__U,
+                                      (__v4di)_mm256_shldv_epi64(__A, __B, __C),
+                                      (__v4di)__A);
 }
 
 static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_shldv_epi64(__m256i __S, __m256i __A, __m256i __B)
+_mm256_maskz_shldv_epi64(__mmask8 __U, __m256i __A, __m256i __B, __m256i __C)
 {
-  return (__m256i) __builtin_ia32_vpshldvq256_mask ((__v4di) __S,
-              (__v4di) __A,
-              (__v4di) __B,
-              (__mmask8) -1);
+  return (__m256i)__builtin_ia32_selectq_256(__U,
+                                      (__v4di)_mm256_shldv_epi64(__A, __B, __C),
+                                      (__v4di)_mm256_setzero_si256());
 }
 
 static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_mask_shldv_epi64(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B)
+_mm_shldv_epi64(__m128i __A, __m128i __B, __m128i __C)
 {
-  return (__m128i) __builtin_ia32_vpshldvq128_mask ((__v2di) __S,
-              (__v2di) __A,
-              (__v2di) __B,
-              __U);
+  return (__m128i)__builtin_ia32_vpshldvq128((__v2di)__A, (__v2di)__B,
+                                             (__v2di)__C);
 }
 
 static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_maskz_shldv_epi64(__mmask8 __U, __m128i __S, __m128i __A, __m128i __B)
+_mm_mask_shldv_epi64(__m128i __A, __mmask8 __U, __m128i __B, __m128i __C)
 {
-  return (__m128i) __builtin_ia32_vpshldvq128_maskz ((__v2di) __S,
-              (__v2di) __A,
-              (__v2di) __B,
-              __U);
+  return (__m128i)__builtin_ia32_selectq_128(__U,
+                                         (__v2di)_mm_shldv_epi64(__A, __B, __C),
+                                         (__v2di)__A);
 }
 
 static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_shldv_epi64(__m128i __S, __m128i __A, __m128i __B)
+_mm_maskz_shldv_epi64(__mmask8 __U, __m128i __A, __m128i __B, __m128i __C)
 {
-  return (__m128i) __builtin_ia32_vpshldvq128_mask ((__v2di) __S,
-              (__v2di) __A,
-              (__v2di) __B,
-              (__mmask8) -1);
+  return (__m128i)__builtin_ia32_selectq_128(__U,
+                                         (__v2di)_mm_shldv_epi64(__A, __B, __C),
+                                         (__v2di)_mm_setzero_si128());
 }
 
 static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_mask_shldv_epi32(__m256i __S, __mmask8 __U, __m256i __A, __m256i __B)
+_mm256_shldv_epi32(__m256i __A, __m256i __B, __m256i __C)
 {
-  return (__m256i) __builtin_ia32_vpshldvd256_mask ((__v8si) __S,
-              (__v8si) __A,
-              (__v8si) __B,
-              __U);
+  return (__m256i)__builtin_ia32_vpshldvd256((__v8si)__A, (__v8si)__B,
+                                             (__v8si)__C);
 }
 
 static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_maskz_shldv_epi32(__mmask8 __U, __m256i __S, __m256i __A, __m256i __B)
+_mm256_mask_shldv_epi32(__m256i __A, __mmask8 __U, __m256i __B, __m256i __C)
 {
-  return (__m256i) __builtin_ia32_vpshldvd256_maskz ((__v8si) __S,
-              (__v8si) __A,
-              (__v8si) __B,
-              __U);
+  return (__m256i)__builtin_ia32_selectd_256(__U,
+                                      (__v8si)_mm256_shldv_epi32(__A, __B, __C),
+                                      (__v8si)__A);
 }
 
 static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_shldv_epi32(__m256i __S, __m256i __A, __m256i __B)
+_mm256_maskz_shldv_epi32(__mmask8 __U, __m256i __A, __m256i __B, __m256i __C)
 {
-  return (__m256i) __builtin_ia32_vpshldvd256_mask ((__v8si) __S,
-              (__v8si) __A,
-              (__v8si) __B,
-              (__mmask8) -1);
+  return (__m256i)__builtin_ia32_selectd_256(__U,
+                                      (__v8si)_mm256_shldv_epi32(__A, __B, __C),
+                                      (__v8si)_mm256_setzero_si256());
 }
 
 static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_mask_shldv_epi32(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B)
+_mm_shldv_epi32(__m128i __A, __m128i __B, __m128i __C)
 {
-  return (__m128i) __builtin_ia32_vpshldvd128_mask ((__v4si) __S,
-              (__v4si) __A,
-              (__v4si) __B,
-              __U);
+  return (__m128i)__builtin_ia32_vpshldvd128((__v4si)__A, (__v4si)__B,
+                                             (__v4si)__C);
 }
 
 static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_maskz_shldv_epi32(__mmask8 __U, __m128i __S, __m128i __A, __m128i __B)
+_mm_mask_shldv_epi32(__m128i __A, __mmask8 __U, __m128i __B, __m128i __C)
 {
-  return (__m128i) __builtin_ia32_vpshldvd128_maskz ((__v4si) __S,
-              (__v4si) __A,
-              (__v4si) __B,
-              __U);
+  return (__m128i)__builtin_ia32_selectd_128(__U,
+                                         (__v4si)_mm_shldv_epi32(__A, __B, __C),
+                                         (__v4si)__A);
 }
 
 static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_shldv_epi32(__m128i __S, __m128i __A, __m128i __B)
+_mm_maskz_shldv_epi32(__mmask8 __U, __m128i __A, __m128i __B, __m128i __C)
 {
-  return (__m128i) __builtin_ia32_vpshldvd128_mask ((__v4si) __S,
-              (__v4si) __A,
-              (__v4si) __B,
-              (__mmask8) -1);
+  return (__m128i)__builtin_ia32_selectd_128(__U,
+                                         (__v4si)_mm_shldv_epi32(__A, __B, __C),
+                                         (__v4si)_mm_setzero_si128());
 }
 
 static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_mask_shldv_epi16(__m256i __S, __mmask16 __U, __m256i __A, __m256i __B)
+_mm256_shldv_epi16(__m256i __A, __m256i __B, __m256i __C)
 {
-  return (__m256i) __builtin_ia32_vpshldvw256_mask ((__v16hi) __S,
-              (__v16hi) __A,
-              (__v16hi) __B,
-              __U);
+  return (__m256i)__builtin_ia32_vpshldvw256((__v16hi)__A, (__v16hi)__B,
+                                             (__v16hi)__C);
 }
 
 static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_maskz_shldv_epi16(__mmask16 __U, __m256i __S, __m256i __A, __m256i __B)
+_mm256_mask_shldv_epi16(__m256i __A, __mmask16 __U, __m256i __B, __m256i __C)
 {
-  return (__m256i) __builtin_ia32_vpshldvw256_maskz ((__v16hi) __S,
-              (__v16hi) __A,
-              (__v16hi) __B,
-              __U);
+  return (__m256i)__builtin_ia32_selectw_256(__U,
+                                      (__v16hi)_mm256_shldv_epi16(__A, __B, __C),
+                                      (__v16hi)__A);
 }
 
 static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_shldv_epi16(__m256i __S, __m256i __A, __m256i __B)
+_mm256_maskz_shldv_epi16(__mmask16 __U, __m256i __A, __m256i __B, __m256i __C)
 {
-  return (__m256i) __builtin_ia32_vpshldvw256_mask ((__v16hi) __S,
-              (__v16hi) __A,
-              (__v16hi) __B,
-              (__mmask16) -1);
+  return (__m256i)__builtin_ia32_selectw_256(__U,
+                                      (__v16hi)_mm256_shldv_epi16(__A, __B, __C),
+                                      (__v16hi)_mm256_setzero_si256());
 }
 
 static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_mask_shldv_epi16(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B)
+_mm_shldv_epi16(__m128i __A, __m128i __B, __m128i __C)
 {
-  return (__m128i) __builtin_ia32_vpshldvw128_mask ((__v8hi) __S,
-              (__v8hi) __A,
-              (__v8hi) __B,
-              __U);
+  return (__m128i)__builtin_ia32_vpshldvw128((__v8hi)__A, (__v8hi)__B,
+                                             (__v8hi)__C);
 }
 
 static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_maskz_shldv_epi16(__mmask8 __U, __m128i __S, __m128i __A, __m128i __B)
+_mm_mask_shldv_epi16(__m128i __A, __mmask8 __U, __m128i __B, __m128i __C)
 {
-  return (__m128i) __builtin_ia32_vpshldvw128_maskz ((__v8hi) __S,
-              (__v8hi) __A,
-              (__v8hi) __B,
-              __U);
+  return (__m128i)__builtin_ia32_selectw_128(__U,
+                                         (__v8hi)_mm_shldv_epi16(__A, __B, __C),
+                                         (__v8hi)__A);
 }
 
 static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_shldv_epi16(__m128i __S, __m128i __A, __m128i __B)
+_mm_maskz_shldv_epi16(__mmask8 __U, __m128i __A, __m128i __B, __m128i __C)
 {
-  return (__m128i) __builtin_ia32_vpshldvw128_mask ((__v8hi) __S,
-              (__v8hi) __A,
-              (__v8hi) __B,
-              (__mmask8) -1);
+  return (__m128i)__builtin_ia32_selectw_128(__U,
+                                         (__v8hi)_mm_shldv_epi16(__A, __B, __C),
+                                         (__v8hi)_mm_setzero_si128());
 }
 
 static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_mask_shrdv_epi64(__m256i __S, __mmask8 __U, __m256i __A, __m256i __B)
+_mm256_shrdv_epi64(__m256i __A, __m256i __B, __m256i __C)
 {
-  return (__m256i) __builtin_ia32_vpshrdvq256_mask ((__v4di) __S,
-              (__v4di) __A,
-              (__v4di) __B,
-              __U);
+  return (__m256i)__builtin_ia32_vpshrdvq256((__v4di)__A, (__v4di)__B,
+                                             (__v4di)__C);
 }
 
 static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_maskz_shrdv_epi64(__mmask8 __U, __m256i __S, __m256i __A, __m256i __B)
+_mm256_mask_shrdv_epi64(__m256i __A, __mmask8 __U, __m256i __B, __m256i __C)
 {
-  return (__m256i) __builtin_ia32_vpshrdvq256_maskz ((__v4di) __S,
-              (__v4di) __A,
-              (__v4di) __B,
-              __U);
+  return (__m256i)__builtin_ia32_selectq_256(__U,
+                                      (__v4di)_mm256_shrdv_epi64(__A, __B, __C),
+                                      (__v4di)__A);
 }
 
 static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_shrdv_epi64(__m256i __S, __m256i __A, __m256i __B)
+_mm256_maskz_shrdv_epi64(__mmask8 __U, __m256i __A, __m256i __B, __m256i __C)
 {
-  return (__m256i) __builtin_ia32_vpshrdvq256_mask ((__v4di) __S,
-              (__v4di) __A,
-              (__v4di) __B,
-              (__mmask8) -1);
+  return (__m256i)__builtin_ia32_selectq_256(__U,
+                                      (__v4di)_mm256_shrdv_epi64(__A, __B, __C),
+                                      (__v4di)_mm256_setzero_si256());
 }
 
 static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_mask_shrdv_epi64(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B)
+_mm_shrdv_epi64(__m128i __A, __m128i __B, __m128i __C)
 {
-  return (__m128i) __builtin_ia32_vpshrdvq128_mask ((__v2di) __S,
-              (__v2di) __A,
-              (__v2di) __B,
-              __U);
+  return (__m128i)__builtin_ia32_vpshrdvq128((__v2di)__A, (__v2di)__B,
+                                             (__v2di)__C);
 }
 
 static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_maskz_shrdv_epi64(__mmask8 __U, __m128i __S, __m128i __A, __m128i __B)
+_mm_mask_shrdv_epi64(__m128i __A, __mmask8 __U, __m128i __B, __m128i __C)
 {
-  return (__m128i) __builtin_ia32_vpshrdvq128_maskz ((__v2di) __S,
-              (__v2di) __A,
-              (__v2di) __B,
-              __U);
+  return (__m128i)__builtin_ia32_selectq_128(__U,
+                                         (__v2di)_mm_shrdv_epi64(__A, __B, __C),
+                                         (__v2di)__A);
 }
 
 static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_shrdv_epi64(__m128i __S, __m128i __A, __m128i __B)
+_mm_maskz_shrdv_epi64(__mmask8 __U, __m128i __A, __m128i __B, __m128i __C)
 {
-  return (__m128i) __builtin_ia32_vpshrdvq128_mask ((__v2di) __S,
-              (__v2di) __A,
-              (__v2di) __B,
-              (__mmask8) -1);
+  return (__m128i)__builtin_ia32_selectq_128(__U,
+                                         (__v2di)_mm_shrdv_epi64(__A, __B, __C),
+                                         (__v2di)_mm_setzero_si128());
 }
 
 static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_mask_shrdv_epi32(__m256i __S, __mmask8 __U, __m256i __A, __m256i __B)
+_mm256_shrdv_epi32(__m256i __A, __m256i __B, __m256i __C)
 {
-  return (__m256i) __builtin_ia32_vpshrdvd256_mask ((__v8si) __S,
-              (__v8si) __A,
-              (__v8si) __B,
-              __U);
+  return (__m256i)__builtin_ia32_vpshrdvd256((__v8si)__A, (__v8si)__B,
+                                             (__v8si)__C);
 }
 
 static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_maskz_shrdv_epi32(__mmask8 __U, __m256i __S, __m256i __A, __m256i __B)
+_mm256_mask_shrdv_epi32(__m256i __A, __mmask8 __U, __m256i __B, __m256i __C)
 {
-  return (__m256i) __builtin_ia32_vpshrdvd256_maskz ((__v8si) __S,
-              (__v8si) __A,
-              (__v8si) __B,
-              __U);
+  return (__m256i)__builtin_ia32_selectd_256(__U,
+                                      (__v8si)_mm256_shrdv_epi32(__A, __B, __C),
+                                      (__v8si)__A);
 }
 
 static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_shrdv_epi32(__m256i __S, __m256i __A, __m256i __B)
+_mm256_maskz_shrdv_epi32(__mmask8 __U, __m256i __A, __m256i __B, __m256i __C)
 {
-  return (__m256i) __builtin_ia32_vpshrdvd256_mask ((__v8si) __S,
-              (__v8si) __A,
-              (__v8si) __B,
-              (__mmask8) -1);
+  return (__m256i)__builtin_ia32_selectd_256(__U,
+                                      (__v8si)_mm256_shrdv_epi32(__A, __B, __C),
+                                      (__v8si)_mm256_setzero_si256());
 }
 
 static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_mask_shrdv_epi32(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B)
+_mm_shrdv_epi32(__m128i __A, __m128i __B, __m128i __C)
 {
-  return (__m128i) __builtin_ia32_vpshrdvd128_mask ((__v4si) __S,
-              (__v4si) __A,
-              (__v4si) __B,
-              __U);
+  return (__m128i)__builtin_ia32_vpshrdvd128((__v4si)__A, (__v4si)__B,
+                                             (__v4si)__C);
 }
 
 static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_maskz_shrdv_epi32(__mmask8 __U, __m128i __S, __m128i __A, __m128i __B)
+_mm_mask_shrdv_epi32(__m128i __A, __mmask8 __U, __m128i __B, __m128i __C)
 {
-  return (__m128i) __builtin_ia32_vpshrdvd128_maskz ((__v4si) __S,
-              (__v4si) __A,
-              (__v4si) __B,
-              __U);
+  return (__m128i)__builtin_ia32_selectd_128(__U,
+                                         (__v4si)_mm_shrdv_epi32(__A, __B, __C),
+                                         (__v4si)__A);
 }
 
 static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_shrdv_epi32(__m128i __S, __m128i __A, __m128i __B)
+_mm_maskz_shrdv_epi32(__mmask8 __U, __m128i __A, __m128i __B, __m128i __C)
 {
-  return (__m128i) __builtin_ia32_vpshrdvd128_mask ((__v4si) __S,
-              (__v4si) __A,
-              (__v4si) __B,
-              (__mmask8) -1);
+  return (__m128i)__builtin_ia32_selectd_128(__U,
+                                         (__v4si)_mm_shrdv_epi32(__A, __B, __C),
+                                         (__v4si)_mm_setzero_si128());
 }
 
 static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_mask_shrdv_epi16(__m256i __S, __mmask16 __U, __m256i __A, __m256i __B)
+_mm256_shrdv_epi16(__m256i __A, __m256i __B, __m256i __C)
 {
-  return (__m256i) __builtin_ia32_vpshrdvw256_mask ((__v16hi) __S,
-              (__v16hi) __A,
-              (__v16hi) __B,
-              __U);
+  return (__m256i)__builtin_ia32_vpshrdvw256((__v16hi)__A, (__v16hi)__B,
+                                             (__v16hi)__C);
 }
 
 static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_maskz_shrdv_epi16(__mmask16 __U, __m256i __S, __m256i __A, __m256i __B)
+_mm256_mask_shrdv_epi16(__m256i __A, __mmask16 __U, __m256i __B, __m256i __C)
 {
-  return (__m256i) __builtin_ia32_vpshrdvw256_maskz ((__v16hi) __S,
-              (__v16hi) __A,
-              (__v16hi) __B,
-              __U);
+  return (__m256i)__builtin_ia32_selectw_256(__U,
+                                     (__v16hi)_mm256_shrdv_epi16(__A, __B, __C),
+                                     (__v16hi)__A);
 }
 
 static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_shrdv_epi16(__m256i __S, __m256i __A, __m256i __B)
+_mm256_maskz_shrdv_epi16(__mmask16 __U, __m256i __A, __m256i __B, __m256i __C)
 {
-  return (__m256i) __builtin_ia32_vpshrdvw256_mask ((__v16hi) __S,
-              (__v16hi) __A,
-              (__v16hi) __B,
-              (__mmask16) -1);
+  return (__m256i)__builtin_ia32_selectw_256(__U,
+                                     (__v16hi)_mm256_shrdv_epi16(__A, __B, __C),
+                                     (__v16hi)_mm256_setzero_si256());
 }
 
 static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_mask_shrdv_epi16(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B)
+_mm_shrdv_epi16(__m128i __A, __m128i __B, __m128i __C)
 {
-  return (__m128i) __builtin_ia32_vpshrdvw128_mask ((__v8hi) __S,
-              (__v8hi) __A,
-              (__v8hi) __B,
-              __U);
+  return (__m128i)__builtin_ia32_vpshrdvw128((__v8hi)__A, (__v8hi)__B,
+                                             (__v8hi)__C);
 }
 
 static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_maskz_shrdv_epi16(__mmask8 __U, __m128i __S, __m128i __A, __m128i __B)
+_mm_mask_shrdv_epi16(__m128i __A, __mmask8 __U, __m128i __B, __m128i __C)
 {
-  return (__m128i) __builtin_ia32_vpshrdvw128_maskz ((__v8hi) __S,
-              (__v8hi) __A,
-              (__v8hi) __B,
-              __U);
+  return (__m128i)__builtin_ia32_selectw_128(__U,
+                                         (__v8hi)_mm_shrdv_epi16(__A, __B, __C),
+                                         (__v8hi)__A);
 }
 
 static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_shrdv_epi16(__m128i __S, __m128i __A, __m128i __B)
+_mm_maskz_shrdv_epi16(__mmask8 __U, __m128i __A, __m128i __B, __m128i __C)
 {
-  return (__m128i) __builtin_ia32_vpshrdvw128_mask ((__v8hi) __S,
-              (__v8hi) __A,
-              (__v8hi) __B,
-              (__mmask8) -1);
+  return (__m128i)__builtin_ia32_selectw_128(__U,
+                                         (__v8hi)_mm_shrdv_epi16(__A, __B, __C),
+                                         (__v8hi)_mm_setzero_si128());
 }
 
 
diff --git a/test/CodeGen/avx512vbmi2-builtins.c b/test/CodeGen/avx512vbmi2-builtins.c
index a29203027d..304561d9fa 100644
--- a/test/CodeGen/avx512vbmi2-builtins.c
+++ b/test/CodeGen/avx512vbmi2-builtins.c
@@ -88,229 +88,241 @@ __m512i test_mm512_maskz_expandloadu_epi8(__mmask64 __U, void const* __P) {
 
 __m512i test_mm512_mask_shldi_epi64(__m512i __S, __mmask8 __U, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_mask_shldi_epi64
-  // CHECK: @llvm.x86.avx512.vpshld.q.512
+  // CHECK: @llvm.fshl.v8i64(<8 x i64> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> )
   // CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}}
   return _mm512_mask_shldi_epi64(__S, __U, __A, __B, 47);
 }
 
 __m512i test_mm512_maskz_shldi_epi64(__mmask8 __U, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_maskz_shldi_epi64
-  // CHECK: @llvm.x86.avx512.vpshld.q.512
+  // CHECK: @llvm.fshl.v8i64(<8 x i64> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> )
   // CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}}
   return _mm512_maskz_shldi_epi64(__U, __A, __B, 63);
 }
 
 __m512i test_mm512_shldi_epi64(__m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_shldi_epi64
-  // CHECK: @llvm.x86.avx512.vpshld.q.512
+  // CHECK: @llvm.fshl.v8i64(<8 x i64> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> )
   return _mm512_shldi_epi64(__A, __B, 31);
 }
 
 __m512i test_mm512_mask_shldi_epi32(__m512i __S, __mmask16 __U, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_mask_shldi_epi32
-  // CHECK: @llvm.x86.avx512.vpshld.d.512
+  // CHECK: @llvm.fshl.v16i32(<16 x i32> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> )
   // CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}}
   return _mm512_mask_shldi_epi32(__S, __U, __A, __B, 7);
 }
 
 __m512i test_mm512_maskz_shldi_epi32(__mmask16 __U, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_maskz_shldi_epi32
-  // CHECK: @llvm.x86.avx512.vpshld.d.512
+  // CHECK: @llvm.fshl.v16i32(<16 x i32> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> )
   // CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}}
   return _mm512_maskz_shldi_epi32(__U, __A, __B, 15);
 }
 
 __m512i test_mm512_shldi_epi32(__m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_shldi_epi32
-  // CHECK: @llvm.x86.avx512.vpshld.d.512
+  // CHECK: @llvm.fshl.v16i32(<16 x i32> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> )
   return _mm512_shldi_epi32(__A, __B, 31);
 }
 
 __m512i test_mm512_mask_shldi_epi16(__m512i __S, __mmask32 __U, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_mask_shldi_epi16
-  // CHECK: @llvm.x86.avx512.vpshld.w.512
+  // CHECK: @llvm.fshl.v32i16(<32 x i16> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> )
   // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}}
   return _mm512_mask_shldi_epi16(__S, __U, __A, __B, 3);
 }
 
 __m512i test_mm512_maskz_shldi_epi16(__mmask32 __U, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_maskz_shldi_epi16
-  // CHECK: @llvm.x86.avx512.vpshld.w.512
+  // CHECK: @llvm.fshl.v32i16(<32 x i16> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> )
   // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}}
   return _mm512_maskz_shldi_epi16(__U, __A, __B, 7);
 }
 
 __m512i test_mm512_shldi_epi16(__m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_shldi_epi16
-  // CHECK: @llvm.x86.avx512.vpshld.w.512
+  // CHECK: @llvm.fshl.v32i16(<32 x i16> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> )
   return _mm512_shldi_epi16(__A, __B, 15);
 }
 
 __m512i test_mm512_mask_shrdi_epi64(__m512i __S, __mmask8 __U, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_mask_shrdi_epi64
-  // CHECK: @llvm.x86.avx512.vpshrd.q.512
+  // CHECK: @llvm.fshr.v8i64(<8 x i64> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> )
   // CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}}
   return _mm512_mask_shrdi_epi64(__S, __U, __A, __B, 47);
 }
 
 __m512i test_mm512_maskz_shrdi_epi64(__mmask8 __U, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_maskz_shrdi_epi64
-  // CHECK: @llvm.x86.avx512.vpshrd.q.512
+  // CHECK: @llvm.fshr.v8i64(<8 x i64> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> )
   // CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}}
   return _mm512_maskz_shrdi_epi64(__U, __A, __B, 63);
 }
 
 __m512i test_mm512_shrdi_epi64(__m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_shrdi_epi64
-  // CHECK: @llvm.x86.avx512.vpshrd.q.512
+  // CHECK: @llvm.fshr.v8i64(<8 x i64> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> )
   return _mm512_shrdi_epi64(__A, __B, 31);
 }
 
 __m512i test_mm512_mask_shrdi_epi32(__m512i __S, __mmask16 __U, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_mask_shrdi_epi32
-  // CHECK: @llvm.x86.avx512.vpshrd.d.512
+  // CHECK: @llvm.fshr.v16i32(<16 x i32> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> )
   // CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}}
   return _mm512_mask_shrdi_epi32(__S, __U, __A, __B, 7);
 }
 
 __m512i test_mm512_maskz_shrdi_epi32(__mmask16 __U, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_maskz_shrdi_epi32
-  // CHECK: @llvm.x86.avx512.vpshrd.d.512
+  // CHECK: @llvm.fshr.v16i32(<16 x i32> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> )
   // CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}}
   return _mm512_maskz_shrdi_epi32(__U, __A, __B, 15);
 }
 
 __m512i test_mm512_shrdi_epi32(__m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_shrdi_epi32
-  // CHECK: @llvm.x86.avx512.vpshrd.d.512
+  // CHECK: @llvm.fshr.v16i32(<16 x i32> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> )
   return _mm512_shrdi_epi32(__A, __B, 31);
 }
 
 __m512i test_mm512_mask_shrdi_epi16(__m512i __S, __mmask32 __U, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_mask_shrdi_epi16
-  // CHECK: @llvm.x86.avx512.vpshrd.w.512
+  // CHECK: @llvm.fshr.v32i16(<32 x i16> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> )
   // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}}
   return _mm512_mask_shrdi_epi16(__S, __U, __A, __B, 3);
 }
 
 __m512i test_mm512_maskz_shrdi_epi16(__mmask32 __U, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_maskz_shrdi_epi16
-  // CHECK: @llvm.x86.avx512.vpshrd.w.512
+  // CHECK: @llvm.fshr.v32i16(<32 x i16> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> )
   // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}}
   return _mm512_maskz_shrdi_epi16(__U, __A, __B, 15);
 }
 
 __m512i test_mm512_shrdi_epi16(__m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_shrdi_epi16
-  // CHECK: @llvm.x86.avx512.vpshrd.w.512
+  // CHECK: @llvm.fshr.v32i16(<32 x i16> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> )
   return _mm512_shrdi_epi16(__A, __B, 31);
 }
 
 __m512i test_mm512_mask_shldv_epi64(__m512i __S, __mmask8 __U, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_mask_shldv_epi64
-  // CHECK: @llvm.x86.avx512.mask.vpshldv.q.512
+  // CHECK: @llvm.fshl.v8i64(<8 x i64> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}})
+  // CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}}
   return _mm512_mask_shldv_epi64(__S, __U, __A, __B);
 }
 
 __m512i test_mm512_maskz_shldv_epi64(__mmask8 __U, __m512i __S, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_maskz_shldv_epi64
-  // CHECK: @llvm.x86.avx512.maskz.vpshldv.q.512
+  // CHECK: @llvm.fshl.v8i64(<8 x i64> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}})
+  // CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}}
   return _mm512_maskz_shldv_epi64(__U, __S, __A, __B);
 }
 
 __m512i test_mm512_shldv_epi64(__m512i __S, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_shldv_epi64
-  // CHECK: @llvm.x86.avx512.mask.vpshldv.q.512
+  // CHECK: @llvm.fshl.v8i64(<8 x i64> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}})
   return _mm512_shldv_epi64(__S, __A, __B);
 }
 
 __m512i test_mm512_mask_shldv_epi32(__m512i __S, __mmask16 __U, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_mask_shldv_epi32
-  // CHECK: @llvm.x86.avx512.mask.vpshldv.d.512
+  // CHECK: @llvm.fshl.v16i32(<16 x i32> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}})
+  // CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}}
   return _mm512_mask_shldv_epi32(__S, __U, __A, __B);
 }
 
 __m512i test_mm512_maskz_shldv_epi32(__mmask16 __U, __m512i __S, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_maskz_shldv_epi32
-  // CHECK: @llvm.x86.avx512.maskz.vpshldv.d.512
+  // CHECK: @llvm.fshl.v16i32(<16 x i32> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}})
+  // CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}}
   return _mm512_maskz_shldv_epi32(__U, __S, __A, __B);
 }
 
 __m512i test_mm512_shldv_epi32(__m512i __S, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_shldv_epi32
-  // CHECK: @llvm.x86.avx512.mask.vpshldv.d.512
+  // CHECK: @llvm.fshl.v16i32(<16 x i32> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}})
   return _mm512_shldv_epi32(__S, __A, __B);
 }
 
 __m512i test_mm512_mask_shldv_epi16(__m512i __S, __mmask32 __U, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_mask_shldv_epi16
-  // CHECK: @llvm.x86.avx512.mask.vpshldv.w.512
+  // CHECK: @llvm.fshl.v32i16(<32 x i16> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}})
+  // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}}
   return _mm512_mask_shldv_epi16(__S, __U, __A, __B);
 }
 
 __m512i test_mm512_maskz_shldv_epi16(__mmask32 __U, __m512i __S, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_maskz_shldv_epi16
-  // CHECK: @llvm.x86.avx512.maskz.vpshldv.w.512
+  // CHECK: @llvm.fshl.v32i16(<32 x i16> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}})
+  // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}}
   return _mm512_maskz_shldv_epi16(__U, __S, __A, __B);
 }
 
 __m512i test_mm512_shldv_epi16(__m512i __S, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_shldv_epi16
-  // CHECK: @llvm.x86.avx512.mask.vpshldv.w.512
+  // CHECK: @llvm.fshl.v32i16(<32 x i16> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}})
   return _mm512_shldv_epi16(__S, __A, __B);
 }
 
 __m512i test_mm512_mask_shrdv_epi64(__m512i __S, __mmask8 __U, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_mask_shrdv_epi64
-  // CHECK: @llvm.x86.avx512.mask.vpshrdv.q.512
+  // CHECK: @llvm.fshr.v8i64(<8 x i64> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}})
+  // CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}}
   return _mm512_mask_shrdv_epi64(__S, __U, __A, __B);
 }
 
 __m512i test_mm512_maskz_shrdv_epi64(__mmask8 __U, __m512i __S, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_maskz_shrdv_epi64
-  // CHECK: @llvm.x86.avx512.maskz.vpshrdv.q.512
+  // CHECK: @llvm.fshr.v8i64(<8 x i64> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}})
+  // CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}}
   return _mm512_maskz_shrdv_epi64(__U, __S, __A, __B);
 }
 
 __m512i test_mm512_shrdv_epi64(__m512i __S, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_shrdv_epi64
-  // CHECK: @llvm.x86.avx512.mask.vpshrdv.q.512
+  // CHECK: @llvm.fshr.v8i64(<8 x i64> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}})
   return _mm512_shrdv_epi64(__S, __A, __B);
 }
 
 __m512i test_mm512_mask_shrdv_epi32(__m512i __S, __mmask16 __U, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_mask_shrdv_epi32
-  // CHECK: @llvm.x86.avx512.mask.vpshrdv.d.512
+  // CHECK: @llvm.fshr.v16i32(<16 x i32> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}})
+  // CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}}
   return _mm512_mask_shrdv_epi32(__S, __U, __A, __B);
 }
 
 __m512i test_mm512_maskz_shrdv_epi32(__mmask16 __U, __m512i __S, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_maskz_shrdv_epi32
-  // CHECK: @llvm.x86.avx512.maskz.vpshrdv.d.512
+  // CHECK: @llvm.fshr.v16i32(<16 x i32> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}})
+  // CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}}
   return _mm512_maskz_shrdv_epi32(__U, __S, __A, __B);
 }
 
 __m512i test_mm512_shrdv_epi32(__m512i __S, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_shrdv_epi32
-  // CHECK: @llvm.x86.avx512.mask.vpshrdv.d.512
+  // CHECK: @llvm.fshr.v16i32(<16 x i32> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}})
   return _mm512_shrdv_epi32(__S, __A, __B);
 }
 
 __m512i test_mm512_mask_shrdv_epi16(__m512i __S, __mmask32 __U, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_mask_shrdv_epi16
-  // CHECK: @llvm.x86.avx512.mask.vpshrdv.w.512
+  // CHECK: @llvm.fshr.v32i16(<32 x i16> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}})
+  // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}}
   return _mm512_mask_shrdv_epi16(__S, __U, __A, __B);
 }
 
 __m512i test_mm512_maskz_shrdv_epi16(__mmask32 __U, __m512i __S, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_maskz_shrdv_epi16
-  // CHECK: @llvm.x86.avx512.maskz.vpshrdv.w.512
+  // CHECK: @llvm.fshr.v32i16(<32 x i16> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}})
+  // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}}
   return _mm512_maskz_shrdv_epi16(__U, __S, __A, __B);
 }
 
 __m512i test_mm512_shrdv_epi16(__m512i __S, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_shrdv_epi16
-  // CHECK: @llvm.x86.avx512.mask.vpshrdv.w.512
+  // CHECK: @llvm.fshr.v32i16(<32 x i16> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}})
   return _mm512_shrdv_epi16(__S, __A, __B);
 }
 
diff --git a/test/CodeGen/avx512vlvbmi2-builtins.c b/test/CodeGen/avx512vlvbmi2-builtins.c
index 53b58400bc..b512a728a5 100644
--- a/test/CodeGen/avx512vlvbmi2-builtins.c
+++ b/test/CodeGen/avx512vlvbmi2-builtins.c
@@ -172,457 +172,481 @@ __m256i test_mm256_maskz_expandloadu_epi8(__mmask32 __U, void const* __P) {
 
 __m256i test_mm256_mask_shldi_epi64(__m256i __S, __mmask8 __U, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_mask_shldi_epi64
-  // CHECK: @llvm.x86.avx512.vpshld.q.256
+  // CHECK: @llvm.fshl.v4i64(<4 x i64> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> )
   // CHECK: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}}
   return _mm256_mask_shldi_epi64(__S, __U, __A, __B, 47);
 }
 
 __m256i test_mm256_maskz_shldi_epi64(__mmask8 __U, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_maskz_shldi_epi64
-  // CHECK: @llvm.x86.avx512.vpshld.q.256
+  // CHECK: @llvm.fshl.v4i64(<4 x i64> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> )
   // CHECK: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}}
   return _mm256_maskz_shldi_epi64(__U, __A, __B, 63);
 }
 
 __m256i test_mm256_shldi_epi64(__m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_shldi_epi64
-  // CHECK: @llvm.x86.avx512.vpshld.q.256
+  // CHECK: @llvm.fshl.v4i64(<4 x i64> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> )
   return _mm256_shldi_epi64(__A, __B, 31);
 }
 
 __m128i test_mm_mask_shldi_epi64(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_mask_shldi_epi64
-  // CHECK: @llvm.x86.avx512.vpshld.q.128
+  // CHECK: @llvm.fshl.v2i64(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> )
   // CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}}
   return _mm_mask_shldi_epi64(__S, __U, __A, __B, 47);
 }
 
 __m128i test_mm_maskz_shldi_epi64(__mmask8 __U, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_maskz_shldi_epi64
-  // CHECK: @llvm.x86.avx512.vpshld.q.128
+  // CHECK: @llvm.fshl.v2i64(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> )
   // CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}}
   return _mm_maskz_shldi_epi64(__U, __A, __B, 63);
 }
 
 __m128i test_mm_shldi_epi64(__m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_shldi_epi64
-  // CHECK: @llvm.x86.avx512.vpshld.q.128
+  // CHECK: @llvm.fshl.v2i64(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> )
   return _mm_shldi_epi64(__A, __B, 31);
 }
 
 __m256i test_mm256_mask_shldi_epi32(__m256i __S, __mmask8 __U, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_mask_shldi_epi32
-  // CHECK: @llvm.x86.avx512.vpshld.d.256
+  // CHECK: @llvm.fshl.v8i32(<8 x i32> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> )
   // CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}}
   return _mm256_mask_shldi_epi32(__S, __U, __A, __B, 7);
 }
 
 __m256i test_mm256_maskz_shldi_epi32(__mmask8 __U, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_maskz_shldi_epi32
-  // CHECK: @llvm.x86.avx512.vpshld.d.256
+  // CHECK: @llvm.fshl.v8i32(<8 x i32> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> )
   // CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}}
   return _mm256_maskz_shldi_epi32(__U, __A, __B, 15);
 }
 
 __m256i test_mm256_shldi_epi32(__m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_shldi_epi32
-  // CHECK: @llvm.x86.avx512.vpshld.d.256
+  // CHECK: @llvm.fshl.v8i32(<8 x i32> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> )
   return _mm256_shldi_epi32(__A, __B, 31);
 }
 
 __m128i test_mm_mask_shldi_epi32(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_mask_shldi_epi32
-  // CHECK: @llvm.x86.avx512.vpshld.d.128
+  // CHECK: @llvm.fshl.v4i32(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> )
   // CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
   return _mm_mask_shldi_epi32(__S, __U, __A, __B, 7);
 }
 
 __m128i test_mm_maskz_shldi_epi32(__mmask8 __U, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_maskz_shldi_epi32
-  // CHECK: @llvm.x86.avx512.vpshld.d.128
+  // CHECK: @llvm.fshl.v4i32(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> )
   // CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
   return _mm_maskz_shldi_epi32(__U, __A, __B, 15);
 }
 
 __m128i test_mm_shldi_epi32(__m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_shldi_epi32
-  // CHECK: @llvm.x86.avx512.vpshld.d.128
+  // CHECK: @llvm.fshl.v4i32(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> )
   return _mm_shldi_epi32(__A, __B, 31);
 }
 
 __m256i test_mm256_mask_shldi_epi16(__m256i __S, __mmask16 __U, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_mask_shldi_epi16
-  // CHECK: @llvm.x86.avx512.vpshld.w.256
+  // CHECK: @llvm.fshl.v16i16(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> )
   // CHECK: select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}}
   return _mm256_mask_shldi_epi16(__S, __U, __A, __B, 3);
 }
 
 __m256i test_mm256_maskz_shldi_epi16(__mmask16 __U, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_maskz_shldi_epi16
-  // CHECK: @llvm.x86.avx512.vpshld.w.256
+  // CHECK: @llvm.fshl.v16i16(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> )
   // CHECK: select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}}
   return _mm256_maskz_shldi_epi16(__U, __A, __B, 7);
 }
 
 __m256i test_mm256_shldi_epi16(__m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_shldi_epi16
-  // CHECK: @llvm.x86.avx512.vpshld.w.256
+  // CHECK: @llvm.fshl.v16i16(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> )
   return _mm256_shldi_epi16(__A, __B, 31);
 }
 
 __m128i test_mm_mask_shldi_epi16(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_mask_shldi_epi16
-  // CHECK: @llvm.x86.avx512.vpshld.w.128
+  // CHECK: @llvm.fshl.v8i16(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> )
   // CHECK: select <8 x i1> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}
   return _mm_mask_shldi_epi16(__S, __U, __A, __B, 3);
 }
 
 __m128i test_mm_maskz_shldi_epi16(__mmask8 __U, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_maskz_shldi_epi16
-  // CHECK: @llvm.x86.avx512.vpshld.w.128
+  // CHECK: @llvm.fshl.v8i16(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> )
   // CHECK: select <8 x i1> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}
   return _mm_maskz_shldi_epi16(__U, __A, __B, 7);
 }
 
 __m128i test_mm_shldi_epi16(__m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_shldi_epi16
-  // CHECK: @llvm.x86.avx512.vpshld.w.128
+  // CHECK: @llvm.fshl.v8i16(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> )
   return _mm_shldi_epi16(__A, __B, 31);
 }
 
 __m256i test_mm256_mask_shrdi_epi64(__m256i __S, __mmask8 __U, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_mask_shrdi_epi64
-  // CHECK: @llvm.x86.avx512.vpshrd.q.256
+  // CHECK: @llvm.fshr.v4i64(<4 x i64> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> )
   // CHECK: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}}
   return _mm256_mask_shrdi_epi64(__S, __U, __A, __B, 47);
 }
 
 __m256i test_mm256_maskz_shrdi_epi64(__mmask8 __U, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_maskz_shrdi_epi64
-  // CHECK: @llvm.x86.avx512.vpshrd.q.256
+  // CHECK: @llvm.fshr.v4i64(<4 x i64> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> )
   // CHECK: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}}
   return _mm256_maskz_shrdi_epi64(__U, __A, __B, 63);
 }
 
 __m256i test_mm256_shrdi_epi64(__m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_shrdi_epi64
-  // CHECK: @llvm.x86.avx512.vpshrd.q.256
+  // CHECK: @llvm.fshr.v4i64(<4 x i64> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> )
   return _mm256_shrdi_epi64(__A, __B, 31);
 }
 
 __m128i test_mm_mask_shrdi_epi64(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_mask_shrdi_epi64
-  // CHECK: @llvm.x86.avx512.vpshrd.q.128
+  // CHECK: @llvm.fshr.v2i64(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> )
   // CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}}
   return _mm_mask_shrdi_epi64(__S, __U, __A, __B, 47);
 }
 
 __m128i test_mm_maskz_shrdi_epi64(__mmask8 __U, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_maskz_shrdi_epi64
-  // CHECK: @llvm.x86.avx512.vpshrd.q.128
+  // CHECK: @llvm.fshr.v2i64(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> )
   // CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}}
   return _mm_maskz_shrdi_epi64(__U, __A, __B, 63);
 }
 
 __m128i test_mm_shrdi_epi64(__m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_shrdi_epi64
-  // CHECK: @llvm.x86.avx512.vpshrd.q.128
+  // CHECK: @llvm.fshr.v2i64(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> )
   return _mm_shrdi_epi64(__A, __B, 31);
 }
 
 __m256i test_mm256_mask_shrdi_epi32(__m256i __S, __mmask8 __U, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_mask_shrdi_epi32
-  // CHECK: @llvm.x86.avx512.vpshrd.d.256
+  // CHECK: @llvm.fshr.v8i32(<8 x i32> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> )
   // CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}}
   return _mm256_mask_shrdi_epi32(__S, __U, __A, __B, 7);
 }
 
 __m256i test_mm256_maskz_shrdi_epi32(__mmask8 __U, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_maskz_shrdi_epi32
-  // CHECK: @llvm.x86.avx512.vpshrd.d.256
+  // CHECK: @llvm.fshr.v8i32(<8 x i32> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> )
   // CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}}
   return _mm256_maskz_shrdi_epi32(__U, __A, __B, 15);
 }
 
 __m256i test_mm256_shrdi_epi32(__m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_shrdi_epi32
-  // CHECK: @llvm.x86.avx512.vpshrd.d.256
+  // CHECK: @llvm.fshr.v8i32(<8 x i32> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> )
   return _mm256_shrdi_epi32(__A, __B, 31);
 }
 
 __m128i test_mm_mask_shrdi_epi32(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_mask_shrdi_epi32
-  // CHECK: @llvm.x86.avx512.vpshrd.d.128
+  // CHECK: @llvm.fshr.v4i32(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> )
   // CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
   return _mm_mask_shrdi_epi32(__S, __U, __A, __B, 7);
 }
 
 __m128i test_mm_maskz_shrdi_epi32(__mmask8 __U, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_maskz_shrdi_epi32
-  // CHECK: @llvm.x86.avx512.vpshrd.d.128
+  // CHECK: @llvm.fshr.v4i32(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> )
   // CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
   return _mm_maskz_shrdi_epi32(__U, __A, __B, 15);
 }
 
 __m128i test_mm_shrdi_epi32(__m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_shrdi_epi32
-  // CHECK: @llvm.x86.avx512.vpshrd.d.128
+  // CHECK: @llvm.fshr.v4i32(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> )
   return _mm_shrdi_epi32(__A, __B, 31);
 }
 
 __m256i test_mm256_mask_shrdi_epi16(__m256i __S, __mmask16 __U, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_mask_shrdi_epi16
-  // CHECK: @llvm.x86.avx512.vpshrd.w.256
+  // CHECK: @llvm.fshr.v16i16(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> )
   // CHECK: select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}}
   return _mm256_mask_shrdi_epi16(__S, __U, __A, __B, 3);
 }
 
 __m256i test_mm256_maskz_shrdi_epi16(__mmask16 __U, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_maskz_shrdi_epi16
-  // CHECK: @llvm.x86.avx512.vpshrd.w.256
+  // CHECK: @llvm.fshr.v16i16(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> )
   // CHECK: select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}}
   return _mm256_maskz_shrdi_epi16(__U, __A, __B, 7);
 }
 
 __m256i test_mm256_shrdi_epi16(__m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_shrdi_epi16
-  // CHECK: @llvm.x86.avx512.vpshrd.w.256
+  // CHECK: @llvm.fshr.v16i16(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> 
   return _mm256_shrdi_epi16(__A, __B, 31);
 }
 
 __m128i test_mm_mask_shrdi_epi16(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_mask_shrdi_epi16
-  // CHECK: @llvm.x86.avx512.vpshrd.w.128
+  // CHECK: @llvm.fshr.v8i16(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> )
   // CHECK: select <8 x i1> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}
   return _mm_mask_shrdi_epi16(__S, __U, __A, __B, 3);
 }
 
 __m128i test_mm_maskz_shrdi_epi16(__mmask8 __U, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_maskz_shrdi_epi16
-  // CHECK: @llvm.x86.avx512.vpshrd.w.128
+  // CHECK: @llvm.fshr.v8i16(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> )
   // CHECK: select <8 x i1> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}
   return _mm_maskz_shrdi_epi16(__U, __A, __B, 7);
 }
 
 __m128i test_mm_shrdi_epi16(__m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_shrdi_epi16
-  // CHECK: @llvm.x86.avx512.vpshrd.w.128
+  // CHECK: @llvm.fshr.v8i16(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> )
   return _mm_shrdi_epi16(__A, __B, 31);
 }
 
 __m256i test_mm256_mask_shldv_epi64(__m256i __S, __mmask8 __U, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_mask_shldv_epi64
-  // CHECK: @llvm.x86.avx512.mask.vpshldv.q.256
+  // CHECK: @llvm.fshl.v4i64(<4 x i64> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}})
+  // CHECK: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}}
   return _mm256_mask_shldv_epi64(__S, __U, __A, __B);
 }
 
 __m256i test_mm256_maskz_shldv_epi64(__mmask8 __U, __m256i __S, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_maskz_shldv_epi64
-  // CHECK: @llvm.x86.avx512.maskz.vpshldv.q.256
+  // CHECK: @llvm.fshl.v4i64(<4 x i64> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}})
+  // CHECK: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}}
   return _mm256_maskz_shldv_epi64(__U, __S, __A, __B);
 }
 
 __m256i test_mm256_shldv_epi64(__m256i __S, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_shldv_epi64
-  // CHECK: @llvm.x86.avx512.mask.vpshldv.q.256
+  // CHECK: @llvm.fshl.v4i64(<4 x i64> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}})
   return _mm256_shldv_epi64(__S, __A, __B);
 }
 
 __m128i test_mm_mask_shldv_epi64(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_mask_shldv_epi64
-  // CHECK: @llvm.x86.avx512.mask.vpshldv.q.128
+  // CHECK: @llvm.fshl.v2i64(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}})
+  // CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}}
   return _mm_mask_shldv_epi64(__S, __U, __A, __B);
 }
 
 __m128i test_mm_maskz_shldv_epi64(__mmask8 __U, __m128i __S, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_maskz_shldv_epi64
-  // CHECK: @llvm.x86.avx512.maskz.vpshldv.q.128
+  // CHECK: @llvm.fshl.v2i64(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}})
+  // CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}}
   return _mm_maskz_shldv_epi64(__U, __S, __A, __B);
 }
 
 __m128i test_mm_shldv_epi64(__m128i __S, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_shldv_epi64
-  // CHECK: @llvm.x86.avx512.mask.vpshldv.q.128
+  // CHECK: @llvm.fshl.v2i64(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}})
   return _mm_shldv_epi64(__S, __A, __B);
 }
 
 __m256i test_mm256_mask_shldv_epi32(__m256i __S, __mmask8 __U, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_mask_shldv_epi32
-  // CHECK: @llvm.x86.avx512.mask.vpshldv.d.256
+  // CHECK: @llvm.fshl.v8i32(<8 x i32> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}})
+  // CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}}
   return _mm256_mask_shldv_epi32(__S, __U, __A, __B);
 }
 
 __m256i test_mm256_maskz_shldv_epi32(__mmask8 __U, __m256i __S, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_maskz_shldv_epi32
-  // CHECK: @llvm.x86.avx512.maskz.vpshldv.d.256
+  // CHECK: @llvm.fshl.v8i32(<8 x i32> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}})
+  // CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}}
   return _mm256_maskz_shldv_epi32(__U, __S, __A, __B);
 }
 
 __m256i test_mm256_shldv_epi32(__m256i __S, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_shldv_epi32
-  // CHECK: @llvm.x86.avx512.mask.vpshldv.d.256
+  // CHECK: @llvm.fshl.v8i32(<8 x i32> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}})
   return _mm256_shldv_epi32(__S, __A, __B);
 }
 
 __m128i test_mm_mask_shldv_epi32(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_mask_shldv_epi32
-  // CHECK: @llvm.x86.avx512.mask.vpshldv.d.128
+  // CHECK: @llvm.fshl.v4i32(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}})
+  // CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
   return _mm_mask_shldv_epi32(__S, __U, __A, __B);
 }
 
 __m128i test_mm_maskz_shldv_epi32(__mmask8 __U, __m128i __S, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_maskz_shldv_epi32
-  // CHECK: @llvm.x86.avx512.maskz.vpshldv.d.128
+  // CHECK: @llvm.fshl.v4i32(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}})
+  // CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
   return _mm_maskz_shldv_epi32(__U, __S, __A, __B);
 }
 
 __m128i test_mm_shldv_epi32(__m128i __S, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_shldv_epi32
-  // CHECK: @llvm.x86.avx512.mask.vpshldv.d.128
+  // CHECK: @llvm.fshl.v4i32(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}})
   return _mm_shldv_epi32(__S, __A, __B);
 }
 
 __m256i test_mm256_mask_shldv_epi16(__m256i __S, __mmask16 __U, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_mask_shldv_epi16
-  // CHECK: @llvm.x86.avx512.mask.vpshldv.w.256
+  // CHECK: @llvm.fshl.v16i16(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}})
+  // CHECK: select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}}
   return _mm256_mask_shldv_epi16(__S, __U, __A, __B);
 }
 
 __m256i test_mm256_maskz_shldv_epi16(__mmask16 __U, __m256i __S, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_maskz_shldv_epi16
-  // CHECK: @llvm.x86.avx512.maskz.vpshldv.w.256
+  // CHECK: @llvm.fshl.v16i16(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}})
+  // CHECK: select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}}
   return _mm256_maskz_shldv_epi16(__U, __S, __A, __B);
 }
 
 __m256i test_mm256_shldv_epi16(__m256i __S, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_shldv_epi16
-  // CHECK: @llvm.x86.avx512.mask.vpshldv.w.256
+  // CHECK: @llvm.fshl.v16i16(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}})
   return _mm256_shldv_epi16(__S, __A, __B);
 }
 
 __m128i test_mm_mask_shldv_epi16(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_mask_shldv_epi16
-  // CHECK: @llvm.x86.avx512.mask.vpshldv.w.128
+  // CHECK: @llvm.fshl.v8i16(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}})
+  // CHECK: select <8 x i1> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}
   return _mm_mask_shldv_epi16(__S, __U, __A, __B);
 }
 
 __m128i test_mm_maskz_shldv_epi16(__mmask8 __U, __m128i __S, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_maskz_shldv_epi16
-  // CHECK: @llvm.x86.avx512.maskz.vpshldv.w.128
+  // CHECK: @llvm.fshl.v8i16(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}})
+  // CHECK: select <8 x i1> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}
   return _mm_maskz_shldv_epi16(__U, __S, __A, __B);
 }
 
 __m128i test_mm_shldv_epi16(__m128i __S, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_shldv_epi16
-  // CHECK: @llvm.x86.avx512.mask.vpshldv.w.128
+  // CHECK: @llvm.fshl.v8i16(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}})
   return _mm_shldv_epi16(__S, __A, __B);
 }
 
 __m256i test_mm256_mask_shrdv_epi64(__m256i __S, __mmask8 __U, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_mask_shrdv_epi64
-  // CHECK: @llvm.x86.avx512.mask.vpshrdv.q.256
+  // CHECK: @llvm.fshr.v4i64(<4 x i64> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}})
+  // CHECK: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}}
   return _mm256_mask_shrdv_epi64(__S, __U, __A, __B);
 }
 
 __m256i test_mm256_maskz_shrdv_epi64(__mmask8 __U, __m256i __S, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_maskz_shrdv_epi64
-  // CHECK: @llvm.x86.avx512.maskz.vpshrdv.q.256
+  // CHECK: @llvm.fshr.v4i64(<4 x i64> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}})
+  // CHECK: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}}
   return _mm256_maskz_shrdv_epi64(__U, __S, __A, __B);
 }
 
 __m256i test_mm256_shrdv_epi64(__m256i __S, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_shrdv_epi64
-  // CHECK: @llvm.x86.avx512.mask.vpshrdv.q.256
+  // CHECK: @llvm.fshr.v4i64(<4 x i64> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}})
   return _mm256_shrdv_epi64(__S, __A, __B);
 }
 
 __m128i test_mm_mask_shrdv_epi64(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_mask_shrdv_epi64
-  // CHECK: @llvm.x86.avx512.mask.vpshrdv.q.128
+  // CHECK: @llvm.fshr.v2i64(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}})
+  // CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}}
   return _mm_mask_shrdv_epi64(__S, __U, __A, __B);
 }
 
 __m128i test_mm_maskz_shrdv_epi64(__mmask8 __U, __m128i __S, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_maskz_shrdv_epi64
-  // CHECK: @llvm.x86.avx512.maskz.vpshrdv.q.128
+  // CHECK: @llvm.fshr.v2i64(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}})
+  // CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}}
   return _mm_maskz_shrdv_epi64(__U, __S, __A, __B);
 }
 
 __m128i test_mm_shrdv_epi64(__m128i __S, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_shrdv_epi64
-  // CHECK: @llvm.x86.avx512.mask.vpshrdv.q.128
+  // CHECK: @llvm.fshr.v2i64(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}})
   return _mm_shrdv_epi64(__S, __A, __B);
 }
 
 __m256i test_mm256_mask_shrdv_epi32(__m256i __S, __mmask8 __U, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_mask_shrdv_epi32
-  // CHECK: @llvm.x86.avx512.mask.vpshrdv.d.256
+  // CHECK: @llvm.fshr.v8i32(<8 x i32> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}})
+  // CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}}
   return _mm256_mask_shrdv_epi32(__S, __U, __A, __B);
 }
 
 __m256i test_mm256_maskz_shrdv_epi32(__mmask8 __U, __m256i __S, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_maskz_shrdv_epi32
-  // CHECK: @llvm.x86.avx512.maskz.vpshrdv.d.256
+  // CHECK: @llvm.fshr.v8i32(<8 x i32> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}})
+  // CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}}
   return _mm256_maskz_shrdv_epi32(__U, __S, __A, __B);
 }
 
 __m256i test_mm256_shrdv_epi32(__m256i __S, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_shrdv_epi32
-  // CHECK: @llvm.x86.avx512.mask.vpshrdv.d.256
+  // CHECK: @llvm.fshr.v8i32(<8 x i32> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}})
   return _mm256_shrdv_epi32(__S, __A, __B);
 }
 
 __m128i test_mm_mask_shrdv_epi32(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_mask_shrdv_epi32
-  // CHECK: @llvm.x86.avx512.mask.vpshrdv.d.128
+  // CHECK: @llvm.fshr.v4i32(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}})
+  // CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
   return _mm_mask_shrdv_epi32(__S, __U, __A, __B);
 }
 
 __m128i test_mm_maskz_shrdv_epi32(__mmask8 __U, __m128i __S, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_maskz_shrdv_epi32
-  // CHECK: @llvm.x86.avx512.maskz.vpshrdv.d.128
+  // CHECK: @llvm.fshr.v4i32(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}})
+  // CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
   return _mm_maskz_shrdv_epi32(__U, __S, __A, __B);
 }
 
 __m128i test_mm_shrdv_epi32(__m128i __S, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_shrdv_epi32
-  // CHECK: @llvm.x86.avx512.mask.vpshrdv.d.128
+  // CHECK: @llvm.fshr.v4i32(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}})
   return _mm_shrdv_epi32(__S, __A, __B);
 }
 
 __m256i test_mm256_mask_shrdv_epi16(__m256i __S, __mmask16 __U, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_mask_shrdv_epi16
-  // CHECK: @llvm.x86.avx512.mask.vpshrdv.w.256
+  // CHECK: @llvm.fshr.v16i16(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}})
+  // CHECK: select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}}
   return _mm256_mask_shrdv_epi16(__S, __U, __A, __B);
 }
 
 __m256i test_mm256_maskz_shrdv_epi16(__mmask16 __U, __m256i __S, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_maskz_shrdv_epi16
-  // CHECK: @llvm.x86.avx512.maskz.vpshrdv.w.256
+  // CHECK: @llvm.fshr.v16i16(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}})
+  // CHECK: select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}}
   return _mm256_maskz_shrdv_epi16(__U, __S, __A, __B);
 }
 
 __m256i test_mm256_shrdv_epi16(__m256i __S, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_shrdv_epi16
-  // CHECK: @llvm.x86.avx512.mask.vpshrdv.w.256
+  // CHECK: @llvm.fshr.v16i16(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}})
   return _mm256_shrdv_epi16(__S, __A, __B);
 }
 
 __m128i test_mm_mask_shrdv_epi16(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_mask_shrdv_epi16
-  // CHECK: @llvm.x86.avx512.mask.vpshrdv.w.128
+  // CHECK: @llvm.fshr.v8i16(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}})
+  // CHECK: select <8 x i1> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}
   return _mm_mask_shrdv_epi16(__S, __U, __A, __B);
 }
 
 __m128i test_mm_maskz_shrdv_epi16(__mmask8 __U, __m128i __S, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_maskz_shrdv_epi16
-  // CHECK: @llvm.x86.avx512.maskz.vpshrdv.w.128
+  // CHECK: @llvm.fshr.v8i16(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}})
+  // CHECK: select <8 x i1> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}
   return _mm_maskz_shrdv_epi16(__U, __S, __A, __B);
 }
 
 __m128i test_mm_shrdv_epi16(__m128i __S, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_shrdv_epi16
-  // CHECK: @llvm.x86.avx512.mask.vpshrdv.w.128
+  // CHECK: @llvm.fshr.v8i16(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}})
   return _mm_shrdv_epi16(__S, __A, __B);
 }
 
-- 
cgit v1.2.3


From 3dad45fb47912e466a6171a7f732ee806e660657 Mon Sep 17 00:00:00 2001
From: Craig Topper 
Date: Mon, 7 Jan 2019 19:39:25 +0000
Subject: Revert r350555 "[X86] Use funnel shift intrinsics for the VBMI2
 vshld/vshrd builtins."

Had to revert the LLVM patch this depends on to fix a MSVC compiler limit in AutoUpgrade.cpp

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350563 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/Basic/BuiltinsX86.def   |  56 +++---
 lib/CodeGen/CGBuiltin.cpp             |  46 -----
 lib/Headers/avx512vbmi2intrin.h       | 158 ++++++++++-------
 lib/Headers/avx512vlvbmi2intrin.h     | 312 ++++++++++++++++++++--------------
 test/CodeGen/avx512vbmi2-builtins.c   |  84 ++++-----
 test/CodeGen/avx512vlvbmi2-builtins.c | 168 ++++++++----------
 6 files changed, 417 insertions(+), 407 deletions(-)

diff --git a/include/clang/Basic/BuiltinsX86.def b/include/clang/Basic/BuiltinsX86.def
index ccb5cd04d2..d97ec58916 100644
--- a/include/clang/Basic/BuiltinsX86.def
+++ b/include/clang/Basic/BuiltinsX86.def
@@ -1256,25 +1256,43 @@ TARGET_BUILTIN(__builtin_ia32_vpshldw128, "V8sV8sV8sIi", "ncV:128:", "avx512vl,a
 TARGET_BUILTIN(__builtin_ia32_vpshldw256, "V16sV16sV16sIi", "ncV:256:", "avx512vl,avx512vbmi2")
 TARGET_BUILTIN(__builtin_ia32_vpshldw512, "V32sV32sV32sIi", "ncV:512:", "avx512vbmi2")
 
-TARGET_BUILTIN(__builtin_ia32_vpshldvd128, "V4iV4iV4iV4i", "ncV:128:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvd256, "V8iV8iV8iV8i", "ncV:256:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvd512, "V16iV16iV16iV16i", "ncV:512:", "avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvq128, "V2LLiV2LLiV2LLiV2LLi", "ncV:128:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvq256, "V4LLiV4LLiV4LLiV4LLi", "ncV:256:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvq512, "V8LLiV8LLiV8LLiV8LLi", "ncV:512:", "avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvw128, "V8sV8sV8sV8s", "ncV:128:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvw256, "V16sV16sV16sV16s", "ncV:256:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvw512, "V32sV32sV32sV32s", "ncV:512:", "avx512vbmi2")
-
-TARGET_BUILTIN(__builtin_ia32_vpshrdvd128, "V4iV4iV4iV4i", "ncV:128:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvd256, "V8iV8iV8iV8i", "ncV:256:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvd512, "V16iV16iV16iV16i", "ncV:512:", "avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvq128, "V2LLiV2LLiV2LLiV2LLi", "ncV:128:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvq256, "V4LLiV4LLiV4LLiV4LLi", "ncV:256:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvq512, "V8LLiV8LLiV8LLiV8LLi", "ncV:512:", "avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvw128, "V8sV8sV8sV8s", "ncV:128:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvw256, "V16sV16sV16sV16s", "ncV:256:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvw512, "V32sV32sV32sV32s", "ncV:512:", "avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvd128_mask, "V4iV4iV4iV4iUc", "ncV:128:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvd256_mask, "V8iV8iV8iV8iUc", "ncV:256:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvd512_mask, "V16iV16iV16iV16iUs", "ncV:512:", "avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "ncV:128:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "ncV:256:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "ncV:512:", "avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvw128_mask, "V8sV8sV8sV8sUc", "ncV:128:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvw256_mask, "V16sV16sV16sV16sUs", "ncV:256:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvw512_mask, "V32sV32sV32sV32sUi", "ncV:512:", "avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvd128_maskz, "V4iV4iV4iV4iUc", "ncV:128:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvd256_maskz, "V8iV8iV8iV8iUc", "ncV:256:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvd512_maskz, "V16iV16iV16iV16iUs", "ncV:512:", "avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvq128_maskz, "V2LLiV2LLiV2LLiV2LLiUc", "ncV:128:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvq256_maskz, "V4LLiV4LLiV4LLiV4LLiUc", "ncV:256:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvq512_maskz, "V8LLiV8LLiV8LLiV8LLiUc", "ncV:512:", "avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvw128_maskz, "V8sV8sV8sV8sUc", "ncV:128:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvw256_maskz, "V16sV16sV16sV16sUs", "ncV:256:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvw512_maskz, "V32sV32sV32sV32sUi", "ncV:512:", "avx512vbmi2")
+
+TARGET_BUILTIN(__builtin_ia32_vpshrdvd128_mask, "V4iV4iV4iV4iUc", "ncV:128:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdvd256_mask, "V8iV8iV8iV8iUc", "ncV:256:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdvd512_mask, "V16iV16iV16iV16iUs", "ncV:512:", "avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdvq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "ncV:128:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdvq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "ncV:256:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdvq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "ncV:512:", "avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdvw128_mask, "V8sV8sV8sV8sUc", "ncV:128:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdvw256_mask, "V16sV16sV16sV16sUs", "ncV:256:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdvw512_mask, "V32sV32sV32sV32sUi", "ncV:512:", "avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdvd128_maskz, "V4iV4iV4iV4iUc", "ncV:128:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdvd256_maskz, "V8iV8iV8iV8iUc", "ncV:256:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdvd512_maskz, "V16iV16iV16iV16iUs", "ncV:512:", "avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdvq128_maskz, "V2LLiV2LLiV2LLiV2LLiUc", "ncV:128:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdvq256_maskz, "V4LLiV4LLiV4LLiV4LLiUc", "ncV:256:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdvq512_maskz, "V8LLiV8LLiV8LLiV8LLiUc", "ncV:512:", "avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdvw128_maskz, "V8sV8sV8sV8sUc", "ncV:128:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdvw256_maskz, "V16sV16sV16sV16sUs", "ncV:256:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdvw512_maskz, "V32sV32sV32sV32sUi", "ncV:512:", "avx512vbmi2")
 
 TARGET_BUILTIN(__builtin_ia32_vpshrdd128, "V4iV4iV4iIi", "ncV:128:", "avx512vl,avx512vbmi2")
 TARGET_BUILTIN(__builtin_ia32_vpshrdd256, "V8iV8iV8iIi", "ncV:256:", "avx512vl,avx512vbmi2")
diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp
index ca7b4691ff..93484f82c3 100644
--- a/lib/CodeGen/CGBuiltin.cpp
+++ b/lib/CodeGen/CGBuiltin.cpp
@@ -10999,52 +10999,6 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID,
   case X86::BI__builtin_ia32_pternlogq256_maskz:
     return EmitX86Ternlog(*this, /*ZeroMask*/true, Ops);
 
-  case X86::BI__builtin_ia32_vpshldd128:
-  case X86::BI__builtin_ia32_vpshldd256:
-  case X86::BI__builtin_ia32_vpshldd512:
-  case X86::BI__builtin_ia32_vpshldq128:
-  case X86::BI__builtin_ia32_vpshldq256:
-  case X86::BI__builtin_ia32_vpshldq512:
-  case X86::BI__builtin_ia32_vpshldw128:
-  case X86::BI__builtin_ia32_vpshldw256:
-  case X86::BI__builtin_ia32_vpshldw512:
-    return EmitX86FunnelShift(*this, Ops[0], Ops[1], Ops[2], false);
-
-  case X86::BI__builtin_ia32_vpshrdd128:
-  case X86::BI__builtin_ia32_vpshrdd256:
-  case X86::BI__builtin_ia32_vpshrdd512:
-  case X86::BI__builtin_ia32_vpshrdq128:
-  case X86::BI__builtin_ia32_vpshrdq256:
-  case X86::BI__builtin_ia32_vpshrdq512:
-  case X86::BI__builtin_ia32_vpshrdw128:
-  case X86::BI__builtin_ia32_vpshrdw256:
-  case X86::BI__builtin_ia32_vpshrdw512:
-    // Ops 0 and 1 are swapped.
-    return EmitX86FunnelShift(*this, Ops[1], Ops[0], Ops[2], true);
-
-  case X86::BI__builtin_ia32_vpshldvd128:
-  case X86::BI__builtin_ia32_vpshldvd256:
-  case X86::BI__builtin_ia32_vpshldvd512:
-  case X86::BI__builtin_ia32_vpshldvq128:
-  case X86::BI__builtin_ia32_vpshldvq256:
-  case X86::BI__builtin_ia32_vpshldvq512:
-  case X86::BI__builtin_ia32_vpshldvw128:
-  case X86::BI__builtin_ia32_vpshldvw256:
-  case X86::BI__builtin_ia32_vpshldvw512:
-    return EmitX86FunnelShift(*this, Ops[0], Ops[1], Ops[2], false);
-
-  case X86::BI__builtin_ia32_vpshrdvd128:
-  case X86::BI__builtin_ia32_vpshrdvd256:
-  case X86::BI__builtin_ia32_vpshrdvd512:
-  case X86::BI__builtin_ia32_vpshrdvq128:
-  case X86::BI__builtin_ia32_vpshrdvq256:
-  case X86::BI__builtin_ia32_vpshrdvq512:
-  case X86::BI__builtin_ia32_vpshrdvw128:
-  case X86::BI__builtin_ia32_vpshrdvw256:
-  case X86::BI__builtin_ia32_vpshrdvw512:
-    // Ops 0 and 1 are swapped.
-    return EmitX86FunnelShift(*this, Ops[1], Ops[0], Ops[2], true);
-
   // 3DNow!
   case X86::BI__builtin_ia32_pswapdsf:
   case X86::BI__builtin_ia32_pswapdsi: {
diff --git a/lib/Headers/avx512vbmi2intrin.h b/lib/Headers/avx512vbmi2intrin.h
index 5324252429..d2a58094fd 100644
--- a/lib/Headers/avx512vbmi2intrin.h
+++ b/lib/Headers/avx512vbmi2intrin.h
@@ -227,141 +227,167 @@ _mm512_maskz_expandloadu_epi8(__mmask64 __U, void const *__P)
                                    (__v32hi)_mm512_setzero_si512())
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_shldv_epi64(__m512i __A, __m512i __B, __m512i __C)
+_mm512_mask_shldv_epi64(__m512i __S, __mmask8 __U, __m512i __A, __m512i __B)
 {
-  return (__m512i)__builtin_ia32_vpshldvq512((__v8di)__A, (__v8di)__B,
-                                             (__v8di)__C);
+  return (__m512i) __builtin_ia32_vpshldvq512_mask ((__v8di) __S,
+              (__v8di) __A,
+              (__v8di) __B,
+              __U);
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_mask_shldv_epi64(__m512i __A, __mmask8 __U, __m512i __B, __m512i __C)
+_mm512_maskz_shldv_epi64(__mmask8 __U, __m512i __S, __m512i __A, __m512i __B)
 {
-  return (__m512i)__builtin_ia32_selectq_512(__U,
-                                      (__v8di)_mm512_shldv_epi64(__A, __B, __C),
-                                      (__v8di)__A);
+  return (__m512i) __builtin_ia32_vpshldvq512_maskz ((__v8di) __S,
+              (__v8di) __A,
+              (__v8di) __B,
+              __U);
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_maskz_shldv_epi64(__mmask8 __U, __m512i __A, __m512i __B, __m512i __C)
+_mm512_shldv_epi64(__m512i __S, __m512i __A, __m512i __B)
 {
-  return (__m512i)__builtin_ia32_selectq_512(__U,
-                                      (__v8di)_mm512_shldv_epi64(__A, __B, __C),
-                                      (__v8di)_mm512_setzero_si512());
+  return (__m512i) __builtin_ia32_vpshldvq512_mask ((__v8di) __S,
+              (__v8di) __A,
+              (__v8di) __B,
+              (__mmask8) -1);
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_shldv_epi32(__m512i __A, __m512i __B, __m512i __C)
+_mm512_mask_shldv_epi32(__m512i __S, __mmask16 __U, __m512i __A, __m512i __B)
 {
-  return (__m512i)__builtin_ia32_vpshldvd512((__v16si)__A, (__v16si)__B,
-                                             (__v16si)__C);
+  return (__m512i) __builtin_ia32_vpshldvd512_mask ((__v16si) __S,
+              (__v16si) __A,
+              (__v16si) __B,
+              __U);
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_mask_shldv_epi32(__m512i __A, __mmask16 __U, __m512i __B, __m512i __C)
+_mm512_maskz_shldv_epi32(__mmask16 __U, __m512i __S, __m512i __A, __m512i __B)
 {
-  return (__m512i)__builtin_ia32_selectd_512(__U,
-                                     (__v16si)_mm512_shldv_epi32(__A, __B, __C),
-                                     (__v16si)__A);
+  return (__m512i) __builtin_ia32_vpshldvd512_maskz ((__v16si) __S,
+              (__v16si) __A,
+              (__v16si) __B,
+              __U);
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_maskz_shldv_epi32(__mmask16 __U, __m512i __A, __m512i __B, __m512i __C)
+_mm512_shldv_epi32(__m512i __S, __m512i __A, __m512i __B)
 {
-  return (__m512i)__builtin_ia32_selectd_512(__U,
-                                     (__v16si)_mm512_shldv_epi32(__A, __B, __C),
-                                     (__v16si)_mm512_setzero_si512());
+  return (__m512i) __builtin_ia32_vpshldvd512_mask ((__v16si) __S,
+              (__v16si) __A,
+              (__v16si) __B,
+              (__mmask16) -1);
 }
 
+
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_shldv_epi16(__m512i __A, __m512i __B, __m512i __C)
+_mm512_mask_shldv_epi16(__m512i __S, __mmask32 __U, __m512i __A, __m512i __B)
 {
-  return (__m512i)__builtin_ia32_vpshldvw512((__v32hi)__A, (__v32hi)__B,
-                                             (__v32hi)__C);
+  return (__m512i) __builtin_ia32_vpshldvw512_mask ((__v32hi) __S,
+              (__v32hi) __A,
+              (__v32hi) __B,
+              __U);
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_mask_shldv_epi16(__m512i __A, __mmask32 __U, __m512i __B, __m512i __C)
+_mm512_maskz_shldv_epi16(__mmask32 __U, __m512i __S, __m512i __A, __m512i __B)
 {
-  return (__m512i)__builtin_ia32_selectw_512(__U,
-                                     (__v32hi)_mm512_shldv_epi16(__A, __B, __C),
-                                     (__v32hi)__A);
+  return (__m512i) __builtin_ia32_vpshldvw512_maskz ((__v32hi) __S,
+              (__v32hi) __A,
+              (__v32hi) __B,
+              __U);
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_maskz_shldv_epi16(__mmask32 __U, __m512i __A, __m512i __B, __m512i __C)
+_mm512_shldv_epi16(__m512i __S, __m512i __A, __m512i __B)
 {
-  return (__m512i)__builtin_ia32_selectw_512(__U,
-                                     (__v32hi)_mm512_shldv_epi16(__A, __B, __C),
-                                     (__v32hi)_mm512_setzero_si512());
+  return (__m512i) __builtin_ia32_vpshldvw512_mask ((__v32hi) __S,
+              (__v32hi) __A,
+              (__v32hi) __B,
+              (__mmask32) -1);
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_shrdv_epi64(__m512i __A, __m512i __B, __m512i __C)
+_mm512_mask_shrdv_epi64(__m512i __S, __mmask8 __U, __m512i __A, __m512i __B)
 {
-  return (__m512i)__builtin_ia32_vpshrdvq512((__v8di)__A, (__v8di)__B,
-                                             (__v8di)__C);
+  return (__m512i) __builtin_ia32_vpshrdvq512_mask ((__v8di) __S,
+              (__v8di) __A,
+              (__v8di) __B,
+              __U);
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_mask_shrdv_epi64(__m512i __A, __mmask8 __U, __m512i __B, __m512i __C)
+_mm512_maskz_shrdv_epi64(__mmask8 __U, __m512i __S, __m512i __A, __m512i __B)
 {
-  return (__m512i)__builtin_ia32_selectq_512(__U,
-                                      (__v8di)_mm512_shrdv_epi64(__A, __B, __C),
-                                      (__v8di)__A);
+  return (__m512i) __builtin_ia32_vpshrdvq512_maskz ((__v8di) __S,
+              (__v8di) __A,
+              (__v8di) __B,
+              __U);
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_maskz_shrdv_epi64(__mmask8 __U, __m512i __A, __m512i __B, __m512i __C)
+_mm512_shrdv_epi64(__m512i __S, __m512i __A, __m512i __B)
 {
-  return (__m512i)__builtin_ia32_selectq_512(__U,
-                                      (__v8di)_mm512_shrdv_epi64(__A, __B, __C),
-                                      (__v8di)_mm512_setzero_si512());
+  return (__m512i) __builtin_ia32_vpshrdvq512_mask ((__v8di) __S,
+              (__v8di) __A,
+              (__v8di) __B,
+              (__mmask8) -1);
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_shrdv_epi32(__m512i __A, __m512i __B, __m512i __C)
+_mm512_mask_shrdv_epi32(__m512i __S, __mmask16 __U, __m512i __A, __m512i __B)
 {
-  return (__m512i)__builtin_ia32_vpshrdvd512((__v16si)__A, (__v16si)__B,
-                                             (__v16si)__C);
+  return (__m512i) __builtin_ia32_vpshrdvd512_mask ((__v16si) __S,
+              (__v16si) __A,
+              (__v16si) __B,
+              __U);
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_mask_shrdv_epi32(__m512i __A, __mmask16 __U, __m512i __B, __m512i __C)
+_mm512_maskz_shrdv_epi32(__mmask16 __U, __m512i __S, __m512i __A, __m512i __B)
 {
-  return (__m512i) __builtin_ia32_selectd_512(__U,
-                                     (__v16si)_mm512_shrdv_epi32(__A, __B, __C),
-                                     (__v16si)__A);
+  return (__m512i) __builtin_ia32_vpshrdvd512_maskz ((__v16si) __S,
+              (__v16si) __A,
+              (__v16si) __B,
+              __U);
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_maskz_shrdv_epi32(__mmask16 __U, __m512i __A, __m512i __B, __m512i __C)
+_mm512_shrdv_epi32(__m512i __S, __m512i __A, __m512i __B)
 {
-  return (__m512i) __builtin_ia32_selectd_512(__U,
-                                     (__v16si)_mm512_shrdv_epi32(__A, __B, __C),
-                                     (__v16si)_mm512_setzero_si512());
+  return (__m512i) __builtin_ia32_vpshrdvd512_mask ((__v16si) __S,
+              (__v16si) __A,
+              (__v16si) __B,
+              (__mmask16) -1);
 }
 
+
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_shrdv_epi16(__m512i __A, __m512i __B, __m512i __C)
+_mm512_mask_shrdv_epi16(__m512i __S, __mmask32 __U, __m512i __A, __m512i __B)
 {
-  return (__m512i)__builtin_ia32_vpshrdvw512((__v32hi)__A, (__v32hi)__B,
-                                             (__v32hi)__C);
+  return (__m512i) __builtin_ia32_vpshrdvw512_mask ((__v32hi) __S,
+              (__v32hi) __A,
+              (__v32hi) __B,
+              __U);
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_mask_shrdv_epi16(__m512i __A, __mmask32 __U, __m512i __B, __m512i __C)
+_mm512_maskz_shrdv_epi16(__mmask32 __U, __m512i __S, __m512i __A, __m512i __B)
 {
-  return (__m512i)__builtin_ia32_selectw_512(__U,
-                                     (__v32hi)_mm512_shrdv_epi16(__A, __B, __C),
-                                     (__v32hi)__A);
+  return (__m512i) __builtin_ia32_vpshrdvw512_maskz ((__v32hi) __S,
+              (__v32hi) __A,
+              (__v32hi) __B,
+              __U);
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_maskz_shrdv_epi16(__mmask32 __U, __m512i __A, __m512i __B, __m512i __C)
+_mm512_shrdv_epi16(__m512i __S, __m512i __A, __m512i __B)
 {
-  return (__m512i)__builtin_ia32_selectw_512(__U,
-                                     (__v32hi)_mm512_shrdv_epi16(__A, __B, __C),
-                                     (__v32hi)_mm512_setzero_si512());
+  return (__m512i) __builtin_ia32_vpshrdvw512_mask ((__v32hi) __S,
+              (__v32hi) __A,
+              (__v32hi) __B,
+              (__mmask32) -1);
 }
 
 
diff --git a/lib/Headers/avx512vlvbmi2intrin.h b/lib/Headers/avx512vlvbmi2intrin.h
index 632d14fb55..baaf565463 100644
--- a/lib/Headers/avx512vlvbmi2intrin.h
+++ b/lib/Headers/avx512vlvbmi2intrin.h
@@ -421,279 +421,327 @@ _mm256_maskz_expandloadu_epi8(__mmask32 __U, void const *__P)
                                       (__v8hi)_mm_setzero_si128())
 
 static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_shldv_epi64(__m256i __A, __m256i __B, __m256i __C)
+_mm256_mask_shldv_epi64(__m256i __S, __mmask8 __U, __m256i __A, __m256i __B)
 {
-  return (__m256i)__builtin_ia32_vpshldvq256((__v4di)__A, (__v4di)__B,
-                                             (__v4di)__C);
+  return (__m256i) __builtin_ia32_vpshldvq256_mask ((__v4di) __S,
+              (__v4di) __A,
+              (__v4di) __B,
+              __U);
 }
 
 static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_mask_shldv_epi64(__m256i __A, __mmask8 __U, __m256i __B, __m256i __C)
+_mm256_maskz_shldv_epi64(__mmask8 __U, __m256i __S, __m256i __A, __m256i __B)
 {
-  return (__m256i)__builtin_ia32_selectq_256(__U,
-                                      (__v4di)_mm256_shldv_epi64(__A, __B, __C),
-                                      (__v4di)__A);
+  return (__m256i) __builtin_ia32_vpshldvq256_maskz ((__v4di) __S,
+              (__v4di) __A,
+              (__v4di) __B,
+              __U);
 }
 
 static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_maskz_shldv_epi64(__mmask8 __U, __m256i __A, __m256i __B, __m256i __C)
+_mm256_shldv_epi64(__m256i __S, __m256i __A, __m256i __B)
 {
-  return (__m256i)__builtin_ia32_selectq_256(__U,
-                                      (__v4di)_mm256_shldv_epi64(__A, __B, __C),
-                                      (__v4di)_mm256_setzero_si256());
+  return (__m256i) __builtin_ia32_vpshldvq256_mask ((__v4di) __S,
+              (__v4di) __A,
+              (__v4di) __B,
+              (__mmask8) -1);
 }
 
 static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_shldv_epi64(__m128i __A, __m128i __B, __m128i __C)
+_mm_mask_shldv_epi64(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B)
 {
-  return (__m128i)__builtin_ia32_vpshldvq128((__v2di)__A, (__v2di)__B,
-                                             (__v2di)__C);
+  return (__m128i) __builtin_ia32_vpshldvq128_mask ((__v2di) __S,
+              (__v2di) __A,
+              (__v2di) __B,
+              __U);
 }
 
 static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_mask_shldv_epi64(__m128i __A, __mmask8 __U, __m128i __B, __m128i __C)
+_mm_maskz_shldv_epi64(__mmask8 __U, __m128i __S, __m128i __A, __m128i __B)
 {
-  return (__m128i)__builtin_ia32_selectq_128(__U,
-                                         (__v2di)_mm_shldv_epi64(__A, __B, __C),
-                                         (__v2di)__A);
+  return (__m128i) __builtin_ia32_vpshldvq128_maskz ((__v2di) __S,
+              (__v2di) __A,
+              (__v2di) __B,
+              __U);
 }
 
 static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_maskz_shldv_epi64(__mmask8 __U, __m128i __A, __m128i __B, __m128i __C)
+_mm_shldv_epi64(__m128i __S, __m128i __A, __m128i __B)
 {
-  return (__m128i)__builtin_ia32_selectq_128(__U,
-                                         (__v2di)_mm_shldv_epi64(__A, __B, __C),
-                                         (__v2di)_mm_setzero_si128());
+  return (__m128i) __builtin_ia32_vpshldvq128_mask ((__v2di) __S,
+              (__v2di) __A,
+              (__v2di) __B,
+              (__mmask8) -1);
 }
 
 static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_shldv_epi32(__m256i __A, __m256i __B, __m256i __C)
+_mm256_mask_shldv_epi32(__m256i __S, __mmask8 __U, __m256i __A, __m256i __B)
 {
-  return (__m256i)__builtin_ia32_vpshldvd256((__v8si)__A, (__v8si)__B,
-                                             (__v8si)__C);
+  return (__m256i) __builtin_ia32_vpshldvd256_mask ((__v8si) __S,
+              (__v8si) __A,
+              (__v8si) __B,
+              __U);
 }
 
 static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_mask_shldv_epi32(__m256i __A, __mmask8 __U, __m256i __B, __m256i __C)
+_mm256_maskz_shldv_epi32(__mmask8 __U, __m256i __S, __m256i __A, __m256i __B)
 {
-  return (__m256i)__builtin_ia32_selectd_256(__U,
-                                      (__v8si)_mm256_shldv_epi32(__A, __B, __C),
-                                      (__v8si)__A);
+  return (__m256i) __builtin_ia32_vpshldvd256_maskz ((__v8si) __S,
+              (__v8si) __A,
+              (__v8si) __B,
+              __U);
 }
 
 static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_maskz_shldv_epi32(__mmask8 __U, __m256i __A, __m256i __B, __m256i __C)
+_mm256_shldv_epi32(__m256i __S, __m256i __A, __m256i __B)
 {
-  return (__m256i)__builtin_ia32_selectd_256(__U,
-                                      (__v8si)_mm256_shldv_epi32(__A, __B, __C),
-                                      (__v8si)_mm256_setzero_si256());
+  return (__m256i) __builtin_ia32_vpshldvd256_mask ((__v8si) __S,
+              (__v8si) __A,
+              (__v8si) __B,
+              (__mmask8) -1);
 }
 
 static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_shldv_epi32(__m128i __A, __m128i __B, __m128i __C)
+_mm_mask_shldv_epi32(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B)
 {
-  return (__m128i)__builtin_ia32_vpshldvd128((__v4si)__A, (__v4si)__B,
-                                             (__v4si)__C);
+  return (__m128i) __builtin_ia32_vpshldvd128_mask ((__v4si) __S,
+              (__v4si) __A,
+              (__v4si) __B,
+              __U);
 }
 
 static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_mask_shldv_epi32(__m128i __A, __mmask8 __U, __m128i __B, __m128i __C)
+_mm_maskz_shldv_epi32(__mmask8 __U, __m128i __S, __m128i __A, __m128i __B)
 {
-  return (__m128i)__builtin_ia32_selectd_128(__U,
-                                         (__v4si)_mm_shldv_epi32(__A, __B, __C),
-                                         (__v4si)__A);
+  return (__m128i) __builtin_ia32_vpshldvd128_maskz ((__v4si) __S,
+              (__v4si) __A,
+              (__v4si) __B,
+              __U);
 }
 
 static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_maskz_shldv_epi32(__mmask8 __U, __m128i __A, __m128i __B, __m128i __C)
+_mm_shldv_epi32(__m128i __S, __m128i __A, __m128i __B)
 {
-  return (__m128i)__builtin_ia32_selectd_128(__U,
-                                         (__v4si)_mm_shldv_epi32(__A, __B, __C),
-                                         (__v4si)_mm_setzero_si128());
+  return (__m128i) __builtin_ia32_vpshldvd128_mask ((__v4si) __S,
+              (__v4si) __A,
+              (__v4si) __B,
+              (__mmask8) -1);
 }
 
 static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_shldv_epi16(__m256i __A, __m256i __B, __m256i __C)
+_mm256_mask_shldv_epi16(__m256i __S, __mmask16 __U, __m256i __A, __m256i __B)
 {
-  return (__m256i)__builtin_ia32_vpshldvw256((__v16hi)__A, (__v16hi)__B,
-                                             (__v16hi)__C);
+  return (__m256i) __builtin_ia32_vpshldvw256_mask ((__v16hi) __S,
+              (__v16hi) __A,
+              (__v16hi) __B,
+              __U);
 }
 
 static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_mask_shldv_epi16(__m256i __A, __mmask16 __U, __m256i __B, __m256i __C)
+_mm256_maskz_shldv_epi16(__mmask16 __U, __m256i __S, __m256i __A, __m256i __B)
 {
-  return (__m256i)__builtin_ia32_selectw_256(__U,
-                                      (__v16hi)_mm256_shldv_epi16(__A, __B, __C),
-                                      (__v16hi)__A);
+  return (__m256i) __builtin_ia32_vpshldvw256_maskz ((__v16hi) __S,
+              (__v16hi) __A,
+              (__v16hi) __B,
+              __U);
 }
 
 static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_maskz_shldv_epi16(__mmask16 __U, __m256i __A, __m256i __B, __m256i __C)
+_mm256_shldv_epi16(__m256i __S, __m256i __A, __m256i __B)
 {
-  return (__m256i)__builtin_ia32_selectw_256(__U,
-                                      (__v16hi)_mm256_shldv_epi16(__A, __B, __C),
-                                      (__v16hi)_mm256_setzero_si256());
+  return (__m256i) __builtin_ia32_vpshldvw256_mask ((__v16hi) __S,
+              (__v16hi) __A,
+              (__v16hi) __B,
+              (__mmask16) -1);
 }
 
 static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_shldv_epi16(__m128i __A, __m128i __B, __m128i __C)
+_mm_mask_shldv_epi16(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B)
 {
-  return (__m128i)__builtin_ia32_vpshldvw128((__v8hi)__A, (__v8hi)__B,
-                                             (__v8hi)__C);
+  return (__m128i) __builtin_ia32_vpshldvw128_mask ((__v8hi) __S,
+              (__v8hi) __A,
+              (__v8hi) __B,
+              __U);
 }
 
 static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_mask_shldv_epi16(__m128i __A, __mmask8 __U, __m128i __B, __m128i __C)
+_mm_maskz_shldv_epi16(__mmask8 __U, __m128i __S, __m128i __A, __m128i __B)
 {
-  return (__m128i)__builtin_ia32_selectw_128(__U,
-                                         (__v8hi)_mm_shldv_epi16(__A, __B, __C),
-                                         (__v8hi)__A);
+  return (__m128i) __builtin_ia32_vpshldvw128_maskz ((__v8hi) __S,
+              (__v8hi) __A,
+              (__v8hi) __B,
+              __U);
 }
 
 static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_maskz_shldv_epi16(__mmask8 __U, __m128i __A, __m128i __B, __m128i __C)
+_mm_shldv_epi16(__m128i __S, __m128i __A, __m128i __B)
 {
-  return (__m128i)__builtin_ia32_selectw_128(__U,
-                                         (__v8hi)_mm_shldv_epi16(__A, __B, __C),
-                                         (__v8hi)_mm_setzero_si128());
+  return (__m128i) __builtin_ia32_vpshldvw128_mask ((__v8hi) __S,
+              (__v8hi) __A,
+              (__v8hi) __B,
+              (__mmask8) -1);
 }
 
 static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_shrdv_epi64(__m256i __A, __m256i __B, __m256i __C)
+_mm256_mask_shrdv_epi64(__m256i __S, __mmask8 __U, __m256i __A, __m256i __B)
 {
-  return (__m256i)__builtin_ia32_vpshrdvq256((__v4di)__A, (__v4di)__B,
-                                             (__v4di)__C);
+  return (__m256i) __builtin_ia32_vpshrdvq256_mask ((__v4di) __S,
+              (__v4di) __A,
+              (__v4di) __B,
+              __U);
 }
 
 static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_mask_shrdv_epi64(__m256i __A, __mmask8 __U, __m256i __B, __m256i __C)
+_mm256_maskz_shrdv_epi64(__mmask8 __U, __m256i __S, __m256i __A, __m256i __B)
 {
-  return (__m256i)__builtin_ia32_selectq_256(__U,
-                                      (__v4di)_mm256_shrdv_epi64(__A, __B, __C),
-                                      (__v4di)__A);
+  return (__m256i) __builtin_ia32_vpshrdvq256_maskz ((__v4di) __S,
+              (__v4di) __A,
+              (__v4di) __B,
+              __U);
 }
 
 static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_maskz_shrdv_epi64(__mmask8 __U, __m256i __A, __m256i __B, __m256i __C)
+_mm256_shrdv_epi64(__m256i __S, __m256i __A, __m256i __B)
 {
-  return (__m256i)__builtin_ia32_selectq_256(__U,
-                                      (__v4di)_mm256_shrdv_epi64(__A, __B, __C),
-                                      (__v4di)_mm256_setzero_si256());
+  return (__m256i) __builtin_ia32_vpshrdvq256_mask ((__v4di) __S,
+              (__v4di) __A,
+              (__v4di) __B,
+              (__mmask8) -1);
 }
 
 static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_shrdv_epi64(__m128i __A, __m128i __B, __m128i __C)
+_mm_mask_shrdv_epi64(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B)
 {
-  return (__m128i)__builtin_ia32_vpshrdvq128((__v2di)__A, (__v2di)__B,
-                                             (__v2di)__C);
+  return (__m128i) __builtin_ia32_vpshrdvq128_mask ((__v2di) __S,
+              (__v2di) __A,
+              (__v2di) __B,
+              __U);
 }
 
 static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_mask_shrdv_epi64(__m128i __A, __mmask8 __U, __m128i __B, __m128i __C)
+_mm_maskz_shrdv_epi64(__mmask8 __U, __m128i __S, __m128i __A, __m128i __B)
 {
-  return (__m128i)__builtin_ia32_selectq_128(__U,
-                                         (__v2di)_mm_shrdv_epi64(__A, __B, __C),
-                                         (__v2di)__A);
+  return (__m128i) __builtin_ia32_vpshrdvq128_maskz ((__v2di) __S,
+              (__v2di) __A,
+              (__v2di) __B,
+              __U);
 }
 
 static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_maskz_shrdv_epi64(__mmask8 __U, __m128i __A, __m128i __B, __m128i __C)
+_mm_shrdv_epi64(__m128i __S, __m128i __A, __m128i __B)
 {
-  return (__m128i)__builtin_ia32_selectq_128(__U,
-                                         (__v2di)_mm_shrdv_epi64(__A, __B, __C),
-                                         (__v2di)_mm_setzero_si128());
+  return (__m128i) __builtin_ia32_vpshrdvq128_mask ((__v2di) __S,
+              (__v2di) __A,
+              (__v2di) __B,
+              (__mmask8) -1);
 }
 
 static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_shrdv_epi32(__m256i __A, __m256i __B, __m256i __C)
+_mm256_mask_shrdv_epi32(__m256i __S, __mmask8 __U, __m256i __A, __m256i __B)
 {
-  return (__m256i)__builtin_ia32_vpshrdvd256((__v8si)__A, (__v8si)__B,
-                                             (__v8si)__C);
+  return (__m256i) __builtin_ia32_vpshrdvd256_mask ((__v8si) __S,
+              (__v8si) __A,
+              (__v8si) __B,
+              __U);
 }
 
 static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_mask_shrdv_epi32(__m256i __A, __mmask8 __U, __m256i __B, __m256i __C)
+_mm256_maskz_shrdv_epi32(__mmask8 __U, __m256i __S, __m256i __A, __m256i __B)
 {
-  return (__m256i)__builtin_ia32_selectd_256(__U,
-                                      (__v8si)_mm256_shrdv_epi32(__A, __B, __C),
-                                      (__v8si)__A);
+  return (__m256i) __builtin_ia32_vpshrdvd256_maskz ((__v8si) __S,
+              (__v8si) __A,
+              (__v8si) __B,
+              __U);
 }
 
 static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_maskz_shrdv_epi32(__mmask8 __U, __m256i __A, __m256i __B, __m256i __C)
+_mm256_shrdv_epi32(__m256i __S, __m256i __A, __m256i __B)
 {
-  return (__m256i)__builtin_ia32_selectd_256(__U,
-                                      (__v8si)_mm256_shrdv_epi32(__A, __B, __C),
-                                      (__v8si)_mm256_setzero_si256());
+  return (__m256i) __builtin_ia32_vpshrdvd256_mask ((__v8si) __S,
+              (__v8si) __A,
+              (__v8si) __B,
+              (__mmask8) -1);
 }
 
 static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_shrdv_epi32(__m128i __A, __m128i __B, __m128i __C)
+_mm_mask_shrdv_epi32(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B)
 {
-  return (__m128i)__builtin_ia32_vpshrdvd128((__v4si)__A, (__v4si)__B,
-                                             (__v4si)__C);
+  return (__m128i) __builtin_ia32_vpshrdvd128_mask ((__v4si) __S,
+              (__v4si) __A,
+              (__v4si) __B,
+              __U);
 }
 
 static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_mask_shrdv_epi32(__m128i __A, __mmask8 __U, __m128i __B, __m128i __C)
+_mm_maskz_shrdv_epi32(__mmask8 __U, __m128i __S, __m128i __A, __m128i __B)
 {
-  return (__m128i)__builtin_ia32_selectd_128(__U,
-                                         (__v4si)_mm_shrdv_epi32(__A, __B, __C),
-                                         (__v4si)__A);
+  return (__m128i) __builtin_ia32_vpshrdvd128_maskz ((__v4si) __S,
+              (__v4si) __A,
+              (__v4si) __B,
+              __U);
 }
 
 static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_maskz_shrdv_epi32(__mmask8 __U, __m128i __A, __m128i __B, __m128i __C)
+_mm_shrdv_epi32(__m128i __S, __m128i __A, __m128i __B)
 {
-  return (__m128i)__builtin_ia32_selectd_128(__U,
-                                         (__v4si)_mm_shrdv_epi32(__A, __B, __C),
-                                         (__v4si)_mm_setzero_si128());
+  return (__m128i) __builtin_ia32_vpshrdvd128_mask ((__v4si) __S,
+              (__v4si) __A,
+              (__v4si) __B,
+              (__mmask8) -1);
 }
 
 static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_shrdv_epi16(__m256i __A, __m256i __B, __m256i __C)
+_mm256_mask_shrdv_epi16(__m256i __S, __mmask16 __U, __m256i __A, __m256i __B)
 {
-  return (__m256i)__builtin_ia32_vpshrdvw256((__v16hi)__A, (__v16hi)__B,
-                                             (__v16hi)__C);
+  return (__m256i) __builtin_ia32_vpshrdvw256_mask ((__v16hi) __S,
+              (__v16hi) __A,
+              (__v16hi) __B,
+              __U);
 }
 
 static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_mask_shrdv_epi16(__m256i __A, __mmask16 __U, __m256i __B, __m256i __C)
+_mm256_maskz_shrdv_epi16(__mmask16 __U, __m256i __S, __m256i __A, __m256i __B)
 {
-  return (__m256i)__builtin_ia32_selectw_256(__U,
-                                     (__v16hi)_mm256_shrdv_epi16(__A, __B, __C),
-                                     (__v16hi)__A);
+  return (__m256i) __builtin_ia32_vpshrdvw256_maskz ((__v16hi) __S,
+              (__v16hi) __A,
+              (__v16hi) __B,
+              __U);
 }
 
 static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_maskz_shrdv_epi16(__mmask16 __U, __m256i __A, __m256i __B, __m256i __C)
+_mm256_shrdv_epi16(__m256i __S, __m256i __A, __m256i __B)
 {
-  return (__m256i)__builtin_ia32_selectw_256(__U,
-                                     (__v16hi)_mm256_shrdv_epi16(__A, __B, __C),
-                                     (__v16hi)_mm256_setzero_si256());
+  return (__m256i) __builtin_ia32_vpshrdvw256_mask ((__v16hi) __S,
+              (__v16hi) __A,
+              (__v16hi) __B,
+              (__mmask16) -1);
 }
 
 static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_shrdv_epi16(__m128i __A, __m128i __B, __m128i __C)
+_mm_mask_shrdv_epi16(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B)
 {
-  return (__m128i)__builtin_ia32_vpshrdvw128((__v8hi)__A, (__v8hi)__B,
-                                             (__v8hi)__C);
+  return (__m128i) __builtin_ia32_vpshrdvw128_mask ((__v8hi) __S,
+              (__v8hi) __A,
+              (__v8hi) __B,
+              __U);
 }
 
 static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_mask_shrdv_epi16(__m128i __A, __mmask8 __U, __m128i __B, __m128i __C)
+_mm_maskz_shrdv_epi16(__mmask8 __U, __m128i __S, __m128i __A, __m128i __B)
 {
-  return (__m128i)__builtin_ia32_selectw_128(__U,
-                                         (__v8hi)_mm_shrdv_epi16(__A, __B, __C),
-                                         (__v8hi)__A);
+  return (__m128i) __builtin_ia32_vpshrdvw128_maskz ((__v8hi) __S,
+              (__v8hi) __A,
+              (__v8hi) __B,
+              __U);
 }
 
 static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_maskz_shrdv_epi16(__mmask8 __U, __m128i __A, __m128i __B, __m128i __C)
+_mm_shrdv_epi16(__m128i __S, __m128i __A, __m128i __B)
 {
-  return (__m128i)__builtin_ia32_selectw_128(__U,
-                                         (__v8hi)_mm_shrdv_epi16(__A, __B, __C),
-                                         (__v8hi)_mm_setzero_si128());
+  return (__m128i) __builtin_ia32_vpshrdvw128_mask ((__v8hi) __S,
+              (__v8hi) __A,
+              (__v8hi) __B,
+              (__mmask8) -1);
 }
 
 
diff --git a/test/CodeGen/avx512vbmi2-builtins.c b/test/CodeGen/avx512vbmi2-builtins.c
index 304561d9fa..a29203027d 100644
--- a/test/CodeGen/avx512vbmi2-builtins.c
+++ b/test/CodeGen/avx512vbmi2-builtins.c
@@ -88,241 +88,229 @@ __m512i test_mm512_maskz_expandloadu_epi8(__mmask64 __U, void const* __P) {
 
 __m512i test_mm512_mask_shldi_epi64(__m512i __S, __mmask8 __U, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_mask_shldi_epi64
-  // CHECK: @llvm.fshl.v8i64(<8 x i64> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> )
+  // CHECK: @llvm.x86.avx512.vpshld.q.512
   // CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}}
   return _mm512_mask_shldi_epi64(__S, __U, __A, __B, 47);
 }
 
 __m512i test_mm512_maskz_shldi_epi64(__mmask8 __U, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_maskz_shldi_epi64
-  // CHECK: @llvm.fshl.v8i64(<8 x i64> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> )
+  // CHECK: @llvm.x86.avx512.vpshld.q.512
   // CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}}
   return _mm512_maskz_shldi_epi64(__U, __A, __B, 63);
 }
 
 __m512i test_mm512_shldi_epi64(__m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_shldi_epi64
-  // CHECK: @llvm.fshl.v8i64(<8 x i64> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> )
+  // CHECK: @llvm.x86.avx512.vpshld.q.512
   return _mm512_shldi_epi64(__A, __B, 31);
 }
 
 __m512i test_mm512_mask_shldi_epi32(__m512i __S, __mmask16 __U, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_mask_shldi_epi32
-  // CHECK: @llvm.fshl.v16i32(<16 x i32> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> )
+  // CHECK: @llvm.x86.avx512.vpshld.d.512
   // CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}}
   return _mm512_mask_shldi_epi32(__S, __U, __A, __B, 7);
 }
 
 __m512i test_mm512_maskz_shldi_epi32(__mmask16 __U, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_maskz_shldi_epi32
-  // CHECK: @llvm.fshl.v16i32(<16 x i32> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> )
+  // CHECK: @llvm.x86.avx512.vpshld.d.512
   // CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}}
   return _mm512_maskz_shldi_epi32(__U, __A, __B, 15);
 }
 
 __m512i test_mm512_shldi_epi32(__m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_shldi_epi32
-  // CHECK: @llvm.fshl.v16i32(<16 x i32> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> )
+  // CHECK: @llvm.x86.avx512.vpshld.d.512
   return _mm512_shldi_epi32(__A, __B, 31);
 }
 
 __m512i test_mm512_mask_shldi_epi16(__m512i __S, __mmask32 __U, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_mask_shldi_epi16
-  // CHECK: @llvm.fshl.v32i16(<32 x i16> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> )
+  // CHECK: @llvm.x86.avx512.vpshld.w.512
   // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}}
   return _mm512_mask_shldi_epi16(__S, __U, __A, __B, 3);
 }
 
 __m512i test_mm512_maskz_shldi_epi16(__mmask32 __U, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_maskz_shldi_epi16
-  // CHECK: @llvm.fshl.v32i16(<32 x i16> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> )
+  // CHECK: @llvm.x86.avx512.vpshld.w.512
   // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}}
   return _mm512_maskz_shldi_epi16(__U, __A, __B, 7);
 }
 
 __m512i test_mm512_shldi_epi16(__m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_shldi_epi16
-  // CHECK: @llvm.fshl.v32i16(<32 x i16> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> )
+  // CHECK: @llvm.x86.avx512.vpshld.w.512
   return _mm512_shldi_epi16(__A, __B, 15);
 }
 
 __m512i test_mm512_mask_shrdi_epi64(__m512i __S, __mmask8 __U, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_mask_shrdi_epi64
-  // CHECK: @llvm.fshr.v8i64(<8 x i64> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> )
+  // CHECK: @llvm.x86.avx512.vpshrd.q.512
   // CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}}
   return _mm512_mask_shrdi_epi64(__S, __U, __A, __B, 47);
 }
 
 __m512i test_mm512_maskz_shrdi_epi64(__mmask8 __U, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_maskz_shrdi_epi64
-  // CHECK: @llvm.fshr.v8i64(<8 x i64> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> )
+  // CHECK: @llvm.x86.avx512.vpshrd.q.512
   // CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}}
   return _mm512_maskz_shrdi_epi64(__U, __A, __B, 63);
 }
 
 __m512i test_mm512_shrdi_epi64(__m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_shrdi_epi64
-  // CHECK: @llvm.fshr.v8i64(<8 x i64> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> )
+  // CHECK: @llvm.x86.avx512.vpshrd.q.512
   return _mm512_shrdi_epi64(__A, __B, 31);
 }
 
 __m512i test_mm512_mask_shrdi_epi32(__m512i __S, __mmask16 __U, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_mask_shrdi_epi32
-  // CHECK: @llvm.fshr.v16i32(<16 x i32> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> )
+  // CHECK: @llvm.x86.avx512.vpshrd.d.512
   // CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}}
   return _mm512_mask_shrdi_epi32(__S, __U, __A, __B, 7);
 }
 
 __m512i test_mm512_maskz_shrdi_epi32(__mmask16 __U, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_maskz_shrdi_epi32
-  // CHECK: @llvm.fshr.v16i32(<16 x i32> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> )
+  // CHECK: @llvm.x86.avx512.vpshrd.d.512
   // CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}}
   return _mm512_maskz_shrdi_epi32(__U, __A, __B, 15);
 }
 
 __m512i test_mm512_shrdi_epi32(__m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_shrdi_epi32
-  // CHECK: @llvm.fshr.v16i32(<16 x i32> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> )
+  // CHECK: @llvm.x86.avx512.vpshrd.d.512
   return _mm512_shrdi_epi32(__A, __B, 31);
 }
 
 __m512i test_mm512_mask_shrdi_epi16(__m512i __S, __mmask32 __U, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_mask_shrdi_epi16
-  // CHECK: @llvm.fshr.v32i16(<32 x i16> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> )
+  // CHECK: @llvm.x86.avx512.vpshrd.w.512
   // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}}
   return _mm512_mask_shrdi_epi16(__S, __U, __A, __B, 3);
 }
 
 __m512i test_mm512_maskz_shrdi_epi16(__mmask32 __U, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_maskz_shrdi_epi16
-  // CHECK: @llvm.fshr.v32i16(<32 x i16> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> )
+  // CHECK: @llvm.x86.avx512.vpshrd.w.512
   // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}}
   return _mm512_maskz_shrdi_epi16(__U, __A, __B, 15);
 }
 
 __m512i test_mm512_shrdi_epi16(__m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_shrdi_epi16
-  // CHECK: @llvm.fshr.v32i16(<32 x i16> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> )
+  // CHECK: @llvm.x86.avx512.vpshrd.w.512
   return _mm512_shrdi_epi16(__A, __B, 31);
 }
 
 __m512i test_mm512_mask_shldv_epi64(__m512i __S, __mmask8 __U, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_mask_shldv_epi64
-  // CHECK: @llvm.fshl.v8i64(<8 x i64> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}})
-  // CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}}
+  // CHECK: @llvm.x86.avx512.mask.vpshldv.q.512
   return _mm512_mask_shldv_epi64(__S, __U, __A, __B);
 }
 
 __m512i test_mm512_maskz_shldv_epi64(__mmask8 __U, __m512i __S, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_maskz_shldv_epi64
-  // CHECK: @llvm.fshl.v8i64(<8 x i64> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}})
-  // CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}}
+  // CHECK: @llvm.x86.avx512.maskz.vpshldv.q.512
   return _mm512_maskz_shldv_epi64(__U, __S, __A, __B);
 }
 
 __m512i test_mm512_shldv_epi64(__m512i __S, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_shldv_epi64
-  // CHECK: @llvm.fshl.v8i64(<8 x i64> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}})
+  // CHECK: @llvm.x86.avx512.mask.vpshldv.q.512
   return _mm512_shldv_epi64(__S, __A, __B);
 }
 
 __m512i test_mm512_mask_shldv_epi32(__m512i __S, __mmask16 __U, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_mask_shldv_epi32
-  // CHECK: @llvm.fshl.v16i32(<16 x i32> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}})
-  // CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}}
+  // CHECK: @llvm.x86.avx512.mask.vpshldv.d.512
   return _mm512_mask_shldv_epi32(__S, __U, __A, __B);
 }
 
 __m512i test_mm512_maskz_shldv_epi32(__mmask16 __U, __m512i __S, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_maskz_shldv_epi32
-  // CHECK: @llvm.fshl.v16i32(<16 x i32> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}})
-  // CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}}
+  // CHECK: @llvm.x86.avx512.maskz.vpshldv.d.512
   return _mm512_maskz_shldv_epi32(__U, __S, __A, __B);
 }
 
 __m512i test_mm512_shldv_epi32(__m512i __S, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_shldv_epi32
-  // CHECK: @llvm.fshl.v16i32(<16 x i32> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}})
+  // CHECK: @llvm.x86.avx512.mask.vpshldv.d.512
   return _mm512_shldv_epi32(__S, __A, __B);
 }
 
 __m512i test_mm512_mask_shldv_epi16(__m512i __S, __mmask32 __U, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_mask_shldv_epi16
-  // CHECK: @llvm.fshl.v32i16(<32 x i16> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}})
-  // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}}
+  // CHECK: @llvm.x86.avx512.mask.vpshldv.w.512
   return _mm512_mask_shldv_epi16(__S, __U, __A, __B);
 }
 
 __m512i test_mm512_maskz_shldv_epi16(__mmask32 __U, __m512i __S, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_maskz_shldv_epi16
-  // CHECK: @llvm.fshl.v32i16(<32 x i16> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}})
-  // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}}
+  // CHECK: @llvm.x86.avx512.maskz.vpshldv.w.512
   return _mm512_maskz_shldv_epi16(__U, __S, __A, __B);
 }
 
 __m512i test_mm512_shldv_epi16(__m512i __S, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_shldv_epi16
-  // CHECK: @llvm.fshl.v32i16(<32 x i16> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}})
+  // CHECK: @llvm.x86.avx512.mask.vpshldv.w.512
   return _mm512_shldv_epi16(__S, __A, __B);
 }
 
 __m512i test_mm512_mask_shrdv_epi64(__m512i __S, __mmask8 __U, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_mask_shrdv_epi64
-  // CHECK: @llvm.fshr.v8i64(<8 x i64> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}})
-  // CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}}
+  // CHECK: @llvm.x86.avx512.mask.vpshrdv.q.512
   return _mm512_mask_shrdv_epi64(__S, __U, __A, __B);
 }
 
 __m512i test_mm512_maskz_shrdv_epi64(__mmask8 __U, __m512i __S, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_maskz_shrdv_epi64
-  // CHECK: @llvm.fshr.v8i64(<8 x i64> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}})
-  // CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}}
+  // CHECK: @llvm.x86.avx512.maskz.vpshrdv.q.512
   return _mm512_maskz_shrdv_epi64(__U, __S, __A, __B);
 }
 
 __m512i test_mm512_shrdv_epi64(__m512i __S, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_shrdv_epi64
-  // CHECK: @llvm.fshr.v8i64(<8 x i64> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}})
+  // CHECK: @llvm.x86.avx512.mask.vpshrdv.q.512
   return _mm512_shrdv_epi64(__S, __A, __B);
 }
 
 __m512i test_mm512_mask_shrdv_epi32(__m512i __S, __mmask16 __U, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_mask_shrdv_epi32
-  // CHECK: @llvm.fshr.v16i32(<16 x i32> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}})
-  // CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}}
+  // CHECK: @llvm.x86.avx512.mask.vpshrdv.d.512
   return _mm512_mask_shrdv_epi32(__S, __U, __A, __B);
 }
 
 __m512i test_mm512_maskz_shrdv_epi32(__mmask16 __U, __m512i __S, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_maskz_shrdv_epi32
-  // CHECK: @llvm.fshr.v16i32(<16 x i32> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}})
-  // CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}}
+  // CHECK: @llvm.x86.avx512.maskz.vpshrdv.d.512
   return _mm512_maskz_shrdv_epi32(__U, __S, __A, __B);
 }
 
 __m512i test_mm512_shrdv_epi32(__m512i __S, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_shrdv_epi32
-  // CHECK: @llvm.fshr.v16i32(<16 x i32> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}})
+  // CHECK: @llvm.x86.avx512.mask.vpshrdv.d.512
   return _mm512_shrdv_epi32(__S, __A, __B);
 }
 
 __m512i test_mm512_mask_shrdv_epi16(__m512i __S, __mmask32 __U, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_mask_shrdv_epi16
-  // CHECK: @llvm.fshr.v32i16(<32 x i16> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}})
-  // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}}
+  // CHECK: @llvm.x86.avx512.mask.vpshrdv.w.512
   return _mm512_mask_shrdv_epi16(__S, __U, __A, __B);
 }
 
 __m512i test_mm512_maskz_shrdv_epi16(__mmask32 __U, __m512i __S, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_maskz_shrdv_epi16
-  // CHECK: @llvm.fshr.v32i16(<32 x i16> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}})
-  // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}}
+  // CHECK: @llvm.x86.avx512.maskz.vpshrdv.w.512
   return _mm512_maskz_shrdv_epi16(__U, __S, __A, __B);
 }
 
 __m512i test_mm512_shrdv_epi16(__m512i __S, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_shrdv_epi16
-  // CHECK: @llvm.fshr.v32i16(<32 x i16> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}})
+  // CHECK: @llvm.x86.avx512.mask.vpshrdv.w.512
   return _mm512_shrdv_epi16(__S, __A, __B);
 }
 
diff --git a/test/CodeGen/avx512vlvbmi2-builtins.c b/test/CodeGen/avx512vlvbmi2-builtins.c
index b512a728a5..53b58400bc 100644
--- a/test/CodeGen/avx512vlvbmi2-builtins.c
+++ b/test/CodeGen/avx512vlvbmi2-builtins.c
@@ -172,481 +172,457 @@ __m256i test_mm256_maskz_expandloadu_epi8(__mmask32 __U, void const* __P) {
 
 __m256i test_mm256_mask_shldi_epi64(__m256i __S, __mmask8 __U, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_mask_shldi_epi64
-  // CHECK: @llvm.fshl.v4i64(<4 x i64> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> )
+  // CHECK: @llvm.x86.avx512.vpshld.q.256
   // CHECK: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}}
   return _mm256_mask_shldi_epi64(__S, __U, __A, __B, 47);
 }
 
 __m256i test_mm256_maskz_shldi_epi64(__mmask8 __U, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_maskz_shldi_epi64
-  // CHECK: @llvm.fshl.v4i64(<4 x i64> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> )
+  // CHECK: @llvm.x86.avx512.vpshld.q.256
   // CHECK: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}}
   return _mm256_maskz_shldi_epi64(__U, __A, __B, 63);
 }
 
 __m256i test_mm256_shldi_epi64(__m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_shldi_epi64
-  // CHECK: @llvm.fshl.v4i64(<4 x i64> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> )
+  // CHECK: @llvm.x86.avx512.vpshld.q.256
   return _mm256_shldi_epi64(__A, __B, 31);
 }
 
 __m128i test_mm_mask_shldi_epi64(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_mask_shldi_epi64
-  // CHECK: @llvm.fshl.v2i64(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> )
+  // CHECK: @llvm.x86.avx512.vpshld.q.128
   // CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}}
   return _mm_mask_shldi_epi64(__S, __U, __A, __B, 47);
 }
 
 __m128i test_mm_maskz_shldi_epi64(__mmask8 __U, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_maskz_shldi_epi64
-  // CHECK: @llvm.fshl.v2i64(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> )
+  // CHECK: @llvm.x86.avx512.vpshld.q.128
   // CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}}
   return _mm_maskz_shldi_epi64(__U, __A, __B, 63);
 }
 
 __m128i test_mm_shldi_epi64(__m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_shldi_epi64
-  // CHECK: @llvm.fshl.v2i64(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> )
+  // CHECK: @llvm.x86.avx512.vpshld.q.128
   return _mm_shldi_epi64(__A, __B, 31);
 }
 
 __m256i test_mm256_mask_shldi_epi32(__m256i __S, __mmask8 __U, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_mask_shldi_epi32
-  // CHECK: @llvm.fshl.v8i32(<8 x i32> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> )
+  // CHECK: @llvm.x86.avx512.vpshld.d.256
   // CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}}
   return _mm256_mask_shldi_epi32(__S, __U, __A, __B, 7);
 }
 
 __m256i test_mm256_maskz_shldi_epi32(__mmask8 __U, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_maskz_shldi_epi32
-  // CHECK: @llvm.fshl.v8i32(<8 x i32> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> )
+  // CHECK: @llvm.x86.avx512.vpshld.d.256
   // CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}}
   return _mm256_maskz_shldi_epi32(__U, __A, __B, 15);
 }
 
 __m256i test_mm256_shldi_epi32(__m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_shldi_epi32
-  // CHECK: @llvm.fshl.v8i32(<8 x i32> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> )
+  // CHECK: @llvm.x86.avx512.vpshld.d.256
   return _mm256_shldi_epi32(__A, __B, 31);
 }
 
 __m128i test_mm_mask_shldi_epi32(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_mask_shldi_epi32
-  // CHECK: @llvm.fshl.v4i32(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> )
+  // CHECK: @llvm.x86.avx512.vpshld.d.128
   // CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
   return _mm_mask_shldi_epi32(__S, __U, __A, __B, 7);
 }
 
 __m128i test_mm_maskz_shldi_epi32(__mmask8 __U, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_maskz_shldi_epi32
-  // CHECK: @llvm.fshl.v4i32(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> )
+  // CHECK: @llvm.x86.avx512.vpshld.d.128
   // CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
   return _mm_maskz_shldi_epi32(__U, __A, __B, 15);
 }
 
 __m128i test_mm_shldi_epi32(__m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_shldi_epi32
-  // CHECK: @llvm.fshl.v4i32(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> )
+  // CHECK: @llvm.x86.avx512.vpshld.d.128
   return _mm_shldi_epi32(__A, __B, 31);
 }
 
 __m256i test_mm256_mask_shldi_epi16(__m256i __S, __mmask16 __U, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_mask_shldi_epi16
-  // CHECK: @llvm.fshl.v16i16(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> )
+  // CHECK: @llvm.x86.avx512.vpshld.w.256
   // CHECK: select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}}
   return _mm256_mask_shldi_epi16(__S, __U, __A, __B, 3);
 }
 
 __m256i test_mm256_maskz_shldi_epi16(__mmask16 __U, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_maskz_shldi_epi16
-  // CHECK: @llvm.fshl.v16i16(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> )
+  // CHECK: @llvm.x86.avx512.vpshld.w.256
   // CHECK: select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}}
   return _mm256_maskz_shldi_epi16(__U, __A, __B, 7);
 }
 
 __m256i test_mm256_shldi_epi16(__m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_shldi_epi16
-  // CHECK: @llvm.fshl.v16i16(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> )
+  // CHECK: @llvm.x86.avx512.vpshld.w.256
   return _mm256_shldi_epi16(__A, __B, 31);
 }
 
 __m128i test_mm_mask_shldi_epi16(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_mask_shldi_epi16
-  // CHECK: @llvm.fshl.v8i16(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> )
+  // CHECK: @llvm.x86.avx512.vpshld.w.128
   // CHECK: select <8 x i1> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}
   return _mm_mask_shldi_epi16(__S, __U, __A, __B, 3);
 }
 
 __m128i test_mm_maskz_shldi_epi16(__mmask8 __U, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_maskz_shldi_epi16
-  // CHECK: @llvm.fshl.v8i16(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> )
+  // CHECK: @llvm.x86.avx512.vpshld.w.128
   // CHECK: select <8 x i1> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}
   return _mm_maskz_shldi_epi16(__U, __A, __B, 7);
 }
 
 __m128i test_mm_shldi_epi16(__m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_shldi_epi16
-  // CHECK: @llvm.fshl.v8i16(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> )
+  // CHECK: @llvm.x86.avx512.vpshld.w.128
   return _mm_shldi_epi16(__A, __B, 31);
 }
 
 __m256i test_mm256_mask_shrdi_epi64(__m256i __S, __mmask8 __U, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_mask_shrdi_epi64
-  // CHECK: @llvm.fshr.v4i64(<4 x i64> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> )
+  // CHECK: @llvm.x86.avx512.vpshrd.q.256
   // CHECK: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}}
   return _mm256_mask_shrdi_epi64(__S, __U, __A, __B, 47);
 }
 
 __m256i test_mm256_maskz_shrdi_epi64(__mmask8 __U, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_maskz_shrdi_epi64
-  // CHECK: @llvm.fshr.v4i64(<4 x i64> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> )
+  // CHECK: @llvm.x86.avx512.vpshrd.q.256
   // CHECK: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}}
   return _mm256_maskz_shrdi_epi64(__U, __A, __B, 63);
 }
 
 __m256i test_mm256_shrdi_epi64(__m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_shrdi_epi64
-  // CHECK: @llvm.fshr.v4i64(<4 x i64> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> )
+  // CHECK: @llvm.x86.avx512.vpshrd.q.256
   return _mm256_shrdi_epi64(__A, __B, 31);
 }
 
 __m128i test_mm_mask_shrdi_epi64(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_mask_shrdi_epi64
-  // CHECK: @llvm.fshr.v2i64(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> )
+  // CHECK: @llvm.x86.avx512.vpshrd.q.128
   // CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}}
   return _mm_mask_shrdi_epi64(__S, __U, __A, __B, 47);
 }
 
 __m128i test_mm_maskz_shrdi_epi64(__mmask8 __U, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_maskz_shrdi_epi64
-  // CHECK: @llvm.fshr.v2i64(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> )
+  // CHECK: @llvm.x86.avx512.vpshrd.q.128
   // CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}}
   return _mm_maskz_shrdi_epi64(__U, __A, __B, 63);
 }
 
 __m128i test_mm_shrdi_epi64(__m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_shrdi_epi64
-  // CHECK: @llvm.fshr.v2i64(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> )
+  // CHECK: @llvm.x86.avx512.vpshrd.q.128
   return _mm_shrdi_epi64(__A, __B, 31);
 }
 
 __m256i test_mm256_mask_shrdi_epi32(__m256i __S, __mmask8 __U, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_mask_shrdi_epi32
-  // CHECK: @llvm.fshr.v8i32(<8 x i32> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> )
+  // CHECK: @llvm.x86.avx512.vpshrd.d.256
   // CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}}
   return _mm256_mask_shrdi_epi32(__S, __U, __A, __B, 7);
 }
 
 __m256i test_mm256_maskz_shrdi_epi32(__mmask8 __U, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_maskz_shrdi_epi32
-  // CHECK: @llvm.fshr.v8i32(<8 x i32> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> )
+  // CHECK: @llvm.x86.avx512.vpshrd.d.256
   // CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}}
   return _mm256_maskz_shrdi_epi32(__U, __A, __B, 15);
 }
 
 __m256i test_mm256_shrdi_epi32(__m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_shrdi_epi32
-  // CHECK: @llvm.fshr.v8i32(<8 x i32> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> )
+  // CHECK: @llvm.x86.avx512.vpshrd.d.256
   return _mm256_shrdi_epi32(__A, __B, 31);
 }
 
 __m128i test_mm_mask_shrdi_epi32(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_mask_shrdi_epi32
-  // CHECK: @llvm.fshr.v4i32(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> )
+  // CHECK: @llvm.x86.avx512.vpshrd.d.128
   // CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
   return _mm_mask_shrdi_epi32(__S, __U, __A, __B, 7);
 }
 
 __m128i test_mm_maskz_shrdi_epi32(__mmask8 __U, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_maskz_shrdi_epi32
-  // CHECK: @llvm.fshr.v4i32(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> )
+  // CHECK: @llvm.x86.avx512.vpshrd.d.128
   // CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
   return _mm_maskz_shrdi_epi32(__U, __A, __B, 15);
 }
 
 __m128i test_mm_shrdi_epi32(__m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_shrdi_epi32
-  // CHECK: @llvm.fshr.v4i32(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> )
+  // CHECK: @llvm.x86.avx512.vpshrd.d.128
   return _mm_shrdi_epi32(__A, __B, 31);
 }
 
 __m256i test_mm256_mask_shrdi_epi16(__m256i __S, __mmask16 __U, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_mask_shrdi_epi16
-  // CHECK: @llvm.fshr.v16i16(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> )
+  // CHECK: @llvm.x86.avx512.vpshrd.w.256
   // CHECK: select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}}
   return _mm256_mask_shrdi_epi16(__S, __U, __A, __B, 3);
 }
 
 __m256i test_mm256_maskz_shrdi_epi16(__mmask16 __U, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_maskz_shrdi_epi16
-  // CHECK: @llvm.fshr.v16i16(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> )
+  // CHECK: @llvm.x86.avx512.vpshrd.w.256
   // CHECK: select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}}
   return _mm256_maskz_shrdi_epi16(__U, __A, __B, 7);
 }
 
 __m256i test_mm256_shrdi_epi16(__m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_shrdi_epi16
-  // CHECK: @llvm.fshr.v16i16(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> 
+  // CHECK: @llvm.x86.avx512.vpshrd.w.256
   return _mm256_shrdi_epi16(__A, __B, 31);
 }
 
 __m128i test_mm_mask_shrdi_epi16(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_mask_shrdi_epi16
-  // CHECK: @llvm.fshr.v8i16(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> )
+  // CHECK: @llvm.x86.avx512.vpshrd.w.128
   // CHECK: select <8 x i1> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}
   return _mm_mask_shrdi_epi16(__S, __U, __A, __B, 3);
 }
 
 __m128i test_mm_maskz_shrdi_epi16(__mmask8 __U, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_maskz_shrdi_epi16
-  // CHECK: @llvm.fshr.v8i16(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> )
+  // CHECK: @llvm.x86.avx512.vpshrd.w.128
   // CHECK: select <8 x i1> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}
   return _mm_maskz_shrdi_epi16(__U, __A, __B, 7);
 }
 
 __m128i test_mm_shrdi_epi16(__m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_shrdi_epi16
-  // CHECK: @llvm.fshr.v8i16(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> )
+  // CHECK: @llvm.x86.avx512.vpshrd.w.128
   return _mm_shrdi_epi16(__A, __B, 31);
 }
 
 __m256i test_mm256_mask_shldv_epi64(__m256i __S, __mmask8 __U, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_mask_shldv_epi64
-  // CHECK: @llvm.fshl.v4i64(<4 x i64> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}})
-  // CHECK: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}}
+  // CHECK: @llvm.x86.avx512.mask.vpshldv.q.256
   return _mm256_mask_shldv_epi64(__S, __U, __A, __B);
 }
 
 __m256i test_mm256_maskz_shldv_epi64(__mmask8 __U, __m256i __S, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_maskz_shldv_epi64
-  // CHECK: @llvm.fshl.v4i64(<4 x i64> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}})
-  // CHECK: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}}
+  // CHECK: @llvm.x86.avx512.maskz.vpshldv.q.256
   return _mm256_maskz_shldv_epi64(__U, __S, __A, __B);
 }
 
 __m256i test_mm256_shldv_epi64(__m256i __S, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_shldv_epi64
-  // CHECK: @llvm.fshl.v4i64(<4 x i64> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}})
+  // CHECK: @llvm.x86.avx512.mask.vpshldv.q.256
   return _mm256_shldv_epi64(__S, __A, __B);
 }
 
 __m128i test_mm_mask_shldv_epi64(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_mask_shldv_epi64
-  // CHECK: @llvm.fshl.v2i64(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}})
-  // CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}}
+  // CHECK: @llvm.x86.avx512.mask.vpshldv.q.128
   return _mm_mask_shldv_epi64(__S, __U, __A, __B);
 }
 
 __m128i test_mm_maskz_shldv_epi64(__mmask8 __U, __m128i __S, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_maskz_shldv_epi64
-  // CHECK: @llvm.fshl.v2i64(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}})
-  // CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}}
+  // CHECK: @llvm.x86.avx512.maskz.vpshldv.q.128
   return _mm_maskz_shldv_epi64(__U, __S, __A, __B);
 }
 
 __m128i test_mm_shldv_epi64(__m128i __S, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_shldv_epi64
-  // CHECK: @llvm.fshl.v2i64(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}})
+  // CHECK: @llvm.x86.avx512.mask.vpshldv.q.128
   return _mm_shldv_epi64(__S, __A, __B);
 }
 
 __m256i test_mm256_mask_shldv_epi32(__m256i __S, __mmask8 __U, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_mask_shldv_epi32
-  // CHECK: @llvm.fshl.v8i32(<8 x i32> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}})
-  // CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}}
+  // CHECK: @llvm.x86.avx512.mask.vpshldv.d.256
   return _mm256_mask_shldv_epi32(__S, __U, __A, __B);
 }
 
 __m256i test_mm256_maskz_shldv_epi32(__mmask8 __U, __m256i __S, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_maskz_shldv_epi32
-  // CHECK: @llvm.fshl.v8i32(<8 x i32> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}})
-  // CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}}
+  // CHECK: @llvm.x86.avx512.maskz.vpshldv.d.256
   return _mm256_maskz_shldv_epi32(__U, __S, __A, __B);
 }
 
 __m256i test_mm256_shldv_epi32(__m256i __S, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_shldv_epi32
-  // CHECK: @llvm.fshl.v8i32(<8 x i32> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}})
+  // CHECK: @llvm.x86.avx512.mask.vpshldv.d.256
   return _mm256_shldv_epi32(__S, __A, __B);
 }
 
 __m128i test_mm_mask_shldv_epi32(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_mask_shldv_epi32
-  // CHECK: @llvm.fshl.v4i32(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}})
-  // CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
+  // CHECK: @llvm.x86.avx512.mask.vpshldv.d.128
   return _mm_mask_shldv_epi32(__S, __U, __A, __B);
 }
 
 __m128i test_mm_maskz_shldv_epi32(__mmask8 __U, __m128i __S, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_maskz_shldv_epi32
-  // CHECK: @llvm.fshl.v4i32(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}})
-  // CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
+  // CHECK: @llvm.x86.avx512.maskz.vpshldv.d.128
   return _mm_maskz_shldv_epi32(__U, __S, __A, __B);
 }
 
 __m128i test_mm_shldv_epi32(__m128i __S, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_shldv_epi32
-  // CHECK: @llvm.fshl.v4i32(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}})
+  // CHECK: @llvm.x86.avx512.mask.vpshldv.d.128
   return _mm_shldv_epi32(__S, __A, __B);
 }
 
 __m256i test_mm256_mask_shldv_epi16(__m256i __S, __mmask16 __U, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_mask_shldv_epi16
-  // CHECK: @llvm.fshl.v16i16(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}})
-  // CHECK: select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}}
+  // CHECK: @llvm.x86.avx512.mask.vpshldv.w.256
   return _mm256_mask_shldv_epi16(__S, __U, __A, __B);
 }
 
 __m256i test_mm256_maskz_shldv_epi16(__mmask16 __U, __m256i __S, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_maskz_shldv_epi16
-  // CHECK: @llvm.fshl.v16i16(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}})
-  // CHECK: select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}}
+  // CHECK: @llvm.x86.avx512.maskz.vpshldv.w.256
   return _mm256_maskz_shldv_epi16(__U, __S, __A, __B);
 }
 
 __m256i test_mm256_shldv_epi16(__m256i __S, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_shldv_epi16
-  // CHECK: @llvm.fshl.v16i16(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}})
+  // CHECK: @llvm.x86.avx512.mask.vpshldv.w.256
   return _mm256_shldv_epi16(__S, __A, __B);
 }
 
 __m128i test_mm_mask_shldv_epi16(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_mask_shldv_epi16
-  // CHECK: @llvm.fshl.v8i16(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}})
-  // CHECK: select <8 x i1> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}
+  // CHECK: @llvm.x86.avx512.mask.vpshldv.w.128
   return _mm_mask_shldv_epi16(__S, __U, __A, __B);
 }
 
 __m128i test_mm_maskz_shldv_epi16(__mmask8 __U, __m128i __S, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_maskz_shldv_epi16
-  // CHECK: @llvm.fshl.v8i16(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}})
-  // CHECK: select <8 x i1> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}
+  // CHECK: @llvm.x86.avx512.maskz.vpshldv.w.128
   return _mm_maskz_shldv_epi16(__U, __S, __A, __B);
 }
 
 __m128i test_mm_shldv_epi16(__m128i __S, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_shldv_epi16
-  // CHECK: @llvm.fshl.v8i16(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}})
+  // CHECK: @llvm.x86.avx512.mask.vpshldv.w.128
   return _mm_shldv_epi16(__S, __A, __B);
 }
 
 __m256i test_mm256_mask_shrdv_epi64(__m256i __S, __mmask8 __U, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_mask_shrdv_epi64
-  // CHECK: @llvm.fshr.v4i64(<4 x i64> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}})
-  // CHECK: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}}
+  // CHECK: @llvm.x86.avx512.mask.vpshrdv.q.256
   return _mm256_mask_shrdv_epi64(__S, __U, __A, __B);
 }
 
 __m256i test_mm256_maskz_shrdv_epi64(__mmask8 __U, __m256i __S, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_maskz_shrdv_epi64
-  // CHECK: @llvm.fshr.v4i64(<4 x i64> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}})
-  // CHECK: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}}
+  // CHECK: @llvm.x86.avx512.maskz.vpshrdv.q.256
   return _mm256_maskz_shrdv_epi64(__U, __S, __A, __B);
 }
 
 __m256i test_mm256_shrdv_epi64(__m256i __S, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_shrdv_epi64
-  // CHECK: @llvm.fshr.v4i64(<4 x i64> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}})
+  // CHECK: @llvm.x86.avx512.mask.vpshrdv.q.256
   return _mm256_shrdv_epi64(__S, __A, __B);
 }
 
 __m128i test_mm_mask_shrdv_epi64(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_mask_shrdv_epi64
-  // CHECK: @llvm.fshr.v2i64(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}})
-  // CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}}
+  // CHECK: @llvm.x86.avx512.mask.vpshrdv.q.128
   return _mm_mask_shrdv_epi64(__S, __U, __A, __B);
 }
 
 __m128i test_mm_maskz_shrdv_epi64(__mmask8 __U, __m128i __S, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_maskz_shrdv_epi64
-  // CHECK: @llvm.fshr.v2i64(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}})
-  // CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}}
+  // CHECK: @llvm.x86.avx512.maskz.vpshrdv.q.128
   return _mm_maskz_shrdv_epi64(__U, __S, __A, __B);
 }
 
 __m128i test_mm_shrdv_epi64(__m128i __S, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_shrdv_epi64
-  // CHECK: @llvm.fshr.v2i64(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}})
+  // CHECK: @llvm.x86.avx512.mask.vpshrdv.q.128
   return _mm_shrdv_epi64(__S, __A, __B);
 }
 
 __m256i test_mm256_mask_shrdv_epi32(__m256i __S, __mmask8 __U, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_mask_shrdv_epi32
-  // CHECK: @llvm.fshr.v8i32(<8 x i32> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}})
-  // CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}}
+  // CHECK: @llvm.x86.avx512.mask.vpshrdv.d.256
   return _mm256_mask_shrdv_epi32(__S, __U, __A, __B);
 }
 
 __m256i test_mm256_maskz_shrdv_epi32(__mmask8 __U, __m256i __S, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_maskz_shrdv_epi32
-  // CHECK: @llvm.fshr.v8i32(<8 x i32> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}})
-  // CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}}
+  // CHECK: @llvm.x86.avx512.maskz.vpshrdv.d.256
   return _mm256_maskz_shrdv_epi32(__U, __S, __A, __B);
 }
 
 __m256i test_mm256_shrdv_epi32(__m256i __S, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_shrdv_epi32
-  // CHECK: @llvm.fshr.v8i32(<8 x i32> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}})
+  // CHECK: @llvm.x86.avx512.mask.vpshrdv.d.256
   return _mm256_shrdv_epi32(__S, __A, __B);
 }
 
 __m128i test_mm_mask_shrdv_epi32(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_mask_shrdv_epi32
-  // CHECK: @llvm.fshr.v4i32(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}})
-  // CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
+  // CHECK: @llvm.x86.avx512.mask.vpshrdv.d.128
   return _mm_mask_shrdv_epi32(__S, __U, __A, __B);
 }
 
 __m128i test_mm_maskz_shrdv_epi32(__mmask8 __U, __m128i __S, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_maskz_shrdv_epi32
-  // CHECK: @llvm.fshr.v4i32(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}})
-  // CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
+  // CHECK: @llvm.x86.avx512.maskz.vpshrdv.d.128
   return _mm_maskz_shrdv_epi32(__U, __S, __A, __B);
 }
 
 __m128i test_mm_shrdv_epi32(__m128i __S, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_shrdv_epi32
-  // CHECK: @llvm.fshr.v4i32(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}})
+  // CHECK: @llvm.x86.avx512.mask.vpshrdv.d.128
   return _mm_shrdv_epi32(__S, __A, __B);
 }
 
 __m256i test_mm256_mask_shrdv_epi16(__m256i __S, __mmask16 __U, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_mask_shrdv_epi16
-  // CHECK: @llvm.fshr.v16i16(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}})
-  // CHECK: select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}}
+  // CHECK: @llvm.x86.avx512.mask.vpshrdv.w.256
   return _mm256_mask_shrdv_epi16(__S, __U, __A, __B);
 }
 
 __m256i test_mm256_maskz_shrdv_epi16(__mmask16 __U, __m256i __S, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_maskz_shrdv_epi16
-  // CHECK: @llvm.fshr.v16i16(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}})
-  // CHECK: select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}}
+  // CHECK: @llvm.x86.avx512.maskz.vpshrdv.w.256
   return _mm256_maskz_shrdv_epi16(__U, __S, __A, __B);
 }
 
 __m256i test_mm256_shrdv_epi16(__m256i __S, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_shrdv_epi16
-  // CHECK: @llvm.fshr.v16i16(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}})
+  // CHECK: @llvm.x86.avx512.mask.vpshrdv.w.256
   return _mm256_shrdv_epi16(__S, __A, __B);
 }
 
 __m128i test_mm_mask_shrdv_epi16(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_mask_shrdv_epi16
-  // CHECK: @llvm.fshr.v8i16(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}})
-  // CHECK: select <8 x i1> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}
+  // CHECK: @llvm.x86.avx512.mask.vpshrdv.w.128
   return _mm_mask_shrdv_epi16(__S, __U, __A, __B);
 }
 
 __m128i test_mm_maskz_shrdv_epi16(__mmask8 __U, __m128i __S, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_maskz_shrdv_epi16
-  // CHECK: @llvm.fshr.v8i16(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}})
-  // CHECK: select <8 x i1> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}
+  // CHECK: @llvm.x86.avx512.maskz.vpshrdv.w.128
   return _mm_maskz_shrdv_epi16(__U, __S, __A, __B);
 }
 
 __m128i test_mm_shrdv_epi16(__m128i __S, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_shrdv_epi16
-  // CHECK: @llvm.fshr.v8i16(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}})
+  // CHECK: @llvm.x86.avx512.mask.vpshrdv.w.128
   return _mm_shrdv_epi16(__S, __A, __B);
 }
 
-- 
cgit v1.2.3


From 7a9019d1530f9e93dcd04078c404194168339d87 Mon Sep 17 00:00:00 2001
From: Craig Topper 
Date: Mon, 7 Jan 2019 21:00:41 +0000
Subject: Recommit r350555 "[X86] Use funnel shift intrinsics for the VBMI2
 vshld/vshrd builtins."

The MSVC limit hit in AutoUpgrade.cpp has been worked around for now.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350568 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/Basic/BuiltinsX86.def   |  56 +++---
 lib/CodeGen/CGBuiltin.cpp             |  46 +++++
 lib/Headers/avx512vbmi2intrin.h       | 158 +++++++----------
 lib/Headers/avx512vlvbmi2intrin.h     | 312 ++++++++++++++--------------------
 test/CodeGen/avx512vbmi2-builtins.c   |  84 +++++----
 test/CodeGen/avx512vlvbmi2-builtins.c | 168 ++++++++++--------
 6 files changed, 407 insertions(+), 417 deletions(-)

diff --git a/include/clang/Basic/BuiltinsX86.def b/include/clang/Basic/BuiltinsX86.def
index d97ec58916..ccb5cd04d2 100644
--- a/include/clang/Basic/BuiltinsX86.def
+++ b/include/clang/Basic/BuiltinsX86.def
@@ -1256,43 +1256,25 @@ TARGET_BUILTIN(__builtin_ia32_vpshldw128, "V8sV8sV8sIi", "ncV:128:", "avx512vl,a
 TARGET_BUILTIN(__builtin_ia32_vpshldw256, "V16sV16sV16sIi", "ncV:256:", "avx512vl,avx512vbmi2")
 TARGET_BUILTIN(__builtin_ia32_vpshldw512, "V32sV32sV32sIi", "ncV:512:", "avx512vbmi2")
 
-TARGET_BUILTIN(__builtin_ia32_vpshldvd128_mask, "V4iV4iV4iV4iUc", "ncV:128:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvd256_mask, "V8iV8iV8iV8iUc", "ncV:256:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvd512_mask, "V16iV16iV16iV16iUs", "ncV:512:", "avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "ncV:128:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "ncV:256:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "ncV:512:", "avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvw128_mask, "V8sV8sV8sV8sUc", "ncV:128:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvw256_mask, "V16sV16sV16sV16sUs", "ncV:256:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvw512_mask, "V32sV32sV32sV32sUi", "ncV:512:", "avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvd128_maskz, "V4iV4iV4iV4iUc", "ncV:128:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvd256_maskz, "V8iV8iV8iV8iUc", "ncV:256:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvd512_maskz, "V16iV16iV16iV16iUs", "ncV:512:", "avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvq128_maskz, "V2LLiV2LLiV2LLiV2LLiUc", "ncV:128:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvq256_maskz, "V4LLiV4LLiV4LLiV4LLiUc", "ncV:256:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvq512_maskz, "V8LLiV8LLiV8LLiV8LLiUc", "ncV:512:", "avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvw128_maskz, "V8sV8sV8sV8sUc", "ncV:128:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvw256_maskz, "V16sV16sV16sV16sUs", "ncV:256:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvw512_maskz, "V32sV32sV32sV32sUi", "ncV:512:", "avx512vbmi2")
-
-TARGET_BUILTIN(__builtin_ia32_vpshrdvd128_mask, "V4iV4iV4iV4iUc", "ncV:128:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvd256_mask, "V8iV8iV8iV8iUc", "ncV:256:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvd512_mask, "V16iV16iV16iV16iUs", "ncV:512:", "avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "ncV:128:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "ncV:256:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "ncV:512:", "avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvw128_mask, "V8sV8sV8sV8sUc", "ncV:128:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvw256_mask, "V16sV16sV16sV16sUs", "ncV:256:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvw512_mask, "V32sV32sV32sV32sUi", "ncV:512:", "avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvd128_maskz, "V4iV4iV4iV4iUc", "ncV:128:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvd256_maskz, "V8iV8iV8iV8iUc", "ncV:256:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvd512_maskz, "V16iV16iV16iV16iUs", "ncV:512:", "avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvq128_maskz, "V2LLiV2LLiV2LLiV2LLiUc", "ncV:128:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvq256_maskz, "V4LLiV4LLiV4LLiV4LLiUc", "ncV:256:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvq512_maskz, "V8LLiV8LLiV8LLiV8LLiUc", "ncV:512:", "avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvw128_maskz, "V8sV8sV8sV8sUc", "ncV:128:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvw256_maskz, "V16sV16sV16sV16sUs", "ncV:256:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvw512_maskz, "V32sV32sV32sV32sUi", "ncV:512:", "avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvd128, "V4iV4iV4iV4i", "ncV:128:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvd256, "V8iV8iV8iV8i", "ncV:256:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvd512, "V16iV16iV16iV16i", "ncV:512:", "avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvq128, "V2LLiV2LLiV2LLiV2LLi", "ncV:128:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvq256, "V4LLiV4LLiV4LLiV4LLi", "ncV:256:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvq512, "V8LLiV8LLiV8LLiV8LLi", "ncV:512:", "avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvw128, "V8sV8sV8sV8s", "ncV:128:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvw256, "V16sV16sV16sV16s", "ncV:256:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvw512, "V32sV32sV32sV32s", "ncV:512:", "avx512vbmi2")
+
+TARGET_BUILTIN(__builtin_ia32_vpshrdvd128, "V4iV4iV4iV4i", "ncV:128:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdvd256, "V8iV8iV8iV8i", "ncV:256:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdvd512, "V16iV16iV16iV16i", "ncV:512:", "avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdvq128, "V2LLiV2LLiV2LLiV2LLi", "ncV:128:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdvq256, "V4LLiV4LLiV4LLiV4LLi", "ncV:256:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdvq512, "V8LLiV8LLiV8LLiV8LLi", "ncV:512:", "avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdvw128, "V8sV8sV8sV8s", "ncV:128:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdvw256, "V16sV16sV16sV16s", "ncV:256:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdvw512, "V32sV32sV32sV32s", "ncV:512:", "avx512vbmi2")
 
 TARGET_BUILTIN(__builtin_ia32_vpshrdd128, "V4iV4iV4iIi", "ncV:128:", "avx512vl,avx512vbmi2")
 TARGET_BUILTIN(__builtin_ia32_vpshrdd256, "V8iV8iV8iIi", "ncV:256:", "avx512vl,avx512vbmi2")
diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp
index 93484f82c3..ca7b4691ff 100644
--- a/lib/CodeGen/CGBuiltin.cpp
+++ b/lib/CodeGen/CGBuiltin.cpp
@@ -10999,6 +10999,52 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID,
   case X86::BI__builtin_ia32_pternlogq256_maskz:
     return EmitX86Ternlog(*this, /*ZeroMask*/true, Ops);
 
+  case X86::BI__builtin_ia32_vpshldd128:
+  case X86::BI__builtin_ia32_vpshldd256:
+  case X86::BI__builtin_ia32_vpshldd512:
+  case X86::BI__builtin_ia32_vpshldq128:
+  case X86::BI__builtin_ia32_vpshldq256:
+  case X86::BI__builtin_ia32_vpshldq512:
+  case X86::BI__builtin_ia32_vpshldw128:
+  case X86::BI__builtin_ia32_vpshldw256:
+  case X86::BI__builtin_ia32_vpshldw512:
+    return EmitX86FunnelShift(*this, Ops[0], Ops[1], Ops[2], false);
+
+  case X86::BI__builtin_ia32_vpshrdd128:
+  case X86::BI__builtin_ia32_vpshrdd256:
+  case X86::BI__builtin_ia32_vpshrdd512:
+  case X86::BI__builtin_ia32_vpshrdq128:
+  case X86::BI__builtin_ia32_vpshrdq256:
+  case X86::BI__builtin_ia32_vpshrdq512:
+  case X86::BI__builtin_ia32_vpshrdw128:
+  case X86::BI__builtin_ia32_vpshrdw256:
+  case X86::BI__builtin_ia32_vpshrdw512:
+    // Ops 0 and 1 are swapped.
+    return EmitX86FunnelShift(*this, Ops[1], Ops[0], Ops[2], true);
+
+  case X86::BI__builtin_ia32_vpshldvd128:
+  case X86::BI__builtin_ia32_vpshldvd256:
+  case X86::BI__builtin_ia32_vpshldvd512:
+  case X86::BI__builtin_ia32_vpshldvq128:
+  case X86::BI__builtin_ia32_vpshldvq256:
+  case X86::BI__builtin_ia32_vpshldvq512:
+  case X86::BI__builtin_ia32_vpshldvw128:
+  case X86::BI__builtin_ia32_vpshldvw256:
+  case X86::BI__builtin_ia32_vpshldvw512:
+    return EmitX86FunnelShift(*this, Ops[0], Ops[1], Ops[2], false);
+
+  case X86::BI__builtin_ia32_vpshrdvd128:
+  case X86::BI__builtin_ia32_vpshrdvd256:
+  case X86::BI__builtin_ia32_vpshrdvd512:
+  case X86::BI__builtin_ia32_vpshrdvq128:
+  case X86::BI__builtin_ia32_vpshrdvq256:
+  case X86::BI__builtin_ia32_vpshrdvq512:
+  case X86::BI__builtin_ia32_vpshrdvw128:
+  case X86::BI__builtin_ia32_vpshrdvw256:
+  case X86::BI__builtin_ia32_vpshrdvw512:
+    // Ops 0 and 1 are swapped.
+    return EmitX86FunnelShift(*this, Ops[1], Ops[0], Ops[2], true);
+
   // 3DNow!
   case X86::BI__builtin_ia32_pswapdsf:
   case X86::BI__builtin_ia32_pswapdsi: {
diff --git a/lib/Headers/avx512vbmi2intrin.h b/lib/Headers/avx512vbmi2intrin.h
index d2a58094fd..5324252429 100644
--- a/lib/Headers/avx512vbmi2intrin.h
+++ b/lib/Headers/avx512vbmi2intrin.h
@@ -227,167 +227,141 @@ _mm512_maskz_expandloadu_epi8(__mmask64 __U, void const *__P)
                                    (__v32hi)_mm512_setzero_si512())
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_mask_shldv_epi64(__m512i __S, __mmask8 __U, __m512i __A, __m512i __B)
+_mm512_shldv_epi64(__m512i __A, __m512i __B, __m512i __C)
 {
-  return (__m512i) __builtin_ia32_vpshldvq512_mask ((__v8di) __S,
-              (__v8di) __A,
-              (__v8di) __B,
-              __U);
+  return (__m512i)__builtin_ia32_vpshldvq512((__v8di)__A, (__v8di)__B,
+                                             (__v8di)__C);
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_maskz_shldv_epi64(__mmask8 __U, __m512i __S, __m512i __A, __m512i __B)
+_mm512_mask_shldv_epi64(__m512i __A, __mmask8 __U, __m512i __B, __m512i __C)
 {
-  return (__m512i) __builtin_ia32_vpshldvq512_maskz ((__v8di) __S,
-              (__v8di) __A,
-              (__v8di) __B,
-              __U);
+  return (__m512i)__builtin_ia32_selectq_512(__U,
+                                      (__v8di)_mm512_shldv_epi64(__A, __B, __C),
+                                      (__v8di)__A);
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_shldv_epi64(__m512i __S, __m512i __A, __m512i __B)
+_mm512_maskz_shldv_epi64(__mmask8 __U, __m512i __A, __m512i __B, __m512i __C)
 {
-  return (__m512i) __builtin_ia32_vpshldvq512_mask ((__v8di) __S,
-              (__v8di) __A,
-              (__v8di) __B,
-              (__mmask8) -1);
+  return (__m512i)__builtin_ia32_selectq_512(__U,
+                                      (__v8di)_mm512_shldv_epi64(__A, __B, __C),
+                                      (__v8di)_mm512_setzero_si512());
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_mask_shldv_epi32(__m512i __S, __mmask16 __U, __m512i __A, __m512i __B)
+_mm512_shldv_epi32(__m512i __A, __m512i __B, __m512i __C)
 {
-  return (__m512i) __builtin_ia32_vpshldvd512_mask ((__v16si) __S,
-              (__v16si) __A,
-              (__v16si) __B,
-              __U);
+  return (__m512i)__builtin_ia32_vpshldvd512((__v16si)__A, (__v16si)__B,
+                                             (__v16si)__C);
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_maskz_shldv_epi32(__mmask16 __U, __m512i __S, __m512i __A, __m512i __B)
+_mm512_mask_shldv_epi32(__m512i __A, __mmask16 __U, __m512i __B, __m512i __C)
 {
-  return (__m512i) __builtin_ia32_vpshldvd512_maskz ((__v16si) __S,
-              (__v16si) __A,
-              (__v16si) __B,
-              __U);
+  return (__m512i)__builtin_ia32_selectd_512(__U,
+                                     (__v16si)_mm512_shldv_epi32(__A, __B, __C),
+                                     (__v16si)__A);
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_shldv_epi32(__m512i __S, __m512i __A, __m512i __B)
+_mm512_maskz_shldv_epi32(__mmask16 __U, __m512i __A, __m512i __B, __m512i __C)
 {
-  return (__m512i) __builtin_ia32_vpshldvd512_mask ((__v16si) __S,
-              (__v16si) __A,
-              (__v16si) __B,
-              (__mmask16) -1);
+  return (__m512i)__builtin_ia32_selectd_512(__U,
+                                     (__v16si)_mm512_shldv_epi32(__A, __B, __C),
+                                     (__v16si)_mm512_setzero_si512());
 }
 
-
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_mask_shldv_epi16(__m512i __S, __mmask32 __U, __m512i __A, __m512i __B)
+_mm512_shldv_epi16(__m512i __A, __m512i __B, __m512i __C)
 {
-  return (__m512i) __builtin_ia32_vpshldvw512_mask ((__v32hi) __S,
-              (__v32hi) __A,
-              (__v32hi) __B,
-              __U);
+  return (__m512i)__builtin_ia32_vpshldvw512((__v32hi)__A, (__v32hi)__B,
+                                             (__v32hi)__C);
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_maskz_shldv_epi16(__mmask32 __U, __m512i __S, __m512i __A, __m512i __B)
+_mm512_mask_shldv_epi16(__m512i __A, __mmask32 __U, __m512i __B, __m512i __C)
 {
-  return (__m512i) __builtin_ia32_vpshldvw512_maskz ((__v32hi) __S,
-              (__v32hi) __A,
-              (__v32hi) __B,
-              __U);
+  return (__m512i)__builtin_ia32_selectw_512(__U,
+                                     (__v32hi)_mm512_shldv_epi16(__A, __B, __C),
+                                     (__v32hi)__A);
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_shldv_epi16(__m512i __S, __m512i __A, __m512i __B)
+_mm512_maskz_shldv_epi16(__mmask32 __U, __m512i __A, __m512i __B, __m512i __C)
 {
-  return (__m512i) __builtin_ia32_vpshldvw512_mask ((__v32hi) __S,
-              (__v32hi) __A,
-              (__v32hi) __B,
-              (__mmask32) -1);
+  return (__m512i)__builtin_ia32_selectw_512(__U,
+                                     (__v32hi)_mm512_shldv_epi16(__A, __B, __C),
+                                     (__v32hi)_mm512_setzero_si512());
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_mask_shrdv_epi64(__m512i __S, __mmask8 __U, __m512i __A, __m512i __B)
+_mm512_shrdv_epi64(__m512i __A, __m512i __B, __m512i __C)
 {
-  return (__m512i) __builtin_ia32_vpshrdvq512_mask ((__v8di) __S,
-              (__v8di) __A,
-              (__v8di) __B,
-              __U);
+  return (__m512i)__builtin_ia32_vpshrdvq512((__v8di)__A, (__v8di)__B,
+                                             (__v8di)__C);
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_maskz_shrdv_epi64(__mmask8 __U, __m512i __S, __m512i __A, __m512i __B)
+_mm512_mask_shrdv_epi64(__m512i __A, __mmask8 __U, __m512i __B, __m512i __C)
 {
-  return (__m512i) __builtin_ia32_vpshrdvq512_maskz ((__v8di) __S,
-              (__v8di) __A,
-              (__v8di) __B,
-              __U);
+  return (__m512i)__builtin_ia32_selectq_512(__U,
+                                      (__v8di)_mm512_shrdv_epi64(__A, __B, __C),
+                                      (__v8di)__A);
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_shrdv_epi64(__m512i __S, __m512i __A, __m512i __B)
+_mm512_maskz_shrdv_epi64(__mmask8 __U, __m512i __A, __m512i __B, __m512i __C)
 {
-  return (__m512i) __builtin_ia32_vpshrdvq512_mask ((__v8di) __S,
-              (__v8di) __A,
-              (__v8di) __B,
-              (__mmask8) -1);
+  return (__m512i)__builtin_ia32_selectq_512(__U,
+                                      (__v8di)_mm512_shrdv_epi64(__A, __B, __C),
+                                      (__v8di)_mm512_setzero_si512());
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_mask_shrdv_epi32(__m512i __S, __mmask16 __U, __m512i __A, __m512i __B)
+_mm512_shrdv_epi32(__m512i __A, __m512i __B, __m512i __C)
 {
-  return (__m512i) __builtin_ia32_vpshrdvd512_mask ((__v16si) __S,
-              (__v16si) __A,
-              (__v16si) __B,
-              __U);
+  return (__m512i)__builtin_ia32_vpshrdvd512((__v16si)__A, (__v16si)__B,
+                                             (__v16si)__C);
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_maskz_shrdv_epi32(__mmask16 __U, __m512i __S, __m512i __A, __m512i __B)
+_mm512_mask_shrdv_epi32(__m512i __A, __mmask16 __U, __m512i __B, __m512i __C)
 {
-  return (__m512i) __builtin_ia32_vpshrdvd512_maskz ((__v16si) __S,
-              (__v16si) __A,
-              (__v16si) __B,
-              __U);
+  return (__m512i) __builtin_ia32_selectd_512(__U,
+                                     (__v16si)_mm512_shrdv_epi32(__A, __B, __C),
+                                     (__v16si)__A);
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_shrdv_epi32(__m512i __S, __m512i __A, __m512i __B)
+_mm512_maskz_shrdv_epi32(__mmask16 __U, __m512i __A, __m512i __B, __m512i __C)
 {
-  return (__m512i) __builtin_ia32_vpshrdvd512_mask ((__v16si) __S,
-              (__v16si) __A,
-              (__v16si) __B,
-              (__mmask16) -1);
+  return (__m512i) __builtin_ia32_selectd_512(__U,
+                                     (__v16si)_mm512_shrdv_epi32(__A, __B, __C),
+                                     (__v16si)_mm512_setzero_si512());
 }
 
-
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_mask_shrdv_epi16(__m512i __S, __mmask32 __U, __m512i __A, __m512i __B)
+_mm512_shrdv_epi16(__m512i __A, __m512i __B, __m512i __C)
 {
-  return (__m512i) __builtin_ia32_vpshrdvw512_mask ((__v32hi) __S,
-              (__v32hi) __A,
-              (__v32hi) __B,
-              __U);
+  return (__m512i)__builtin_ia32_vpshrdvw512((__v32hi)__A, (__v32hi)__B,
+                                             (__v32hi)__C);
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_maskz_shrdv_epi16(__mmask32 __U, __m512i __S, __m512i __A, __m512i __B)
+_mm512_mask_shrdv_epi16(__m512i __A, __mmask32 __U, __m512i __B, __m512i __C)
 {
-  return (__m512i) __builtin_ia32_vpshrdvw512_maskz ((__v32hi) __S,
-              (__v32hi) __A,
-              (__v32hi) __B,
-              __U);
+  return (__m512i)__builtin_ia32_selectw_512(__U,
+                                     (__v32hi)_mm512_shrdv_epi16(__A, __B, __C),
+                                     (__v32hi)__A);
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_shrdv_epi16(__m512i __S, __m512i __A, __m512i __B)
+_mm512_maskz_shrdv_epi16(__mmask32 __U, __m512i __A, __m512i __B, __m512i __C)
 {
-  return (__m512i) __builtin_ia32_vpshrdvw512_mask ((__v32hi) __S,
-              (__v32hi) __A,
-              (__v32hi) __B,
-              (__mmask32) -1);
+  return (__m512i)__builtin_ia32_selectw_512(__U,
+                                     (__v32hi)_mm512_shrdv_epi16(__A, __B, __C),
+                                     (__v32hi)_mm512_setzero_si512());
 }
 
 
diff --git a/lib/Headers/avx512vlvbmi2intrin.h b/lib/Headers/avx512vlvbmi2intrin.h
index baaf565463..632d14fb55 100644
--- a/lib/Headers/avx512vlvbmi2intrin.h
+++ b/lib/Headers/avx512vlvbmi2intrin.h
@@ -421,327 +421,279 @@ _mm256_maskz_expandloadu_epi8(__mmask32 __U, void const *__P)
                                       (__v8hi)_mm_setzero_si128())
 
 static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_mask_shldv_epi64(__m256i __S, __mmask8 __U, __m256i __A, __m256i __B)
+_mm256_shldv_epi64(__m256i __A, __m256i __B, __m256i __C)
 {
-  return (__m256i) __builtin_ia32_vpshldvq256_mask ((__v4di) __S,
-              (__v4di) __A,
-              (__v4di) __B,
-              __U);
+  return (__m256i)__builtin_ia32_vpshldvq256((__v4di)__A, (__v4di)__B,
+                                             (__v4di)__C);
 }
 
 static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_maskz_shldv_epi64(__mmask8 __U, __m256i __S, __m256i __A, __m256i __B)
+_mm256_mask_shldv_epi64(__m256i __A, __mmask8 __U, __m256i __B, __m256i __C)
 {
-  return (__m256i) __builtin_ia32_vpshldvq256_maskz ((__v4di) __S,
-              (__v4di) __A,
-              (__v4di) __B,
-              __U);
+  return (__m256i)__builtin_ia32_selectq_256(__U,
+                                      (__v4di)_mm256_shldv_epi64(__A, __B, __C),
+                                      (__v4di)__A);
 }
 
 static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_shldv_epi64(__m256i __S, __m256i __A, __m256i __B)
+_mm256_maskz_shldv_epi64(__mmask8 __U, __m256i __A, __m256i __B, __m256i __C)
 {
-  return (__m256i) __builtin_ia32_vpshldvq256_mask ((__v4di) __S,
-              (__v4di) __A,
-              (__v4di) __B,
-              (__mmask8) -1);
+  return (__m256i)__builtin_ia32_selectq_256(__U,
+                                      (__v4di)_mm256_shldv_epi64(__A, __B, __C),
+                                      (__v4di)_mm256_setzero_si256());
 }
 
 static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_mask_shldv_epi64(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B)
+_mm_shldv_epi64(__m128i __A, __m128i __B, __m128i __C)
 {
-  return (__m128i) __builtin_ia32_vpshldvq128_mask ((__v2di) __S,
-              (__v2di) __A,
-              (__v2di) __B,
-              __U);
+  return (__m128i)__builtin_ia32_vpshldvq128((__v2di)__A, (__v2di)__B,
+                                             (__v2di)__C);
 }
 
 static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_maskz_shldv_epi64(__mmask8 __U, __m128i __S, __m128i __A, __m128i __B)
+_mm_mask_shldv_epi64(__m128i __A, __mmask8 __U, __m128i __B, __m128i __C)
 {
-  return (__m128i) __builtin_ia32_vpshldvq128_maskz ((__v2di) __S,
-              (__v2di) __A,
-              (__v2di) __B,
-              __U);
+  return (__m128i)__builtin_ia32_selectq_128(__U,
+                                         (__v2di)_mm_shldv_epi64(__A, __B, __C),
+                                         (__v2di)__A);
 }
 
 static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_shldv_epi64(__m128i __S, __m128i __A, __m128i __B)
+_mm_maskz_shldv_epi64(__mmask8 __U, __m128i __A, __m128i __B, __m128i __C)
 {
-  return (__m128i) __builtin_ia32_vpshldvq128_mask ((__v2di) __S,
-              (__v2di) __A,
-              (__v2di) __B,
-              (__mmask8) -1);
+  return (__m128i)__builtin_ia32_selectq_128(__U,
+                                         (__v2di)_mm_shldv_epi64(__A, __B, __C),
+                                         (__v2di)_mm_setzero_si128());
 }
 
 static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_mask_shldv_epi32(__m256i __S, __mmask8 __U, __m256i __A, __m256i __B)
+_mm256_shldv_epi32(__m256i __A, __m256i __B, __m256i __C)
 {
-  return (__m256i) __builtin_ia32_vpshldvd256_mask ((__v8si) __S,
-              (__v8si) __A,
-              (__v8si) __B,
-              __U);
+  return (__m256i)__builtin_ia32_vpshldvd256((__v8si)__A, (__v8si)__B,
+                                             (__v8si)__C);
 }
 
 static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_maskz_shldv_epi32(__mmask8 __U, __m256i __S, __m256i __A, __m256i __B)
+_mm256_mask_shldv_epi32(__m256i __A, __mmask8 __U, __m256i __B, __m256i __C)
 {
-  return (__m256i) __builtin_ia32_vpshldvd256_maskz ((__v8si) __S,
-              (__v8si) __A,
-              (__v8si) __B,
-              __U);
+  return (__m256i)__builtin_ia32_selectd_256(__U,
+                                      (__v8si)_mm256_shldv_epi32(__A, __B, __C),
+                                      (__v8si)__A);
 }
 
 static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_shldv_epi32(__m256i __S, __m256i __A, __m256i __B)
+_mm256_maskz_shldv_epi32(__mmask8 __U, __m256i __A, __m256i __B, __m256i __C)
 {
-  return (__m256i) __builtin_ia32_vpshldvd256_mask ((__v8si) __S,
-              (__v8si) __A,
-              (__v8si) __B,
-              (__mmask8) -1);
+  return (__m256i)__builtin_ia32_selectd_256(__U,
+                                      (__v8si)_mm256_shldv_epi32(__A, __B, __C),
+                                      (__v8si)_mm256_setzero_si256());
 }
 
 static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_mask_shldv_epi32(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B)
+_mm_shldv_epi32(__m128i __A, __m128i __B, __m128i __C)
 {
-  return (__m128i) __builtin_ia32_vpshldvd128_mask ((__v4si) __S,
-              (__v4si) __A,
-              (__v4si) __B,
-              __U);
+  return (__m128i)__builtin_ia32_vpshldvd128((__v4si)__A, (__v4si)__B,
+                                             (__v4si)__C);
 }
 
 static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_maskz_shldv_epi32(__mmask8 __U, __m128i __S, __m128i __A, __m128i __B)
+_mm_mask_shldv_epi32(__m128i __A, __mmask8 __U, __m128i __B, __m128i __C)
 {
-  return (__m128i) __builtin_ia32_vpshldvd128_maskz ((__v4si) __S,
-              (__v4si) __A,
-              (__v4si) __B,
-              __U);
+  return (__m128i)__builtin_ia32_selectd_128(__U,
+                                         (__v4si)_mm_shldv_epi32(__A, __B, __C),
+                                         (__v4si)__A);
 }
 
 static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_shldv_epi32(__m128i __S, __m128i __A, __m128i __B)
+_mm_maskz_shldv_epi32(__mmask8 __U, __m128i __A, __m128i __B, __m128i __C)
 {
-  return (__m128i) __builtin_ia32_vpshldvd128_mask ((__v4si) __S,
-              (__v4si) __A,
-              (__v4si) __B,
-              (__mmask8) -1);
+  return (__m128i)__builtin_ia32_selectd_128(__U,
+                                         (__v4si)_mm_shldv_epi32(__A, __B, __C),
+                                         (__v4si)_mm_setzero_si128());
 }
 
 static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_mask_shldv_epi16(__m256i __S, __mmask16 __U, __m256i __A, __m256i __B)
+_mm256_shldv_epi16(__m256i __A, __m256i __B, __m256i __C)
 {
-  return (__m256i) __builtin_ia32_vpshldvw256_mask ((__v16hi) __S,
-              (__v16hi) __A,
-              (__v16hi) __B,
-              __U);
+  return (__m256i)__builtin_ia32_vpshldvw256((__v16hi)__A, (__v16hi)__B,
+                                             (__v16hi)__C);
 }
 
 static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_maskz_shldv_epi16(__mmask16 __U, __m256i __S, __m256i __A, __m256i __B)
+_mm256_mask_shldv_epi16(__m256i __A, __mmask16 __U, __m256i __B, __m256i __C)
 {
-  return (__m256i) __builtin_ia32_vpshldvw256_maskz ((__v16hi) __S,
-              (__v16hi) __A,
-              (__v16hi) __B,
-              __U);
+  return (__m256i)__builtin_ia32_selectw_256(__U,
+                                      (__v16hi)_mm256_shldv_epi16(__A, __B, __C),
+                                      (__v16hi)__A);
 }
 
 static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_shldv_epi16(__m256i __S, __m256i __A, __m256i __B)
+_mm256_maskz_shldv_epi16(__mmask16 __U, __m256i __A, __m256i __B, __m256i __C)
 {
-  return (__m256i) __builtin_ia32_vpshldvw256_mask ((__v16hi) __S,
-              (__v16hi) __A,
-              (__v16hi) __B,
-              (__mmask16) -1);
+  return (__m256i)__builtin_ia32_selectw_256(__U,
+                                      (__v16hi)_mm256_shldv_epi16(__A, __B, __C),
+                                      (__v16hi)_mm256_setzero_si256());
 }
 
 static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_mask_shldv_epi16(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B)
+_mm_shldv_epi16(__m128i __A, __m128i __B, __m128i __C)
 {
-  return (__m128i) __builtin_ia32_vpshldvw128_mask ((__v8hi) __S,
-              (__v8hi) __A,
-              (__v8hi) __B,
-              __U);
+  return (__m128i)__builtin_ia32_vpshldvw128((__v8hi)__A, (__v8hi)__B,
+                                             (__v8hi)__C);
 }
 
 static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_maskz_shldv_epi16(__mmask8 __U, __m128i __S, __m128i __A, __m128i __B)
+_mm_mask_shldv_epi16(__m128i __A, __mmask8 __U, __m128i __B, __m128i __C)
 {
-  return (__m128i) __builtin_ia32_vpshldvw128_maskz ((__v8hi) __S,
-              (__v8hi) __A,
-              (__v8hi) __B,
-              __U);
+  return (__m128i)__builtin_ia32_selectw_128(__U,
+                                         (__v8hi)_mm_shldv_epi16(__A, __B, __C),
+                                         (__v8hi)__A);
 }
 
 static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_shldv_epi16(__m128i __S, __m128i __A, __m128i __B)
+_mm_maskz_shldv_epi16(__mmask8 __U, __m128i __A, __m128i __B, __m128i __C)
 {
-  return (__m128i) __builtin_ia32_vpshldvw128_mask ((__v8hi) __S,
-              (__v8hi) __A,
-              (__v8hi) __B,
-              (__mmask8) -1);
+  return (__m128i)__builtin_ia32_selectw_128(__U,
+                                         (__v8hi)_mm_shldv_epi16(__A, __B, __C),
+                                         (__v8hi)_mm_setzero_si128());
 }
 
 static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_mask_shrdv_epi64(__m256i __S, __mmask8 __U, __m256i __A, __m256i __B)
+_mm256_shrdv_epi64(__m256i __A, __m256i __B, __m256i __C)
 {
-  return (__m256i) __builtin_ia32_vpshrdvq256_mask ((__v4di) __S,
-              (__v4di) __A,
-              (__v4di) __B,
-              __U);
+  return (__m256i)__builtin_ia32_vpshrdvq256((__v4di)__A, (__v4di)__B,
+                                             (__v4di)__C);
 }
 
 static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_maskz_shrdv_epi64(__mmask8 __U, __m256i __S, __m256i __A, __m256i __B)
+_mm256_mask_shrdv_epi64(__m256i __A, __mmask8 __U, __m256i __B, __m256i __C)
 {
-  return (__m256i) __builtin_ia32_vpshrdvq256_maskz ((__v4di) __S,
-              (__v4di) __A,
-              (__v4di) __B,
-              __U);
+  return (__m256i)__builtin_ia32_selectq_256(__U,
+                                      (__v4di)_mm256_shrdv_epi64(__A, __B, __C),
+                                      (__v4di)__A);
 }
 
 static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_shrdv_epi64(__m256i __S, __m256i __A, __m256i __B)
+_mm256_maskz_shrdv_epi64(__mmask8 __U, __m256i __A, __m256i __B, __m256i __C)
 {
-  return (__m256i) __builtin_ia32_vpshrdvq256_mask ((__v4di) __S,
-              (__v4di) __A,
-              (__v4di) __B,
-              (__mmask8) -1);
+  return (__m256i)__builtin_ia32_selectq_256(__U,
+                                      (__v4di)_mm256_shrdv_epi64(__A, __B, __C),
+                                      (__v4di)_mm256_setzero_si256());
 }
 
 static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_mask_shrdv_epi64(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B)
+_mm_shrdv_epi64(__m128i __A, __m128i __B, __m128i __C)
 {
-  return (__m128i) __builtin_ia32_vpshrdvq128_mask ((__v2di) __S,
-              (__v2di) __A,
-              (__v2di) __B,
-              __U);
+  return (__m128i)__builtin_ia32_vpshrdvq128((__v2di)__A, (__v2di)__B,
+                                             (__v2di)__C);
 }
 
 static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_maskz_shrdv_epi64(__mmask8 __U, __m128i __S, __m128i __A, __m128i __B)
+_mm_mask_shrdv_epi64(__m128i __A, __mmask8 __U, __m128i __B, __m128i __C)
 {
-  return (__m128i) __builtin_ia32_vpshrdvq128_maskz ((__v2di) __S,
-              (__v2di) __A,
-              (__v2di) __B,
-              __U);
+  return (__m128i)__builtin_ia32_selectq_128(__U,
+                                         (__v2di)_mm_shrdv_epi64(__A, __B, __C),
+                                         (__v2di)__A);
 }
 
 static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_shrdv_epi64(__m128i __S, __m128i __A, __m128i __B)
+_mm_maskz_shrdv_epi64(__mmask8 __U, __m128i __A, __m128i __B, __m128i __C)
 {
-  return (__m128i) __builtin_ia32_vpshrdvq128_mask ((__v2di) __S,
-              (__v2di) __A,
-              (__v2di) __B,
-              (__mmask8) -1);
+  return (__m128i)__builtin_ia32_selectq_128(__U,
+                                         (__v2di)_mm_shrdv_epi64(__A, __B, __C),
+                                         (__v2di)_mm_setzero_si128());
 }
 
 static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_mask_shrdv_epi32(__m256i __S, __mmask8 __U, __m256i __A, __m256i __B)
+_mm256_shrdv_epi32(__m256i __A, __m256i __B, __m256i __C)
 {
-  return (__m256i) __builtin_ia32_vpshrdvd256_mask ((__v8si) __S,
-              (__v8si) __A,
-              (__v8si) __B,
-              __U);
+  return (__m256i)__builtin_ia32_vpshrdvd256((__v8si)__A, (__v8si)__B,
+                                             (__v8si)__C);
 }
 
 static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_maskz_shrdv_epi32(__mmask8 __U, __m256i __S, __m256i __A, __m256i __B)
+_mm256_mask_shrdv_epi32(__m256i __A, __mmask8 __U, __m256i __B, __m256i __C)
 {
-  return (__m256i) __builtin_ia32_vpshrdvd256_maskz ((__v8si) __S,
-              (__v8si) __A,
-              (__v8si) __B,
-              __U);
+  return (__m256i)__builtin_ia32_selectd_256(__U,
+                                      (__v8si)_mm256_shrdv_epi32(__A, __B, __C),
+                                      (__v8si)__A);
 }
 
 static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_shrdv_epi32(__m256i __S, __m256i __A, __m256i __B)
+_mm256_maskz_shrdv_epi32(__mmask8 __U, __m256i __A, __m256i __B, __m256i __C)
 {
-  return (__m256i) __builtin_ia32_vpshrdvd256_mask ((__v8si) __S,
-              (__v8si) __A,
-              (__v8si) __B,
-              (__mmask8) -1);
+  return (__m256i)__builtin_ia32_selectd_256(__U,
+                                      (__v8si)_mm256_shrdv_epi32(__A, __B, __C),
+                                      (__v8si)_mm256_setzero_si256());
 }
 
 static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_mask_shrdv_epi32(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B)
+_mm_shrdv_epi32(__m128i __A, __m128i __B, __m128i __C)
 {
-  return (__m128i) __builtin_ia32_vpshrdvd128_mask ((__v4si) __S,
-              (__v4si) __A,
-              (__v4si) __B,
-              __U);
+  return (__m128i)__builtin_ia32_vpshrdvd128((__v4si)__A, (__v4si)__B,
+                                             (__v4si)__C);
 }
 
 static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_maskz_shrdv_epi32(__mmask8 __U, __m128i __S, __m128i __A, __m128i __B)
+_mm_mask_shrdv_epi32(__m128i __A, __mmask8 __U, __m128i __B, __m128i __C)
 {
-  return (__m128i) __builtin_ia32_vpshrdvd128_maskz ((__v4si) __S,
-              (__v4si) __A,
-              (__v4si) __B,
-              __U);
+  return (__m128i)__builtin_ia32_selectd_128(__U,
+                                         (__v4si)_mm_shrdv_epi32(__A, __B, __C),
+                                         (__v4si)__A);
 }
 
 static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_shrdv_epi32(__m128i __S, __m128i __A, __m128i __B)
+_mm_maskz_shrdv_epi32(__mmask8 __U, __m128i __A, __m128i __B, __m128i __C)
 {
-  return (__m128i) __builtin_ia32_vpshrdvd128_mask ((__v4si) __S,
-              (__v4si) __A,
-              (__v4si) __B,
-              (__mmask8) -1);
+  return (__m128i)__builtin_ia32_selectd_128(__U,
+                                         (__v4si)_mm_shrdv_epi32(__A, __B, __C),
+                                         (__v4si)_mm_setzero_si128());
 }
 
 static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_mask_shrdv_epi16(__m256i __S, __mmask16 __U, __m256i __A, __m256i __B)
+_mm256_shrdv_epi16(__m256i __A, __m256i __B, __m256i __C)
 {
-  return (__m256i) __builtin_ia32_vpshrdvw256_mask ((__v16hi) __S,
-              (__v16hi) __A,
-              (__v16hi) __B,
-              __U);
+  return (__m256i)__builtin_ia32_vpshrdvw256((__v16hi)__A, (__v16hi)__B,
+                                             (__v16hi)__C);
 }
 
 static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_maskz_shrdv_epi16(__mmask16 __U, __m256i __S, __m256i __A, __m256i __B)
+_mm256_mask_shrdv_epi16(__m256i __A, __mmask16 __U, __m256i __B, __m256i __C)
 {
-  return (__m256i) __builtin_ia32_vpshrdvw256_maskz ((__v16hi) __S,
-              (__v16hi) __A,
-              (__v16hi) __B,
-              __U);
+  return (__m256i)__builtin_ia32_selectw_256(__U,
+                                     (__v16hi)_mm256_shrdv_epi16(__A, __B, __C),
+                                     (__v16hi)__A);
 }
 
 static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_shrdv_epi16(__m256i __S, __m256i __A, __m256i __B)
+_mm256_maskz_shrdv_epi16(__mmask16 __U, __m256i __A, __m256i __B, __m256i __C)
 {
-  return (__m256i) __builtin_ia32_vpshrdvw256_mask ((__v16hi) __S,
-              (__v16hi) __A,
-              (__v16hi) __B,
-              (__mmask16) -1);
+  return (__m256i)__builtin_ia32_selectw_256(__U,
+                                     (__v16hi)_mm256_shrdv_epi16(__A, __B, __C),
+                                     (__v16hi)_mm256_setzero_si256());
 }
 
 static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_mask_shrdv_epi16(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B)
+_mm_shrdv_epi16(__m128i __A, __m128i __B, __m128i __C)
 {
-  return (__m128i) __builtin_ia32_vpshrdvw128_mask ((__v8hi) __S,
-              (__v8hi) __A,
-              (__v8hi) __B,
-              __U);
+  return (__m128i)__builtin_ia32_vpshrdvw128((__v8hi)__A, (__v8hi)__B,
+                                             (__v8hi)__C);
 }
 
 static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_maskz_shrdv_epi16(__mmask8 __U, __m128i __S, __m128i __A, __m128i __B)
+_mm_mask_shrdv_epi16(__m128i __A, __mmask8 __U, __m128i __B, __m128i __C)
 {
-  return (__m128i) __builtin_ia32_vpshrdvw128_maskz ((__v8hi) __S,
-              (__v8hi) __A,
-              (__v8hi) __B,
-              __U);
+  return (__m128i)__builtin_ia32_selectw_128(__U,
+                                         (__v8hi)_mm_shrdv_epi16(__A, __B, __C),
+                                         (__v8hi)__A);
 }
 
 static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_shrdv_epi16(__m128i __S, __m128i __A, __m128i __B)
+_mm_maskz_shrdv_epi16(__mmask8 __U, __m128i __A, __m128i __B, __m128i __C)
 {
-  return (__m128i) __builtin_ia32_vpshrdvw128_mask ((__v8hi) __S,
-              (__v8hi) __A,
-              (__v8hi) __B,
-              (__mmask8) -1);
+  return (__m128i)__builtin_ia32_selectw_128(__U,
+                                         (__v8hi)_mm_shrdv_epi16(__A, __B, __C),
+                                         (__v8hi)_mm_setzero_si128());
 }
 
 
diff --git a/test/CodeGen/avx512vbmi2-builtins.c b/test/CodeGen/avx512vbmi2-builtins.c
index a29203027d..304561d9fa 100644
--- a/test/CodeGen/avx512vbmi2-builtins.c
+++ b/test/CodeGen/avx512vbmi2-builtins.c
@@ -88,229 +88,241 @@ __m512i test_mm512_maskz_expandloadu_epi8(__mmask64 __U, void const* __P) {
 
 __m512i test_mm512_mask_shldi_epi64(__m512i __S, __mmask8 __U, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_mask_shldi_epi64
-  // CHECK: @llvm.x86.avx512.vpshld.q.512
+  // CHECK: @llvm.fshl.v8i64(<8 x i64> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> )
   // CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}}
   return _mm512_mask_shldi_epi64(__S, __U, __A, __B, 47);
 }
 
 __m512i test_mm512_maskz_shldi_epi64(__mmask8 __U, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_maskz_shldi_epi64
-  // CHECK: @llvm.x86.avx512.vpshld.q.512
+  // CHECK: @llvm.fshl.v8i64(<8 x i64> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> )
   // CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}}
   return _mm512_maskz_shldi_epi64(__U, __A, __B, 63);
 }
 
 __m512i test_mm512_shldi_epi64(__m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_shldi_epi64
-  // CHECK: @llvm.x86.avx512.vpshld.q.512
+  // CHECK: @llvm.fshl.v8i64(<8 x i64> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> )
   return _mm512_shldi_epi64(__A, __B, 31);
 }
 
 __m512i test_mm512_mask_shldi_epi32(__m512i __S, __mmask16 __U, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_mask_shldi_epi32
-  // CHECK: @llvm.x86.avx512.vpshld.d.512
+  // CHECK: @llvm.fshl.v16i32(<16 x i32> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> )
   // CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}}
   return _mm512_mask_shldi_epi32(__S, __U, __A, __B, 7);
 }
 
 __m512i test_mm512_maskz_shldi_epi32(__mmask16 __U, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_maskz_shldi_epi32
-  // CHECK: @llvm.x86.avx512.vpshld.d.512
+  // CHECK: @llvm.fshl.v16i32(<16 x i32> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> )
   // CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}}
   return _mm512_maskz_shldi_epi32(__U, __A, __B, 15);
 }
 
 __m512i test_mm512_shldi_epi32(__m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_shldi_epi32
-  // CHECK: @llvm.x86.avx512.vpshld.d.512
+  // CHECK: @llvm.fshl.v16i32(<16 x i32> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> )
   return _mm512_shldi_epi32(__A, __B, 31);
 }
 
 __m512i test_mm512_mask_shldi_epi16(__m512i __S, __mmask32 __U, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_mask_shldi_epi16
-  // CHECK: @llvm.x86.avx512.vpshld.w.512
+  // CHECK: @llvm.fshl.v32i16(<32 x i16> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> )
   // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}}
   return _mm512_mask_shldi_epi16(__S, __U, __A, __B, 3);
 }
 
 __m512i test_mm512_maskz_shldi_epi16(__mmask32 __U, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_maskz_shldi_epi16
-  // CHECK: @llvm.x86.avx512.vpshld.w.512
+  // CHECK: @llvm.fshl.v32i16(<32 x i16> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> )
   // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}}
   return _mm512_maskz_shldi_epi16(__U, __A, __B, 7);
 }
 
 __m512i test_mm512_shldi_epi16(__m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_shldi_epi16
-  // CHECK: @llvm.x86.avx512.vpshld.w.512
+  // CHECK: @llvm.fshl.v32i16(<32 x i16> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> )
   return _mm512_shldi_epi16(__A, __B, 15);
 }
 
 __m512i test_mm512_mask_shrdi_epi64(__m512i __S, __mmask8 __U, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_mask_shrdi_epi64
-  // CHECK: @llvm.x86.avx512.vpshrd.q.512
+  // CHECK: @llvm.fshr.v8i64(<8 x i64> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> )
   // CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}}
   return _mm512_mask_shrdi_epi64(__S, __U, __A, __B, 47);
 }
 
 __m512i test_mm512_maskz_shrdi_epi64(__mmask8 __U, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_maskz_shrdi_epi64
-  // CHECK: @llvm.x86.avx512.vpshrd.q.512
+  // CHECK: @llvm.fshr.v8i64(<8 x i64> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> )
   // CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}}
   return _mm512_maskz_shrdi_epi64(__U, __A, __B, 63);
 }
 
 __m512i test_mm512_shrdi_epi64(__m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_shrdi_epi64
-  // CHECK: @llvm.x86.avx512.vpshrd.q.512
+  // CHECK: @llvm.fshr.v8i64(<8 x i64> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> )
   return _mm512_shrdi_epi64(__A, __B, 31);
 }
 
 __m512i test_mm512_mask_shrdi_epi32(__m512i __S, __mmask16 __U, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_mask_shrdi_epi32
-  // CHECK: @llvm.x86.avx512.vpshrd.d.512
+  // CHECK: @llvm.fshr.v16i32(<16 x i32> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> )
   // CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}}
   return _mm512_mask_shrdi_epi32(__S, __U, __A, __B, 7);
 }
 
 __m512i test_mm512_maskz_shrdi_epi32(__mmask16 __U, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_maskz_shrdi_epi32
-  // CHECK: @llvm.x86.avx512.vpshrd.d.512
+  // CHECK: @llvm.fshr.v16i32(<16 x i32> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> )
   // CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}}
   return _mm512_maskz_shrdi_epi32(__U, __A, __B, 15);
 }
 
 __m512i test_mm512_shrdi_epi32(__m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_shrdi_epi32
-  // CHECK: @llvm.x86.avx512.vpshrd.d.512
+  // CHECK: @llvm.fshr.v16i32(<16 x i32> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> )
   return _mm512_shrdi_epi32(__A, __B, 31);
 }
 
 __m512i test_mm512_mask_shrdi_epi16(__m512i __S, __mmask32 __U, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_mask_shrdi_epi16
-  // CHECK: @llvm.x86.avx512.vpshrd.w.512
+  // CHECK: @llvm.fshr.v32i16(<32 x i16> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> )
   // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}}
   return _mm512_mask_shrdi_epi16(__S, __U, __A, __B, 3);
 }
 
 __m512i test_mm512_maskz_shrdi_epi16(__mmask32 __U, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_maskz_shrdi_epi16
-  // CHECK: @llvm.x86.avx512.vpshrd.w.512
+  // CHECK: @llvm.fshr.v32i16(<32 x i16> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> )
   // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}}
   return _mm512_maskz_shrdi_epi16(__U, __A, __B, 15);
 }
 
 __m512i test_mm512_shrdi_epi16(__m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_shrdi_epi16
-  // CHECK: @llvm.x86.avx512.vpshrd.w.512
+  // CHECK: @llvm.fshr.v32i16(<32 x i16> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> )
   return _mm512_shrdi_epi16(__A, __B, 31);
 }
 
 __m512i test_mm512_mask_shldv_epi64(__m512i __S, __mmask8 __U, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_mask_shldv_epi64
-  // CHECK: @llvm.x86.avx512.mask.vpshldv.q.512
+  // CHECK: @llvm.fshl.v8i64(<8 x i64> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}})
+  // CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}}
   return _mm512_mask_shldv_epi64(__S, __U, __A, __B);
 }
 
 __m512i test_mm512_maskz_shldv_epi64(__mmask8 __U, __m512i __S, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_maskz_shldv_epi64
-  // CHECK: @llvm.x86.avx512.maskz.vpshldv.q.512
+  // CHECK: @llvm.fshl.v8i64(<8 x i64> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}})
+  // CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}}
   return _mm512_maskz_shldv_epi64(__U, __S, __A, __B);
 }
 
 __m512i test_mm512_shldv_epi64(__m512i __S, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_shldv_epi64
-  // CHECK: @llvm.x86.avx512.mask.vpshldv.q.512
+  // CHECK: @llvm.fshl.v8i64(<8 x i64> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}})
   return _mm512_shldv_epi64(__S, __A, __B);
 }
 
 __m512i test_mm512_mask_shldv_epi32(__m512i __S, __mmask16 __U, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_mask_shldv_epi32
-  // CHECK: @llvm.x86.avx512.mask.vpshldv.d.512
+  // CHECK: @llvm.fshl.v16i32(<16 x i32> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}})
+  // CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}}
   return _mm512_mask_shldv_epi32(__S, __U, __A, __B);
 }
 
 __m512i test_mm512_maskz_shldv_epi32(__mmask16 __U, __m512i __S, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_maskz_shldv_epi32
-  // CHECK: @llvm.x86.avx512.maskz.vpshldv.d.512
+  // CHECK: @llvm.fshl.v16i32(<16 x i32> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}})
+  // CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}}
   return _mm512_maskz_shldv_epi32(__U, __S, __A, __B);
 }
 
 __m512i test_mm512_shldv_epi32(__m512i __S, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_shldv_epi32
-  // CHECK: @llvm.x86.avx512.mask.vpshldv.d.512
+  // CHECK: @llvm.fshl.v16i32(<16 x i32> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}})
   return _mm512_shldv_epi32(__S, __A, __B);
 }
 
 __m512i test_mm512_mask_shldv_epi16(__m512i __S, __mmask32 __U, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_mask_shldv_epi16
-  // CHECK: @llvm.x86.avx512.mask.vpshldv.w.512
+  // CHECK: @llvm.fshl.v32i16(<32 x i16> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}})
+  // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}}
   return _mm512_mask_shldv_epi16(__S, __U, __A, __B);
 }
 
 __m512i test_mm512_maskz_shldv_epi16(__mmask32 __U, __m512i __S, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_maskz_shldv_epi16
-  // CHECK: @llvm.x86.avx512.maskz.vpshldv.w.512
+  // CHECK: @llvm.fshl.v32i16(<32 x i16> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}})
+  // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}}
   return _mm512_maskz_shldv_epi16(__U, __S, __A, __B);
 }
 
 __m512i test_mm512_shldv_epi16(__m512i __S, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_shldv_epi16
-  // CHECK: @llvm.x86.avx512.mask.vpshldv.w.512
+  // CHECK: @llvm.fshl.v32i16(<32 x i16> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}})
   return _mm512_shldv_epi16(__S, __A, __B);
 }
 
 __m512i test_mm512_mask_shrdv_epi64(__m512i __S, __mmask8 __U, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_mask_shrdv_epi64
-  // CHECK: @llvm.x86.avx512.mask.vpshrdv.q.512
+  // CHECK: @llvm.fshr.v8i64(<8 x i64> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}})
+  // CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}}
   return _mm512_mask_shrdv_epi64(__S, __U, __A, __B);
 }
 
 __m512i test_mm512_maskz_shrdv_epi64(__mmask8 __U, __m512i __S, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_maskz_shrdv_epi64
-  // CHECK: @llvm.x86.avx512.maskz.vpshrdv.q.512
+  // CHECK: @llvm.fshr.v8i64(<8 x i64> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}})
+  // CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}}
   return _mm512_maskz_shrdv_epi64(__U, __S, __A, __B);
 }
 
 __m512i test_mm512_shrdv_epi64(__m512i __S, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_shrdv_epi64
-  // CHECK: @llvm.x86.avx512.mask.vpshrdv.q.512
+  // CHECK: @llvm.fshr.v8i64(<8 x i64> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}})
   return _mm512_shrdv_epi64(__S, __A, __B);
 }
 
 __m512i test_mm512_mask_shrdv_epi32(__m512i __S, __mmask16 __U, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_mask_shrdv_epi32
-  // CHECK: @llvm.x86.avx512.mask.vpshrdv.d.512
+  // CHECK: @llvm.fshr.v16i32(<16 x i32> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}})
+  // CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}}
   return _mm512_mask_shrdv_epi32(__S, __U, __A, __B);
 }
 
 __m512i test_mm512_maskz_shrdv_epi32(__mmask16 __U, __m512i __S, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_maskz_shrdv_epi32
-  // CHECK: @llvm.x86.avx512.maskz.vpshrdv.d.512
+  // CHECK: @llvm.fshr.v16i32(<16 x i32> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}})
+  // CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}}
   return _mm512_maskz_shrdv_epi32(__U, __S, __A, __B);
 }
 
 __m512i test_mm512_shrdv_epi32(__m512i __S, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_shrdv_epi32
-  // CHECK: @llvm.x86.avx512.mask.vpshrdv.d.512
+  // CHECK: @llvm.fshr.v16i32(<16 x i32> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}})
   return _mm512_shrdv_epi32(__S, __A, __B);
 }
 
 __m512i test_mm512_mask_shrdv_epi16(__m512i __S, __mmask32 __U, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_mask_shrdv_epi16
-  // CHECK: @llvm.x86.avx512.mask.vpshrdv.w.512
+  // CHECK: @llvm.fshr.v32i16(<32 x i16> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}})
+  // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}}
   return _mm512_mask_shrdv_epi16(__S, __U, __A, __B);
 }
 
 __m512i test_mm512_maskz_shrdv_epi16(__mmask32 __U, __m512i __S, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_maskz_shrdv_epi16
-  // CHECK: @llvm.x86.avx512.maskz.vpshrdv.w.512
+  // CHECK: @llvm.fshr.v32i16(<32 x i16> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}})
+  // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}}
   return _mm512_maskz_shrdv_epi16(__U, __S, __A, __B);
 }
 
 __m512i test_mm512_shrdv_epi16(__m512i __S, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_shrdv_epi16
-  // CHECK: @llvm.x86.avx512.mask.vpshrdv.w.512
+  // CHECK: @llvm.fshr.v32i16(<32 x i16> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}})
   return _mm512_shrdv_epi16(__S, __A, __B);
 }
 
diff --git a/test/CodeGen/avx512vlvbmi2-builtins.c b/test/CodeGen/avx512vlvbmi2-builtins.c
index 53b58400bc..b512a728a5 100644
--- a/test/CodeGen/avx512vlvbmi2-builtins.c
+++ b/test/CodeGen/avx512vlvbmi2-builtins.c
@@ -172,457 +172,481 @@ __m256i test_mm256_maskz_expandloadu_epi8(__mmask32 __U, void const* __P) {
 
 __m256i test_mm256_mask_shldi_epi64(__m256i __S, __mmask8 __U, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_mask_shldi_epi64
-  // CHECK: @llvm.x86.avx512.vpshld.q.256
+  // CHECK: @llvm.fshl.v4i64(<4 x i64> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> )
   // CHECK: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}}
   return _mm256_mask_shldi_epi64(__S, __U, __A, __B, 47);
 }
 
 __m256i test_mm256_maskz_shldi_epi64(__mmask8 __U, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_maskz_shldi_epi64
-  // CHECK: @llvm.x86.avx512.vpshld.q.256
+  // CHECK: @llvm.fshl.v4i64(<4 x i64> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> )
   // CHECK: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}}
   return _mm256_maskz_shldi_epi64(__U, __A, __B, 63);
 }
 
 __m256i test_mm256_shldi_epi64(__m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_shldi_epi64
-  // CHECK: @llvm.x86.avx512.vpshld.q.256
+  // CHECK: @llvm.fshl.v4i64(<4 x i64> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> )
   return _mm256_shldi_epi64(__A, __B, 31);
 }
 
 __m128i test_mm_mask_shldi_epi64(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_mask_shldi_epi64
-  // CHECK: @llvm.x86.avx512.vpshld.q.128
+  // CHECK: @llvm.fshl.v2i64(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> )
   // CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}}
   return _mm_mask_shldi_epi64(__S, __U, __A, __B, 47);
 }
 
 __m128i test_mm_maskz_shldi_epi64(__mmask8 __U, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_maskz_shldi_epi64
-  // CHECK: @llvm.x86.avx512.vpshld.q.128
+  // CHECK: @llvm.fshl.v2i64(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> )
   // CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}}
   return _mm_maskz_shldi_epi64(__U, __A, __B, 63);
 }
 
 __m128i test_mm_shldi_epi64(__m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_shldi_epi64
-  // CHECK: @llvm.x86.avx512.vpshld.q.128
+  // CHECK: @llvm.fshl.v2i64(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> )
   return _mm_shldi_epi64(__A, __B, 31);
 }
 
 __m256i test_mm256_mask_shldi_epi32(__m256i __S, __mmask8 __U, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_mask_shldi_epi32
-  // CHECK: @llvm.x86.avx512.vpshld.d.256
+  // CHECK: @llvm.fshl.v8i32(<8 x i32> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> )
   // CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}}
   return _mm256_mask_shldi_epi32(__S, __U, __A, __B, 7);
 }
 
 __m256i test_mm256_maskz_shldi_epi32(__mmask8 __U, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_maskz_shldi_epi32
-  // CHECK: @llvm.x86.avx512.vpshld.d.256
+  // CHECK: @llvm.fshl.v8i32(<8 x i32> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> )
   // CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}}
   return _mm256_maskz_shldi_epi32(__U, __A, __B, 15);
 }
 
 __m256i test_mm256_shldi_epi32(__m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_shldi_epi32
-  // CHECK: @llvm.x86.avx512.vpshld.d.256
+  // CHECK: @llvm.fshl.v8i32(<8 x i32> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> )
   return _mm256_shldi_epi32(__A, __B, 31);
 }
 
 __m128i test_mm_mask_shldi_epi32(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_mask_shldi_epi32
-  // CHECK: @llvm.x86.avx512.vpshld.d.128
+  // CHECK: @llvm.fshl.v4i32(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> )
   // CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
   return _mm_mask_shldi_epi32(__S, __U, __A, __B, 7);
 }
 
 __m128i test_mm_maskz_shldi_epi32(__mmask8 __U, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_maskz_shldi_epi32
-  // CHECK: @llvm.x86.avx512.vpshld.d.128
+  // CHECK: @llvm.fshl.v4i32(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> )
   // CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
   return _mm_maskz_shldi_epi32(__U, __A, __B, 15);
 }
 
 __m128i test_mm_shldi_epi32(__m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_shldi_epi32
-  // CHECK: @llvm.x86.avx512.vpshld.d.128
+  // CHECK: @llvm.fshl.v4i32(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> )
   return _mm_shldi_epi32(__A, __B, 31);
 }
 
 __m256i test_mm256_mask_shldi_epi16(__m256i __S, __mmask16 __U, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_mask_shldi_epi16
-  // CHECK: @llvm.x86.avx512.vpshld.w.256
+  // CHECK: @llvm.fshl.v16i16(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> )
   // CHECK: select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}}
   return _mm256_mask_shldi_epi16(__S, __U, __A, __B, 3);
 }
 
 __m256i test_mm256_maskz_shldi_epi16(__mmask16 __U, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_maskz_shldi_epi16
-  // CHECK: @llvm.x86.avx512.vpshld.w.256
+  // CHECK: @llvm.fshl.v16i16(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> )
   // CHECK: select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}}
   return _mm256_maskz_shldi_epi16(__U, __A, __B, 7);
 }
 
 __m256i test_mm256_shldi_epi16(__m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_shldi_epi16
-  // CHECK: @llvm.x86.avx512.vpshld.w.256
+  // CHECK: @llvm.fshl.v16i16(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> )
   return _mm256_shldi_epi16(__A, __B, 31);
 }
 
 __m128i test_mm_mask_shldi_epi16(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_mask_shldi_epi16
-  // CHECK: @llvm.x86.avx512.vpshld.w.128
+  // CHECK: @llvm.fshl.v8i16(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> )
   // CHECK: select <8 x i1> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}
   return _mm_mask_shldi_epi16(__S, __U, __A, __B, 3);
 }
 
 __m128i test_mm_maskz_shldi_epi16(__mmask8 __U, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_maskz_shldi_epi16
-  // CHECK: @llvm.x86.avx512.vpshld.w.128
+  // CHECK: @llvm.fshl.v8i16(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> )
   // CHECK: select <8 x i1> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}
   return _mm_maskz_shldi_epi16(__U, __A, __B, 7);
 }
 
 __m128i test_mm_shldi_epi16(__m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_shldi_epi16
-  // CHECK: @llvm.x86.avx512.vpshld.w.128
+  // CHECK: @llvm.fshl.v8i16(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> )
   return _mm_shldi_epi16(__A, __B, 31);
 }
 
 __m256i test_mm256_mask_shrdi_epi64(__m256i __S, __mmask8 __U, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_mask_shrdi_epi64
-  // CHECK: @llvm.x86.avx512.vpshrd.q.256
+  // CHECK: @llvm.fshr.v4i64(<4 x i64> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> )
   // CHECK: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}}
   return _mm256_mask_shrdi_epi64(__S, __U, __A, __B, 47);
 }
 
 __m256i test_mm256_maskz_shrdi_epi64(__mmask8 __U, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_maskz_shrdi_epi64
-  // CHECK: @llvm.x86.avx512.vpshrd.q.256
+  // CHECK: @llvm.fshr.v4i64(<4 x i64> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> )
   // CHECK: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}}
   return _mm256_maskz_shrdi_epi64(__U, __A, __B, 63);
 }
 
 __m256i test_mm256_shrdi_epi64(__m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_shrdi_epi64
-  // CHECK: @llvm.x86.avx512.vpshrd.q.256
+  // CHECK: @llvm.fshr.v4i64(<4 x i64> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> )
   return _mm256_shrdi_epi64(__A, __B, 31);
 }
 
 __m128i test_mm_mask_shrdi_epi64(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_mask_shrdi_epi64
-  // CHECK: @llvm.x86.avx512.vpshrd.q.128
+  // CHECK: @llvm.fshr.v2i64(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> )
   // CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}}
   return _mm_mask_shrdi_epi64(__S, __U, __A, __B, 47);
 }
 
 __m128i test_mm_maskz_shrdi_epi64(__mmask8 __U, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_maskz_shrdi_epi64
-  // CHECK: @llvm.x86.avx512.vpshrd.q.128
+  // CHECK: @llvm.fshr.v2i64(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> )
   // CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}}
   return _mm_maskz_shrdi_epi64(__U, __A, __B, 63);
 }
 
 __m128i test_mm_shrdi_epi64(__m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_shrdi_epi64
-  // CHECK: @llvm.x86.avx512.vpshrd.q.128
+  // CHECK: @llvm.fshr.v2i64(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> )
   return _mm_shrdi_epi64(__A, __B, 31);
 }
 
 __m256i test_mm256_mask_shrdi_epi32(__m256i __S, __mmask8 __U, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_mask_shrdi_epi32
-  // CHECK: @llvm.x86.avx512.vpshrd.d.256
+  // CHECK: @llvm.fshr.v8i32(<8 x i32> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> )
   // CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}}
   return _mm256_mask_shrdi_epi32(__S, __U, __A, __B, 7);
 }
 
 __m256i test_mm256_maskz_shrdi_epi32(__mmask8 __U, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_maskz_shrdi_epi32
-  // CHECK: @llvm.x86.avx512.vpshrd.d.256
+  // CHECK: @llvm.fshr.v8i32(<8 x i32> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> )
   // CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}}
   return _mm256_maskz_shrdi_epi32(__U, __A, __B, 15);
 }
 
 __m256i test_mm256_shrdi_epi32(__m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_shrdi_epi32
-  // CHECK: @llvm.x86.avx512.vpshrd.d.256
+  // CHECK: @llvm.fshr.v8i32(<8 x i32> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> )
   return _mm256_shrdi_epi32(__A, __B, 31);
 }
 
 __m128i test_mm_mask_shrdi_epi32(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_mask_shrdi_epi32
-  // CHECK: @llvm.x86.avx512.vpshrd.d.128
+  // CHECK: @llvm.fshr.v4i32(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> )
   // CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
   return _mm_mask_shrdi_epi32(__S, __U, __A, __B, 7);
 }
 
 __m128i test_mm_maskz_shrdi_epi32(__mmask8 __U, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_maskz_shrdi_epi32
-  // CHECK: @llvm.x86.avx512.vpshrd.d.128
+  // CHECK: @llvm.fshr.v4i32(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> )
   // CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
   return _mm_maskz_shrdi_epi32(__U, __A, __B, 15);
 }
 
 __m128i test_mm_shrdi_epi32(__m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_shrdi_epi32
-  // CHECK: @llvm.x86.avx512.vpshrd.d.128
+  // CHECK: @llvm.fshr.v4i32(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> )
   return _mm_shrdi_epi32(__A, __B, 31);
 }
 
 __m256i test_mm256_mask_shrdi_epi16(__m256i __S, __mmask16 __U, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_mask_shrdi_epi16
-  // CHECK: @llvm.x86.avx512.vpshrd.w.256
+  // CHECK: @llvm.fshr.v16i16(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> )
   // CHECK: select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}}
   return _mm256_mask_shrdi_epi16(__S, __U, __A, __B, 3);
 }
 
 __m256i test_mm256_maskz_shrdi_epi16(__mmask16 __U, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_maskz_shrdi_epi16
-  // CHECK: @llvm.x86.avx512.vpshrd.w.256
+  // CHECK: @llvm.fshr.v16i16(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> )
   // CHECK: select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}}
   return _mm256_maskz_shrdi_epi16(__U, __A, __B, 7);
 }
 
 __m256i test_mm256_shrdi_epi16(__m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_shrdi_epi16
-  // CHECK: @llvm.x86.avx512.vpshrd.w.256
+  // CHECK: @llvm.fshr.v16i16(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> 
   return _mm256_shrdi_epi16(__A, __B, 31);
 }
 
 __m128i test_mm_mask_shrdi_epi16(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_mask_shrdi_epi16
-  // CHECK: @llvm.x86.avx512.vpshrd.w.128
+  // CHECK: @llvm.fshr.v8i16(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> )
   // CHECK: select <8 x i1> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}
   return _mm_mask_shrdi_epi16(__S, __U, __A, __B, 3);
 }
 
 __m128i test_mm_maskz_shrdi_epi16(__mmask8 __U, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_maskz_shrdi_epi16
-  // CHECK: @llvm.x86.avx512.vpshrd.w.128
+  // CHECK: @llvm.fshr.v8i16(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> )
   // CHECK: select <8 x i1> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}
   return _mm_maskz_shrdi_epi16(__U, __A, __B, 7);
 }
 
 __m128i test_mm_shrdi_epi16(__m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_shrdi_epi16
-  // CHECK: @llvm.x86.avx512.vpshrd.w.128
+  // CHECK: @llvm.fshr.v8i16(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> )
   return _mm_shrdi_epi16(__A, __B, 31);
 }
 
 __m256i test_mm256_mask_shldv_epi64(__m256i __S, __mmask8 __U, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_mask_shldv_epi64
-  // CHECK: @llvm.x86.avx512.mask.vpshldv.q.256
+  // CHECK: @llvm.fshl.v4i64(<4 x i64> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}})
+  // CHECK: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}}
   return _mm256_mask_shldv_epi64(__S, __U, __A, __B);
 }
 
 __m256i test_mm256_maskz_shldv_epi64(__mmask8 __U, __m256i __S, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_maskz_shldv_epi64
-  // CHECK: @llvm.x86.avx512.maskz.vpshldv.q.256
+  // CHECK: @llvm.fshl.v4i64(<4 x i64> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}})
+  // CHECK: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}}
   return _mm256_maskz_shldv_epi64(__U, __S, __A, __B);
 }
 
 __m256i test_mm256_shldv_epi64(__m256i __S, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_shldv_epi64
-  // CHECK: @llvm.x86.avx512.mask.vpshldv.q.256
+  // CHECK: @llvm.fshl.v4i64(<4 x i64> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}})
   return _mm256_shldv_epi64(__S, __A, __B);
 }
 
 __m128i test_mm_mask_shldv_epi64(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_mask_shldv_epi64
-  // CHECK: @llvm.x86.avx512.mask.vpshldv.q.128
+  // CHECK: @llvm.fshl.v2i64(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}})
+  // CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}}
   return _mm_mask_shldv_epi64(__S, __U, __A, __B);
 }
 
 __m128i test_mm_maskz_shldv_epi64(__mmask8 __U, __m128i __S, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_maskz_shldv_epi64
-  // CHECK: @llvm.x86.avx512.maskz.vpshldv.q.128
+  // CHECK: @llvm.fshl.v2i64(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}})
+  // CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}}
   return _mm_maskz_shldv_epi64(__U, __S, __A, __B);
 }
 
 __m128i test_mm_shldv_epi64(__m128i __S, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_shldv_epi64
-  // CHECK: @llvm.x86.avx512.mask.vpshldv.q.128
+  // CHECK: @llvm.fshl.v2i64(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}})
   return _mm_shldv_epi64(__S, __A, __B);
 }
 
 __m256i test_mm256_mask_shldv_epi32(__m256i __S, __mmask8 __U, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_mask_shldv_epi32
-  // CHECK: @llvm.x86.avx512.mask.vpshldv.d.256
+  // CHECK: @llvm.fshl.v8i32(<8 x i32> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}})
+  // CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}}
   return _mm256_mask_shldv_epi32(__S, __U, __A, __B);
 }
 
 __m256i test_mm256_maskz_shldv_epi32(__mmask8 __U, __m256i __S, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_maskz_shldv_epi32
-  // CHECK: @llvm.x86.avx512.maskz.vpshldv.d.256
+  // CHECK: @llvm.fshl.v8i32(<8 x i32> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}})
+  // CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}}
   return _mm256_maskz_shldv_epi32(__U, __S, __A, __B);
 }
 
 __m256i test_mm256_shldv_epi32(__m256i __S, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_shldv_epi32
-  // CHECK: @llvm.x86.avx512.mask.vpshldv.d.256
+  // CHECK: @llvm.fshl.v8i32(<8 x i32> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}})
   return _mm256_shldv_epi32(__S, __A, __B);
 }
 
 __m128i test_mm_mask_shldv_epi32(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_mask_shldv_epi32
-  // CHECK: @llvm.x86.avx512.mask.vpshldv.d.128
+  // CHECK: @llvm.fshl.v4i32(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}})
+  // CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
   return _mm_mask_shldv_epi32(__S, __U, __A, __B);
 }
 
 __m128i test_mm_maskz_shldv_epi32(__mmask8 __U, __m128i __S, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_maskz_shldv_epi32
-  // CHECK: @llvm.x86.avx512.maskz.vpshldv.d.128
+  // CHECK: @llvm.fshl.v4i32(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}})
+  // CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
   return _mm_maskz_shldv_epi32(__U, __S, __A, __B);
 }
 
 __m128i test_mm_shldv_epi32(__m128i __S, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_shldv_epi32
-  // CHECK: @llvm.x86.avx512.mask.vpshldv.d.128
+  // CHECK: @llvm.fshl.v4i32(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}})
   return _mm_shldv_epi32(__S, __A, __B);
 }
 
 __m256i test_mm256_mask_shldv_epi16(__m256i __S, __mmask16 __U, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_mask_shldv_epi16
-  // CHECK: @llvm.x86.avx512.mask.vpshldv.w.256
+  // CHECK: @llvm.fshl.v16i16(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}})
+  // CHECK: select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}}
   return _mm256_mask_shldv_epi16(__S, __U, __A, __B);
 }
 
 __m256i test_mm256_maskz_shldv_epi16(__mmask16 __U, __m256i __S, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_maskz_shldv_epi16
-  // CHECK: @llvm.x86.avx512.maskz.vpshldv.w.256
+  // CHECK: @llvm.fshl.v16i16(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}})
+  // CHECK: select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}}
   return _mm256_maskz_shldv_epi16(__U, __S, __A, __B);
 }
 
 __m256i test_mm256_shldv_epi16(__m256i __S, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_shldv_epi16
-  // CHECK: @llvm.x86.avx512.mask.vpshldv.w.256
+  // CHECK: @llvm.fshl.v16i16(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}})
   return _mm256_shldv_epi16(__S, __A, __B);
 }
 
 __m128i test_mm_mask_shldv_epi16(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_mask_shldv_epi16
-  // CHECK: @llvm.x86.avx512.mask.vpshldv.w.128
+  // CHECK: @llvm.fshl.v8i16(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}})
+  // CHECK: select <8 x i1> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}
   return _mm_mask_shldv_epi16(__S, __U, __A, __B);
 }
 
 __m128i test_mm_maskz_shldv_epi16(__mmask8 __U, __m128i __S, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_maskz_shldv_epi16
-  // CHECK: @llvm.x86.avx512.maskz.vpshldv.w.128
+  // CHECK: @llvm.fshl.v8i16(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}})
+  // CHECK: select <8 x i1> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}
   return _mm_maskz_shldv_epi16(__U, __S, __A, __B);
 }
 
 __m128i test_mm_shldv_epi16(__m128i __S, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_shldv_epi16
-  // CHECK: @llvm.x86.avx512.mask.vpshldv.w.128
+  // CHECK: @llvm.fshl.v8i16(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}})
   return _mm_shldv_epi16(__S, __A, __B);
 }
 
 __m256i test_mm256_mask_shrdv_epi64(__m256i __S, __mmask8 __U, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_mask_shrdv_epi64
-  // CHECK: @llvm.x86.avx512.mask.vpshrdv.q.256
+  // CHECK: @llvm.fshr.v4i64(<4 x i64> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}})
+  // CHECK: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}}
   return _mm256_mask_shrdv_epi64(__S, __U, __A, __B);
 }
 
 __m256i test_mm256_maskz_shrdv_epi64(__mmask8 __U, __m256i __S, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_maskz_shrdv_epi64
-  // CHECK: @llvm.x86.avx512.maskz.vpshrdv.q.256
+  // CHECK: @llvm.fshr.v4i64(<4 x i64> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}})
+  // CHECK: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}}
   return _mm256_maskz_shrdv_epi64(__U, __S, __A, __B);
 }
 
 __m256i test_mm256_shrdv_epi64(__m256i __S, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_shrdv_epi64
-  // CHECK: @llvm.x86.avx512.mask.vpshrdv.q.256
+  // CHECK: @llvm.fshr.v4i64(<4 x i64> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}})
   return _mm256_shrdv_epi64(__S, __A, __B);
 }
 
 __m128i test_mm_mask_shrdv_epi64(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_mask_shrdv_epi64
-  // CHECK: @llvm.x86.avx512.mask.vpshrdv.q.128
+  // CHECK: @llvm.fshr.v2i64(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}})
+  // CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}}
   return _mm_mask_shrdv_epi64(__S, __U, __A, __B);
 }
 
 __m128i test_mm_maskz_shrdv_epi64(__mmask8 __U, __m128i __S, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_maskz_shrdv_epi64
-  // CHECK: @llvm.x86.avx512.maskz.vpshrdv.q.128
+  // CHECK: @llvm.fshr.v2i64(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}})
+  // CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}}
   return _mm_maskz_shrdv_epi64(__U, __S, __A, __B);
 }
 
 __m128i test_mm_shrdv_epi64(__m128i __S, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_shrdv_epi64
-  // CHECK: @llvm.x86.avx512.mask.vpshrdv.q.128
+  // CHECK: @llvm.fshr.v2i64(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}})
   return _mm_shrdv_epi64(__S, __A, __B);
 }
 
 __m256i test_mm256_mask_shrdv_epi32(__m256i __S, __mmask8 __U, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_mask_shrdv_epi32
-  // CHECK: @llvm.x86.avx512.mask.vpshrdv.d.256
+  // CHECK: @llvm.fshr.v8i32(<8 x i32> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}})
+  // CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}}
   return _mm256_mask_shrdv_epi32(__S, __U, __A, __B);
 }
 
 __m256i test_mm256_maskz_shrdv_epi32(__mmask8 __U, __m256i __S, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_maskz_shrdv_epi32
-  // CHECK: @llvm.x86.avx512.maskz.vpshrdv.d.256
+  // CHECK: @llvm.fshr.v8i32(<8 x i32> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}})
+  // CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}}
   return _mm256_maskz_shrdv_epi32(__U, __S, __A, __B);
 }
 
 __m256i test_mm256_shrdv_epi32(__m256i __S, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_shrdv_epi32
-  // CHECK: @llvm.x86.avx512.mask.vpshrdv.d.256
+  // CHECK: @llvm.fshr.v8i32(<8 x i32> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}})
   return _mm256_shrdv_epi32(__S, __A, __B);
 }
 
 __m128i test_mm_mask_shrdv_epi32(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_mask_shrdv_epi32
-  // CHECK: @llvm.x86.avx512.mask.vpshrdv.d.128
+  // CHECK: @llvm.fshr.v4i32(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}})
+  // CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
   return _mm_mask_shrdv_epi32(__S, __U, __A, __B);
 }
 
 __m128i test_mm_maskz_shrdv_epi32(__mmask8 __U, __m128i __S, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_maskz_shrdv_epi32
-  // CHECK: @llvm.x86.avx512.maskz.vpshrdv.d.128
+  // CHECK: @llvm.fshr.v4i32(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}})
+  // CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
   return _mm_maskz_shrdv_epi32(__U, __S, __A, __B);
 }
 
 __m128i test_mm_shrdv_epi32(__m128i __S, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_shrdv_epi32
-  // CHECK: @llvm.x86.avx512.mask.vpshrdv.d.128
+  // CHECK: @llvm.fshr.v4i32(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}})
   return _mm_shrdv_epi32(__S, __A, __B);
 }
 
 __m256i test_mm256_mask_shrdv_epi16(__m256i __S, __mmask16 __U, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_mask_shrdv_epi16
-  // CHECK: @llvm.x86.avx512.mask.vpshrdv.w.256
+  // CHECK: @llvm.fshr.v16i16(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}})
+  // CHECK: select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}}
   return _mm256_mask_shrdv_epi16(__S, __U, __A, __B);
 }
 
 __m256i test_mm256_maskz_shrdv_epi16(__mmask16 __U, __m256i __S, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_maskz_shrdv_epi16
-  // CHECK: @llvm.x86.avx512.maskz.vpshrdv.w.256
+  // CHECK: @llvm.fshr.v16i16(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}})
+  // CHECK: select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}}
   return _mm256_maskz_shrdv_epi16(__U, __S, __A, __B);
 }
 
 __m256i test_mm256_shrdv_epi16(__m256i __S, __m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_shrdv_epi16
-  // CHECK: @llvm.x86.avx512.mask.vpshrdv.w.256
+  // CHECK: @llvm.fshr.v16i16(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}})
   return _mm256_shrdv_epi16(__S, __A, __B);
 }
 
 __m128i test_mm_mask_shrdv_epi16(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_mask_shrdv_epi16
-  // CHECK: @llvm.x86.avx512.mask.vpshrdv.w.128
+  // CHECK: @llvm.fshr.v8i16(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}})
+  // CHECK: select <8 x i1> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}
   return _mm_mask_shrdv_epi16(__S, __U, __A, __B);
 }
 
 __m128i test_mm_maskz_shrdv_epi16(__mmask8 __U, __m128i __S, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_maskz_shrdv_epi16
-  // CHECK: @llvm.x86.avx512.maskz.vpshrdv.w.128
+  // CHECK: @llvm.fshr.v8i16(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}})
+  // CHECK: select <8 x i1> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}
   return _mm_maskz_shrdv_epi16(__U, __S, __A, __B);
 }
 
 __m128i test_mm_shrdv_epi16(__m128i __S, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_shrdv_epi16
-  // CHECK: @llvm.x86.avx512.mask.vpshrdv.w.128
+  // CHECK: @llvm.fshr.v8i16(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}})
   return _mm_shrdv_epi16(__S, __A, __B);
 }
 
-- 
cgit v1.2.3


From 95d3faa7e80d75dfaf71f63aca109c43b63a4c82 Mon Sep 17 00:00:00 2001
From: Alexey Bataev 
Date: Mon, 7 Jan 2019 21:30:43 +0000
Subject: [OPENMP]Add call to __kmpc_push_target_tripcount() function.

Each we create the target regions with the teams distribute inner
region, we can better estimate number of the teams required to execute
the target region. Function __kmpc_push_target_tripcount() is used for
purpose, which accepts device_id and the number of the iterations,
performed by the associated loop.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350571 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/CodeGen/CGOpenMPRuntime.cpp                    | 189 +++++++++++++++++++++
 lib/CodeGen/CGOpenMPRuntime.h                      |   9 +
 lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp               |   4 +-
 lib/CodeGen/CGStmtOpenMP.cpp                       |  10 ++
 ...arget_teams_distribute_parallel_for_codegen.cpp |   4 +
 ...et_teams_distribute_parallel_for_if_codegen.cpp |   5 +
 ..._teams_distribute_parallel_for_simd_codegen.cpp |   7 +-
 ...ams_distribute_parallel_for_simd_if_codegen.cpp |   5 +
 test/OpenMP/teams_distribute_codegen.cpp           |   6 +-
 .../teams_distribute_parallel_for_codegen.cpp      |   4 +
 .../teams_distribute_parallel_for_simd_codegen.cpp |   4 +
 test/OpenMP/teams_distribute_simd_codegen.cpp      |   4 +
 12 files changed, 247 insertions(+), 4 deletions(-)

diff --git a/lib/CodeGen/CGOpenMPRuntime.cpp b/lib/CodeGen/CGOpenMPRuntime.cpp
index 8176093840..20eb0b29f4 100644
--- a/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -673,6 +673,9 @@ enum OpenMPRTLFunction {
   //
   // Offloading related calls
   //
+  // Call to void __kmpc_push_target_tripcount(int64_t device_id, kmp_uint64
+  // size);
+  OMPRTL__kmpc_push_target_tripcount,
   // Call to int32_t __tgt_target(int64_t device_id, void *host_ptr, int32_t
   // arg_num, void** args_base, void **args, size_t *arg_sizes, int64_t
   // *arg_types);
@@ -2163,6 +2166,15 @@ CGOpenMPRuntime::createRuntimeFunction(unsigned Function) {
         FnTy, /*Name=*/"__kmpc_task_reduction_get_th_data");
     break;
   }
+  case OMPRTL__kmpc_push_target_tripcount: {
+    // Build void __kmpc_push_target_tripcount(int64_t device_id, kmp_uint64
+    // size);
+    llvm::Type *TypeParams[] = {CGM.Int64Ty, CGM.Int64Ty};
+    llvm::FunctionType *FnTy =
+        llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
+    RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_push_target_tripcount");
+    break;
+  }
   case OMPRTL__tgt_target: {
     // Build int32_t __tgt_target(int64_t device_id, void *host_ptr, int32_t
     // arg_num, void** args_base, void **args, size_t *arg_sizes, int64_t
@@ -8053,6 +8065,183 @@ static void emitOffloadingArraysArgument(
   }
 }
 
+/// Checks if the expression is constant or does not have non-trivial function
+/// calls.
+static bool isTrivial(ASTContext &Ctx, const Expr * E) {
+  // We can skip constant expressions.
+  // We can skip expressions with trivial calls or simple expressions.
+  return (E->isEvaluatable(Ctx, Expr::SE_AllowUndefinedBehavior) ||
+          !E->hasNonTrivialCall(Ctx)) &&
+         !E->HasSideEffects(Ctx, /*IncludePossibleEffects=*/true);
+}
+
+/// Checks if the \p Body is the \a CompoundStmt and returns its child statement
+/// iff there is only one that is not evaluatable at the compile time.
+static const Stmt *getSingleCompoundChild(ASTContext &Ctx, const Stmt *Body) {
+  if (const auto *C = dyn_cast(Body)) {
+    const Stmt *Child = nullptr;
+    for (const Stmt *S : C->body()) {
+      if (const auto *E = dyn_cast(S)) {
+        if (isTrivial(Ctx, E))
+          continue;
+      }
+      // Some of the statements can be ignored.
+      if (isa(S) || isa(S) || isa(S) ||
+          isa(S) || isa(S))
+        continue;
+      // Analyze declarations.
+      if (const auto *DS = dyn_cast(S)) {
+        if (llvm::all_of(DS->decls(), [&Ctx](const Decl *D) {
+              if (isa(D) || isa(D) ||
+                  isa(D) || isa(D) ||
+                  isa(D) || isa(D) ||
+                  isa(D) ||
+                  isa(D) ||
+                  isa(D))
+                return true;
+              const auto *VD = dyn_cast(D);
+              if (!VD)
+                return false;
+              return VD->isConstexpr() ||
+                     ((VD->getType().isTrivialType(Ctx) ||
+                       VD->getType()->isReferenceType()) &&
+                      (!VD->hasInit() || isTrivial(Ctx, VD->getInit())));
+            }))
+          continue;
+      }
+      // Found multiple children - cannot get the one child only.
+      if (Child)
+        return Body;
+      Child = S;
+    }
+    if (Child)
+      return Child;
+  }
+  return Body;
+}
+
+/// Check for inner distribute directive.
+static const OMPExecutableDirective *
+getNestedDistributeDirective(ASTContext &Ctx, const OMPExecutableDirective &D) {
+  const auto *CS = D.getInnermostCapturedStmt();
+  const auto *Body =
+      CS->getCapturedStmt()->IgnoreContainers(/*IgnoreCaptured=*/true);
+  const Stmt *ChildStmt = getSingleCompoundChild(Ctx, Body);
+
+  if (const auto *NestedDir = dyn_cast(ChildStmt)) {
+    OpenMPDirectiveKind DKind = NestedDir->getDirectiveKind();
+    switch (D.getDirectiveKind()) {
+    case OMPD_target:
+      if (isOpenMPDistributeDirective(DKind))
+        return NestedDir;
+      if (DKind == OMPD_teams) {
+        Body = NestedDir->getInnermostCapturedStmt()->IgnoreContainers(
+            /*IgnoreCaptured=*/true);
+        if (!Body)
+          return nullptr;
+        ChildStmt = getSingleCompoundChild(Ctx, Body);
+        if (const auto *NND = dyn_cast(ChildStmt)) {
+          DKind = NND->getDirectiveKind();
+          if (isOpenMPDistributeDirective(DKind))
+            return NND;
+        }
+      }
+      return nullptr;
+    case OMPD_target_teams:
+      if (isOpenMPDistributeDirective(DKind))
+        return NestedDir;
+      return nullptr;
+    case OMPD_target_parallel:
+    case OMPD_target_simd:
+    case OMPD_target_parallel_for:
+    case OMPD_target_parallel_for_simd:
+      return nullptr;
+    case OMPD_target_teams_distribute:
+    case OMPD_target_teams_distribute_simd:
+    case OMPD_target_teams_distribute_parallel_for:
+    case OMPD_target_teams_distribute_parallel_for_simd:
+    case OMPD_parallel:
+    case OMPD_for:
+    case OMPD_parallel_for:
+    case OMPD_parallel_sections:
+    case OMPD_for_simd:
+    case OMPD_parallel_for_simd:
+    case OMPD_cancel:
+    case OMPD_cancellation_point:
+    case OMPD_ordered:
+    case OMPD_threadprivate:
+    case OMPD_task:
+    case OMPD_simd:
+    case OMPD_sections:
+    case OMPD_section:
+    case OMPD_single:
+    case OMPD_master:
+    case OMPD_critical:
+    case OMPD_taskyield:
+    case OMPD_barrier:
+    case OMPD_taskwait:
+    case OMPD_taskgroup:
+    case OMPD_atomic:
+    case OMPD_flush:
+    case OMPD_teams:
+    case OMPD_target_data:
+    case OMPD_target_exit_data:
+    case OMPD_target_enter_data:
+    case OMPD_distribute:
+    case OMPD_distribute_simd:
+    case OMPD_distribute_parallel_for:
+    case OMPD_distribute_parallel_for_simd:
+    case OMPD_teams_distribute:
+    case OMPD_teams_distribute_simd:
+    case OMPD_teams_distribute_parallel_for:
+    case OMPD_teams_distribute_parallel_for_simd:
+    case OMPD_target_update:
+    case OMPD_declare_simd:
+    case OMPD_declare_target:
+    case OMPD_end_declare_target:
+    case OMPD_declare_reduction:
+    case OMPD_taskloop:
+    case OMPD_taskloop_simd:
+    case OMPD_requires:
+    case OMPD_unknown:
+      llvm_unreachable("Unexpected directive.");
+    }
+  }
+
+  return nullptr;
+}
+
+void CGOpenMPRuntime::emitTargetNumIterationsCall(
+    CodeGenFunction &CGF, const OMPExecutableDirective &D, const Expr *Device,
+    const llvm::function_ref &SizeEmitter) {
+  OpenMPDirectiveKind Kind = D.getDirectiveKind();
+  const OMPExecutableDirective *TD = &D;
+  // Get nested teams distribute kind directive, if any.
+  if (!isOpenMPDistributeDirective(Kind) || !isOpenMPTeamsDirective(Kind))
+    TD = getNestedDistributeDirective(CGM.getContext(), D);
+  if (!TD)
+    return;
+  const auto *LD = cast(TD);
+  auto &&CodeGen = [LD, &Device, &SizeEmitter, this](CodeGenFunction &CGF,
+                                                     PrePostActionTy &) {
+    llvm::Value *NumIterations = SizeEmitter(CGF, *LD);
+
+    // Emit device ID if any.
+    llvm::Value *DeviceID;
+    if (Device)
+      DeviceID = CGF.Builder.CreateIntCast(CGF.EmitScalarExpr(Device),
+                                           CGF.Int64Ty, /*isSigned=*/true);
+    else
+      DeviceID = CGF.Builder.getInt64(OMP_DEVICEID_UNDEF);
+
+    llvm::Value *Args[] = {DeviceID, NumIterations};
+    CGF.EmitRuntimeCall(
+        createRuntimeFunction(OMPRTL__kmpc_push_target_tripcount), Args);
+  };
+  emitInlinedDirective(CGF, OMPD_unknown, CodeGen);
+}
+
 void CGOpenMPRuntime::emitTargetCall(CodeGenFunction &CGF,
                                      const OMPExecutableDirective &D,
                                      llvm::Value *OutlinedFn,
diff --git a/lib/CodeGen/CGOpenMPRuntime.h b/lib/CodeGen/CGOpenMPRuntime.h
index d9ac5df36b..933c8af116 100644
--- a/lib/CodeGen/CGOpenMPRuntime.h
+++ b/lib/CodeGen/CGOpenMPRuntime.h
@@ -1367,6 +1367,15 @@ public:
                                           bool IsOffloadEntry,
                                           const RegionCodeGenTy &CodeGen);
 
+  /// Emit code that pushes the trip count of loops associated with constructs
+  /// 'target teams distribute' and 'teams distribute parallel for'.
+  /// \param SizeEmitter Emits the int64 value for the number of iterations of
+  /// the associated loop.
+  virtual void emitTargetNumIterationsCall(
+      CodeGenFunction &CGF, const OMPExecutableDirective &D, const Expr *Device,
+      const llvm::function_ref &SizeEmitter);
+
   /// Emit the target offloading code associated with \a D. The emitted
   /// code attempts offloading the execution to the device, an the event of
   /// a failure it executes the host version outlined in \a OutlinedFn.
diff --git a/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp b/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp
index 403aefbef9..7046ab3aa3 100644
--- a/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp
+++ b/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp
@@ -705,8 +705,8 @@ getDataSharingMode(CodeGenModule &CGM) {
                                           : CGOpenMPRuntimeNVPTX::Generic;
 }
 
-// Checks if the expression is constant or does not have non-trivial function
-// calls.
+/// Checks if the expression is constant or does not have non-trivial function
+/// calls.
 static bool isTrivial(ASTContext &Ctx, const Expr * E) {
   // We can skip constant expressions.
   // We can skip expressions with trivial calls or simple expressions.
diff --git a/lib/CodeGen/CGStmtOpenMP.cpp b/lib/CodeGen/CGStmtOpenMP.cpp
index ee38593084..650f4e8b91 100644
--- a/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/lib/CodeGen/CGStmtOpenMP.cpp
@@ -4071,6 +4071,16 @@ static void emitCommonOMPTargetDirective(CodeGenFunction &CGF,
   CGM.getOpenMPRuntime().emitTargetOutlinedFunction(S, ParentName, Fn, FnID,
                                                     IsOffloadEntry, CodeGen);
   OMPLexicalScope Scope(CGF, S, OMPD_task);
+  auto &&SizeEmitter = [](CodeGenFunction &CGF, const OMPLoopDirective &D) {
+    OMPLoopScope(CGF, D);
+    // Emit calculation of the iterations count.
+    llvm::Value *NumIterations = CGF.EmitScalarExpr(D.getNumIterations());
+    NumIterations = CGF.Builder.CreateIntCast(NumIterations, CGF.Int64Ty,
+                                              /*IsSigned=*/false);
+    return NumIterations;
+  };
+  CGM.getOpenMPRuntime().emitTargetNumIterationsCall(CGF, S, Device,
+                                                     SizeEmitter);
   CGM.getOpenMPRuntime().emitTargetCall(CGF, S, Fn, FnID, IfCond, Device);
 }
 
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_codegen.cpp b/test/OpenMP/target_teams_distribute_parallel_for_codegen.cpp
index 4d263cf69f..e439431a05 100644
--- a/test/OpenMP/target_teams_distribute_parallel_for_codegen.cpp
+++ b/test/OpenMP/target_teams_distribute_parallel_for_codegen.cpp
@@ -51,9 +51,13 @@ int target_teams_fun(int *g){
   // discard capture expressions for te and th
   // HCK1: = alloca i32,
   // HCK1: = alloca i32,
+  // HCK1: = alloca i32,
+  // HCK1: = alloca i32,
+  // HCK1: = alloca i32,
   // HCK1: [[N_CAST:%.+]] = alloca i{{32|64}},
   // HCK1: [[TE_CAST:%.+]] = alloca i{{32|64}},
   // HCK1: [[TH_CAST:%.+]] = alloca i{{32|64}},
+  // HCK1: call void @__kmpc_push_target_tripcount(i64 -1, i64 %{{.+}})
   // HCK1: [[N_PAR:%.+]] = load{{.+}}, {{.+}} [[N_CAST]],
   // HCK1: [[TE_PAR:%.+]] = load{{.+}}, {{.+}} [[TE_CAST]],
   // HCK1: [[TH_PAR:%.+]] = load{{.+}}, {{.+}} [[TH_CAST]],
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_if_codegen.cpp b/test/OpenMP/target_teams_distribute_parallel_for_if_codegen.cpp
index 8cd90a610b..af6ed9744a 100644
--- a/test/OpenMP/target_teams_distribute_parallel_for_if_codegen.cpp
+++ b/test/OpenMP/target_teams_distribute_parallel_for_if_codegen.cpp
@@ -22,8 +22,10 @@ int Arg;
 
 // CHECK-LABEL: define {{.*}}void @{{.+}}gtid_test
 void gtid_test() {
+// CHECK: call void @__kmpc_push_target_tripcount(i64 -1, i64 100)
 // CHECK: call i{{[0-9]+}} @__tgt_target_teams(
 // CHECK: call void [[OFFLOADING_FUN_0:@.+]](
+// CHECK: call void @__kmpc_push_target_tripcount(i64 -1, i64 100)
 // CHECK: call i{{[0-9]+}} @__tgt_target_teams(
 // CHECK: call void [[OFFLOADING_FUN_1:@.+]](
 #pragma omp target teams distribute parallel for
@@ -78,9 +80,12 @@ int tmain(T Arg) {
 
 // CHECK-LABEL: define {{.*}}i{{[0-9]+}} @main()
 int main() {
+// CHECK: call void @__kmpc_push_target_tripcount(i64 -1, i64 100)
 // CHECK: call i{{[0-9]+}} @__tgt_target_teams(
 // CHECK: call void [[OFFLOADING_FUN_0:@.+]](
+// CHECK: call void @__kmpc_push_target_tripcount(i64 -1, i64 100)
 // CHECK: call void [[OFFLOADING_FUN_1:@.+]](
+// CHECK: call void @__kmpc_push_target_tripcount(i64 -1, i64 100)
 // CHECK: call i{{[0-9]+}} @__tgt_target_teams(
 // CHECK: call void [[OFFLOADING_FUN_2:@.+]](
 // CHECK: = call {{.*}}i{{.+}} @{{.+}}tmain
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_simd_codegen.cpp b/test/OpenMP/target_teams_distribute_parallel_for_simd_codegen.cpp
index 0329d7e278..7a1ea81091 100644
--- a/test/OpenMP/target_teams_distribute_parallel_for_simd_codegen.cpp
+++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_codegen.cpp
@@ -52,10 +52,14 @@ int target_teams_fun(int *g){
 // discard capture expressions for te and th
 // HCK1: = alloca i32,
 // HCK1: = alloca i32,
+// HCK1: = alloca i32,
+// HCK1: = alloca i32,
+// HCK1: = alloca i32,
 // HCK1: [[I_CAST:%.+]] = alloca i{{32|64}},
 // HCK1: [[N_CAST:%.+]] = alloca i{{32|64}},
 // HCK1: [[TE_CAST:%.+]] = alloca i{{32|64}},
 // HCK1: [[TH_CAST:%.+]] = alloca i{{32|64}},
+// HCK1: call void @__kmpc_push_target_tripcount(i64 -1, i64 %{{.+}})
 // HCK1: [[I_PAR:%.+]] = load{{.+}}, {{.+}} [[I_CAST]],
 // HCK1: [[N_PAR:%.+]] = load{{.+}}, {{.+}} [[N_CAST]],
 // HCK1: [[TE_PAR:%.+]] = load{{.+}}, {{.+}} [[TE_CAST]],
@@ -73,7 +77,8 @@ int target_teams_fun(int *g){
   // HCK1: call void @[[OFFL2:.+]](i{{64|32}} %{{.+}})
   {{{
   #pragma omp target teams distribute parallel for simd is_device_ptr(g) simdlen(8)
-  for(int i = 0; i < n; i++) {
+  for(
+    int i = 0; i < n; i++) {
     a[i] = g[0];
   }
   }}}
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_simd_if_codegen.cpp b/test/OpenMP/target_teams_distribute_parallel_for_simd_if_codegen.cpp
index a3a14fbf1e..b6778417be 100644
--- a/test/OpenMP/target_teams_distribute_parallel_for_simd_if_codegen.cpp
+++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_if_codegen.cpp
@@ -22,8 +22,10 @@ int Arg;
 
 // CHECK-LABEL: define {{.*}}void @{{.+}}gtid_test
 void gtid_test() {
+// CHECK: call void @__kmpc_push_target_tripcount(i64 -1, i64 100)
 // CHECK: call i{{[0-9]+}} @__tgt_target_teams(
 // CHECK: call void [[OFFLOADING_FUN_0:@.+]](
+// CHECK: call void @__kmpc_push_target_tripcount(i64 -1, i64 100)
 // CHECK: call i{{[0-9]+}} @__tgt_target_teams(
 // CHECK: call void [[OFFLOADING_FUN_1:@.+]](
 #pragma omp target teams distribute parallel for simd
@@ -78,9 +80,12 @@ int tmain(T Arg) {
 
 // CHECK-LABEL: define {{.*}}i{{[0-9]+}} @main()
 int main() {
+// CHECK: call void @__kmpc_push_target_tripcount(i64 -1, i64 100)
 // CHECK: call i{{[0-9]+}} @__tgt_target_teams(
 // CHECK: call void [[OFFLOADING_FUN_0:@.+]](
+// CHECK: call void @__kmpc_push_target_tripcount(i64 -1, i64 100)
 // CHECK: call void [[OFFLOADING_FUN_1:@.+]](
+// CHECK: call void @__kmpc_push_target_tripcount(i64 -1, i64 100)
 // CHECK: call i{{[0-9]+}} @__tgt_target_teams(
 // CHECK: call void [[OFFLOADING_FUN_2:@.+]](
 // CHECK: = call {{.*}}i{{.+}} @{{.+}}tmain
diff --git a/test/OpenMP/teams_distribute_codegen.cpp b/test/OpenMP/teams_distribute_codegen.cpp
index 0f6b5f2f25..ea299bc346 100644
--- a/test/OpenMP/teams_distribute_codegen.cpp
+++ b/test/OpenMP/teams_distribute_codegen.cpp
@@ -21,15 +21,19 @@
 int a[100];
 
 // CK1: define {{.*}}i32 @{{.+}}teams_argument_globali(
-int teams_argument_global(int n){  
+int teams_argument_global(int n){
   int te = n / 128;
   int th = 128;
   // discard n_addr
   // CK1: alloca i32,
   // CK1: [[TE:%.+]] = alloca i32,
   // CK1: [[TH:%.+]] = alloca i32,
+  // CK1: alloca i32,
+  // CK1: alloca i32,
+  // CK1: alloca i32,
   // CK1: [[TE_CAST:%.+]] = alloca i{{32|64}},
   // CK1: [[TH_CAST:%.+]] = alloca i{{32|64}},
+  // CK1: call void @__kmpc_push_target_tripcount(i64 -1, i64 %{{.+}})
   // CK1: [[TE_PAR:%.+]] = load{{.+}}, {{.+}} [[TE_CAST]],
   // CK1: [[TH_PAR:%.+]] = load{{.+}}, {{.+}} [[TH_CAST]],
 
diff --git a/test/OpenMP/teams_distribute_parallel_for_codegen.cpp b/test/OpenMP/teams_distribute_parallel_for_codegen.cpp
index 865ea129f9..fa425b3eca 100644
--- a/test/OpenMP/teams_distribute_parallel_for_codegen.cpp
+++ b/test/OpenMP/teams_distribute_parallel_for_codegen.cpp
@@ -28,8 +28,12 @@ int teams_argument_global(int n){
   // CK1: alloca i32,
   // CK1: [[TE:%.+]] = alloca i32,
   // CK1: [[TH:%.+]] = alloca i32,
+  // CK1: alloca i32,
+  // CK1: alloca i32,
+  // CK1: alloca i32,
   // CK1: [[TE_CAST:%.+]] = alloca i{{32|64}},
   // CK1: [[TH_CAST:%.+]] = alloca i{{32|64}},
+  // CK1: call void @__kmpc_push_target_tripcount(i64 -1, i64 %{{.+}})
   // CK1: [[TE_PAR:%.+]] = load{{.+}}, {{.+}} [[TE_CAST]],
   // CK1: [[TH_PAR:%.+]] = load{{.+}}, {{.+}} [[TH_CAST]],
   // CK1: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 4, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 {{.+}}, i32 {{.+}})
diff --git a/test/OpenMP/teams_distribute_parallel_for_simd_codegen.cpp b/test/OpenMP/teams_distribute_parallel_for_simd_codegen.cpp
index 784deeef7c..45793419d7 100644
--- a/test/OpenMP/teams_distribute_parallel_for_simd_codegen.cpp
+++ b/test/OpenMP/teams_distribute_parallel_for_simd_codegen.cpp
@@ -28,8 +28,12 @@ int teams_argument_global(int n){
   // CK1: alloca i32,
   // CK1: [[TE:%.+]] = alloca i32,
   // CK1: [[TH:%.+]] = alloca i32,
+  // CK1: alloca i32,
+  // CK1: alloca i32,
+  // CK1: alloca i32,
   // CK1: [[TE_CAST:%.+]] = alloca i{{32|64}},
   // CK1: [[TH_CAST:%.+]] = alloca i{{32|64}},
+  // CK1: call void @__kmpc_push_target_tripcount(i64 -1, i64 %{{.+}})
   // CK1: [[TE_PAR:%.+]] = load{{.+}}, {{.+}} [[TE_CAST]],
   // CK1: [[TH_PAR:%.+]] = load{{.+}}, {{.+}} [[TH_CAST]],
 
diff --git a/test/OpenMP/teams_distribute_simd_codegen.cpp b/test/OpenMP/teams_distribute_simd_codegen.cpp
index 813d3912c3..c89a936b64 100644
--- a/test/OpenMP/teams_distribute_simd_codegen.cpp
+++ b/test/OpenMP/teams_distribute_simd_codegen.cpp
@@ -30,8 +30,12 @@ int teams_argument_global(int n) {
   // CK1: alloca i32,
   // CK1: [[TE:%.+]] = alloca i32,
   // CK1: [[TH:%.+]] = alloca i32,
+  // CK1: alloca i32,
+  // CK1: alloca i32,
+  // CK1: alloca i32,
   // CK1: [[TE_CAST:%.+]] = alloca i{{32|64}},
   // CK1: [[TH_CAST:%.+]] = alloca i{{32|64}},
+  // CK1: call void @__kmpc_push_target_tripcount(i64 -1, i64 %{{.+}})
   // CK1: [[TE_PAR:%.+]] = load{{.+}}, {{.+}} [[TE_CAST]],
   // CK1: [[TH_PAR:%.+]] = load{{.+}}, {{.+}} [[TH_CAST]],
 
-- 
cgit v1.2.3


From b4cc996c03cf35e987db6c831d711ed8996e4ec1 Mon Sep 17 00:00:00 2001
From: Erik Pilkington 
Date: Mon, 7 Jan 2019 21:54:00 +0000
Subject: Add a __has_feature check for namespaces on #pragma clang attribute.

Support for this was added in r349845.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350572 91177308-0d34-0410-b5e6-96231b3b80d8
---
 docs/LanguageExtensions.rst            | 4 +++-
 include/clang/Basic/Features.def       | 1 +
 test/Sema/pragma-attribute-namespace.c | 4 ++++
 3 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/docs/LanguageExtensions.rst b/docs/LanguageExtensions.rst
index c800a96e6d..574bb77345 100644
--- a/docs/LanguageExtensions.rst
+++ b/docs/LanguageExtensions.rst
@@ -2725,7 +2725,9 @@ same namespace. For instance:
 Without the namespaces on the macros, ``other_function`` will be annotated with
 ``[[noreturn]]`` instead of ``__attribute__((unavailable))``. This may seem like
 a contrived example, but its very possible for this kind of situation to appear
-in real code if the pragmas are spread out across a large file.
+in real code if the pragmas are spread out across a large file. You can test if
+your version of clang supports namespaces on ``#pragma clang attribute`` with
+``__has_feature(pragma_clang_attribute_namespaces)``.
 
 Subject Match Rules
 -------------------
diff --git a/include/clang/Basic/Features.def b/include/clang/Basic/Features.def
index 0cece27eef..e3b97fd078 100644
--- a/include/clang/Basic/Features.def
+++ b/include/clang/Basic/Features.def
@@ -69,6 +69,7 @@ FEATURE(attribute_overloadable, true)
 FEATURE(attribute_unavailable_with_message, true)
 FEATURE(attribute_unused_on_fields, true)
 FEATURE(attribute_diagnose_if_objc, true)
+FEATURE(pragma_clang_attribute_namespaces, true)
 FEATURE(blocks, LangOpts.Blocks)
 FEATURE(c_thread_safety_attributes, true)
 FEATURE(cxx_exceptions, LangOpts.CXXExceptions)
diff --git a/test/Sema/pragma-attribute-namespace.c b/test/Sema/pragma-attribute-namespace.c
index 35b6419f7d..2db788865b 100644
--- a/test/Sema/pragma-attribute-namespace.c
+++ b/test/Sema/pragma-attribute-namespace.c
@@ -1,5 +1,9 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
 
+#if !__has_feature(pragma_clang_attribute_namespaces)
+#error
+#endif
+
 #pragma clang attribute MyNamespace.push (__attribute__((annotate)), apply_to=function) // expected-error 2 {{'annotate' attribute}}
 
 int some_func(); // expected-note{{when applied to this declaration}}
-- 
cgit v1.2.3


From 425b89a8d02393a39cfe223b84e3396841708794 Mon Sep 17 00:00:00 2001
From: Stephen Kelly 
Date: Mon, 7 Jan 2019 21:57:30 +0000
Subject: NFC: Replace asserts with if() in SourceLocation accessors

Summary:
Nowhere else in the AST classes assert on these kinds of accessors.

This way, we can call the accessors and check the validity of the result
instead of externally duplicating the conditions.  This generality will
make it possible to introspect instances for source locations:

 http://ec2-18-191-7-3.us-east-2.compute.amazonaws.com:10240/z/iiaWhw

Reviewers: aaron.ballman

Subscribers: cfe-commits

Differential Revision: https://reviews.llvm.org/D56354

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350573 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/AST/DeclarationName.h | 13 ++++++++-----
 include/clang/AST/TemplateBase.h    | 13 ++++++++-----
 lib/AST/NestedNameSpecifier.cpp     |  6 +++---
 3 files changed, 19 insertions(+), 13 deletions(-)

diff --git a/include/clang/AST/DeclarationName.h b/include/clang/AST/DeclarationName.h
index d196233de1..62afae23ec 100644
--- a/include/clang/AST/DeclarationName.h
+++ b/include/clang/AST/DeclarationName.h
@@ -729,9 +729,10 @@ public:
   /// getNamedTypeInfo - Returns the source type info associated to
   /// the name. Assumes it is a constructor, destructor or conversion.
   TypeSourceInfo *getNamedTypeInfo() const {
-    assert(Name.getNameKind() == DeclarationName::CXXConstructorName ||
-           Name.getNameKind() == DeclarationName::CXXDestructorName ||
-           Name.getNameKind() == DeclarationName::CXXConversionFunctionName);
+    if (Name.getNameKind() != DeclarationName::CXXConstructorName &&
+        Name.getNameKind() != DeclarationName::CXXDestructorName &&
+        Name.getNameKind() != DeclarationName::CXXConversionFunctionName)
+      return nullptr;
     return LocInfo.NamedType.TInfo;
   }
 
@@ -747,7 +748,8 @@ public:
   /// getCXXOperatorNameRange - Gets the range of the operator name
   /// (without the operator keyword). Assumes it is a (non-literal) operator.
   SourceRange getCXXOperatorNameRange() const {
-    assert(Name.getNameKind() == DeclarationName::CXXOperatorName);
+    if (Name.getNameKind() != DeclarationName::CXXOperatorName)
+      return SourceRange();
     return SourceRange(
      SourceLocation::getFromRawEncoding(LocInfo.CXXOperatorName.BeginOpNameLoc),
      SourceLocation::getFromRawEncoding(LocInfo.CXXOperatorName.EndOpNameLoc)
@@ -766,7 +768,8 @@ public:
   /// operator name (not the operator keyword).
   /// Assumes it is a literal operator.
   SourceLocation getCXXLiteralOperatorNameLoc() const {
-    assert(Name.getNameKind() == DeclarationName::CXXLiteralOperatorName);
+    if (Name.getNameKind() != DeclarationName::CXXLiteralOperatorName)
+      return SourceLocation();
     return SourceLocation::
       getFromRawEncoding(LocInfo.CXXLiteralOperatorName.OpNameLoc);
   }
diff --git a/include/clang/AST/TemplateBase.h b/include/clang/AST/TemplateBase.h
index 8f92e799d7..01bdc0df1a 100644
--- a/include/clang/AST/TemplateBase.h
+++ b/include/clang/AST/TemplateBase.h
@@ -530,19 +530,22 @@ public:
   }
 
   NestedNameSpecifierLoc getTemplateQualifierLoc() const {
-    assert(Argument.getKind() == TemplateArgument::Template ||
-           Argument.getKind() == TemplateArgument::TemplateExpansion);
+    if (Argument.getKind() != TemplateArgument::Template &&
+        Argument.getKind() != TemplateArgument::TemplateExpansion)
+      return NestedNameSpecifierLoc();
     return LocInfo.getTemplateQualifierLoc();
   }
 
   SourceLocation getTemplateNameLoc() const {
-    assert(Argument.getKind() == TemplateArgument::Template ||
-           Argument.getKind() == TemplateArgument::TemplateExpansion);
+    if (Argument.getKind() != TemplateArgument::Template &&
+        Argument.getKind() != TemplateArgument::TemplateExpansion)
+      return SourceLocation();
     return LocInfo.getTemplateNameLoc();
   }
 
   SourceLocation getTemplateEllipsisLoc() const {
-    assert(Argument.getKind() == TemplateArgument::TemplateExpansion);
+    if (Argument.getKind() != TemplateArgument::TemplateExpansion)
+      return SourceLocation();
     return LocInfo.getTemplateEllipsisLoc();
   }
 };
diff --git a/lib/AST/NestedNameSpecifier.cpp b/lib/AST/NestedNameSpecifier.cpp
index 548f2f8e3b..42f6a133d7 100644
--- a/lib/AST/NestedNameSpecifier.cpp
+++ b/lib/AST/NestedNameSpecifier.cpp
@@ -462,9 +462,9 @@ SourceRange NestedNameSpecifierLoc::getLocalSourceRange() const {
 }
 
 TypeLoc NestedNameSpecifierLoc::getTypeLoc() const {
-  assert((Qualifier->getKind() == NestedNameSpecifier::TypeSpec ||
-          Qualifier->getKind() == NestedNameSpecifier::TypeSpecWithTemplate) &&
-         "Nested-name-specifier location is not a type");
+  if (Qualifier->getKind() != NestedNameSpecifier::TypeSpec &&
+      Qualifier->getKind() != NestedNameSpecifier::TypeSpecWithTemplate)
+    return TypeLoc();
 
   // The "void*" that points at the TypeLoc data.
   unsigned Offset = getDataLength(Qualifier->getPrefix());
-- 
cgit v1.2.3


From 2b01328de2b9738cf847a27b227eceac8ac5bcf6 Mon Sep 17 00:00:00 2001
From: Erik Pilkington 
Date: Tue, 8 Jan 2019 00:21:05 +0000
Subject: Split -Wdelete-non-virtual-dtor into
 -Wdelete-abstract-non-virtual-dtor

-Wdelete-non-virtual-dtor previously controlled two diagnostics: 1)
calling a non-virtual dtor from an abstract class, and 2) calling a
non-virtual dtor from a polymorphic class. 1) is a lot more severe
than 2), since 1) is a guaranteed crash, but 2) is just "code smell".
Previously, projects compiled with -Wall -Wno-delete-non-virtual-dtor,
which is somewhat reasonable, silently crashed on 1).

rdar://40380564

Differential revision: https://reviews.llvm.org/D56405

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350585 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/Basic/DiagnosticGroups.td    |  2 ++
 include/clang/Basic/DiagnosticSemaKinds.td |  2 +-
 test/SemaCXX/non-virtual-dtors.cpp         | 32 ++++++++++++++++++++++++++++++
 3 files changed, 35 insertions(+), 1 deletion(-)
 create mode 100644 test/SemaCXX/non-virtual-dtors.cpp

diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td
index 6ba6c19a28..52bd87d79a 100644
--- a/include/clang/Basic/DiagnosticGroups.td
+++ b/include/clang/Basic/DiagnosticGroups.td
@@ -105,6 +105,8 @@ def MissingNoEscape : DiagGroup<"missing-noescape">;
 
 def DeleteIncomplete : DiagGroup<"delete-incomplete">;
 def DeleteNonVirtualDtor : DiagGroup<"delete-non-virtual-dtor">;
+def DeleteAbstractNonVirtualDtor : DiagGroup<"delete-abstract-non-virtual-dtor",
+                                             [DeleteNonVirtualDtor]>;
 def AbstractFinalClass : DiagGroup<"abstract-final-class">;
 
 def CXX11CompatDeprecatedWritableStr :
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index c54fbc8b4c..d6c5ccffd8 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -6460,7 +6460,7 @@ def note_delete_non_virtual : Note<
   "qualify call to silence this warning">;
 def warn_delete_abstract_non_virtual_dtor : Warning<
   "%select{delete|destructor}0 called on %1 that is abstract but has "
-  "non-virtual destructor">, InGroup, ShowInSystemHeader;
+  "non-virtual destructor">, InGroup, ShowInSystemHeader;
 def warn_overloaded_virtual : Warning<
   "%q0 hides overloaded virtual %select{function|functions}1">,
   InGroup, DefaultIgnore;
diff --git a/test/SemaCXX/non-virtual-dtors.cpp b/test/SemaCXX/non-virtual-dtors.cpp
new file mode 100644
index 0000000000..230b899a7f
--- /dev/null
+++ b/test/SemaCXX/non-virtual-dtors.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 %s -verify -DDIAG1
+// RUN: %clang_cc1 %s -verify -DDIAG1 -DDIAG2 -Wdelete-non-virtual-dtor
+// RUN: %clang_cc1 %s -verify -DDIAG1         -Wmost -Wno-delete-non-virtual-dtor
+// RUN: %clang_cc1 %s -verify                 -Wmost -Wno-delete-abstract-non-virtual-dtor
+
+#ifndef DIAG1
+#ifndef DIAG2
+// expected-no-diagnostics
+#endif
+#endif
+
+struct S1 {
+  ~S1() {}
+  virtual void abs() = 0;
+};
+
+void f1(S1 *s1) { delete s1; }
+#ifdef DIAG1
+// expected-warning@-2 {{delete called on 'S1' that is abstract but has non-virtual destructor}}
+#endif
+
+struct Base {
+  virtual void abs() = 0;
+};
+struct S2 : Base {
+  ~S2() {}
+  void abs() {}
+};
+void f2(S2 *s2) { delete s2; }
+#ifdef DIAG2
+// expected-warning@-2 {{delete called on non-final 'S2' that has virtual functions but non-virtual destructor}}
+#endif
-- 
cgit v1.2.3


From 1831e52ca5d0d56cb5b82e61e74dfc468797a27e Mon Sep 17 00:00:00 2001
From: Sam McCall 
Date: Tue, 8 Jan 2019 07:29:46 +0000
Subject: [ASTMatchers] Improve assert message for broken parent map.

Summary:
This assert catches places where the AST (as seen by RecursiveASTVisitor)
becomes disconnected due to incomplete traversal.
Making it print the actual parent-less node is a lot more helpful - it's
possible to work out which part of the tree wasn't traversed.

Reviewers: ilya-biryukov

Subscribers: cfe-commits

Differential Revision: https://reviews.llvm.org/D56395

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350612 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/ASTMatchers/ASTMatchFinder.cpp | 18 +++++++++++-------
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/lib/ASTMatchers/ASTMatchFinder.cpp b/lib/ASTMatchers/ASTMatchFinder.cpp
index 32d8282f6d..dec2e2ad1f 100644
--- a/lib/ASTMatchers/ASTMatchFinder.cpp
+++ b/lib/ASTMatchers/ASTMatchFinder.cpp
@@ -676,13 +676,17 @@ private:
       //  c) there is a bug in the AST, and the node is not reachable
       // Usually the traversal scope is the whole AST, which precludes b.
       // Bugs are common enough that it's worthwhile asserting when we can.
-      assert((Node.get() ||
-              /* Traversal scope is limited if none of the bounds are the TU */
-              llvm::none_of(ActiveASTContext->getTraversalScope(),
-                            [](Decl *D) {
-                              return D->getKind() == Decl::TranslationUnit;
-                            })) &&
-             "Found node that is not in the complete parent map!");
+#ifndef NDEBUG
+      if (!Node.get() &&
+          /* Traversal scope is full AST if any of the bounds are the TU */
+          llvm::any_of(ActiveASTContext->getTraversalScope(), [](Decl *D) {
+            return D->getKind() == Decl::TranslationUnit;
+          })) {
+        llvm::errs() << "Tried to match orphan node:\n";
+        Node.dump(llvm::errs(), ActiveASTContext->getSourceManager());
+        llvm_unreachable("Parent map should be complete!");
+      }
+#endif
       return false;
     }
     if (Parents.size() == 1) {
-- 
cgit v1.2.3


From ddc3fb27d3231b95658f460a74ce24e9d645eac2 Mon Sep 17 00:00:00 2001
From: Simon Pilgrim 
Date: Tue, 8 Jan 2019 12:59:15 +0000
Subject: [X86] Add shift-by-immediate tests for non-immediate/out-of-range
 values

As noted on PR40203, for gcc compatibility we need to support non-immediate values in the 'slli/srli/srai' shift by immediate vector intrinsics.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350619 91177308-0d34-0410-b5e6-96231b3b80d8
---
 test/CodeGen/avx2-builtins.c       |  48 ++++++++++
 test/CodeGen/avx512bw-builtins.c   |  60 +++++++++++++
 test/CodeGen/avx512f-builtins.c    | 121 +++++++++++++++++++++++++
 test/CodeGen/avx512vl-builtins.c   | 179 +++++++++++++++++++++++++++++++++++++
 test/CodeGen/avx512vlbw-builtins.c |  84 +++++++++++++++++
 test/CodeGen/sse2-builtins.c       |  96 ++++++++++++++++++++
 6 files changed, 588 insertions(+)

diff --git a/test/CodeGen/avx2-builtins.c b/test/CodeGen/avx2-builtins.c
index 89225e69aa..90c07c1d38 100644
--- a/test/CodeGen/avx2-builtins.c
+++ b/test/CodeGen/avx2-builtins.c
@@ -995,18 +995,36 @@ __m256i test_mm256_slli_epi16(__m256i a) {
   return _mm256_slli_epi16(a, 3);
 }
 
+__m256i test_mm256_slli_epi16_2(__m256i a, int b) {
+  // CHECK-LABEL: test_mm256_slli_epi16_2
+  // CHECK: call <16 x i16> @llvm.x86.avx2.pslli.w(<16 x i16> %{{.*}}, i32 %{{.*}})
+  return _mm256_slli_epi16(a, b);
+}
+
 __m256i test_mm256_slli_epi32(__m256i a) {
   // CHECK-LABEL: test_mm256_slli_epi32
   // CHECK: call <8 x i32> @llvm.x86.avx2.pslli.d(<8 x i32> %{{.*}}, i32 %{{.*}})
   return _mm256_slli_epi32(a, 3);
 }
 
+__m256i test_mm256_slli_epi32_2(__m256i a, int b) {
+  // CHECK-LABEL: test_mm256_slli_epi32_2
+  // CHECK: call <8 x i32> @llvm.x86.avx2.pslli.d(<8 x i32> %{{.*}}, i32 %{{.*}})
+  return _mm256_slli_epi32(a, b);
+}
+
 __m256i test_mm256_slli_epi64(__m256i a) {
   // CHECK-LABEL: test_mm256_slli_epi64
   // CHECK: call <4 x i64> @llvm.x86.avx2.pslli.q(<4 x i64> %{{.*}}, i32 %{{.*}})
   return _mm256_slli_epi64(a, 3);
 }
 
+__m256i test_mm256_slli_epi64_2(__m256i a, int b) {
+  // CHECK-LABEL: test_mm256_slli_epi64_2
+  // CHECK: call <4 x i64> @llvm.x86.avx2.pslli.q(<4 x i64> %{{.*}}, i32 %{{.*}})
+  return _mm256_slli_epi64(a, b);
+}
+
 __m256i test_mm256_slli_si256(__m256i a) {
   // CHECK-LABEL: test_mm256_slli_si256
   // CHECK: shufflevector <32 x i8> zeroinitializer, <32 x i8> %{{.*}}, <32 x i32> 
@@ -1055,12 +1073,24 @@ __m256i test_mm256_srai_epi16(__m256i a) {
   return _mm256_srai_epi16(a, 3);
 }
 
+__m256i test_mm256_srai_epi16_2(__m256i a, int b) {
+  // CHECK-LABEL: test_mm256_srai_epi16_2
+  // CHECK: call <16 x i16> @llvm.x86.avx2.psrai.w(<16 x i16> %{{.*}}, i32 %{{.*}})
+  return _mm256_srai_epi16(a, b);
+}
+
 __m256i test_mm256_srai_epi32(__m256i a) {
   // CHECK-LABEL: test_mm256_srai_epi32
   // CHECK: call <8 x i32> @llvm.x86.avx2.psrai.d(<8 x i32> %{{.*}}, i32 %{{.*}})
   return _mm256_srai_epi32(a, 3);
 }
 
+__m256i test_mm256_srai_epi32_2(__m256i a, int b) {
+  // CHECK-LABEL: test_mm256_srai_epi32_2
+  // CHECK: call <8 x i32> @llvm.x86.avx2.psrai.d(<8 x i32> %{{.*}}, i32 %{{.*}})
+  return _mm256_srai_epi32(a, b);
+}
+
 __m128i test_mm_srav_epi32(__m128i a, __m128i b) {
   // CHECK-LABEL: test_mm_srav_epi32
   // CHECK: call <4 x i32> @llvm.x86.avx2.psrav.d(<4 x i32> %{{.*}}, <4 x i32> %{{.*}})
@@ -1097,18 +1127,36 @@ __m256i test_mm256_srli_epi16(__m256i a) {
   return _mm256_srli_epi16(a, 3);
 }
 
+__m256i test_mm256_srli_epi16_2(__m256i a, int b) {
+  // CHECK-LABEL: test_mm256_srli_epi16_2
+  // CHECK: call <16 x i16> @llvm.x86.avx2.psrli.w(<16 x i16> %{{.*}}, i32 %{{.*}})
+  return _mm256_srli_epi16(a, b);
+}
+
 __m256i test_mm256_srli_epi32(__m256i a) {
   // CHECK-LABEL: test_mm256_srli_epi32
   // CHECK: call <8 x i32> @llvm.x86.avx2.psrli.d(<8 x i32> %{{.*}}, i32 %{{.*}})
   return _mm256_srli_epi32(a, 3);
 }
 
+__m256i test_mm256_srli_epi32_2(__m256i a, int b) {
+  // CHECK-LABEL: test_mm256_srli_epi32_2
+  // CHECK: call <8 x i32> @llvm.x86.avx2.psrli.d(<8 x i32> %{{.*}}, i32 %{{.*}})
+  return _mm256_srli_epi32(a, b);
+}
+
 __m256i test_mm256_srli_epi64(__m256i a) {
   // CHECK-LABEL: test_mm256_srli_epi64
   // CHECK: call <4 x i64> @llvm.x86.avx2.psrli.q(<4 x i64> %{{.*}}, i32 %{{.*}})
   return _mm256_srli_epi64(a, 3);
 }
 
+__m256i test_mm256_srli_epi64_2(__m256i a, int b) {
+  // CHECK-LABEL: test_mm256_srli_epi64_2
+  // CHECK: call <4 x i64> @llvm.x86.avx2.psrli.q(<4 x i64> %{{.*}}, i32 %{{.*}})
+  return _mm256_srli_epi64(a, b);
+}
+
 __m256i test_mm256_srli_si256(__m256i a) {
   // CHECK-LABEL: test_mm256_srli_si256
   // CHECK: shufflevector <32 x i8> %{{.*}}, <32 x i8> zeroinitializer, <32 x i32> 
diff --git a/test/CodeGen/avx512bw-builtins.c b/test/CodeGen/avx512bw-builtins.c
index aa6b45325c..9e75baae77 100644
--- a/test/CodeGen/avx512bw-builtins.c
+++ b/test/CodeGen/avx512bw-builtins.c
@@ -1760,6 +1760,12 @@ __m512i test_mm512_slli_epi16(__m512i __A) {
   return _mm512_slli_epi16(__A, 5); 
 }
 
+__m512i test_mm512_slli_epi16_2(__m512i __A, int __B) {
+  // CHECK-LABEL: @test_mm512_slli_epi16_2
+  // CHECK: @llvm.x86.avx512.pslli.w.512
+  return _mm512_slli_epi16(__A, __B); 
+}
+
 __m512i test_mm512_mask_slli_epi16(__m512i __W, __mmask32 __U, __m512i __A) {
   // CHECK-LABEL: @test_mm512_mask_slli_epi16
   // CHECK: @llvm.x86.avx512.pslli.w.512
@@ -1767,6 +1773,13 @@ __m512i test_mm512_mask_slli_epi16(__m512i __W, __mmask32 __U, __m512i __A) {
   return _mm512_mask_slli_epi16(__W, __U, __A, 5); 
 }
 
+__m512i test_mm512_mask_slli_epi16_2(__m512i __W, __mmask32 __U, __m512i __A, int __B) {
+  // CHECK-LABEL: @test_mm512_mask_slli_epi16_2
+  // CHECK: @llvm.x86.avx512.pslli.w.512
+  // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}}
+  return _mm512_mask_slli_epi16(__W, __U, __A, __B); 
+}
+
 __m512i test_mm512_maskz_slli_epi16(__mmask32 __U, __m512i __A) {
   // CHECK-LABEL: @test_mm512_maskz_slli_epi16
   // CHECK: @llvm.x86.avx512.pslli.w.512
@@ -1774,6 +1787,13 @@ __m512i test_mm512_maskz_slli_epi16(__mmask32 __U, __m512i __A) {
   return _mm512_maskz_slli_epi16(__U, __A, 5); 
 }
 
+__m512i test_mm512_maskz_slli_epi16_2(__mmask32 __U, __m512i __A, int __B) {
+  // CHECK-LABEL: @test_mm512_maskz_slli_epi16_2
+  // CHECK: @llvm.x86.avx512.pslli.w.512
+  // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}}
+  return _mm512_maskz_slli_epi16(__U, __A, __B); 
+}
+
 __m512i test_mm512_bslli_epi128(__m512i __A) {
   // CHECK-LABEL: @test_mm512_bslli_epi128
   // CHECK: shufflevector <64 x i8> zeroinitializer, <64 x i8> %{{.*}}, <64 x i32> 
@@ -1846,6 +1866,12 @@ __m512i test_mm512_srai_epi16(__m512i __A) {
   return _mm512_srai_epi16(__A, 5); 
 }
 
+__m512i test_mm512_srai_epi16_2(__m512i __A, int __B) {
+  // CHECK-LABEL: @test_mm512_srai_epi16_2
+  // CHECK: @llvm.x86.avx512.psrai.w.512
+  return _mm512_srai_epi16(__A, __B); 
+}
+
 __m512i test_mm512_mask_srai_epi16(__m512i __W, __mmask32 __U, __m512i __A) {
   // CHECK-LABEL: @test_mm512_mask_srai_epi16
   // CHECK: @llvm.x86.avx512.psrai.w.512
@@ -1853,6 +1879,13 @@ __m512i test_mm512_mask_srai_epi16(__m512i __W, __mmask32 __U, __m512i __A) {
   return _mm512_mask_srai_epi16(__W, __U, __A, 5); 
 }
 
+__m512i test_mm512_mask_srai_epi16_2(__m512i __W, __mmask32 __U, __m512i __A, int __B) {
+  // CHECK-LABEL: @test_mm512_mask_srai_epi16_2
+  // CHECK: @llvm.x86.avx512.psrai.w.512
+  // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}}
+  return _mm512_mask_srai_epi16(__W, __U, __A, __B); 
+}
+
 __m512i test_mm512_maskz_srai_epi16(__mmask32 __U, __m512i __A) {
   // CHECK-LABEL: @test_mm512_maskz_srai_epi16
   // CHECK: @llvm.x86.avx512.psrai.w.512
@@ -1860,6 +1893,13 @@ __m512i test_mm512_maskz_srai_epi16(__mmask32 __U, __m512i __A) {
   return _mm512_maskz_srai_epi16(__U, __A, 5); 
 }
 
+__m512i test_mm512_maskz_srai_epi16_2(__mmask32 __U, __m512i __A, int __B) {
+  // CHECK-LABEL: @test_mm512_maskz_srai_epi16_2
+  // CHECK: @llvm.x86.avx512.psrai.w.512
+  // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}}
+  return _mm512_maskz_srai_epi16(__U, __A, __B); 
+}
+
 __m512i test_mm512_srl_epi16(__m512i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm512_srl_epi16
   // CHECK: @llvm.x86.avx512.psrl.w.512
@@ -1886,6 +1926,12 @@ __m512i test_mm512_srli_epi16(__m512i __A) {
   return _mm512_srli_epi16(__A, 5); 
 }
 
+__m512i test_mm512_srli_epi16_2(__m512i __A, int __B) {
+  // CHECK-LABEL: @test_mm512_srli_epi16_2
+  // CHECK: @llvm.x86.avx512.psrli.w.512
+  return _mm512_srli_epi16(__A, __B); 
+}
+
 __m512i test_mm512_mask_srli_epi16(__m512i __W, __mmask32 __U, __m512i __A) {
   // CHECK-LABEL: @test_mm512_mask_srli_epi16
   // CHECK: @llvm.x86.avx512.psrli.w.512
@@ -1893,6 +1939,13 @@ __m512i test_mm512_mask_srli_epi16(__m512i __W, __mmask32 __U, __m512i __A) {
   return _mm512_mask_srli_epi16(__W, __U, __A, 5); 
 }
 
+__m512i test_mm512_mask_srli_epi16_2(__m512i __W, __mmask32 __U, __m512i __A, int __B) {
+  // CHECK-LABEL: @test_mm512_mask_srli_epi16_2
+  // CHECK: @llvm.x86.avx512.psrli.w.512
+  // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}}
+  return _mm512_mask_srli_epi16(__W, __U, __A, __B); 
+}
+
 __m512i test_mm512_maskz_srli_epi16(__mmask32 __U, __m512i __A) {
   // CHECK-LABEL: @test_mm512_maskz_srli_epi16
   // CHECK: @llvm.x86.avx512.psrli.w.512
@@ -1900,6 +1953,13 @@ __m512i test_mm512_maskz_srli_epi16(__mmask32 __U, __m512i __A) {
   return _mm512_maskz_srli_epi16(__U, __A, 5); 
 }
 
+__m512i test_mm512_maskz_srli_epi16_2(__mmask32 __U, __m512i __A, int __B) {
+  // CHECK-LABEL: @test_mm512_maskz_srli_epi16_2
+  // CHECK: @llvm.x86.avx512.psrli.w.512
+  // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}}
+  return _mm512_maskz_srli_epi16(__U, __A, __B); 
+}
+
 __m512i test_mm512_bsrli_epi128(__m512i __A) {
   // CHECK-LABEL: @test_mm512_bsrli_epi128
   // CHECK: shufflevector <64 x i8> %{{.*}}, <64 x i8> zeroinitializer, <64 x i32> 
diff --git a/test/CodeGen/avx512f-builtins.c b/test/CodeGen/avx512f-builtins.c
index 0f21bae6ab..5154e820bd 100644
--- a/test/CodeGen/avx512f-builtins.c
+++ b/test/CodeGen/avx512f-builtins.c
@@ -4201,6 +4201,12 @@ __m512i test_mm512_slli_epi32(__m512i __A) {
   return _mm512_slli_epi32(__A, 5); 
 }
 
+__m512i test_mm512_slli_epi32_2(__m512i __A, int __B) {
+  // CHECK-LABEL: @test_mm512_slli_epi32_2
+  // CHECK: @llvm.x86.avx512.pslli.d.512
+  return _mm512_slli_epi32(__A, __B); 
+}
+
 __m512i test_mm512_mask_slli_epi32(__m512i __W, __mmask16 __U, __m512i __A) {
   // CHECK-LABEL: @test_mm512_mask_slli_epi32
   // CHECK: @llvm.x86.avx512.pslli.d.512
@@ -4208,6 +4214,13 @@ __m512i test_mm512_mask_slli_epi32(__m512i __W, __mmask16 __U, __m512i __A) {
   return _mm512_mask_slli_epi32(__W, __U, __A, 5); 
 }
 
+__m512i test_mm512_mask_slli_epi32_2(__m512i __W, __mmask16 __U, __m512i __A, int __B) {
+  // CHECK-LABEL: @test_mm512_mask_slli_epi32_2
+  // CHECK: @llvm.x86.avx512.pslli.d.512
+  // CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}}
+  return _mm512_mask_slli_epi32(__W, __U, __A, __B); 
+}
+
 __m512i test_mm512_maskz_slli_epi32(__mmask16 __U, __m512i __A) {
   // CHECK-LABEL: @test_mm512_maskz_slli_epi32
   // CHECK: @llvm.x86.avx512.pslli.d.512
@@ -4215,12 +4228,25 @@ __m512i test_mm512_maskz_slli_epi32(__mmask16 __U, __m512i __A) {
   return _mm512_maskz_slli_epi32(__U, __A, 5); 
 }
 
+__m512i test_mm512_maskz_slli_epi32_2(__mmask16 __U, __m512i __A, int __B) {
+  // CHECK-LABEL: @test_mm512_maskz_slli_epi32_2
+  // CHECK: @llvm.x86.avx512.pslli.d.512
+  // CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}}
+  return _mm512_maskz_slli_epi32(__U, __A, __B); 
+}
+
 __m512i test_mm512_slli_epi64(__m512i __A) {
   // CHECK-LABEL: @test_mm512_slli_epi64
   // CHECK: @llvm.x86.avx512.pslli.q.512
   return _mm512_slli_epi64(__A, 5); 
 }
 
+__m512i test_mm512_slli_epi64_2(__m512i __A, int __B) {
+  // CHECK-LABEL: @test_mm512_slli_epi64_2
+  // CHECK: @llvm.x86.avx512.pslli.q.512
+  return _mm512_slli_epi64(__A, __B); 
+}
+
 __m512i test_mm512_mask_slli_epi64(__m512i __W, __mmask8 __U, __m512i __A) {
   // CHECK-LABEL: @test_mm512_mask_slli_epi64
   // CHECK: @llvm.x86.avx512.pslli.q.512
@@ -4228,18 +4254,39 @@ __m512i test_mm512_mask_slli_epi64(__m512i __W, __mmask8 __U, __m512i __A) {
   return _mm512_mask_slli_epi64(__W, __U, __A, 5); 
 }
 
+__m512i test_mm512_mask_slli_epi64_2(__m512i __W, __mmask8 __U, __m512i __A, int __B) {
+  // CHECK-LABEL: @test_mm512_mask_slli_epi64_2
+  // CHECK: @llvm.x86.avx512.pslli.q.512
+  // CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}}
+  return _mm512_mask_slli_epi64(__W, __U, __A, __B); 
+}
+
 __m512i test_mm512_maskz_slli_epi64(__mmask8 __U, __m512i __A) {
   // CHECK-LABEL: @test_mm512_maskz_slli_epi64
+  // CHECK: @llvm.x86.avx512.pslli.q.512
   // CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}}
   return _mm512_maskz_slli_epi64(__U, __A, 5); 
 }
 
+__m512i test_mm512_maskz_slli_epi64_2(__mmask8 __U, __m512i __A, int __B) {
+  // CHECK-LABEL: @test_mm512_maskz_slli_epi64_2
+  // CHECK: @llvm.x86.avx512.pslli.q.512
+  // CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}}
+  return _mm512_maskz_slli_epi64(__U, __A, __B); 
+}
+
 __m512i test_mm512_srli_epi32(__m512i __A) {
   // CHECK-LABEL: @test_mm512_srli_epi32
   // CHECK: @llvm.x86.avx512.psrli.d.512
   return _mm512_srli_epi32(__A, 5); 
 }
 
+__m512i test_mm512_srli_epi32_2(__m512i __A, int __B) {
+  // CHECK-LABEL: @test_mm512_srli_epi32_2
+  // CHECK: @llvm.x86.avx512.psrli.d.512
+  return _mm512_srli_epi32(__A, __B); 
+}
+
 __m512i test_mm512_mask_srli_epi32(__m512i __W, __mmask16 __U, __m512i __A) {
   // CHECK-LABEL: @test_mm512_mask_srli_epi32
   // CHECK: @llvm.x86.avx512.psrli.d.512
@@ -4247,6 +4294,13 @@ __m512i test_mm512_mask_srli_epi32(__m512i __W, __mmask16 __U, __m512i __A) {
   return _mm512_mask_srli_epi32(__W, __U, __A, 5); 
 }
 
+__m512i test_mm512_mask_srli_epi32_2(__m512i __W, __mmask16 __U, __m512i __A, int __B) {
+  // CHECK-LABEL: @test_mm512_mask_srli_epi32_2
+  // CHECK: @llvm.x86.avx512.psrli.d.512
+  // CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}}
+  return _mm512_mask_srli_epi32(__W, __U, __A, __B); 
+}
+
 __m512i test_mm512_maskz_srli_epi32(__mmask16 __U, __m512i __A) {
   // CHECK-LABEL: @test_mm512_maskz_srli_epi32
   // CHECK: @llvm.x86.avx512.psrli.d.512
@@ -4254,12 +4308,25 @@ __m512i test_mm512_maskz_srli_epi32(__mmask16 __U, __m512i __A) {
   return _mm512_maskz_srli_epi32(__U, __A, 5); 
 }
 
+__m512i test_mm512_maskz_srli_epi32_2(__mmask16 __U, __m512i __A, int __B) {
+  // CHECK-LABEL: @test_mm512_maskz_srli_epi32_2
+  // CHECK: @llvm.x86.avx512.psrli.d.512
+  // CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}}
+  return _mm512_maskz_srli_epi32(__U, __A, __B); 
+}
+
 __m512i test_mm512_srli_epi64(__m512i __A) {
   // CHECK-LABEL: @test_mm512_srli_epi64
   // CHECK: @llvm.x86.avx512.psrli.q.512
   return _mm512_srli_epi64(__A, 5); 
 }
 
+__m512i test_mm512_srli_epi64_2(__m512i __A, int __B) {
+  // CHECK-LABEL: @test_mm512_srli_epi64_2
+  // CHECK: @llvm.x86.avx512.psrli.q.512
+  return _mm512_srli_epi64(__A, __B); 
+}
+
 __m512i test_mm512_mask_srli_epi64(__m512i __W, __mmask8 __U, __m512i __A) {
   // CHECK-LABEL: @test_mm512_mask_srli_epi64
   // CHECK: @llvm.x86.avx512.psrli.q.512
@@ -4267,6 +4334,13 @@ __m512i test_mm512_mask_srli_epi64(__m512i __W, __mmask8 __U, __m512i __A) {
   return _mm512_mask_srli_epi64(__W, __U, __A, 5); 
 }
 
+__m512i test_mm512_mask_srli_epi64_2(__m512i __W, __mmask8 __U, __m512i __A, int __B) {
+  // CHECK-LABEL: @test_mm512_mask_srli_epi64_2
+  // CHECK: @llvm.x86.avx512.psrli.q.512
+  // CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}}
+  return _mm512_mask_srli_epi64(__W, __U, __A, __B); 
+}
+
 __m512i test_mm512_maskz_srli_epi64(__mmask8 __U, __m512i __A) {
   // CHECK-LABEL: @test_mm512_maskz_srli_epi64
   // CHECK: @llvm.x86.avx512.psrli.q.512
@@ -4274,6 +4348,13 @@ __m512i test_mm512_maskz_srli_epi64(__mmask8 __U, __m512i __A) {
   return _mm512_maskz_srli_epi64(__U, __A, 5); 
 }
 
+__m512i test_mm512_maskz_srli_epi64_2(__mmask8 __U, __m512i __A, int __B) {
+  // CHECK-LABEL: @test_mm512_maskz_srli_epi64_2
+  // CHECK: @llvm.x86.avx512.psrli.q.512
+  // CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}}
+  return _mm512_maskz_srli_epi64(__U, __A, __B); 
+}
+
 __m512i test_mm512_mask_load_epi32(__m512i __W, __mmask16 __U, void const *__P) {
   // CHECK-LABEL: @test_mm512_mask_load_epi32
   // CHECK: @llvm.masked.load.v16i32.p0v16i32(<16 x i32>* %{{.*}}, i32 64, <16 x i1> %{{.*}}, <16 x i32> %{{.*}})
@@ -5575,6 +5656,12 @@ __m512i test_mm512_srai_epi32(__m512i __A) {
   return _mm512_srai_epi32(__A, 5); 
 }
 
+__m512i test_mm512_srai_epi32_2(__m512i __A, int __B) {
+  // CHECK-LABEL: @test_mm512_srai_epi32_2
+  // CHECK: @llvm.x86.avx512.psrai.d.512
+  return _mm512_srai_epi32(__A, __B); 
+}
+
 __m512i test_mm512_mask_srai_epi32(__m512i __W, __mmask16 __U, __m512i __A) {
   // CHECK-LABEL: @test_mm512_mask_srai_epi32
   // CHECK: @llvm.x86.avx512.psrai.d.512
@@ -5582,6 +5669,13 @@ __m512i test_mm512_mask_srai_epi32(__m512i __W, __mmask16 __U, __m512i __A) {
   return _mm512_mask_srai_epi32(__W, __U, __A, 5); 
 }
 
+__m512i test_mm512_mask_srai_epi32_2(__m512i __W, __mmask16 __U, __m512i __A, int __B) {
+  // CHECK-LABEL: @test_mm512_mask_srai_epi32_2
+  // CHECK: @llvm.x86.avx512.psrai.d.512
+  // CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}}
+  return _mm512_mask_srai_epi32(__W, __U, __A, __B); 
+}
+
 __m512i test_mm512_maskz_srai_epi32(__mmask16 __U, __m512i __A) {
   // CHECK-LABEL: @test_mm512_maskz_srai_epi32
   // CHECK: @llvm.x86.avx512.psrai.d.512
@@ -5589,12 +5683,25 @@ __m512i test_mm512_maskz_srai_epi32(__mmask16 __U, __m512i __A) {
   return _mm512_maskz_srai_epi32(__U, __A, 5); 
 }
 
+__m512i test_mm512_maskz_srai_epi32_2(__mmask16 __U, __m512i __A, int __B) {
+  // CHECK-LABEL: @test_mm512_maskz_srai_epi32_2
+  // CHECK: @llvm.x86.avx512.psrai.d.512
+  // CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}}
+  return _mm512_maskz_srai_epi32(__U, __A, __B); 
+}
+
 __m512i test_mm512_srai_epi64(__m512i __A) {
   // CHECK-LABEL: @test_mm512_srai_epi64
   // CHECK: @llvm.x86.avx512.psrai.q.512
   return _mm512_srai_epi64(__A, 5); 
 }
 
+__m512i test_mm512_srai_epi64_2(__m512i __A, int __B) {
+  // CHECK-LABEL: @test_mm512_srai_epi64_2
+  // CHECK: @llvm.x86.avx512.psrai.q.512
+  return _mm512_srai_epi64(__A, __B); 
+}
+
 __m512i test_mm512_mask_srai_epi64(__m512i __W, __mmask8 __U, __m512i __A) {
   // CHECK-LABEL: @test_mm512_mask_srai_epi64
   // CHECK: @llvm.x86.avx512.psrai.q.512
@@ -5602,6 +5709,13 @@ __m512i test_mm512_mask_srai_epi64(__m512i __W, __mmask8 __U, __m512i __A) {
   return _mm512_mask_srai_epi64(__W, __U, __A, 5); 
 }
 
+__m512i test_mm512_mask_srai_epi64_2(__m512i __W, __mmask8 __U, __m512i __A, int __B) {
+  // CHECK-LABEL: @test_mm512_mask_srai_epi64_2
+  // CHECK: @llvm.x86.avx512.psrai.q.512
+  // CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}}
+  return _mm512_mask_srai_epi64(__W, __U, __A, __B); 
+}
+
 __m512i test_mm512_maskz_srai_epi64(__mmask8 __U, __m512i __A) {
   // CHECK-LABEL: @test_mm512_maskz_srai_epi64
   // CHECK: @llvm.x86.avx512.psrai.q.512
@@ -5609,6 +5723,13 @@ __m512i test_mm512_maskz_srai_epi64(__mmask8 __U, __m512i __A) {
   return _mm512_maskz_srai_epi64(__U, __A, 5); 
 }
 
+__m512i test_mm512_maskz_srai_epi64_2(__mmask8 __U, __m512i __A, int __B) {
+  // CHECK-LABEL: @test_mm512_maskz_srai_epi64_2
+  // CHECK: @llvm.x86.avx512.psrai.q.512
+  // CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}}
+  return _mm512_maskz_srai_epi64(__U, __A, __B); 
+}
+
 __m512i test_mm512_sll_epi32(__m512i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm512_sll_epi32
   // CHECK: @llvm.x86.avx512.psll.d.512
diff --git a/test/CodeGen/avx512vl-builtins.c b/test/CodeGen/avx512vl-builtins.c
index eb69e1c0f1..5547ac9e2f 100644
--- a/test/CodeGen/avx512vl-builtins.c
+++ b/test/CodeGen/avx512vl-builtins.c
@@ -6245,6 +6245,13 @@ __m128i test_mm_mask_srli_epi32(__m128i __W, __mmask8 __U, __m128i __A) {
   return _mm_mask_srli_epi32(__W, __U, __A, 5); 
 }
 
+__m128i test_mm_mask_srli_epi32_2(__m128i __W, __mmask8 __U, __m128i __A, int __B) {
+  // CHECK-LABEL: @test_mm_mask_srli_epi32_2
+  // CHECK: @llvm.x86.sse2.psrli.d
+  // CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
+  return _mm_mask_srli_epi32(__W, __U, __A, __B); 
+}
+
 __m128i test_mm_maskz_srli_epi32(__mmask8 __U, __m128i __A) {
   // CHECK-LABEL: @test_mm_maskz_srli_epi32
   // CHECK: @llvm.x86.sse2.psrli.d
@@ -6252,6 +6259,13 @@ __m128i test_mm_maskz_srli_epi32(__mmask8 __U, __m128i __A) {
   return _mm_maskz_srli_epi32(__U, __A, 5); 
 }
 
+__m128i test_mm_maskz_srli_epi32_2(__mmask8 __U, __m128i __A, int __B) {
+  // CHECK-LABEL: @test_mm_maskz_srli_epi32_2
+  // CHECK: @llvm.x86.sse2.psrli.d
+  // CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
+  return _mm_maskz_srli_epi32(__U, __A, __B); 
+}
+
 __m256i test_mm256_mask_srli_epi32(__m256i __W, __mmask8 __U, __m256i __A) {
   // CHECK-LABEL: @test_mm256_mask_srli_epi32
   // CHECK: @llvm.x86.avx2.psrli.d
@@ -6259,6 +6273,13 @@ __m256i test_mm256_mask_srli_epi32(__m256i __W, __mmask8 __U, __m256i __A) {
   return _mm256_mask_srli_epi32(__W, __U, __A, 5); 
 }
 
+__m256i test_mm256_mask_srli_epi32_2(__m256i __W, __mmask8 __U, __m256i __A, int __B) {
+  // CHECK-LABEL: @test_mm256_mask_srli_epi32_2
+  // CHECK: @llvm.x86.avx2.psrli.d
+  // CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}}
+  return _mm256_mask_srli_epi32(__W, __U, __A, __B); 
+}
+
 __m256i test_mm256_maskz_srli_epi32(__mmask8 __U, __m256i __A) {
   // CHECK-LABEL: @test_mm256_maskz_srli_epi32
   // CHECK: @llvm.x86.avx2.psrli.d
@@ -6266,6 +6287,12 @@ __m256i test_mm256_maskz_srli_epi32(__mmask8 __U, __m256i __A) {
   return _mm256_maskz_srli_epi32(__U, __A, 5); 
 }
 
+__m256i test_mm256_maskz_srli_epi32_2(__mmask8 __U, __m256i __A, int __B) {
+  // CHECK-LABEL: @test_mm256_maskz_srli_epi32_2
+  // CHECK: @llvm.x86.avx2.psrli.d
+  // CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}}
+  return _mm256_maskz_srli_epi32(__U, __A, __B); 
+}
 __m128i test_mm_mask_srl_epi64(__m128i __W, __mmask8 __U, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_mask_srl_epi64
   // CHECK: @llvm.x86.sse2.psrl.q
@@ -6301,6 +6328,13 @@ __m128i test_mm_mask_srli_epi64(__m128i __W, __mmask8 __U, __m128i __A) {
   return _mm_mask_srli_epi64(__W, __U, __A, 5); 
 }
 
+__m128i test_mm_mask_srli_epi64_2(__m128i __W, __mmask8 __U, __m128i __A, int __B) {
+  // CHECK-LABEL: @test_mm_mask_srli_epi64_2
+  // CHECK: @llvm.x86.sse2.psrli.q
+  // CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}}
+  return _mm_mask_srli_epi64(__W, __U, __A, __B); 
+}
+
 __m128i test_mm_maskz_srli_epi64(__mmask8 __U, __m128i __A) {
   // CHECK-LABEL: @test_mm_maskz_srli_epi64
   // CHECK: @llvm.x86.sse2.psrli.q
@@ -6308,6 +6342,13 @@ __m128i test_mm_maskz_srli_epi64(__mmask8 __U, __m128i __A) {
   return _mm_maskz_srli_epi64(__U, __A, 5); 
 }
 
+__m128i test_mm_maskz_srli_epi64_2(__mmask8 __U, __m128i __A, int __B) {
+  // CHECK-LABEL: @test_mm_maskz_srli_epi64_2
+  // CHECK: @llvm.x86.sse2.psrli.q
+  // CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}}
+  return _mm_maskz_srli_epi64(__U, __A, __B); 
+}
+
 __m256i test_mm256_mask_srli_epi64(__m256i __W, __mmask8 __U, __m256i __A) {
   // CHECK-LABEL: @test_mm256_mask_srli_epi64
   // CHECK: @llvm.x86.avx2.psrli.q
@@ -6315,6 +6356,13 @@ __m256i test_mm256_mask_srli_epi64(__m256i __W, __mmask8 __U, __m256i __A) {
   return _mm256_mask_srli_epi64(__W, __U, __A, 5); 
 }
 
+__m256i test_mm256_mask_srli_epi64_2(__m256i __W, __mmask8 __U, __m256i __A, int __B) {
+  // CHECK-LABEL: @test_mm256_mask_srli_epi64_2
+  // CHECK: @llvm.x86.avx2.psrli.q
+  // CHECK: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}}
+  return _mm256_mask_srli_epi64(__W, __U, __A, __B); 
+}
+
 __m256i test_mm256_maskz_srli_epi64(__mmask8 __U, __m256i __A) {
   // CHECK-LABEL: @test_mm256_maskz_srli_epi64
   // CHECK: @llvm.x86.avx2.psrli.q
@@ -6322,6 +6370,13 @@ __m256i test_mm256_maskz_srli_epi64(__mmask8 __U, __m256i __A) {
   return _mm256_maskz_srli_epi64(__U, __A, 5); 
 }
 
+__m256i test_mm256_maskz_srli_epi64_2(__mmask8 __U, __m256i __A) {
+  // CHECK-LABEL: @test_mm256_maskz_srli_epi64_2
+  // CHECK: @llvm.x86.avx2.psrli.q
+  // CHECK: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}}
+  return _mm256_maskz_srli_epi64(__U, __A, 5); 
+}
+
 __m128i test_mm_mask_sll_epi32(__m128i __W, __mmask8 __U, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_mask_sll_epi32
   // CHECK: @llvm.x86.sse2.psll.d
@@ -6357,6 +6412,13 @@ __m128i test_mm_mask_slli_epi32(__m128i __W, __mmask8 __U, __m128i __A) {
   return _mm_mask_slli_epi32(__W, __U, __A, 5); 
 }
 
+__m128i test_mm_mask_slli_epi32_2(__m128i __W, __mmask8 __U, __m128i __A, int __B) {
+  // CHECK-LABEL: @test_mm_mask_slli_epi32_2
+  // CHECK: @llvm.x86.sse2.pslli.d
+  // CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
+  return _mm_mask_slli_epi32(__W, __U, __A, __B); 
+}
+
 __m128i test_mm_maskz_slli_epi32(__mmask8 __U, __m128i __A) {
   // CHECK-LABEL: @test_mm_maskz_slli_epi32
   // CHECK: @llvm.x86.sse2.pslli.d
@@ -6364,6 +6426,13 @@ __m128i test_mm_maskz_slli_epi32(__mmask8 __U, __m128i __A) {
   return _mm_maskz_slli_epi32(__U, __A, 5); 
 }
 
+__m128i test_mm_maskz_slli_epi32_2(__mmask8 __U, __m128i __A, int __B) {
+  // CHECK-LABEL: @test_mm_maskz_slli_epi32_2
+  // CHECK: @llvm.x86.sse2.pslli.d
+  // CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
+  return _mm_maskz_slli_epi32(__U, __A, __B); 
+}
+
 __m256i test_mm256_mask_slli_epi32(__m256i __W, __mmask8 __U, __m256i __A) {
   // CHECK-LABEL: @test_mm256_mask_slli_epi32
   // CHECK: @llvm.x86.avx2.pslli.d
@@ -6371,6 +6440,13 @@ __m256i test_mm256_mask_slli_epi32(__m256i __W, __mmask8 __U, __m256i __A) {
   return _mm256_mask_slli_epi32(__W, __U, __A, 5); 
 }
 
+__m256i test_mm256_mask_slli_epi32_2(__m256i __W, __mmask8 __U, __m256i __A, int __B) {
+  // CHECK-LABEL: @test_mm256_mask_slli_epi32_2
+  // CHECK: @llvm.x86.avx2.pslli.d
+  // CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}}
+  return _mm256_mask_slli_epi32(__W, __U, __A, __B); 
+}
+
 __m256i test_mm256_maskz_slli_epi32(__mmask8 __U, __m256i __A) {
   // CHECK-LABEL: @test_mm256_maskz_slli_epi32
   // CHECK: @llvm.x86.avx2.pslli.d
@@ -6378,6 +6454,13 @@ __m256i test_mm256_maskz_slli_epi32(__mmask8 __U, __m256i __A) {
   return _mm256_maskz_slli_epi32(__U, __A, 5); 
 }
 
+__m256i test_mm256_maskz_slli_epi32_2(__mmask8 __U, __m256i __A, int __B) {
+  // CHECK-LABEL: @test_mm256_maskz_slli_epi32_2
+  // CHECK: @llvm.x86.avx2.pslli.d
+  // CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}}
+  return _mm256_maskz_slli_epi32(__U, __A, __B); 
+}
+
 __m128i test_mm_mask_sll_epi64(__m128i __W, __mmask8 __U, __m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_mask_sll_epi64
   // CHECK: @llvm.x86.sse2.psll.q
@@ -6413,6 +6496,13 @@ __m128i test_mm_mask_slli_epi64(__m128i __W, __mmask8 __U, __m128i __A) {
   return _mm_mask_slli_epi64(__W, __U, __A, 5); 
 }
 
+__m128i test_mm_mask_slli_epi64_2(__m128i __W, __mmask8 __U, __m128i __A, int __B) {
+  // CHECK-LABEL: @test_mm_mask_slli_epi64_2
+  // CHECK: @llvm.x86.sse2.pslli.q
+  // CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}}
+  return _mm_mask_slli_epi64(__W, __U, __A, __B); 
+}
+
 __m128i test_mm_maskz_slli_epi64(__mmask8 __U, __m128i __A) {
   // CHECK-LABEL: @test_mm_maskz_slli_epi64
   // CHECK: @llvm.x86.sse2.pslli.q
@@ -6420,6 +6510,13 @@ __m128i test_mm_maskz_slli_epi64(__mmask8 __U, __m128i __A) {
   return _mm_maskz_slli_epi64(__U, __A, 5); 
 }
 
+__m128i test_mm_maskz_slli_epi64_2(__mmask8 __U, __m128i __A, int __B) {
+  // CHECK-LABEL: @test_mm_maskz_slli_epi64_2
+  // CHECK: @llvm.x86.sse2.pslli.q
+  // CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}}
+  return _mm_maskz_slli_epi64(__U, __A, __B); 
+}
+
 __m256i test_mm256_mask_slli_epi64(__m256i __W, __mmask8 __U, __m256i __A) {
   // CHECK-LABEL: @test_mm256_mask_slli_epi64
   // CHECK: @llvm.x86.avx2.pslli.q
@@ -6427,6 +6524,13 @@ __m256i test_mm256_mask_slli_epi64(__m256i __W, __mmask8 __U, __m256i __A) {
   return _mm256_mask_slli_epi64(__W, __U, __A, 5); 
 }
 
+__m256i test_mm256_mask_slli_epi64_2(__m256i __W, __mmask8 __U, __m256i __A, int __B) {
+  // CHECK-LABEL: @test_mm256_mask_slli_epi64_2
+  // CHECK: @llvm.x86.avx2.pslli.q
+  // CHECK: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}}
+  return _mm256_mask_slli_epi64(__W, __U, __A, __B); 
+}
+
 __m256i test_mm256_maskz_slli_epi64(__mmask8 __U, __m256i __A) {
   // CHECK-LABEL: @test_mm256_maskz_slli_epi64
   // CHECK: @llvm.x86.avx2.pslli.q
@@ -6434,6 +6538,13 @@ __m256i test_mm256_maskz_slli_epi64(__mmask8 __U, __m256i __A) {
   return _mm256_maskz_slli_epi64(__U, __A, 5); 
 }
 
+__m256i test_mm256_maskz_slli_epi64_2(__mmask8 __U, __m256i __A) {
+  // CHECK-LABEL: @test_mm256_maskz_slli_epi64_2
+  // CHECK: @llvm.x86.avx2.pslli.q
+  // CHECK: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}}
+  return _mm256_maskz_slli_epi64(__U, __A, 5); 
+}
+
 __m128i test_mm_mask_srav_epi32(__m128i __W, __mmask8 __U, __m128i __X, __m128i __Y) {
   // CHECK-LABEL: @test_mm_mask_srav_epi32
   // CHECK: @llvm.x86.avx2.psrav.d
@@ -7687,6 +7798,13 @@ __m128i test_mm_mask_srai_epi32(__m128i __W, __mmask8 __U, __m128i __A) {
   return _mm_mask_srai_epi32(__W, __U, __A, 5); 
 }
 
+__m128i test_mm_mask_srai_epi32_2(__m128i __W, __mmask8 __U, __m128i __A, int __B) {
+  // CHECK-LABEL: @test_mm_mask_srai_epi32_2
+  // CHECK: @llvm.x86.sse2.psrai.d
+  // CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
+  return _mm_mask_srai_epi32(__W, __U, __A, __B); 
+}
+
 __m128i test_mm_maskz_srai_epi32(__mmask8 __U, __m128i __A) {
   // CHECK-LABEL: @test_mm_maskz_srai_epi32
   // CHECK: @llvm.x86.sse2.psrai.d
@@ -7694,6 +7812,13 @@ __m128i test_mm_maskz_srai_epi32(__mmask8 __U, __m128i __A) {
   return _mm_maskz_srai_epi32(__U, __A, 5); 
 }
 
+__m128i test_mm_maskz_srai_epi32_2(__mmask8 __U, __m128i __A, int __B) {
+  // CHECK-LABEL: @test_mm_maskz_srai_epi32_2
+  // CHECK: @llvm.x86.sse2.psrai.d
+  // CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
+  return _mm_maskz_srai_epi32(__U, __A, __B); 
+}
+
 __m256i test_mm256_mask_srai_epi32(__m256i __W, __mmask8 __U, __m256i __A) {
   // CHECK-LABEL: @test_mm256_mask_srai_epi32
   // CHECK: @llvm.x86.avx2.psrai.d
@@ -7701,6 +7826,13 @@ __m256i test_mm256_mask_srai_epi32(__m256i __W, __mmask8 __U, __m256i __A) {
   return _mm256_mask_srai_epi32(__W, __U, __A, 5); 
 }
 
+__m256i test_mm256_mask_srai_epi32_2(__m256i __W, __mmask8 __U, __m256i __A, int __B) {
+  // CHECK-LABEL: @test_mm256_mask_srai_epi32_2
+  // CHECK: @llvm.x86.avx2.psrai.d
+  // CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}}
+  return _mm256_mask_srai_epi32(__W, __U, __A, __B); 
+}
+
 __m256i test_mm256_maskz_srai_epi32(__mmask8 __U, __m256i __A) {
   // CHECK-LABEL: @test_mm256_maskz_srai_epi32
   // CHECK: @llvm.x86.avx2.psrai.d
@@ -7708,6 +7840,13 @@ __m256i test_mm256_maskz_srai_epi32(__mmask8 __U, __m256i __A) {
   return _mm256_maskz_srai_epi32(__U, __A, 5); 
 }
 
+__m256i test_mm256_maskz_srai_epi32_2(__mmask8 __U, __m256i __A, int __B) {
+  // CHECK-LABEL: @test_mm256_maskz_srai_epi32_2
+  // CHECK: @llvm.x86.avx2.psrai.d
+  // CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}}
+  return _mm256_maskz_srai_epi32(__U, __A, __B); 
+}
+
 __m128i test_mm_sra_epi64(__m128i __A, __m128i __B) {
   // CHECK-LABEL: @test_mm_sra_epi64
   // CHECK: @llvm.x86.avx512.psra.q.128
@@ -7754,6 +7893,12 @@ __m128i test_mm_srai_epi64(__m128i __A) {
   return _mm_srai_epi64(__A, 5); 
 }
 
+__m128i test_mm_srai_epi64_2(__m128i __A, int __B) {
+  // CHECK-LABEL: @test_mm_srai_epi64_2
+  // CHECK: @llvm.x86.avx512.psrai.q.128
+  return _mm_srai_epi64(__A, __B); 
+}
+
 __m128i test_mm_mask_srai_epi64(__m128i __W, __mmask8 __U, __m128i __A) {
   // CHECK-LABEL: @test_mm_mask_srai_epi64
   // CHECK: @llvm.x86.avx512.psrai.q.128
@@ -7761,6 +7906,13 @@ __m128i test_mm_mask_srai_epi64(__m128i __W, __mmask8 __U, __m128i __A) {
   return _mm_mask_srai_epi64(__W, __U, __A, 5); 
 }
 
+__m128i test_mm_mask_srai_epi64_2(__m128i __W, __mmask8 __U, __m128i __A, int __B) {
+  // CHECK-LABEL: @test_mm_mask_srai_epi64_2
+  // CHECK: @llvm.x86.avx512.psrai.q.128
+  // CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}}
+  return _mm_mask_srai_epi64(__W, __U, __A, __B); 
+}
+
 __m128i test_mm_maskz_srai_epi64(__mmask8 __U, __m128i __A) {
   // CHECK-LABEL: @test_mm_maskz_srai_epi64
   // CHECK: @llvm.x86.avx512.psrai.q.128
@@ -7768,12 +7920,25 @@ __m128i test_mm_maskz_srai_epi64(__mmask8 __U, __m128i __A) {
   return _mm_maskz_srai_epi64(__U, __A, 5); 
 }
 
+__m128i test_mm_maskz_srai_epi64_2(__mmask8 __U, __m128i __A, int __B) {
+  // CHECK-LABEL: @test_mm_maskz_srai_epi64_2
+  // CHECK: @llvm.x86.avx512.psrai.q.128
+  // CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}}
+  return _mm_maskz_srai_epi64(__U, __A, __B); 
+}
+
 __m256i test_mm256_srai_epi64(__m256i __A) {
   // CHECK-LABEL: @test_mm256_srai_epi64
   // CHECK: @llvm.x86.avx512.psrai.q.256
   return _mm256_srai_epi64(__A, 5); 
 }
 
+__m256i test_mm256_srai_epi64_2(__m256i __A, int __B) {
+  // CHECK-LABEL: @test_mm256_srai_epi64_2
+  // CHECK: @llvm.x86.avx512.psrai.q.256
+  return _mm256_srai_epi64(__A, __B); 
+}
+
 __m256i test_mm256_mask_srai_epi64(__m256i __W, __mmask8 __U, __m256i __A) {
   // CHECK-LABEL: @test_mm256_mask_srai_epi64
   // CHECK: @llvm.x86.avx512.psrai.q.256
@@ -7781,6 +7946,13 @@ __m256i test_mm256_mask_srai_epi64(__m256i __W, __mmask8 __U, __m256i __A) {
   return _mm256_mask_srai_epi64(__W, __U, __A, 5); 
 }
 
+__m256i test_mm256_mask_srai_epi64_2(__m256i __W, __mmask8 __U, __m256i __A, int __B) {
+  // CHECK-LABEL: @test_mm256_mask_srai_epi64_2
+  // CHECK: @llvm.x86.avx512.psrai.q.256
+  // CHECK: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}}
+  return _mm256_mask_srai_epi64(__W, __U, __A, __B); 
+}
+
 __m256i test_mm256_maskz_srai_epi64(__mmask8 __U, __m256i __A) {
   // CHECK-LABEL: @test_mm256_maskz_srai_epi64
   // CHECK: @llvm.x86.avx512.psrai.q.256
@@ -7788,6 +7960,13 @@ __m256i test_mm256_maskz_srai_epi64(__mmask8 __U, __m256i __A) {
   return _mm256_maskz_srai_epi64(__U, __A, 5); 
 }
 
+__m256i test_mm256_maskz_srai_epi64_2(__mmask8 __U, __m256i __A, int __B) {
+  // CHECK-LABEL: @test_mm256_maskz_srai_epi64_2
+  // CHECK: @llvm.x86.avx512.psrai.q.256
+  // CHECK: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}}
+  return _mm256_maskz_srai_epi64(__U, __A, __B); 
+}
+
 __m128i test_mm_ternarylogic_epi32(__m128i __A, __m128i __B, __m128i __C) {
   // CHECK-LABEL: @test_mm_ternarylogic_epi32
   // CHECK: @llvm.x86.avx512.pternlog.d.128
diff --git a/test/CodeGen/avx512vlbw-builtins.c b/test/CodeGen/avx512vlbw-builtins.c
index 1037617eab..80efe72787 100644
--- a/test/CodeGen/avx512vlbw-builtins.c
+++ b/test/CodeGen/avx512vlbw-builtins.c
@@ -2172,6 +2172,13 @@ __m128i test_mm_mask_slli_epi16(__m128i __W, __mmask8 __U, __m128i __A) {
   return _mm_mask_slli_epi16(__W, __U, __A, 5); 
 }
 
+__m128i test_mm_mask_slli_epi16_2(__m128i __W, __mmask8 __U, __m128i __A, int __B) {
+  // CHECK-LABEL: @test_mm_mask_slli_epi16_2
+  // CHECK: @llvm.x86.sse2.pslli.w
+  // CHECK: select <8 x i1> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}
+  return _mm_mask_slli_epi16(__W, __U, __A, __B); 
+}
+
 __m128i test_mm_maskz_slli_epi16(__mmask8 __U, __m128i __A) {
   // CHECK-LABEL: @test_mm_maskz_slli_epi16
   // CHECK: @llvm.x86.sse2.pslli.w
@@ -2179,6 +2186,13 @@ __m128i test_mm_maskz_slli_epi16(__mmask8 __U, __m128i __A) {
   return _mm_maskz_slli_epi16(__U, __A, 5); 
 }
 
+__m128i test_mm_maskz_slli_epi16_2(__mmask8 __U, __m128i __A, int __B) {
+  // CHECK-LABEL: @test_mm_maskz_slli_epi16_2
+  // CHECK: @llvm.x86.sse2.pslli.w
+  // CHECK: select <8 x i1> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}
+  return _mm_maskz_slli_epi16(__U, __A, __B); 
+}
+
 __m256i test_mm256_mask_slli_epi16(__m256i __W, __mmask16 __U, __m256i __A) {
   // CHECK-LABEL: @test_mm256_mask_slli_epi16
   // CHECK: @llvm.x86.avx2.pslli.w
@@ -2186,6 +2200,13 @@ __m256i test_mm256_mask_slli_epi16(__m256i __W, __mmask16 __U, __m256i __A) {
   return _mm256_mask_slli_epi16(__W, __U, __A, 5); 
 }
 
+__m256i test_mm256_mask_slli_epi16_2(__m256i __W, __mmask16 __U, __m256i __A, int __B) {
+  // CHECK-LABEL: @test_mm256_mask_slli_epi16_2
+  // CHECK: @llvm.x86.avx2.pslli.w
+  // CHECK: select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}}
+  return _mm256_mask_slli_epi16(__W, __U, __A, __B); 
+}
+
 __m256i test_mm256_maskz_slli_epi16(__mmask16 __U, __m256i __A) {
   // CHECK-LABEL: @test_mm256_maskz_slli_epi16
   // CHECK: @llvm.x86.avx2.pslli.w
@@ -2193,6 +2214,13 @@ __m256i test_mm256_maskz_slli_epi16(__mmask16 __U, __m256i __A) {
   return _mm256_maskz_slli_epi16(__U, __A, 5); 
 }
 
+__m256i test_mm256_maskz_slli_epi16_2(__mmask16 __U, __m256i __A, int __B) {
+  // CHECK-LABEL: @test_mm256_maskz_slli_epi16_2
+  // CHECK: @llvm.x86.avx2.pslli.w
+  // CHECK: select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}}
+  return _mm256_maskz_slli_epi16(__U, __A, __B); 
+}
+
 __m256i test_mm256_srlv_epi16(__m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_srlv_epi16
   // CHECK: @llvm.x86.avx512.psrlv.w.256(
@@ -2268,6 +2296,13 @@ __m128i test_mm_mask_srli_epi16(__m128i __W, __mmask8 __U, __m128i __A) {
   return _mm_mask_srli_epi16(__W, __U, __A, 5); 
 }
 
+__m128i test_mm_mask_srli_epi16_2(__m128i __W, __mmask8 __U, __m128i __A, int __B) {
+  // CHECK-LABEL: @test_mm_mask_srli_epi16_2
+  // CHECK: @llvm.x86.sse2.psrli.w
+  // CHECK: select <8 x i1> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}
+  return _mm_mask_srli_epi16(__W, __U, __A, __B); 
+}
+
 __m128i test_mm_maskz_srli_epi16(__mmask8 __U, __m128i __A) {
   // CHECK-LABEL: @test_mm_maskz_srli_epi16
   // CHECK: @llvm.x86.sse2.psrli.w
@@ -2275,6 +2310,13 @@ __m128i test_mm_maskz_srli_epi16(__mmask8 __U, __m128i __A) {
   return _mm_maskz_srli_epi16(__U, __A, 5); 
 }
 
+__m128i test_mm_maskz_srli_epi16_2(__mmask8 __U, __m128i __A, int __B) {
+  // CHECK-LABEL: @test_mm_maskz_srli_epi16_2
+  // CHECK: @llvm.x86.sse2.psrli.w
+  // CHECK: select <8 x i1> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}
+  return _mm_maskz_srli_epi16(__U, __A, __B); 
+}
+
 __m256i test_mm256_mask_srli_epi16(__m256i __W, __mmask16 __U, __m256i __A) {
   // CHECK-LABEL: @test_mm256_mask_srli_epi16
   // CHECK: @llvm.x86.avx2.psrli.w
@@ -2282,6 +2324,13 @@ __m256i test_mm256_mask_srli_epi16(__m256i __W, __mmask16 __U, __m256i __A) {
   return _mm256_mask_srli_epi16(__W, __U, __A, 5); 
 }
 
+__m256i test_mm256_mask_srli_epi16_2(__m256i __W, __mmask16 __U, __m256i __A, int __B) {
+  // CHECK-LABEL: @test_mm256_mask_srli_epi16_2
+  // CHECK: @llvm.x86.avx2.psrli.w
+  // CHECK: select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}}
+  return _mm256_mask_srli_epi16(__W, __U, __A, __B); 
+}
+
 __m256i test_mm256_maskz_srli_epi16(__mmask16 __U, __m256i __A) {
   // CHECK-LABEL: @test_mm256_maskz_srli_epi16
   // CHECK: @llvm.x86.avx2.psrli.w
@@ -2289,6 +2338,13 @@ __m256i test_mm256_maskz_srli_epi16(__mmask16 __U, __m256i __A) {
   return _mm256_maskz_srli_epi16(__U, __A, 5); 
 }
 
+__m256i test_mm256_maskz_srli_epi16_2(__mmask16 __U, __m256i __A, int __B) {
+  // CHECK-LABEL: @test_mm256_maskz_srli_epi16_2
+  // CHECK: @llvm.x86.avx2.psrli.w
+  // CHECK: select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}}
+  return _mm256_maskz_srli_epi16(__U, __A, __B); 
+}
+
 __m256i test_mm256_srav_epi16(__m256i __A, __m256i __B) {
   // CHECK-LABEL: @test_mm256_srav_epi16
   // CHECK: @llvm.x86.avx512.psrav.w.256(
@@ -2364,6 +2420,13 @@ __m128i test_mm_mask_srai_epi16(__m128i __W, __mmask8 __U, __m128i __A) {
   return _mm_mask_srai_epi16(__W, __U, __A, 5); 
 }
 
+__m128i test_mm_mask_srai_epi16_2(__m128i __W, __mmask8 __U, __m128i __A, int __B) {
+  // CHECK-LABEL: @test_mm_mask_srai_epi16_2
+  // CHECK: @llvm.x86.sse2.psrai.w
+  // CHECK: select <8 x i1> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}
+  return _mm_mask_srai_epi16(__W, __U, __A, __B); 
+}
+
 __m128i test_mm_maskz_srai_epi16(__mmask8 __U, __m128i __A) {
   // CHECK-LABEL: @test_mm_maskz_srai_epi16
   // CHECK: @llvm.x86.sse2.psrai.w
@@ -2371,6 +2434,13 @@ __m128i test_mm_maskz_srai_epi16(__mmask8 __U, __m128i __A) {
   return _mm_maskz_srai_epi16(__U, __A, 5); 
 }
 
+__m128i test_mm_maskz_srai_epi16_2(__mmask8 __U, __m128i __A, int __B) {
+  // CHECK-LABEL: @test_mm_maskz_srai_epi16_2
+  // CHECK: @llvm.x86.sse2.psrai.w
+  // CHECK: select <8 x i1> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}
+  return _mm_maskz_srai_epi16(__U, __A, __B); 
+}
+
 __m256i test_mm256_mask_srai_epi16(__m256i __W, __mmask16 __U, __m256i __A) {
   // CHECK-LABEL: @test_mm256_mask_srai_epi16
   // CHECK: @llvm.x86.avx2.psrai.w
@@ -2378,6 +2448,13 @@ __m256i test_mm256_mask_srai_epi16(__m256i __W, __mmask16 __U, __m256i __A) {
   return _mm256_mask_srai_epi16(__W, __U, __A, 5); 
 }
 
+__m256i test_mm256_mask_srai_epi16_2(__m256i __W, __mmask16 __U, __m256i __A, int __B) {
+  // CHECK-LABEL: @test_mm256_mask_srai_epi16_2
+  // CHECK: @llvm.x86.avx2.psrai.w
+  // CHECK: select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}}
+  return _mm256_mask_srai_epi16(__W, __U, __A, __B); 
+}
+
 __m256i test_mm256_maskz_srai_epi16(__mmask16 __U, __m256i __A) {
   // CHECK-LABEL: @test_mm256_maskz_srai_epi16
   // CHECK: @llvm.x86.avx2.psrai.w
@@ -2385,6 +2462,13 @@ __m256i test_mm256_maskz_srai_epi16(__mmask16 __U, __m256i __A) {
   return _mm256_maskz_srai_epi16(__U, __A, 5); 
 }
 
+__m256i test_mm256_maskz_srai_epi16_2(__mmask16 __U, __m256i __A, int __B) {
+  // CHECK-LABEL: @test_mm256_maskz_srai_epi16_2
+  // CHECK: @llvm.x86.avx2.psrai.w
+  // CHECK: select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}}
+  return _mm256_maskz_srai_epi16(__U, __A, __B); 
+}
+
 __m128i test_mm_mask_mov_epi16(__m128i __W, __mmask8 __U, __m128i __A) {
   // CHECK-LABEL: @test_mm_mask_mov_epi16
   // CHECK: select <8 x i1> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}
diff --git a/test/CodeGen/sse2-builtins.c b/test/CodeGen/sse2-builtins.c
index 029340abd9..28ee523ac8 100644
--- a/test/CodeGen/sse2-builtins.c
+++ b/test/CodeGen/sse2-builtins.c
@@ -1186,18 +1186,54 @@ __m128i test_mm_slli_epi16(__m128i A) {
   return _mm_slli_epi16(A, 1);
 }
 
+__m128i test_mm_slli_epi16_1(__m128i A) {
+  // CHECK-LABEL: test_mm_slli_epi16_1
+  // CHECK: call <8 x i16> @llvm.x86.sse2.pslli.w(<8 x i16> %{{.*}}, i32 %{{.*}})
+  return _mm_slli_epi16(A, -1);
+}
+
+__m128i test_mm_slli_epi16_2(__m128i A, int B) {
+  // CHECK-LABEL: test_mm_slli_epi16_2
+  // CHECK: call <8 x i16> @llvm.x86.sse2.pslli.w(<8 x i16> %{{.*}}, i32 %{{.*}})
+  return _mm_slli_epi16(A, B);
+}
+
 __m128i test_mm_slli_epi32(__m128i A) {
   // CHECK-LABEL: test_mm_slli_epi32
   // CHECK: call <4 x i32> @llvm.x86.sse2.pslli.d(<4 x i32> %{{.*}}, i32 %{{.*}})
   return _mm_slli_epi32(A, 1);
 }
 
+__m128i test_mm_slli_epi32_1(__m128i A) {
+  // CHECK-LABEL: test_mm_slli_epi32_1
+  // CHECK: call <4 x i32> @llvm.x86.sse2.pslli.d(<4 x i32> %{{.*}}, i32 %{{.*}})
+  return _mm_slli_epi32(A, -1);
+}
+
+__m128i test_mm_slli_epi32_2(__m128i A, int B) {
+  // CHECK-LABEL: test_mm_slli_epi32_2
+  // CHECK: call <4 x i32> @llvm.x86.sse2.pslli.d(<4 x i32> %{{.*}}, i32 %{{.*}})
+  return _mm_slli_epi32(A, B);
+}
+
 __m128i test_mm_slli_epi64(__m128i A) {
   // CHECK-LABEL: test_mm_slli_epi64
   // CHECK: call <2 x i64> @llvm.x86.sse2.pslli.q(<2 x i64> %{{.*}}, i32 %{{.*}})
   return _mm_slli_epi64(A, 1);
 }
 
+__m128i test_mm_slli_epi64_1(__m128i A) {
+  // CHECK-LABEL: test_mm_slli_epi64_1
+  // CHECK: call <2 x i64> @llvm.x86.sse2.pslli.q(<2 x i64> %{{.*}}, i32 %{{.*}})
+  return _mm_slli_epi64(A, -1);
+}
+
+__m128i test_mm_slli_epi64_2(__m128i A, int B) {
+  // CHECK-LABEL: test_mm_slli_epi64_2
+  // CHECK: call <2 x i64> @llvm.x86.sse2.pslli.q(<2 x i64> %{{.*}}, i32 %{{.*}})
+  return _mm_slli_epi64(A, B);
+}
+
 __m128i test_mm_slli_si128(__m128i A) {
   // CHECK-LABEL: test_mm_slli_si128
   // CHECK: shufflevector <16 x i8> zeroinitializer, <16 x i8> %{{.*}}, <16 x i32> 
@@ -1242,12 +1278,36 @@ __m128i test_mm_srai_epi16(__m128i A) {
   return _mm_srai_epi16(A, 1);
 }
 
+__m128i test_mm_srai_epi16_1(__m128i A) {
+  // CHECK-LABEL: test_mm_srai_epi16_1
+  // CHECK: call <8 x i16> @llvm.x86.sse2.psrai.w(<8 x i16> %{{.*}}, i32 %{{.*}})
+  return _mm_srai_epi16(A, -1);
+}
+
+__m128i test_mm_srai_epi16_2(__m128i A, int B) {
+  // CHECK-LABEL: test_mm_srai_epi16_2
+  // CHECK: call <8 x i16> @llvm.x86.sse2.psrai.w(<8 x i16> %{{.*}}, i32 %{{.*}})
+  return _mm_srai_epi16(A, B);
+}
+
 __m128i test_mm_srai_epi32(__m128i A) {
   // CHECK-LABEL: test_mm_srai_epi32
   // CHECK: call <4 x i32> @llvm.x86.sse2.psrai.d(<4 x i32> %{{.*}}, i32 %{{.*}})
   return _mm_srai_epi32(A, 1);
 }
 
+__m128i test_mm_srai_epi32_1(__m128i A) {
+  // CHECK-LABEL: test_mm_srai_epi32_1
+  // CHECK: call <4 x i32> @llvm.x86.sse2.psrai.d(<4 x i32> %{{.*}}, i32 %{{.*}})
+  return _mm_srai_epi32(A, -1);
+}
+
+__m128i test_mm_srai_epi32_2(__m128i A, int B) {
+  // CHECK-LABEL: test_mm_srai_epi32_2
+  // CHECK: call <4 x i32> @llvm.x86.sse2.psrai.d(<4 x i32> %{{.*}}, i32 %{{.*}})
+  return _mm_srai_epi32(A, B);
+}
+
 __m128i test_mm_srl_epi16(__m128i A, __m128i B) {
   // CHECK-LABEL: test_mm_srl_epi16
   // CHECK: call <8 x i16> @llvm.x86.sse2.psrl.w(<8 x i16> %{{.*}}, <8 x i16> %{{.*}})
@@ -1272,18 +1332,54 @@ __m128i test_mm_srli_epi16(__m128i A) {
   return _mm_srli_epi16(A, 1);
 }
 
+__m128i test_mm_srli_epi16_1(__m128i A) {
+  // CHECK-LABEL: test_mm_srli_epi16_1
+  // CHECK: call <8 x i16> @llvm.x86.sse2.psrli.w(<8 x i16> %{{.*}}, i32 %{{.*}})
+  return _mm_srli_epi16(A, -1);
+}
+
+__m128i test_mm_srli_epi16_2(__m128i A, int B) {
+  // CHECK-LABEL: test_mm_srli_epi16
+  // CHECK: call <8 x i16> @llvm.x86.sse2.psrli.w(<8 x i16> %{{.*}}, i32 %{{.*}})
+  return _mm_srli_epi16(A, B);
+}
+
 __m128i test_mm_srli_epi32(__m128i A) {
   // CHECK-LABEL: test_mm_srli_epi32
   // CHECK: call <4 x i32> @llvm.x86.sse2.psrli.d(<4 x i32> %{{.*}}, i32 %{{.*}})
   return _mm_srli_epi32(A, 1);
 }
 
+__m128i test_mm_srli_epi32_1(__m128i A) {
+  // CHECK-LABEL: test_mm_srli_epi32_1
+  // CHECK: call <4 x i32> @llvm.x86.sse2.psrli.d(<4 x i32> %{{.*}}, i32 %{{.*}})
+  return _mm_srli_epi32(A, -1);
+}
+
+__m128i test_mm_srli_epi32_2(__m128i A, int B) {
+  // CHECK-LABEL: test_mm_srli_epi32_2
+  // CHECK: call <4 x i32> @llvm.x86.sse2.psrli.d(<4 x i32> %{{.*}}, i32 %{{.*}})
+  return _mm_srli_epi32(A, B);
+}
+
 __m128i test_mm_srli_epi64(__m128i A) {
   // CHECK-LABEL: test_mm_srli_epi64
   // CHECK: call <2 x i64> @llvm.x86.sse2.psrli.q(<2 x i64> %{{.*}}, i32 %{{.*}})
   return _mm_srli_epi64(A, 1);
 }
 
+__m128i test_mm_srli_epi64_1(__m128i A) {
+  // CHECK-LABEL: test_mm_srli_epi64_1
+  // CHECK: call <2 x i64> @llvm.x86.sse2.psrli.q(<2 x i64> %{{.*}}, i32 %{{.*}})
+  return _mm_srli_epi64(A, -1);
+}
+
+__m128i test_mm_srli_epi64_2(__m128i A, int B) {
+  // CHECK-LABEL: test_mm_srli_epi64_2
+  // CHECK: call <2 x i64> @llvm.x86.sse2.psrli.q(<2 x i64> %{{.*}}, i32 %{{.*}})
+  return _mm_srli_epi64(A, B);
+}
+
 __m128i test_mm_srli_si128(__m128i A) {
   // CHECK-LABEL: test_mm_srli_si128
   // CHECK: shufflevector <16 x i8> %{{.*}}, <16 x i8> zeroinitializer, <16 x i32> 
-- 
cgit v1.2.3


From 1ad54e198af85c779c11a265af0737772300051d Mon Sep 17 00:00:00 2001
From: Bruno Ricci 
Date: Tue, 8 Jan 2019 13:52:54 +0000
Subject: [Sema] Diagnose array access preceding the array bounds even when the
 base type is incomplete.

When the type of the base expression after IgnoreParenCasts is incomplete,
it is still possible to diagnose an array access which precedes the array
bounds.

This is a follow-up on D55862 which added an early return when the type of
the base expression after IgnoreParenCasts was incomplete.

Differential Revision: https://reviews.llvm.org/D56050

Reviewed By: efriedma



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350622 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/Sema/SemaChecking.cpp     | 15 +++++++++------
 test/SemaCXX/array-bounds.cpp |  5 ++++-
 2 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index b9284a5b46..cd96200b81 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -12383,12 +12383,6 @@ void Sema::CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr,
     return;
 
   const Type *BaseType = ArrayTy->getElementType().getTypePtr();
-  // It is possible that the type of the base expression after IgnoreParenCasts
-  // is incomplete, even though the type of the base expression before
-  // IgnoreParenCasts is complete (see PR39746 for an example). In this case we
-  // have no information about whether the array access is out-of-bounds.
-  if (BaseType->isIncompleteType())
-    return;
 
   Expr::EvalResult Result;
   if (!IndexExpr->EvaluateAsInt(Result, Context, Expr::SE_AllowSideEffects))
@@ -12405,6 +12399,15 @@ void Sema::CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr,
     ND = ME->getMemberDecl();
 
   if (index.isUnsigned() || !index.isNegative()) {
+    // It is possible that the type of the base expression after
+    // IgnoreParenCasts is incomplete, even though the type of the base
+    // expression before IgnoreParenCasts is complete (see PR39746 for an
+    // example). In this case we have no information about whether the array
+    // access exceeds the array bounds. However we can still diagnose an array
+    // access which precedes the array bounds.
+    if (BaseType->isIncompleteType())
+      return;
+
     llvm::APInt size = ArrayTy->getSize();
     if (!size.isStrictlyPositive())
       return;
diff --git a/test/SemaCXX/array-bounds.cpp b/test/SemaCXX/array-bounds.cpp
index 3eb929b93e..6ebff8c992 100644
--- a/test/SemaCXX/array-bounds.cpp
+++ b/test/SemaCXX/array-bounds.cpp
@@ -287,9 +287,12 @@ int test_struct_multiarray() {
 
 namespace PR39746 {
   struct S;
-  extern S xxx[2];
+  extern S xxx[2]; // expected-note {{array 'xxx' declared here}}
   class C {};
 
   C &f() { return reinterpret_cast(xxx)[1]; } // no-warning
+  // We have no info on whether this is out-of-bounds.
   C &g() { return reinterpret_cast(xxx)[2]; } // no-warning
+  // We can still diagnose this.
+  C &h() { return reinterpret_cast(xxx)[-1]; } // expected-warning {{array index -1 is before the beginning of the array}}
 }
-- 
cgit v1.2.3


From e4d246c86329b82b8017e9a540279f07c8bb54ab Mon Sep 17 00:00:00 2001
From: Bruno Ricci 
Date: Tue, 8 Jan 2019 14:17:00 +0000
Subject: [AST] Pack CXXDependentScopeMemberExpr

Use the newly available space in the bit-fields of Stmt. Additionally store
FirstQualifierFoundInScope as a trailing object since it is most of the time
null (non-null for 2 of the 35446 CXXDependentScopeMemberExpr when parsing
all of Boost).

It would be possible to move the data for the nested-name-specifier to a
trailing object too to save another 2 pointers, however doing so did actually
regress the time taken to parse all of Boost slightly.

This saves 8 bytes + 1 pointer per CXXDependentScopeMemberExpr in the vast
majority of cases.

Differential Revision: https://reviews.llvm.org/D56367

Reviewed By: rjmccall



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350625 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/AST/ExprCXX.h         | 119 ++++++++++++++++++++----------------
 include/clang/AST/Stmt.h            |  23 +++++++
 lib/AST/ExprCXX.cpp                 | 102 +++++++++++++++----------------
 lib/Serialization/ASTReaderStmt.cpp |  44 ++++++++-----
 lib/Serialization/ASTWriterStmt.cpp |  29 +++++----
 5 files changed, 189 insertions(+), 128 deletions(-)

diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index 5155b6095e..e105f33da7 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -3306,7 +3306,11 @@ class CXXDependentScopeMemberExpr final
     : public Expr,
       private llvm::TrailingObjects {
+                                    TemplateArgumentLoc, NamedDecl *> {
+  friend class ASTStmtReader;
+  friend class ASTStmtWriter;
+  friend TrailingObjects;
+
   /// The expression for the base pointer or class reference,
   /// e.g., the \c x in x.f.  Can be null in implicit accesses.
   Stmt *Base;
@@ -3315,40 +3319,53 @@ class CXXDependentScopeMemberExpr final
   /// implicit accesses.
   QualType BaseType;
 
-  /// Whether this member expression used the '->' operator or
-  /// the '.' operator.
-  bool IsArrow : 1;
-
-  /// Whether this member expression has info for explicit template
-  /// keyword and arguments.
-  bool HasTemplateKWAndArgsInfo : 1;
-
-  /// The location of the '->' or '.' operator.
-  SourceLocation OperatorLoc;
-
   /// The nested-name-specifier that precedes the member name, if any.
+  /// FIXME: This could be in principle store as a trailing object.
+  /// However the performance impact of doing so should be investigated first.
   NestedNameSpecifierLoc QualifierLoc;
 
-  /// In a qualified member access expression such as t->Base::f, this
-  /// member stores the resolves of name lookup in the context of the member
-  /// access expression, to be used at instantiation time.
-  ///
-  /// FIXME: This member, along with the QualifierLoc, could
-  /// be stuck into a structure that is optionally allocated at the end of
-  /// the CXXDependentScopeMemberExpr, to save space in the common case.
-  NamedDecl *FirstQualifierFoundInScope;
-
   /// The member to which this member expression refers, which
   /// can be name, overloaded operator, or destructor.
   ///
   /// FIXME: could also be a template-id
   DeclarationNameInfo MemberNameInfo;
 
-  size_t numTrailingObjects(OverloadToken) const {
-    return HasTemplateKWAndArgsInfo ? 1 : 0;
+  // CXXDependentScopeMemberExpr is followed by several trailing objects,
+  // some of which optional. They are in order:
+  //
+  // * An optional ASTTemplateKWAndArgsInfo for the explicitly specified
+  //   template keyword and arguments. Present if and only if
+  //   hasTemplateKWAndArgsInfo().
+  //
+  // * An array of getNumTemplateArgs() TemplateArgumentLoc containing location
+  //   information for the explicitly specified template arguments.
+  //
+  // * An optional NamedDecl *. In a qualified member access expression such
+  //   as t->Base::f, this member stores the resolves of name lookup in the
+  //   context of the member access expression, to be used at instantiation
+  //   time. Present if and only if hasFirstQualifierFoundInScope().
+
+  bool hasTemplateKWAndArgsInfo() const {
+    return CXXDependentScopeMemberExprBits.HasTemplateKWAndArgsInfo;
+  }
+
+  bool hasFirstQualifierFoundInScope() const {
+    return CXXDependentScopeMemberExprBits.HasFirstQualifierFoundInScope;
   }
 
-  CXXDependentScopeMemberExpr(const ASTContext &C, Expr *Base,
+  unsigned numTrailingObjects(OverloadToken) const {
+    return hasTemplateKWAndArgsInfo();
+  }
+
+  unsigned numTrailingObjects(OverloadToken) const {
+    return getNumTemplateArgs();
+  }
+
+  unsigned numTrailingObjects(OverloadToken) const {
+    return hasFirstQualifierFoundInScope();
+  }
+
+  CXXDependentScopeMemberExpr(const ASTContext &Ctx, Expr *Base,
                               QualType BaseType, bool IsArrow,
                               SourceLocation OperatorLoc,
                               NestedNameSpecifierLoc QualifierLoc,
@@ -3357,33 +3374,29 @@ class CXXDependentScopeMemberExpr final
                               DeclarationNameInfo MemberNameInfo,
                               const TemplateArgumentListInfo *TemplateArgs);
 
-public:
-  friend class ASTStmtReader;
-  friend class ASTStmtWriter;
-  friend TrailingObjects;
-
-  CXXDependentScopeMemberExpr(const ASTContext &C, Expr *Base,
-                              QualType BaseType, bool IsArrow,
-                              SourceLocation OperatorLoc,
-                              NestedNameSpecifierLoc QualifierLoc,
-                              NamedDecl *FirstQualifierFoundInScope,
-                              DeclarationNameInfo MemberNameInfo);
+  CXXDependentScopeMemberExpr(EmptyShell Empty, bool HasTemplateKWAndArgsInfo,
+                              bool HasFirstQualifierFoundInScope);
 
+public:
   static CXXDependentScopeMemberExpr *
-  Create(const ASTContext &C, Expr *Base, QualType BaseType, bool IsArrow,
+  Create(const ASTContext &Ctx, Expr *Base, QualType BaseType, bool IsArrow,
          SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc,
          SourceLocation TemplateKWLoc, NamedDecl *FirstQualifierFoundInScope,
          DeclarationNameInfo MemberNameInfo,
          const TemplateArgumentListInfo *TemplateArgs);
 
   static CXXDependentScopeMemberExpr *
-  CreateEmpty(const ASTContext &C, bool HasTemplateKWAndArgsInfo,
-              unsigned NumTemplateArgs);
+  CreateEmpty(const ASTContext &Ctx, bool HasTemplateKWAndArgsInfo,
+              unsigned NumTemplateArgs, bool HasFirstQualifierFoundInScope);
 
   /// True if this is an implicit access, i.e. one in which the
   /// member being accessed was not written in the source.  The source
   /// location of the operator is invalid in this case.
-  bool isImplicitAccess() const;
+  bool isImplicitAccess() const {
+    if (!Base)
+      return true;
+    return cast(Base)->isImplicitCXXThis();
+  }
 
   /// Retrieve the base object of this member expressions,
   /// e.g., the \c x in \c x.m.
@@ -3396,13 +3409,14 @@ public:
 
   /// Determine whether this member expression used the '->'
   /// operator; otherwise, it used the '.' operator.
-  bool isArrow() const { return IsArrow; }
+  bool isArrow() const { return CXXDependentScopeMemberExprBits.IsArrow; }
 
   /// Retrieve the location of the '->' or '.' operator.
-  SourceLocation getOperatorLoc() const { return OperatorLoc; }
+  SourceLocation getOperatorLoc() const {
+    return CXXDependentScopeMemberExprBits.OperatorLoc;
+  }
 
-  /// Retrieve the nested-name-specifier that qualifies the member
-  /// name.
+  /// Retrieve the nested-name-specifier that qualifies the member name.
   NestedNameSpecifier *getQualifier() const {
     return QualifierLoc.getNestedNameSpecifier();
   }
@@ -3423,17 +3437,17 @@ public:
   /// combined with the results of name lookup into the type of the object
   /// expression itself (the class type of x).
   NamedDecl *getFirstQualifierFoundInScope() const {
-    return FirstQualifierFoundInScope;
+    if (!hasFirstQualifierFoundInScope())
+      return nullptr;
+    return *getTrailingObjects();
   }
 
-  /// Retrieve the name of the member that this expression
-  /// refers to.
+  /// Retrieve the name of the member that this expression refers to.
   const DeclarationNameInfo &getMemberNameInfo() const {
     return MemberNameInfo;
   }
 
-  /// Retrieve the name of the member that this expression
-  /// refers to.
+  /// Retrieve the name of the member that this expression refers to.
   DeclarationName getMember() const { return MemberNameInfo.getName(); }
 
   // Retrieve the location of the name of the member that this
@@ -3443,21 +3457,24 @@ public:
   /// Retrieve the location of the template keyword preceding the
   /// member name, if any.
   SourceLocation getTemplateKeywordLoc() const {
-    if (!HasTemplateKWAndArgsInfo) return SourceLocation();
+    if (!hasTemplateKWAndArgsInfo())
+      return SourceLocation();
     return getTrailingObjects()->TemplateKWLoc;
   }
 
   /// Retrieve the location of the left angle bracket starting the
   /// explicit template argument list following the member name, if any.
   SourceLocation getLAngleLoc() const {
-    if (!HasTemplateKWAndArgsInfo) return SourceLocation();
+    if (!hasTemplateKWAndArgsInfo())
+      return SourceLocation();
     return getTrailingObjects()->LAngleLoc;
   }
 
   /// Retrieve the location of the right angle bracket ending the
   /// explicit template argument list following the member name, if any.
   SourceLocation getRAngleLoc() const {
-    if (!HasTemplateKWAndArgsInfo) return SourceLocation();
+    if (!hasTemplateKWAndArgsInfo())
+      return SourceLocation();
     return getTrailingObjects()->RAngleLoc;
   }
 
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index 2f94faee2c..792f96e6a1 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -738,6 +738,28 @@ protected:
     unsigned NumArgs;
   };
 
+  class CXXDependentScopeMemberExprBitfields {
+    friend class ASTStmtReader;
+    friend class CXXDependentScopeMemberExpr;
+
+    unsigned : NumExprBits;
+
+    /// Whether this member expression used the '->' operator or
+    /// the '.' operator.
+    unsigned IsArrow : 1;
+
+    /// Whether this member expression has info for explicit template
+    /// keyword and arguments.
+    unsigned HasTemplateKWAndArgsInfo : 1;
+
+    /// See getFirstQualifierFoundInScope() and the comment listing
+    /// the trailing objects.
+    unsigned HasFirstQualifierFoundInScope : 1;
+
+    /// The location of the '->' or '.' operator.
+    SourceLocation OperatorLoc;
+  };
+
   //===--- C++ Coroutines TS bitfields classes ---===//
 
   class CoawaitExprBitfields {
@@ -825,6 +847,7 @@ protected:
     CXXConstructExprBitfields CXXConstructExprBits;
     ExprWithCleanupsBitfields ExprWithCleanupsBits;
     CXXUnresolvedConstructExprBitfields CXXUnresolvedConstructExprBits;
+    CXXDependentScopeMemberExprBitfields CXXDependentScopeMemberExprBits;
 
     // C++ Coroutines TS expressions
     CoawaitExprBitfields CoawaitBits;
diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp
index 4eb3d333bc..e336fddae0 100644
--- a/lib/AST/ExprCXX.cpp
+++ b/lib/AST/ExprCXX.cpp
@@ -1301,24 +1301,26 @@ SourceLocation CXXUnresolvedConstructExpr::getBeginLoc() const {
 }
 
 CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr(
-    const ASTContext &C, Expr *Base, QualType BaseType, bool IsArrow,
+    const ASTContext &Ctx, Expr *Base, QualType BaseType, bool IsArrow,
     SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc,
     SourceLocation TemplateKWLoc, NamedDecl *FirstQualifierFoundInScope,
     DeclarationNameInfo MemberNameInfo,
     const TemplateArgumentListInfo *TemplateArgs)
-    : Expr(CXXDependentScopeMemberExprClass, C.DependentTy, VK_LValue,
+    : Expr(CXXDependentScopeMemberExprClass, Ctx.DependentTy, VK_LValue,
            OK_Ordinary, true, true, true,
            ((Base && Base->containsUnexpandedParameterPack()) ||
-            (QualifierLoc &&
-             QualifierLoc.getNestedNameSpecifier()
-                 ->containsUnexpandedParameterPack()) ||
+            (QualifierLoc && QualifierLoc.getNestedNameSpecifier()
+                                 ->containsUnexpandedParameterPack()) ||
             MemberNameInfo.containsUnexpandedParameterPack())),
-      Base(Base), BaseType(BaseType), IsArrow(IsArrow),
-      HasTemplateKWAndArgsInfo(TemplateArgs != nullptr ||
-                               TemplateKWLoc.isValid()),
-      OperatorLoc(OperatorLoc), QualifierLoc(QualifierLoc),
-      FirstQualifierFoundInScope(FirstQualifierFoundInScope),
+      Base(Base), BaseType(BaseType), QualifierLoc(QualifierLoc),
       MemberNameInfo(MemberNameInfo) {
+  CXXDependentScopeMemberExprBits.IsArrow = IsArrow;
+  CXXDependentScopeMemberExprBits.HasTemplateKWAndArgsInfo =
+      (TemplateArgs != nullptr) || TemplateKWLoc.isValid();
+  CXXDependentScopeMemberExprBits.HasFirstQualifierFoundInScope =
+      FirstQualifierFoundInScope != nullptr;
+  CXXDependentScopeMemberExprBits.OperatorLoc = OperatorLoc;
+
   if (TemplateArgs) {
     bool Dependent = true;
     bool InstantiationDependent = true;
@@ -1332,56 +1334,54 @@ CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr(
     getTrailingObjects()->initializeFrom(
         TemplateKWLoc);
   }
+
+  if (hasFirstQualifierFoundInScope())
+    *getTrailingObjects() = FirstQualifierFoundInScope;
 }
 
-CXXDependentScopeMemberExpr *
-CXXDependentScopeMemberExpr::Create(const ASTContext &C,
-                                Expr *Base, QualType BaseType, bool IsArrow,
-                                SourceLocation OperatorLoc,
-                                NestedNameSpecifierLoc QualifierLoc,
-                                SourceLocation TemplateKWLoc,
-                                NamedDecl *FirstQualifierFoundInScope,
-                                DeclarationNameInfo MemberNameInfo,
-                                const TemplateArgumentListInfo *TemplateArgs) {
-  bool HasTemplateKWAndArgsInfo = TemplateArgs || TemplateKWLoc.isValid();
+CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr(
+    EmptyShell Empty, bool HasTemplateKWAndArgsInfo,
+    bool HasFirstQualifierFoundInScope)
+    : Expr(CXXDependentScopeMemberExprClass, Empty) {
+  CXXDependentScopeMemberExprBits.HasTemplateKWAndArgsInfo =
+      HasTemplateKWAndArgsInfo;
+  CXXDependentScopeMemberExprBits.HasFirstQualifierFoundInScope =
+      HasFirstQualifierFoundInScope;
+}
+
+CXXDependentScopeMemberExpr *CXXDependentScopeMemberExpr::Create(
+    const ASTContext &Ctx, Expr *Base, QualType BaseType, bool IsArrow,
+    SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc,
+    SourceLocation TemplateKWLoc, NamedDecl *FirstQualifierFoundInScope,
+    DeclarationNameInfo MemberNameInfo,
+    const TemplateArgumentListInfo *TemplateArgs) {
+  bool HasTemplateKWAndArgsInfo =
+      (TemplateArgs != nullptr) || TemplateKWLoc.isValid();
   unsigned NumTemplateArgs = TemplateArgs ? TemplateArgs->size() : 0;
-  std::size_t Size =
-      totalSizeToAlloc(
-          HasTemplateKWAndArgsInfo, NumTemplateArgs);
+  bool HasFirstQualifierFoundInScope = FirstQualifierFoundInScope != nullptr;
 
-  void *Mem = C.Allocate(Size, alignof(CXXDependentScopeMemberExpr));
-  return new (Mem) CXXDependentScopeMemberExpr(C, Base, BaseType,
-                                               IsArrow, OperatorLoc,
-                                               QualifierLoc,
-                                               TemplateKWLoc,
-                                               FirstQualifierFoundInScope,
-                                               MemberNameInfo, TemplateArgs);
+  unsigned Size = totalSizeToAlloc(
+      HasTemplateKWAndArgsInfo, NumTemplateArgs, HasFirstQualifierFoundInScope);
+
+  void *Mem = Ctx.Allocate(Size, alignof(CXXDependentScopeMemberExpr));
+  return new (Mem) CXXDependentScopeMemberExpr(
+      Ctx, Base, BaseType, IsArrow, OperatorLoc, QualifierLoc, TemplateKWLoc,
+      FirstQualifierFoundInScope, MemberNameInfo, TemplateArgs);
 }
 
-CXXDependentScopeMemberExpr *
-CXXDependentScopeMemberExpr::CreateEmpty(const ASTContext &C,
-                                         bool HasTemplateKWAndArgsInfo,
-                                         unsigned NumTemplateArgs) {
+CXXDependentScopeMemberExpr *CXXDependentScopeMemberExpr::CreateEmpty(
+    const ASTContext &Ctx, bool HasTemplateKWAndArgsInfo,
+    unsigned NumTemplateArgs, bool HasFirstQualifierFoundInScope) {
   assert(NumTemplateArgs == 0 || HasTemplateKWAndArgsInfo);
-  std::size_t Size =
-      totalSizeToAlloc(
-          HasTemplateKWAndArgsInfo, NumTemplateArgs);
-  void *Mem = C.Allocate(Size, alignof(CXXDependentScopeMemberExpr));
-  auto *E =
-      new (Mem) CXXDependentScopeMemberExpr(C, nullptr, QualType(),
-                                            false, SourceLocation(),
-                                            NestedNameSpecifierLoc(),
-                                            SourceLocation(), nullptr,
-                                            DeclarationNameInfo(), nullptr);
-  E->HasTemplateKWAndArgsInfo = HasTemplateKWAndArgsInfo;
-  return E;
-}
 
-bool CXXDependentScopeMemberExpr::isImplicitAccess() const {
-  if (!Base)
-    return true;
+  unsigned Size = totalSizeToAlloc(
+      HasTemplateKWAndArgsInfo, NumTemplateArgs, HasFirstQualifierFoundInScope);
 
-  return cast(Base)->isImplicitCXXThis();
+  void *Mem = Ctx.Allocate(Size, alignof(CXXDependentScopeMemberExpr));
+  return new (Mem) CXXDependentScopeMemberExpr(
+      EmptyShell(), HasTemplateKWAndArgsInfo, HasFirstQualifierFoundInScope);
 }
 
 static bool hasOnlyNonStaticMemberFunctions(UnresolvedSetIterator begin,
diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp
index 80b987a662..53eb5bcf38 100644
--- a/lib/Serialization/ASTReaderStmt.cpp
+++ b/lib/Serialization/ASTReaderStmt.cpp
@@ -1584,22 +1584,37 @@ void ASTStmtReader::VisitExprWithCleanups(ExprWithCleanups *E) {
   E->SubExpr = Record.readSubExpr();
 }
 
-void
-ASTStmtReader::VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E){
+void ASTStmtReader::VisitCXXDependentScopeMemberExpr(
+    CXXDependentScopeMemberExpr *E) {
   VisitExpr(E);
 
-  if (Record.readInt()) // HasTemplateKWAndArgsInfo
+  bool HasTemplateKWAndArgsInfo = Record.readInt();
+  unsigned NumTemplateArgs = Record.readInt();
+  bool HasFirstQualifierFoundInScope = Record.readInt();
+
+  assert((HasTemplateKWAndArgsInfo == E->hasTemplateKWAndArgsInfo()) &&
+         "Wrong HasTemplateKWAndArgsInfo!");
+  assert(
+      (HasFirstQualifierFoundInScope == E->hasFirstQualifierFoundInScope()) &&
+      "Wrong HasFirstQualifierFoundInScope!");
+
+  if (HasTemplateKWAndArgsInfo)
     ReadTemplateKWAndArgsInfo(
         *E->getTrailingObjects(),
-        E->getTrailingObjects(),
-        /*NumTemplateArgs=*/Record.readInt());
+        E->getTrailingObjects(), NumTemplateArgs);
 
-  E->Base = Record.readSubExpr();
+  assert((NumTemplateArgs == E->getNumTemplateArgs()) &&
+         "Wrong NumTemplateArgs!");
+
+  E->CXXDependentScopeMemberExprBits.IsArrow = Record.readInt();
+  E->CXXDependentScopeMemberExprBits.OperatorLoc = ReadSourceLocation();
   E->BaseType = Record.readType();
-  E->IsArrow = Record.readInt();
-  E->OperatorLoc = ReadSourceLocation();
   E->QualifierLoc = Record.readNestedNameSpecifierLoc();
-  E->FirstQualifierFoundInScope = ReadDeclAs();
+  E->Base = Record.readSubExpr();
+
+  if (HasFirstQualifierFoundInScope)
+    *E->getTrailingObjects() = ReadDeclAs();
+
   ReadDeclarationNameInfo(E->MemberNameInfo);
 }
 
@@ -3224,11 +3239,12 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
       break;
 
     case EXPR_CXX_DEPENDENT_SCOPE_MEMBER:
-      S = CXXDependentScopeMemberExpr::CreateEmpty(Context,
-         /*HasTemplateKWAndArgsInfo=*/Record[ASTStmtReader::NumExprFields],
-                  /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields]
-                                   ? Record[ASTStmtReader::NumExprFields + 1]
-                                   : 0);
+      S = CXXDependentScopeMemberExpr::CreateEmpty(
+          Context,
+          /*HasTemplateKWAndArgsInfo=*/Record[ASTStmtReader::NumExprFields],
+          /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields + 1],
+          /*HasFirstQualifierFoundInScope=*/
+          Record[ASTStmtReader::NumExprFields + 2]);
       break;
 
     case EXPR_CXX_DEPENDENT_SCOPE_DECL_REF:
diff --git a/lib/Serialization/ASTWriterStmt.cpp b/lib/Serialization/ASTWriterStmt.cpp
index 14c3b3278e..b1908f7991 100644
--- a/lib/Serialization/ASTWriterStmt.cpp
+++ b/lib/Serialization/ASTWriterStmt.cpp
@@ -1554,31 +1554,36 @@ void ASTStmtWriter::VisitExprWithCleanups(ExprWithCleanups *E) {
   Code = serialization::EXPR_EXPR_WITH_CLEANUPS;
 }
 
-void
-ASTStmtWriter::VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E){
+void ASTStmtWriter::VisitCXXDependentScopeMemberExpr(
+    CXXDependentScopeMemberExpr *E) {
   VisitExpr(E);
 
-  // Don't emit anything here, HasTemplateKWAndArgsInfo must be
-  // emitted first.
+  // Don't emit anything here (or if you do you will have to update
+  // the corresponding deserialization function).
 
-  Record.push_back(E->HasTemplateKWAndArgsInfo);
-  if (E->HasTemplateKWAndArgsInfo) {
+  Record.push_back(E->hasTemplateKWAndArgsInfo());
+  Record.push_back(E->getNumTemplateArgs());
+  Record.push_back(E->hasFirstQualifierFoundInScope());
+
+  if (E->hasTemplateKWAndArgsInfo()) {
     const ASTTemplateKWAndArgsInfo &ArgInfo =
         *E->getTrailingObjects();
-    Record.push_back(ArgInfo.NumTemplateArgs);
     AddTemplateKWAndArgsInfo(ArgInfo,
                              E->getTrailingObjects());
   }
 
+  Record.push_back(E->isArrow());
+  Record.AddSourceLocation(E->getOperatorLoc());
+  Record.AddTypeRef(E->getBaseType());
+  Record.AddNestedNameSpecifierLoc(E->getQualifierLoc());
   if (!E->isImplicitAccess())
     Record.AddStmt(E->getBase());
   else
     Record.AddStmt(nullptr);
-  Record.AddTypeRef(E->getBaseType());
-  Record.push_back(E->isArrow());
-  Record.AddSourceLocation(E->getOperatorLoc());
-  Record.AddNestedNameSpecifierLoc(E->getQualifierLoc());
-  Record.AddDeclRef(E->getFirstQualifierFoundInScope());
+
+  if (E->hasFirstQualifierFoundInScope())
+    Record.AddDeclRef(E->getFirstQualifierFoundInScope());
+
   Record.AddDeclarationNameInfo(E->MemberNameInfo);
   Code = serialization::EXPR_CXX_DEPENDENT_SCOPE_MEMBER;
 }
-- 
cgit v1.2.3


From e26ec09fb3d4d9554a12fd57c688be751abf220f Mon Sep 17 00:00:00 2001
From: Bruno Ricci 
Date: Tue, 8 Jan 2019 14:44:34 +0000
Subject: [AST][NFC] Pack CXXNoexceptExpr and SubstNonTypeTemplateParmExpr

Use the newly available space in the bit-fields of Stmt.
This saves one pointer per CXXNoexceptExpr/SubstNonTypeTemplateParmExpr.

Use this opportunity to run clang-format on these two classes and
fix some style issues. NFC overall.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350627 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/AST/ExprCXX.h         | 55 +++++++++++++++++++------------------
 include/clang/AST/Stmt.h            | 21 ++++++++++++++
 lib/Serialization/ASTReaderStmt.cpp |  4 +--
 3 files changed, 51 insertions(+), 29 deletions(-)

diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index e105f33da7..00e83eb723 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -3720,7 +3720,6 @@ inline TemplateArgumentLoc *OverloadExpr::getTrailingTemplateArgumentLoc() {
 class CXXNoexceptExpr : public Expr {
   friend class ASTStmtReader;
 
-  bool Value : 1;
   Stmt *Operand;
   SourceRange Range;
 
@@ -3728,21 +3727,23 @@ public:
   CXXNoexceptExpr(QualType Ty, Expr *Operand, CanThrowResult Val,
                   SourceLocation Keyword, SourceLocation RParen)
       : Expr(CXXNoexceptExprClass, Ty, VK_RValue, OK_Ordinary,
-             /*TypeDependent*/false,
-             /*ValueDependent*/Val == CT_Dependent,
+             /*TypeDependent*/ false,
+             /*ValueDependent*/ Val == CT_Dependent,
              Val == CT_Dependent || Operand->isInstantiationDependent(),
              Operand->containsUnexpandedParameterPack()),
-        Value(Val == CT_Cannot), Operand(Operand), Range(Keyword, RParen) {}
+        Operand(Operand), Range(Keyword, RParen) {
+    CXXNoexceptExprBits.Value = Val == CT_Cannot;
+  }
 
   CXXNoexceptExpr(EmptyShell Empty) : Expr(CXXNoexceptExprClass, Empty) {}
 
-  Expr *getOperand() const { return static_cast(Operand); }
+  Expr *getOperand() const { return static_cast(Operand); }
 
-  SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); }
-  SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); }
-  SourceRange getSourceRange() const LLVM_READONLY { return Range; }
+  SourceLocation getBeginLoc() const { return Range.getBegin(); }
+  SourceLocation getEndLoc() const { return Range.getEnd(); }
+  SourceRange getSourceRange() const { return Range; }
 
-  bool getValue() const { return Value; }
+  bool getValue() const { return CXXNoexceptExprBits.Value; }
 
   static bool classof(const Stmt *T) {
     return T->getStmtClass() == CXXNoexceptExprClass;
@@ -3965,27 +3966,27 @@ class SubstNonTypeTemplateParmExpr : public Expr {
   /// The replacement expression.
   Stmt *Replacement;
 
-  /// The location of the non-type template parameter reference.
-  SourceLocation NameLoc;
-
   explicit SubstNonTypeTemplateParmExpr(EmptyShell Empty)
       : Expr(SubstNonTypeTemplateParmExprClass, Empty) {}
 
 public:
-  SubstNonTypeTemplateParmExpr(QualType type,
-                               ExprValueKind valueKind,
-                               SourceLocation loc,
-                               NonTypeTemplateParmDecl *param,
-                               Expr *replacement)
-      : Expr(SubstNonTypeTemplateParmExprClass, type, valueKind, OK_Ordinary,
-             replacement->isTypeDependent(), replacement->isValueDependent(),
-             replacement->isInstantiationDependent(),
-             replacement->containsUnexpandedParameterPack()),
-        Param(param), Replacement(replacement), NameLoc(loc) {}
-
-  SourceLocation getNameLoc() const { return NameLoc; }
-  SourceLocation getBeginLoc() const LLVM_READONLY { return NameLoc; }
-  SourceLocation getEndLoc() const LLVM_READONLY { return NameLoc; }
+  SubstNonTypeTemplateParmExpr(QualType Ty, ExprValueKind ValueKind,
+                               SourceLocation Loc,
+                               NonTypeTemplateParmDecl *Param,
+                               Expr *Replacement)
+      : Expr(SubstNonTypeTemplateParmExprClass, Ty, ValueKind, OK_Ordinary,
+             Replacement->isTypeDependent(), Replacement->isValueDependent(),
+             Replacement->isInstantiationDependent(),
+             Replacement->containsUnexpandedParameterPack()),
+        Param(Param), Replacement(Replacement) {
+    SubstNonTypeTemplateParmExprBits.NameLoc = Loc;
+  }
+
+  SourceLocation getNameLoc() const {
+    return SubstNonTypeTemplateParmExprBits.NameLoc;
+  }
+  SourceLocation getBeginLoc() const { return getNameLoc(); }
+  SourceLocation getEndLoc() const { return getNameLoc(); }
 
   Expr *getReplacement() const { return cast(Replacement); }
 
@@ -3996,7 +3997,7 @@ public:
   }
 
   // Iterators
-  child_range children() { return child_range(&Replacement, &Replacement+1); }
+  child_range children() { return child_range(&Replacement, &Replacement + 1); }
 };
 
 /// Represents a reference to a non-type template parameter pack that
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index 792f96e6a1..e11e319703 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -760,6 +760,25 @@ protected:
     SourceLocation OperatorLoc;
   };
 
+  class CXXNoexceptExprBitfields {
+    friend class ASTStmtReader;
+    friend class CXXNoexceptExpr;
+
+    unsigned : NumExprBits;
+
+    unsigned Value : 1;
+  };
+
+  class SubstNonTypeTemplateParmExprBitfields {
+    friend class ASTStmtReader;
+    friend class SubstNonTypeTemplateParmExpr;
+
+    unsigned : NumExprBits;
+
+    /// The location of the non-type template parameter reference.
+    SourceLocation NameLoc;
+  };
+
   //===--- C++ Coroutines TS bitfields classes ---===//
 
   class CoawaitExprBitfields {
@@ -848,6 +867,8 @@ protected:
     ExprWithCleanupsBitfields ExprWithCleanupsBits;
     CXXUnresolvedConstructExprBitfields CXXUnresolvedConstructExprBits;
     CXXDependentScopeMemberExprBitfields CXXDependentScopeMemberExprBits;
+    CXXNoexceptExprBitfields CXXNoexceptExprBits;
+    SubstNonTypeTemplateParmExprBitfields SubstNonTypeTemplateParmExprBits;
 
     // C++ Coroutines TS expressions
     CoawaitExprBitfields CoawaitBits;
diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp
index 53eb5bcf38..edaaef0033 100644
--- a/lib/Serialization/ASTReaderStmt.cpp
+++ b/lib/Serialization/ASTReaderStmt.cpp
@@ -1719,7 +1719,7 @@ void ASTStmtReader::VisitExpressionTraitExpr(ExpressionTraitExpr *E) {
 
 void ASTStmtReader::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) {
   VisitExpr(E);
-  E->Value = (bool)Record.readInt();
+  E->CXXNoexceptExprBits.Value = Record.readInt();
   E->Range = ReadSourceRange();
   E->Operand = Record.readSubExpr();
 }
@@ -1753,7 +1753,7 @@ void ASTStmtReader::VisitSubstNonTypeTemplateParmExpr(
                                               SubstNonTypeTemplateParmExpr *E) {
   VisitExpr(E);
   E->Param = ReadDeclAs();
-  E->NameLoc = ReadSourceLocation();
+  E->SubstNonTypeTemplateParmExprBits.NameLoc = ReadSourceLocation();
   E->Replacement = Record.readSubExpr();
 }
 
-- 
cgit v1.2.3


From ce0c29eaa30c642bf27aa11aedf61d575193c197 Mon Sep 17 00:00:00 2001
From: Alexey Bataev 
Date: Tue, 8 Jan 2019 15:53:42 +0000
Subject: [OPENMP]Fix PR40191: Do not allow orphaned cancellation constructs.

Prohibited use of the orphaned cancellation directives.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350634 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/Sema/SemaOpenMP.cpp                     | 11 +++++---
 test/OpenMP/cancel_messages.cpp             | 40 ++++++++++++++---------------
 test/OpenMP/cancellation_point_messages.cpp | 40 ++++++++++++++---------------
 3 files changed, 47 insertions(+), 44 deletions(-)

diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp
index eac5f64e6e..140ccd15bb 100644
--- a/lib/Sema/SemaOpenMP.cpp
+++ b/lib/Sema/SemaOpenMP.cpp
@@ -3094,11 +3094,13 @@ static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
       }
       return false;
     }
-    // Allow some constructs (except teams) to be orphaned (they could be
-    // used in functions, called from OpenMP regions with the required
-    // preconditions).
+    // Allow some constructs (except teams and cancellation constructs) to be
+    // orphaned (they could be used in functions, called from OpenMP regions
+    // with the required preconditions).
     if (ParentRegion == OMPD_unknown &&
-        !isOpenMPNestingTeamsDirective(CurrentRegion))
+        !isOpenMPNestingTeamsDirective(CurrentRegion) &&
+        CurrentRegion != OMPD_cancellation_point &&
+        CurrentRegion != OMPD_cancel)
       return false;
     if (CurrentRegion == OMPD_cancellation_point ||
         CurrentRegion == OMPD_cancel) {
@@ -3127,6 +3129,7 @@ static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
             (CancelRegion == OMPD_sections &&
              (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
               ParentRegion == OMPD_parallel_sections)));
+      OrphanSeen = ParentRegion == OMPD_unknown;
     } else if (CurrentRegion == OMPD_master) {
       // OpenMP [2.16, Nesting of Regions]
       // A master region may not be closely nested inside a worksharing,
diff --git a/test/OpenMP/cancel_messages.cpp b/test/OpenMP/cancel_messages.cpp
index 28f22d17ea..b14c42f395 100644
--- a/test/OpenMP/cancel_messages.cpp
+++ b/test/OpenMP/cancel_messages.cpp
@@ -10,18 +10,18 @@ int main(int argc, char **argv) {
   {
 #pragma omp cancel // expected-error {{one of 'for', 'parallel', 'sections' or 'taskgroup' is expected}}
   }
-#pragma omp cancel parallel untied // expected-error {{unexpected OpenMP clause 'untied' in directive '#pragma omp cancel'}}
+#pragma omp cancel parallel untied // expected-error {{unexpected OpenMP clause 'untied' in directive '#pragma omp cancel'}} expected-error {{orphaned 'omp cancel' directives are prohibited; perhaps you forget to enclose the directive into a region?}}
 #pragma omp cancel unknown         // expected-error {{one of 'for', 'parallel', 'sections' or 'taskgroup' is expected}}
 #pragma omp parallel
   {
 #pragma omp cancel unknown         // expected-error {{one of 'for', 'parallel', 'sections' or 'taskgroup' is expected}}
   }
-#pragma omp cancel sections(       // expected-warning {{extra tokens at the end of '#pragma omp cancel' are ignored}}
-#pragma omp cancel for, )          // expected-warning {{extra tokens at the end of '#pragma omp cancel' are ignored}}
-#pragma omp cancel taskgroup()     // expected-warning {{extra tokens at the end of '#pragma omp cancel' are ignored}}
-#pragma omp cancel parallel, if    // expected-warning {{extra tokens at the end of '#pragma omp cancel' are ignored}}
+#pragma omp cancel sections(       // expected-warning {{extra tokens at the end of '#pragma omp cancel' are ignored}} expected-error {{orphaned 'omp cancel' directives are prohibited; perhaps you forget to enclose the directive into a region?}}
+#pragma omp cancel for, )          // expected-warning {{extra tokens at the end of '#pragma omp cancel' are ignored}} expected-error {{orphaned 'omp cancel' directives are prohibited; perhaps you forget to enclose the directive into a region?}}
+#pragma omp cancel taskgroup()     // expected-warning {{extra tokens at the end of '#pragma omp cancel' are ignored}} expected-error {{orphaned 'omp cancel' directives are prohibited; perhaps you forget to enclose the directive into a region?}}
+#pragma omp cancel parallel, if    // expected-warning {{extra tokens at the end of '#pragma omp cancel' are ignored}} expected-error {{orphaned 'omp cancel' directives are prohibited; perhaps you forget to enclose the directive into a region?}}
   if (argc)
-#pragma omp cancel for // expected-error {{'#pragma omp cancel' cannot be an immediate substatement}}
+#pragma omp cancel for // expected-error {{'#pragma omp cancel' cannot be an immediate substatement}} expected-error {{orphaned 'omp cancel' directives are prohibited; perhaps you forget to enclose the directive into a region?}}
     if (argc) {
 #pragma omp taskgroup
 #pragma omp task
@@ -48,44 +48,44 @@ int main(int argc, char **argv) {
 #pragma omp cancel parallel // expected-error {{region cannot be closely nested inside 'sections' region}}
   }
   while (argc)
-#pragma omp cancel for // expected-error {{'#pragma omp cancel' cannot be an immediate substatement}}
+#pragma omp cancel for // expected-error {{'#pragma omp cancel' cannot be an immediate substatement}} expected-error {{orphaned 'omp cancel' directives are prohibited; perhaps you forget to enclose the directive into a region?}}
     while (argc) {
-#pragma omp cancel sections
+#pragma omp cancel sections // expected-error {{orphaned 'omp cancel' directives are prohibited; perhaps you forget to enclose the directive into a region?}}
     }
   do
-#pragma omp cancel parallel // expected-error {{'#pragma omp cancel' cannot be an immediate substatement}}
+#pragma omp cancel parallel // expected-error {{'#pragma omp cancel' cannot be an immediate substatement}} expected-error {{orphaned 'omp cancel' directives are prohibited; perhaps you forget to enclose the directive into a region?}}
     while (argc)
       ;
   do {
-#pragma omp cancel taskgroup
+#pragma omp cancel taskgroup // expected-error {{orphaned 'omp cancel' directives are prohibited; perhaps you forget to enclose the directive into a region?}}
   } while (argc);
   switch (argc)
-#pragma omp cancel parallel // expected-error {{'#pragma omp cancel' cannot be an immediate substatement}}
+#pragma omp cancel parallel // expected-error {{'#pragma omp cancel' cannot be an immediate substatement}} expected-error {{orphaned 'omp cancel' directives are prohibited; perhaps you forget to enclose the directive into a region?}}
     switch (argc)
     case 1:
-#pragma omp cancel sections
+#pragma omp cancel sections // expected-error {{orphaned 'omp cancel' directives are prohibited; perhaps you forget to enclose the directive into a region?}}
   switch (argc)
   case 1: {
-#pragma omp cancel for
+#pragma omp cancel for // expected-error {{orphaned 'omp cancel' directives are prohibited; perhaps you forget to enclose the directive into a region?}}
   }
   switch (argc) {
-#pragma omp cancel taskgroup
+#pragma omp cancel taskgroup // expected-error {{orphaned 'omp cancel' directives are prohibited; perhaps you forget to enclose the directive into a region?}}
   case 1:
-#pragma omp cancel parallel
+#pragma omp cancel parallel // expected-error {{orphaned 'omp cancel' directives are prohibited; perhaps you forget to enclose the directive into a region?}}
     break;
   default: {
-#pragma omp cancel sections
+#pragma omp cancel sections // expected-error {{orphaned 'omp cancel' directives are prohibited; perhaps you forget to enclose the directive into a region?}}
   } break;
   }
   for (;;)
-#pragma omp cancel for // expected-error {{'#pragma omp cancel' cannot be an immediate substatement}}
+#pragma omp cancel for // expected-error {{'#pragma omp cancel' cannot be an immediate substatement}} expected-error {{orphaned 'omp cancel' directives are prohibited; perhaps you forget to enclose the directive into a region?}}
     for (;;) {
-#pragma omp cancel taskgroup
+#pragma omp cancel taskgroup // expected-error {{orphaned 'omp cancel' directives are prohibited; perhaps you forget to enclose the directive into a region?}}
     }
 label:
-#pragma omp cancel parallel // expected-error {{'#pragma omp cancel' cannot be an immediate substatement}}
+#pragma omp cancel parallel // expected-error {{'#pragma omp cancel' cannot be an immediate substatement}} expected-error {{orphaned 'omp cancel' directives are prohibited; perhaps you forget to enclose the directive into a region?}}
 label1 : {
-#pragma omp cancel sections
+#pragma omp cancel sections // expected-error {{orphaned 'omp cancel' directives are prohibited; perhaps you forget to enclose the directive into a region?}}
 }
 
   return 0;
diff --git a/test/OpenMP/cancellation_point_messages.cpp b/test/OpenMP/cancellation_point_messages.cpp
index 8bf5b3d55f..2bf667c407 100644
--- a/test/OpenMP/cancellation_point_messages.cpp
+++ b/test/OpenMP/cancellation_point_messages.cpp
@@ -10,18 +10,18 @@ int main(int argc, char **argv) {
   {
 #pragma omp cancellation point // expected-error {{one of 'for', 'parallel', 'sections' or 'taskgroup' is expected}}
   }
-#pragma omp cancellation point parallel untied // expected-error {{unexpected OpenMP clause 'untied' in directive '#pragma omp cancellation point'}}
+#pragma omp cancellation point parallel untied // expected-error {{unexpected OpenMP clause 'untied' in directive '#pragma omp cancellation point'}} expected-error {{orphaned 'omp cancellation point' directives are prohibited; perhaps you forget to enclose the directive into a region?}}
 #pragma omp cancellation point unknown         // expected-error {{one of 'for', 'parallel', 'sections' or 'taskgroup' is expected}}
 #pragma omp parallel
   {
 #pragma omp cancellation point unknown         // expected-error {{one of 'for', 'parallel', 'sections' or 'taskgroup' is expected}}
   }
-#pragma omp cancellation point sections(       // expected-warning {{extra tokens at the end of '#pragma omp cancellation point' are ignored}}
-#pragma omp cancellation point for, )          // expected-warning {{extra tokens at the end of '#pragma omp cancellation point' are ignored}}
-#pragma omp cancellation point taskgroup()     // expected-warning {{extra tokens at the end of '#pragma omp cancellation point' are ignored}}
-#pragma omp cancellation point parallel, if    // expected-warning {{extra tokens at the end of '#pragma omp cancellation point' are ignored}}
+#pragma omp cancellation point sections(       // expected-warning {{extra tokens at the end of '#pragma omp cancellation point' are ignored}} expected-error {{orphaned 'omp cancellation point' directives are prohibited; perhaps you forget to enclose the directive into a region?}}
+#pragma omp cancellation point for, )          // expected-warning {{extra tokens at the end of '#pragma omp cancellation point' are ignored}} expected-error {{orphaned 'omp cancellation point' directives are prohibited; perhaps you forget to enclose the directive into a region?}}
+#pragma omp cancellation point taskgroup()     // expected-warning {{extra tokens at the end of '#pragma omp cancellation point' are ignored}} expected-error {{orphaned 'omp cancellation point' directives are prohibited; perhaps you forget to enclose the directive into a region?}}
+#pragma omp cancellation point parallel, if    // expected-warning {{extra tokens at the end of '#pragma omp cancellation point' are ignored}} expected-error {{orphaned 'omp cancellation point' directives are prohibited; perhaps you forget to enclose the directive into a region?}}
   if (argc)
-#pragma omp cancellation point for // expected-error {{'#pragma omp cancellation point' cannot be an immediate substatement}}
+#pragma omp cancellation point for // expected-error {{'#pragma omp cancellation point' cannot be an immediate substatement}} expected-error {{orphaned 'omp cancellation point' directives are prohibited; perhaps you forget to enclose the directive into a region?}}
     if (argc) {
 #pragma omp taskgroup
 #pragma omp task
@@ -48,44 +48,44 @@ int main(int argc, char **argv) {
 #pragma omp cancellation point parallel // expected-error {{region cannot be closely nested inside 'sections' region}}
   }
   while (argc)
-#pragma omp cancellation point for // expected-error {{'#pragma omp cancellation point' cannot be an immediate substatement}}
+#pragma omp cancellation point for // expected-error {{'#pragma omp cancellation point' cannot be an immediate substatement}} expected-error {{orphaned 'omp cancellation point' directives are prohibited; perhaps you forget to enclose the directive into a region?}}
     while (argc) {
-#pragma omp cancellation point sections
+#pragma omp cancellation point sections // expected-error {{orphaned 'omp cancellation point' directives are prohibited; perhaps you forget to enclose the directive into a region?}}
     }
   do
-#pragma omp cancellation point parallel // expected-error {{'#pragma omp cancellation point' cannot be an immediate substatement}}
+#pragma omp cancellation point parallel // expected-error {{'#pragma omp cancellation point' cannot be an immediate substatement}} expected-error {{orphaned 'omp cancellation point' directives are prohibited; perhaps you forget to enclose the directive into a region?}}
     while (argc)
       ;
   do {
-#pragma omp cancellation point taskgroup
+#pragma omp cancellation point taskgroup // expected-error {{orphaned 'omp cancellation point' directives are prohibited; perhaps you forget to enclose the directive into a region?}}
   } while (argc);
   switch (argc)
-#pragma omp cancellation point parallel // expected-error {{'#pragma omp cancellation point' cannot be an immediate substatement}}
+#pragma omp cancellation point parallel // expected-error {{'#pragma omp cancellation point' cannot be an immediate substatement}} expected-error {{orphaned 'omp cancellation point' directives are prohibited; perhaps you forget to enclose the directive into a region?}}
     switch (argc)
     case 1:
-#pragma omp cancellation point sections
+#pragma omp cancellation point sections // expected-error {{orphaned 'omp cancellation point' directives are prohibited; perhaps you forget to enclose the directive into a region?}}
   switch (argc)
   case 1: {
-#pragma omp cancellation point for
+#pragma omp cancellation point for // expected-error {{orphaned 'omp cancellation point' directives are prohibited; perhaps you forget to enclose the directive into a region?}}
   }
   switch (argc) {
-#pragma omp cancellation point taskgroup
+#pragma omp cancellation point taskgroup // expected-error {{orphaned 'omp cancellation point' directives are prohibited; perhaps you forget to enclose the directive into a region?}}
   case 1:
-#pragma omp cancellation point parallel
+#pragma omp cancellation point parallel // expected-error {{orphaned 'omp cancellation point' directives are prohibited; perhaps you forget to enclose the directive into a region?}}
     break;
   default: {
-#pragma omp cancellation point sections
+#pragma omp cancellation point sections // expected-error {{orphaned 'omp cancellation point' directives are prohibited; perhaps you forget to enclose the directive into a region?}}
   } break;
   }
   for (;;)
-#pragma omp cancellation point for // expected-error {{'#pragma omp cancellation point' cannot be an immediate substatement}}
+#pragma omp cancellation point for // expected-error {{'#pragma omp cancellation point' cannot be an immediate substatement}} expected-error {{orphaned 'omp cancellation point' directives are prohibited; perhaps you forget to enclose the directive into a region?}}
     for (;;) {
-#pragma omp cancellation point taskgroup
+#pragma omp cancellation point taskgroup // expected-error {{orphaned 'omp cancellation point' directives are prohibited; perhaps you forget to enclose the directive into a region?}}
     }
 label:
-#pragma omp cancellation point parallel // expected-error {{'#pragma omp cancellation point' cannot be an immediate substatement}}
+#pragma omp cancellation point parallel // expected-error {{'#pragma omp cancellation point' cannot be an immediate substatement}} expected-error {{orphaned 'omp cancellation point' directives are prohibited; perhaps you forget to enclose the directive into a region?}}
 label1 : {
-#pragma omp cancellation point sections
+#pragma omp cancellation point sections // expected-error {{orphaned 'omp cancellation point' directives are prohibited; perhaps you forget to enclose the directive into a region?}}
 }
 
   return 0;
-- 
cgit v1.2.3


From e5791bbff62f63f2bd51e8f19f47fcf93e531b61 Mon Sep 17 00:00:00 2001
From: Bruno Ricci 
Date: Tue, 8 Jan 2019 16:08:54 +0000
Subject: [AST][NFC] Pack CXXScalarValueInitExpr

Use the newly available space in the bit-fields of Stmt.
This saves one pointer per CXXScalarValueInitExpr. NFC.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350635 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/AST/ExprCXX.h         | 17 ++++++++++-------
 include/clang/AST/Stmt.h            | 10 ++++++++++
 lib/AST/ExprCXX.cpp                 |  2 +-
 lib/Serialization/ASTReaderStmt.cpp |  2 +-
 4 files changed, 22 insertions(+), 9 deletions(-)

diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index 00e83eb723..15f2156418 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -1896,18 +1896,19 @@ public:
 class CXXScalarValueInitExpr : public Expr {
   friend class ASTStmtReader;
 
-  SourceLocation RParenLoc;
   TypeSourceInfo *TypeInfo;
 
 public:
   /// Create an explicitly-written scalar-value initialization
   /// expression.
   CXXScalarValueInitExpr(QualType Type, TypeSourceInfo *TypeInfo,
-                         SourceLocation rParenLoc)
-      : Expr(CXXScalarValueInitExprClass, Type, VK_RValue, OK_Ordinary,
-             false, false, Type->isInstantiationDependentType(),
+                         SourceLocation RParenLoc)
+      : Expr(CXXScalarValueInitExprClass, Type, VK_RValue, OK_Ordinary, false,
+             false, Type->isInstantiationDependentType(),
              Type->containsUnexpandedParameterPack()),
-        RParenLoc(rParenLoc), TypeInfo(TypeInfo) {}
+        TypeInfo(TypeInfo) {
+    CXXScalarValueInitExprBits.RParenLoc = RParenLoc;
+  }
 
   explicit CXXScalarValueInitExpr(EmptyShell Shell)
       : Expr(CXXScalarValueInitExprClass, Shell) {}
@@ -1916,10 +1917,12 @@ public:
     return TypeInfo;
   }
 
-  SourceLocation getRParenLoc() const { return RParenLoc; }
+  SourceLocation getRParenLoc() const {
+    return CXXScalarValueInitExprBits.RParenLoc;
+  }
 
   SourceLocation getBeginLoc() const LLVM_READONLY;
-  SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
+  SourceLocation getEndLoc() const { return getRParenLoc(); }
 
   static bool classof(const Stmt *T) {
     return T->getStmtClass() == CXXScalarValueInitExprClass;
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index e11e319703..162cfa52ed 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -612,6 +612,15 @@ protected:
     SourceLocation Loc;
   };
 
+  class CXXScalarValueInitExprBitfields {
+    friend class ASTStmtReader;
+    friend class CXXScalarValueInitExpr;
+
+    unsigned : NumExprBits;
+
+    SourceLocation RParenLoc;
+  };
+
   class CXXNewExprBitfields {
     friend class ASTStmtReader;
     friend class ASTStmtWriter;
@@ -859,6 +868,7 @@ protected:
     CXXThrowExprBitfields CXXThrowExprBits;
     CXXDefaultArgExprBitfields CXXDefaultArgExprBits;
     CXXDefaultInitExprBitfields CXXDefaultInitExprBits;
+    CXXScalarValueInitExprBitfields CXXScalarValueInitExprBits;
     CXXNewExprBitfields CXXNewExprBits;
     CXXDeleteExprBitfields CXXDeleteExprBits;
     TypeTraitExprBitfields TypeTraitExprBits;
diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp
index e336fddae0..9a724cd08e 100644
--- a/lib/AST/ExprCXX.cpp
+++ b/lib/AST/ExprCXX.cpp
@@ -90,7 +90,7 @@ QualType CXXUuidofExpr::getTypeOperand(ASTContext &Context) const {
 
 // CXXScalarValueInitExpr
 SourceLocation CXXScalarValueInitExpr::getBeginLoc() const {
-  return TypeInfo ? TypeInfo->getTypeLoc().getBeginLoc() : RParenLoc;
+  return TypeInfo ? TypeInfo->getTypeLoc().getBeginLoc() : getRParenLoc();
 }
 
 // CXXNewExpr
diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp
index edaaef0033..b4b2965f12 100644
--- a/lib/Serialization/ASTReaderStmt.cpp
+++ b/lib/Serialization/ASTReaderStmt.cpp
@@ -1502,7 +1502,7 @@ void ASTStmtReader::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
 void ASTStmtReader::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
   VisitExpr(E);
   E->TypeInfo = GetTypeSourceInfo();
-  E->RParenLoc = ReadSourceLocation();
+  E->CXXScalarValueInitExprBits.RParenLoc = ReadSourceLocation();
 }
 
 void ASTStmtReader::VisitCXXNewExpr(CXXNewExpr *E) {
-- 
cgit v1.2.3


From 24b21ed3f748f679552f56ffe65914d0108d4eca Mon Sep 17 00:00:00 2001
From: Paul Robinson 
Date: Tue, 8 Jan 2019 16:28:11 +0000
Subject: Don't emit DW_AT_enum_class unless it's actually an 'enum class'.

Finishes off the functional part of PR36168.

Differential Revision: https://reviews.llvm.org/D56393

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350636 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/CodeGen/CGDebugInfo.cpp               | 2 +-
 test/CodeGenCXX/debug-info-enum-class.cpp | 3 +++
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp
index f3a07a30eb..7ebbfbe2ff 100644
--- a/lib/CodeGen/CGDebugInfo.cpp
+++ b/lib/CodeGen/CGDebugInfo.cpp
@@ -2711,7 +2711,7 @@ llvm::DIType *CGDebugInfo::CreateTypeDefinition(const EnumType *Ty) {
   llvm::DIType *ClassTy = getOrCreateType(ED->getIntegerType(), DefUnit);
   return DBuilder.createEnumerationType(EnumContext, ED->getName(), DefUnit,
                                         Line, Size, Align, EltArray, ClassTy,
-                                        Identifier, ED->isFixed());
+                                        Identifier, ED->isScoped());
 }
 
 llvm::DIMacro *CGDebugInfo::CreateMacro(llvm::DIMacroFile *Parent,
diff --git a/test/CodeGenCXX/debug-info-enum-class.cpp b/test/CodeGenCXX/debug-info-enum-class.cpp
index e857bb1959..664fbb74a8 100644
--- a/test/CodeGenCXX/debug-info-enum-class.cpp
+++ b/test/CodeGenCXX/debug-info-enum-class.cpp
@@ -52,6 +52,7 @@ namespace test2 {
 // FIXME: this should just be a declaration under -fno-standalone-debug
 // CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "E"
 // CHECK-SAME:             scope: [[TEST2:![0-9]+]]
+// CHECK-NOT:              DIFlagFixedEnum
 // CHECK-SAME:             elements: [[TEST_ENUMS:![0-9]+]]
 // CHECK-SAME:             identifier: "_ZTSN5test21EE"
 // CHECK: [[TEST2]] = !DINamespace(name: "test2"
@@ -67,6 +68,7 @@ namespace test3 {
 // FIXME: this should just be a declaration under -fno-standalone-debug
 // CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "E"
 // CHECK-SAME:             scope: [[TEST3:![0-9]+]]
+// CHECK-NOT:              DIFlagFixedEnum
 // CHECK-SAME:             elements: [[TEST_ENUMS]]
 // CHECK-SAME:             identifier: "_ZTSN5test31EE"
 // CHECK: [[TEST3]] = !DINamespace(name: "test3"
@@ -78,6 +80,7 @@ void func(E *) {
 namespace test4 {
 // CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "E"
 // CHECK-SAME:             scope: [[TEST4:![0-9]+]]
+// CHECK-NOT:              DIFlagFixedEnum
 // CHECK-SAME:             elements: [[TEST_ENUMS]]
 // CHECK-SAME:             identifier: "_ZTSN5test41EE"
 // CHECK: [[TEST4]] = !DINamespace(name: "test4"
-- 
cgit v1.2.3


From 3957586ddbbd230dc6dcff6f187f11f013ab827d Mon Sep 17 00:00:00 2001
From: Alexander Kornienko 
Date: Tue, 8 Jan 2019 16:55:13 +0000
Subject: Fix use-after-free bug in Tooling.

Summary:
`buildASTFromCodeWithArgs()` was creating a memory buffer referencing a
stack-allocated string.  This diff changes the implementation to copy the code
string into the memory buffer so that said buffer owns the memory.

Patch by Yitzhak Mandelbaum.

Reviewers: alexfh

Reviewed By: alexfh

Subscribers: cfe-commits, EricWF

Differential Revision: https://reviews.llvm.org/D55765

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350638 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/Tooling/Tooling.h                 |  8 ++++----
 lib/Tooling/Tooling.cpp                         | 18 ++++++------------
 unittests/Analysis/ExprMutationAnalyzerTest.cpp |  5 ++++-
 3 files changed, 14 insertions(+), 17 deletions(-)

diff --git a/include/clang/Tooling/Tooling.h b/include/clang/Tooling/Tooling.h
index 358acf3e2d..662a980547 100644
--- a/include/clang/Tooling/Tooling.h
+++ b/include/clang/Tooling/Tooling.h
@@ -205,7 +205,7 @@ bool runToolOnCodeWithArgs(
 ///
 /// \return The resulting AST or null if an error occurred.
 std::unique_ptr
-buildASTFromCode(const Twine &Code, const Twine &FileName = "input.cc",
+buildASTFromCode(StringRef Code, StringRef FileName = "input.cc",
                  std::shared_ptr PCHContainerOps =
                      std::make_shared());
 
@@ -223,10 +223,10 @@ buildASTFromCode(const Twine &Code, const Twine &FileName = "input.cc",
 ///
 /// \return The resulting AST or null if an error occurred.
 std::unique_ptr buildASTFromCodeWithArgs(
-    const Twine &Code, const std::vector &Args,
-    const Twine &FileName = "input.cc", const Twine &ToolName = "clang-tool",
+    StringRef Code, const std::vector &Args,
+    StringRef FileName = "input.cc", StringRef ToolName = "clang-tool",
     std::shared_ptr PCHContainerOps =
-      std::make_shared(),
+        std::make_shared(),
     ArgumentsAdjuster Adjuster = getClangStripDependencyFileAdjuster());
 
 /// Utility to run a FrontendAction in a single clang invocation.
diff --git a/lib/Tooling/Tooling.cpp b/lib/Tooling/Tooling.cpp
index 84a4ac648c..63aa64a533 100644
--- a/lib/Tooling/Tooling.cpp
+++ b/lib/Tooling/Tooling.cpp
@@ -574,20 +574,16 @@ namespace clang {
 namespace tooling {
 
 std::unique_ptr
-buildASTFromCode(const Twine &Code, const Twine &FileName,
+buildASTFromCode(StringRef Code, StringRef FileName,
                  std::shared_ptr PCHContainerOps) {
   return buildASTFromCodeWithArgs(Code, std::vector(), FileName,
                                   "clang-tool", std::move(PCHContainerOps));
 }
 
 std::unique_ptr buildASTFromCodeWithArgs(
-    const Twine &Code, const std::vector &Args,
-    const Twine &FileName, const Twine &ToolName,
-    std::shared_ptr PCHContainerOps,
+    StringRef Code, const std::vector &Args, StringRef FileName,
+    StringRef ToolName, std::shared_ptr PCHContainerOps,
     ArgumentsAdjuster Adjuster) {
-  SmallString<16> FileNameStorage;
-  StringRef FileNameRef = FileName.toNullTerminatedStringRef(FileNameStorage);
-
   std::vector> ASTs;
   ASTBuilderAction Action(ASTs);
   llvm::IntrusiveRefCntPtr OverlayFileSystem(
@@ -599,13 +595,11 @@ std::unique_ptr buildASTFromCodeWithArgs(
       new FileManager(FileSystemOptions(), OverlayFileSystem));
 
   ToolInvocation Invocation(
-      getSyntaxOnlyToolArgs(ToolName, Adjuster(Args, FileNameRef), FileNameRef),
+      getSyntaxOnlyToolArgs(ToolName, Adjuster(Args, FileName), FileName),
       &Action, Files.get(), std::move(PCHContainerOps));
 
-  SmallString<1024> CodeStorage;
-  InMemoryFileSystem->addFile(FileNameRef, 0,
-                              llvm::MemoryBuffer::getMemBuffer(
-                                  Code.toNullTerminatedStringRef(CodeStorage)));
+  InMemoryFileSystem->addFile(FileName, 0,
+                              llvm::MemoryBuffer::getMemBufferCopy(Code));
   if (!Invocation.run())
     return nullptr;
 
diff --git a/unittests/Analysis/ExprMutationAnalyzerTest.cpp b/unittests/Analysis/ExprMutationAnalyzerTest.cpp
index 9c6bc783b3..68c921e439 100644
--- a/unittests/Analysis/ExprMutationAnalyzerTest.cpp
+++ b/unittests/Analysis/ExprMutationAnalyzerTest.cpp
@@ -11,6 +11,7 @@
 #include "clang/ASTMatchers/ASTMatchFinder.h"
 #include "clang/ASTMatchers/ASTMatchers.h"
 #include "clang/Tooling/Tooling.h"
+#include "llvm/ADT/SmallString.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 #include 
@@ -32,7 +33,9 @@ using StmtMatcher = internal::Matcher;
 std::unique_ptr
 buildASTFromCodeWithArgs(const Twine &Code,
                          const std::vector &Args) {
-  auto AST = tooling::buildASTFromCodeWithArgs(Code, Args);
+  SmallString<1024> CodeStorage;
+  auto AST =
+      tooling::buildASTFromCodeWithArgs(Code.toStringRef(CodeStorage), Args);
   EXPECT_FALSE(AST->getDiagnostics().hasErrorOccurred());
   return AST;
 }
-- 
cgit v1.2.3


From 6dfb50adbbc259befb4c03b4559df7c52562c4db Mon Sep 17 00:00:00 2001
From: Erik Pilkington 
Date: Tue, 8 Jan 2019 17:04:38 +0000
Subject: Revert "Split -Wdelete-non-virtual-dtor into
 -Wdelete-abstract-non-virtual-dtor"

This reverts commit r350585. There was some late post-commit review
on phab.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350639 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/Basic/DiagnosticGroups.td    |  2 --
 include/clang/Basic/DiagnosticSemaKinds.td |  2 +-
 test/SemaCXX/non-virtual-dtors.cpp         | 32 ------------------------------
 3 files changed, 1 insertion(+), 35 deletions(-)
 delete mode 100644 test/SemaCXX/non-virtual-dtors.cpp

diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td
index 52bd87d79a..6ba6c19a28 100644
--- a/include/clang/Basic/DiagnosticGroups.td
+++ b/include/clang/Basic/DiagnosticGroups.td
@@ -105,8 +105,6 @@ def MissingNoEscape : DiagGroup<"missing-noescape">;
 
 def DeleteIncomplete : DiagGroup<"delete-incomplete">;
 def DeleteNonVirtualDtor : DiagGroup<"delete-non-virtual-dtor">;
-def DeleteAbstractNonVirtualDtor : DiagGroup<"delete-abstract-non-virtual-dtor",
-                                             [DeleteNonVirtualDtor]>;
 def AbstractFinalClass : DiagGroup<"abstract-final-class">;
 
 def CXX11CompatDeprecatedWritableStr :
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index d6c5ccffd8..c54fbc8b4c 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -6460,7 +6460,7 @@ def note_delete_non_virtual : Note<
   "qualify call to silence this warning">;
 def warn_delete_abstract_non_virtual_dtor : Warning<
   "%select{delete|destructor}0 called on %1 that is abstract but has "
-  "non-virtual destructor">, InGroup, ShowInSystemHeader;
+  "non-virtual destructor">, InGroup, ShowInSystemHeader;
 def warn_overloaded_virtual : Warning<
   "%q0 hides overloaded virtual %select{function|functions}1">,
   InGroup, DefaultIgnore;
diff --git a/test/SemaCXX/non-virtual-dtors.cpp b/test/SemaCXX/non-virtual-dtors.cpp
deleted file mode 100644
index 230b899a7f..0000000000
--- a/test/SemaCXX/non-virtual-dtors.cpp
+++ /dev/null
@@ -1,32 +0,0 @@
-// RUN: %clang_cc1 %s -verify -DDIAG1
-// RUN: %clang_cc1 %s -verify -DDIAG1 -DDIAG2 -Wdelete-non-virtual-dtor
-// RUN: %clang_cc1 %s -verify -DDIAG1         -Wmost -Wno-delete-non-virtual-dtor
-// RUN: %clang_cc1 %s -verify                 -Wmost -Wno-delete-abstract-non-virtual-dtor
-
-#ifndef DIAG1
-#ifndef DIAG2
-// expected-no-diagnostics
-#endif
-#endif
-
-struct S1 {
-  ~S1() {}
-  virtual void abs() = 0;
-};
-
-void f1(S1 *s1) { delete s1; }
-#ifdef DIAG1
-// expected-warning@-2 {{delete called on 'S1' that is abstract but has non-virtual destructor}}
-#endif
-
-struct Base {
-  virtual void abs() = 0;
-};
-struct S2 : Base {
-  ~S2() {}
-  void abs() {}
-};
-void f2(S2 *s2) { delete s2; }
-#ifdef DIAG2
-// expected-warning@-2 {{delete called on non-final 'S2' that has virtual functions but non-virtual destructor}}
-#endif
-- 
cgit v1.2.3


From 2444c788c494a66f7183cad8dfa6208352a2f46c Mon Sep 17 00:00:00 2001
From: Paul Robinson 
Date: Tue, 8 Jan 2019 17:52:29 +0000
Subject: Rename DIFlagFixedEnum to DIFlagEnumClass. NFC

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350641 91177308-0d34-0410-b5e6-96231b3b80d8
---
 test/CodeGen/debug-info-enum.cpp          | 18 +++++++++---------
 test/CodeGenCXX/debug-info-enum-class.cpp | 10 +++++-----
 2 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/test/CodeGen/debug-info-enum.cpp b/test/CodeGen/debug-info-enum.cpp
index 1237f28b9a..bbe66bb9fa 100644
--- a/test/CodeGen/debug-info-enum.cpp
+++ b/test/CodeGen/debug-info-enum.cpp
@@ -12,7 +12,7 @@ enum class E0 : signed char {
 } x0;
 // CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "E0"
 // CHECK-SAME: baseType: ![[SCHAR:[0-9]+]]
-// CHECK-SAME: DIFlagFixedEnum
+// CHECK-SAME: DIFlagEnumClass
 // CHECK-SAME: elements: ![[ELTS0:[0-9]+]]
 // CHECK: ![[SCHAR]] = !DIBasicType(name: "signed char", size: 8, encoding: DW_ATE_signed_char)
 // CHECK: ![[ELTS0]] = !{![[A0:[0-9]+]], ![[B0:[0-9]+]]}
@@ -22,7 +22,7 @@ enum class E0 : signed char {
 enum class E1 : unsigned char { A1 = 255 } x1;
 // CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "E1"
 // CHECK-SAME: baseType: ![[UCHAR:[0-9]+]]
-// CHECK-SAME: DIFlagFixedEnum
+// CHECK-SAME: DIFlagEnumClass
 // CHECK-SAME: elements: ![[ELTS1:[0-9]+]]
 // CHECK: ![[UCHAR]] = !DIBasicType(name: "unsigned char", size: 8, encoding: DW_ATE_unsigned_char)
 // CHECK: ![[ELTS1]] = !{![[A1:[0-9]+]]}
@@ -34,7 +34,7 @@ enum class E2 : signed short {
 } x2;
 // CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "E2"
 // CHECK-SAME: baseType: ![[SHORT:[0-9]+]]
-// CHECK-SAME: DIFlagFixedEnum
+// CHECK-SAME: DIFlagEnumClass
 // CHECK-SAME: elements: ![[ELTS2:[0-9]+]]
 // CHECK: ![[SHORT]] = !DIBasicType(name: "short", size: 16, encoding: DW_ATE_signed)
 // CHECK: ![[ELTS2]] = !{![[A2:[0-9]+]], ![[B2:[0-9]+]]}
@@ -44,7 +44,7 @@ enum class E2 : signed short {
 enum class E3 : unsigned short { A3 = 65535 } x3;
 // CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "E3"
 // CHECK-SAME: baseType: ![[USHORT:[0-9]+]]
-// CHECK-SAME: DIFlagFixedEnum
+// CHECK-SAME: DIFlagEnumClass
 // CHECK-SAME: elements: ![[ELTS3:[0-9]+]]
 // CHECK: ![[USHORT]] = !DIBasicType(name: "unsigned short", size: 16, encoding: DW_ATE_unsigned)
 // CHECK: ![[ELTS3]] = !{![[A3:[0-9]+]]}
@@ -53,7 +53,7 @@ enum class E3 : unsigned short { A3 = 65535 } x3;
 enum class E4 : signed int { A4 = -2147483648, B4 = 2147483647 } x4;
 // CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "E4"
 // CHECK-SAME: baseType: ![[INT:[0-9]+]]
-// CHECK-SAME: DIFlagFixedEnum
+// CHECK-SAME: DIFlagEnumClass
 // CHECK-SAME: elements: ![[ELTS4:[0-9]+]]
 // CHECK: ![[INT]] = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
 // CHECK: ![[ELTS4]] = !{![[A4:[0-9]+]], ![[B4:[0-9]+]]}
@@ -63,7 +63,7 @@ enum class E4 : signed int { A4 = -2147483648, B4 = 2147483647 } x4;
 enum class E5 : unsigned int { A5 = 4294967295 } x5;
 // CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "E5"
 // CHECK-SAME: baseType: ![[UINT:[0-9]+]]
-// CHECK-SAME: DIFlagFixedEnum
+// CHECK-SAME: DIFlagEnumClass
 // CHECK-SAME: elements: ![[ELTS5:[0-9]+]]
 // CHECK: ![[UINT]] = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned)
 // CHECK: ![[ELTS5]] = !{![[A5:[0-9]+]]}
@@ -75,7 +75,7 @@ enum class E6 : signed long long {
 } x6;
 // CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "E6"
 // CHECK-SAME: baseType: ![[LONG:[0-9]+]]
-// CHECK-SAME: DIFlagFixedEnum
+// CHECK-SAME: DIFlagEnumClass
 // CHECK-SAME: elements: ![[ELTS6:[0-9]+]]
 // CHECK: ![[LONG]] = !DIBasicType(name: "long long int", size: 64, encoding: DW_ATE_signed)
 // CHECK: ![[ELTS6]] = !{![[A6:[0-9]+]], ![[B6:[0-9]+]]}
@@ -85,7 +85,7 @@ enum class E6 : signed long long {
 enum class E7 : unsigned long long { A7 = 18446744073709551615ULL } x7;
 // CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "E7"
 // CHECK-SAME: baseType: ![[ULONG:[0-9]+]]
-// CHECK-SAME: DIFlagFixedEnum
+// CHECK-SAME: DIFlagEnumClass
 // CHECK-SAME: elements: ![[ELTS7:[0-9]+]]
 // CHECK: ![[ULONG]] = !DIBasicType(name: "long long unsigned int", size: 64, encoding: DW_ATE_unsigned)
 // CHECK: ![[ELTS7]] = !{![[A7:[0-9]+]]}
@@ -95,6 +95,6 @@ enum class E7 : unsigned long long { A7 = 18446744073709551615ULL } x7;
 enum E8 { A8 = -128, B8 = 127 } x8;
 // CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "E8"
 // CHECK-SAME: baseType: ![[INT]]
-// CHECK-NOT: DIFlagFixedEnum
+// CHECK-NOT: DIFlagEnumClass
 // CHECK: !DIEnumerator(name: "A8", value: -128)
 
diff --git a/test/CodeGenCXX/debug-info-enum-class.cpp b/test/CodeGenCXX/debug-info-enum-class.cpp
index 664fbb74a8..3664c67bf3 100644
--- a/test/CodeGenCXX/debug-info-enum-class.cpp
+++ b/test/CodeGenCXX/debug-info-enum-class.cpp
@@ -15,7 +15,7 @@ D d;
 // CHECK-SAME:             baseType: ![[INT:[0-9]+]]
 // CHECK-SAME:             size: 32
 // CHECK-NOT:              offset:
-// CHECK-SAME:             flags: DIFlagFixedEnum
+// CHECK-SAME:             flags: DIFlagEnumClass
 // CHECK-SAME:             ){{$}}
 // CHECK: ![[INT]] = !DIBasicType(name: "int"
 // CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "B"
@@ -23,7 +23,7 @@ D d;
 // CHECK-SAME:             baseType: ![[ULONG:[0-9]+]]
 // CHECK-SAME:             size: 64
 // CHECK-NOT:              offset:
-// CHECK-SAME:             flags: DIFlagFixedEnum
+// CHECK-SAME:             flags: DIFlagEnumClass
 // CHECK-SAME:             ){{$}}
 // CHECK: ![[ULONG]] = !DIBasicType(name: "long unsigned int"
 // CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "C"
@@ -52,7 +52,7 @@ namespace test2 {
 // FIXME: this should just be a declaration under -fno-standalone-debug
 // CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "E"
 // CHECK-SAME:             scope: [[TEST2:![0-9]+]]
-// CHECK-NOT:              DIFlagFixedEnum
+// CHECK-NOT:              DIFlagEnumClass
 // CHECK-SAME:             elements: [[TEST_ENUMS:![0-9]+]]
 // CHECK-SAME:             identifier: "_ZTSN5test21EE"
 // CHECK: [[TEST2]] = !DINamespace(name: "test2"
@@ -68,7 +68,7 @@ namespace test3 {
 // FIXME: this should just be a declaration under -fno-standalone-debug
 // CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "E"
 // CHECK-SAME:             scope: [[TEST3:![0-9]+]]
-// CHECK-NOT:              DIFlagFixedEnum
+// CHECK-NOT:              DIFlagEnumClass
 // CHECK-SAME:             elements: [[TEST_ENUMS]]
 // CHECK-SAME:             identifier: "_ZTSN5test31EE"
 // CHECK: [[TEST3]] = !DINamespace(name: "test3"
@@ -80,7 +80,7 @@ void func(E *) {
 namespace test4 {
 // CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "E"
 // CHECK-SAME:             scope: [[TEST4:![0-9]+]]
-// CHECK-NOT:              DIFlagFixedEnum
+// CHECK-NOT:              DIFlagEnumClass
 // CHECK-SAME:             elements: [[TEST_ENUMS]]
 // CHECK-SAME:             identifier: "_ZTSN5test41EE"
 // CHECK: [[TEST4]] = !DINamespace(name: "test4"
-- 
cgit v1.2.3


From bb0807fa5dfc699fa26e4c7d40c42dfe513f0aa0 Mon Sep 17 00:00:00 2001
From: Erik Pilkington 
Date: Tue, 8 Jan 2019 18:24:39 +0000
Subject: __has_feature(pragma_clang_attribute_namespaces) should be
 __has_extension

Thanks to Richard Smith for pointing this out.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350642 91177308-0d34-0410-b5e6-96231b3b80d8
---
 docs/LanguageExtensions.rst            | 2 +-
 include/clang/Basic/Features.def       | 8 +++++++-
 test/Sema/pragma-attribute-namespace.c | 2 +-
 3 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/docs/LanguageExtensions.rst b/docs/LanguageExtensions.rst
index 574bb77345..e155cefb78 100644
--- a/docs/LanguageExtensions.rst
+++ b/docs/LanguageExtensions.rst
@@ -2727,7 +2727,7 @@ Without the namespaces on the macros, ``other_function`` will be annotated with
 a contrived example, but its very possible for this kind of situation to appear
 in real code if the pragmas are spread out across a large file. You can test if
 your version of clang supports namespaces on ``#pragma clang attribute`` with
-``__has_feature(pragma_clang_attribute_namespaces)``.
+``__has_extension(pragma_clang_attribute_namespaces)``.
 
 Subject Match Rules
 -------------------
diff --git a/include/clang/Basic/Features.def b/include/clang/Basic/Features.def
index e3b97fd078..05464ed85f 100644
--- a/include/clang/Basic/Features.def
+++ b/include/clang/Basic/Features.def
@@ -17,6 +17,12 @@
 //
 // The Predicate field dictates the conditions under which the feature or
 // extension will be made available.
+//
+// FEATURE(...) should be used to advertise support for standard language
+// features, whereas EXTENSION(...) should be used for clang extensions. Note
+// that many of the identifiers in this file don't follow this rule for backward
+// compatibility reasons.
+//
 //===----------------------------------------------------------------------===//
 
 #if !defined(FEATURE) && !defined(EXTENSION)
@@ -69,7 +75,6 @@ FEATURE(attribute_overloadable, true)
 FEATURE(attribute_unavailable_with_message, true)
 FEATURE(attribute_unused_on_fields, true)
 FEATURE(attribute_diagnose_if_objc, true)
-FEATURE(pragma_clang_attribute_namespaces, true)
 FEATURE(blocks, LangOpts.Blocks)
 FEATURE(c_thread_safety_attributes, true)
 FEATURE(cxx_exceptions, LangOpts.CXXExceptions)
@@ -241,6 +246,7 @@ EXTENSION(cxx_init_captures, LangOpts.CPlusPlus11)
 EXTENSION(cxx_variable_templates, LangOpts.CPlusPlus)
 // Miscellaneous language extensions
 EXTENSION(overloadable_unmarked, true)
+EXTENSION(pragma_clang_attribute_namespaces, true)
 
 #undef EXTENSION
 #undef FEATURE
diff --git a/test/Sema/pragma-attribute-namespace.c b/test/Sema/pragma-attribute-namespace.c
index 2db788865b..e7a36afcdc 100644
--- a/test/Sema/pragma-attribute-namespace.c
+++ b/test/Sema/pragma-attribute-namespace.c
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
 
-#if !__has_feature(pragma_clang_attribute_namespaces)
+#if !__has_extension(pragma_clang_attribute_namespaces)
 #error
 #endif
 
-- 
cgit v1.2.3


From 92f4b5cbeee88f31a8df876f73b823db284f68de Mon Sep 17 00:00:00 2001
From: Erich Keane 
Date: Tue, 8 Jan 2019 18:44:22 +0000
Subject: Limit COFF 'common' emission to <=32 alignment types.

As reported in PR33035, LLVM crashes if given a common object with an
alignment of greater than 32 bits. This is because the COFF file format
does not support these alignments, so emitting them is broken anyway.

This patch changes any global definitions greater than 32 bit alignment
to no longer be in 'common'.

https://bugs.llvm.org/show_bug.cgi?id=33035

Differential Revision: https://reviews.llvm.org/D56391

Change-Id: I48609289753b7f3b58c5e2bc1712756750fbd45a

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350643 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/CodeGen/CodeGenModule.cpp            | 5 +++++
 test/CodeGen/microsoft-no-common-align.c | 8 ++++++++
 2 files changed, 13 insertions(+)
 create mode 100644 test/CodeGen/microsoft-no-common-align.c

diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index 54190493f0..ab0ac67d8e 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -3761,6 +3761,11 @@ static bool isVarDeclStrongDefinition(const ASTContext &Context,
       }
     }
   }
+  // COFF doesn't support alignments greater than 32, so these cannot be
+  // in common.
+  if (Context.getTargetInfo().getTriple().isKnownWindowsMSVCEnvironment() &&
+      Context.getTypeAlignIfKnown(D->getType()) > 32)
+    return true;
 
   return false;
 }
diff --git a/test/CodeGen/microsoft-no-common-align.c b/test/CodeGen/microsoft-no-common-align.c
new file mode 100644
index 0000000000..fc46946c00
--- /dev/null
+++ b/test/CodeGen/microsoft-no-common-align.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -emit-llvm -o - %s | FileCheck %s
+typedef float TooLargeAlignment __attribute__((__vector_size__(64)));
+typedef float NormalAlignment __attribute__((__vector_size__(4)));
+
+TooLargeAlignment TooBig;
+// CHECK: @TooBig = dso_local global <16 x float>  zeroinitializer, align 64
+NormalAlignment JustRight;
+// CHECK: @JustRight = common dso_local global <1 x float>  zeroinitializer, align 4
-- 
cgit v1.2.3


From 509536157bf1e1feb1098ace99260d61035dee64 Mon Sep 17 00:00:00 2001
From: JF Bastien 
Date: Tue, 8 Jan 2019 18:51:38 +0000
Subject: [NFC] Don't over-eagerly check block alignment

Alignment of __block isn't relevant to this test, remove its checking.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350644 91177308-0d34-0410-b5e6-96231b3b80d8
---
 test/CodeGenCXX/trivial-auto-var-init.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/test/CodeGenCXX/trivial-auto-var-init.cpp b/test/CodeGenCXX/trivial-auto-var-init.cpp
index 8b35fdb441..b795c0755b 100644
--- a/test/CodeGenCXX/trivial-auto-var-init.cpp
+++ b/test/CodeGenCXX/trivial-auto-var-init.cpp
@@ -22,9 +22,9 @@ void test_selfinit() {
 
 // UNINIT-LABEL:  test_block(
 // ZERO-LABEL:    test_block(
-// ZERO: store i32 0, i32* %block, align 4
+// ZERO: store i32 0, i32* %block
 // PATTERN-LABEL: test_block(
-// PATTERN: store i32 -1431655766, i32* %block, align 4
+// PATTERN: store i32 -1431655766, i32* %block
 void test_block() {
   __block int block;
   used(block);
-- 
cgit v1.2.3


From 8f09d50c0d3680cf9261c21d079f5aab62e50dd1 Mon Sep 17 00:00:00 2001
From: Erich Keane 
Date: Tue, 8 Jan 2019 19:10:43 +0000
Subject: Fix opencl test broken on windows by r350643.

Windows doesn't allow common with alignment >32 bits, so these tests
were broken in windows mode.  This patch makes 'common' optional in
these cases.

Change-Id: I4d5fdd07ecdafc3570ef9b09cd816c2e5e4ed15e

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350645 91177308-0d34-0410-b5e6-96231b3b80d8
---
 test/CodeGenOpenCL/address-spaces.cl | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/test/CodeGenOpenCL/address-spaces.cl b/test/CodeGenOpenCL/address-spaces.cl
index 60f5e30d32..3c8fea2a80 100644
--- a/test/CodeGenOpenCL/address-spaces.cl
+++ b/test/CodeGenOpenCL/address-spaces.cl
@@ -19,7 +19,7 @@ struct S {
 // CL20-DAG: @g_static_var = internal addrspace(1) global float 0.000000e+00
 
 #ifdef CL20
-// CL20-DAG: @g_s = common {{(dso_local )?}}addrspace(1) global %struct.S zeroinitializer
+// CL20-DAG: @g_s = {{(common )?}}{{(dso_local )?}}addrspace(1) global %struct.S zeroinitializer
 struct S g_s;
 #endif
 
@@ -55,7 +55,7 @@ void fc(constant int *arg) {}
 int i;
 // CL20-DAG: @i = common {{(dso_local )?}}addrspace(1) global i32 0
 int *ptr;
-// CL20SPIR-DAG: @ptr = common {{(dso_local )?}}addrspace(1) global i32 addrspace(4)* null
+// CL20SPIR-DAG: @ptr = {{(common )?}}{{(dso_local )?}}addrspace(1) global i32 addrspace(4)* null
 // CL20AMDGCN-DAG: @ptr = common {{(dso_local )?}}addrspace(1) global i32* null
 #endif
 
-- 
cgit v1.2.3


From 3b7841f9358527f31acc805a7f9565350cd62afd Mon Sep 17 00:00:00 2001
From: Philip Pfaffe 
Date: Tue, 8 Jan 2019 20:00:55 +0000
Subject: Fix clang for r350647: Missed a function rename

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350648 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/CodeGen/BackendUtil.cpp | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/lib/CodeGen/BackendUtil.cpp b/lib/CodeGen/BackendUtil.cpp
index 1311af9168..828ff2e66e 100644
--- a/lib/CodeGen/BackendUtil.cpp
+++ b/lib/CodeGen/BackendUtil.cpp
@@ -53,9 +53,10 @@
 #include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h"
 #include "llvm/Transforms/InstCombine/InstCombine.h"
 #include "llvm/Transforms/Instrumentation.h"
-#include "llvm/Transforms/Instrumentation/MemorySanitizer.h"
 #include "llvm/Transforms/Instrumentation/BoundsChecking.h"
 #include "llvm/Transforms/Instrumentation/GCOVProfiler.h"
+#include "llvm/Transforms/Instrumentation/MemorySanitizer.h"
+#include "llvm/Transforms/Instrumentation/ThreadSanitizer.h"
 #include "llvm/Transforms/ObjCARC.h"
 #include "llvm/Transforms/Scalar.h"
 #include "llvm/Transforms/Scalar/GVN.h"
@@ -305,7 +306,7 @@ static void addKernelMemorySanitizerPass(const PassManagerBuilder &Builder,
 
 static void addThreadSanitizerPass(const PassManagerBuilder &Builder,
                                    legacy::PassManagerBase &PM) {
-  PM.add(createThreadSanitizerPass());
+  PM.add(createThreadSanitizerLegacyPassPass());
 }
 
 static void addDataFlowSanitizerPass(const PassManagerBuilder &Builder,
-- 
cgit v1.2.3


From db6158cc4b9ec43fc9a6c46a65461f1a4338a999 Mon Sep 17 00:00:00 2001
From: Louis Dionne 
Date: Tue, 8 Jan 2019 20:26:56 +0000
Subject: [Sema] Teach Clang that aligned allocation is not supported with
 macosx10.13

Summary:
r306722 added diagnostics when aligned allocation is used with deployment
targets that do not support it, but the first macosx supporting aligned
allocation was incorrectly set to 10.13. In reality, the dylib shipped
with macosx10.13 does not support aligned allocation, but the dylib
shipped with macosx10.14 does.

Reviewers: ahatanak

Subscribers: christof, jkorous, dexonsmith, cfe-commits

Differential Revision: https://reviews.llvm.org/D56445

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350649 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/Basic/AlignedAllocation.h         |  4 ++--
 test/Driver/unavailable_aligned_allocation.cpp  |  8 ++++----
 test/SemaCXX/unavailable_aligned_allocation.cpp | 12 ++++++------
 3 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/include/clang/Basic/AlignedAllocation.h b/include/clang/Basic/AlignedAllocation.h
index 9751f41184..c995f47a7d 100644
--- a/include/clang/Basic/AlignedAllocation.h
+++ b/include/clang/Basic/AlignedAllocation.h
@@ -27,8 +27,8 @@ inline llvm::VersionTuple alignedAllocMinVersion(llvm::Triple::OSType OS) {
   default:
     break;
   case llvm::Triple::Darwin:
-  case llvm::Triple::MacOSX: // Earliest supporting version is 10.13.
-    return llvm::VersionTuple(10U, 13U);
+  case llvm::Triple::MacOSX: // Earliest supporting version is 10.14.
+    return llvm::VersionTuple(10U, 14U);
   case llvm::Triple::IOS:
   case llvm::Triple::TvOS: // Earliest supporting version is 11.0.0.
     return llvm::VersionTuple(11U);
diff --git a/test/Driver/unavailable_aligned_allocation.cpp b/test/Driver/unavailable_aligned_allocation.cpp
index 508202de9f..131bc116be 100644
--- a/test/Driver/unavailable_aligned_allocation.cpp
+++ b/test/Driver/unavailable_aligned_allocation.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang -target x86_64-apple-macosx10.12 -c -### %s 2>&1 \
+// RUN: %clang -target x86_64-apple-macosx10.13 -c -### %s 2>&1 \
 // RUN:   | FileCheck %s -check-prefix=UNAVAILABLE
 //
 // RUN: %clang -target arm64-apple-ios10 -c -### %s 2>&1 \
@@ -24,7 +24,7 @@
 //
 // UNAVAILABLE: "-faligned-alloc-unavailable"
 
-// RUN: %clang -target x86_64-apple-macosx10.13 -c -### %s 2>&1 \
+// RUN: %clang -target x86_64-apple-macosx10.14 -c -### %s 2>&1 \
 // RUN:   | FileCheck %s -check-prefix=AVAILABLE
 //
 // RUN: %clang -target arm64-apple-ios11 -c -### %s 2>&1 \
@@ -54,10 +54,10 @@
 // Check that passing -faligned-allocation or -fno-aligned-allocation stops the
 // driver from passing -faligned-alloc-unavailable to cc1.
 //
-// RUN: %clang -target x86_64-apple-macosx10.12 -faligned-allocation -c -### %s 2>&1 \
+// RUN: %clang -target x86_64-apple-macosx10.13 -faligned-allocation -c -### %s 2>&1 \
 // RUN:   | FileCheck %s -check-prefix=AVAILABLE
 //
-// RUN: %clang -target x86_64-apple-macosx10.12 -fno-aligned-allocation -c -### %s 2>&1 \
+// RUN: %clang -target x86_64-apple-macosx10.13 -fno-aligned-allocation -c -### %s 2>&1 \
 // RUN:   | FileCheck %s -check-prefix=AVAILABLE
 
 // AVAILABLE-NOT: "-faligned-alloc-unavailable"
diff --git a/test/SemaCXX/unavailable_aligned_allocation.cpp b/test/SemaCXX/unavailable_aligned_allocation.cpp
index 3c746c38c6..2f0f8fe7a4 100644
--- a/test/SemaCXX/unavailable_aligned_allocation.cpp
+++ b/test/SemaCXX/unavailable_aligned_allocation.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -triple x86_64-apple-macosx10.12.0 -fexceptions -faligned-alloc-unavailable -std=c++1z -verify %s
-// RUN: %clang_cc1 -triple x86_64-apple-macosx10.12.0 -fexceptions -std=c++1z -verify -DNO_ERRORS %s
-// RUN: %clang_cc1 -triple x86_64-apple-macosx10.12.0 -fexceptions -faligned-allocation -faligned-alloc-unavailable -std=c++14 -verify %s
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.13.0 -fexceptions -faligned-alloc-unavailable -std=c++1z -verify %s
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.13.0 -fexceptions -std=c++1z -verify -DNO_ERRORS %s
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.13.0 -fexceptions -faligned-allocation -faligned-alloc-unavailable -std=c++14 -verify %s
 // RUN: %clang_cc1 -triple arm64-apple-ios10.0.0 -fexceptions -faligned-alloc-unavailable -std=c++1z -verify -DIOS %s
 // RUN: %clang_cc1 -triple arm64-apple-ios10.0.0 -fexceptions -std=c++1z -verify -DNO_ERRORS %s
 // RUN: %clang_cc1 -triple arm64-apple-tvos10.0.0 -fexceptions -faligned-alloc-unavailable -std=c++1z -verify -DTVOS %s
@@ -117,8 +117,8 @@ void testOveralignedCheckOS() {
 // expected-error@-13 {{aligned allocation function of type 'void *(unsigned long, enum std::align_val_t)' is only available on watchOS 4 or newer}}}
 // expected-error@-14 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on watchOS 4 or newer}}}
 #else
-// expected-error@-16 {{aligned allocation function of type 'void *(unsigned long, enum std::align_val_t)' is only available on macOS 10.13 or newer}}}
-// expected-error@-17 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on macOS 10.13 or newer}}}
+// expected-error@-16 {{aligned allocation function of type 'void *(unsigned long, enum std::align_val_t)' is only available on macOS 10.14 or newer}}}
+// expected-error@-17 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on macOS 10.14 or newer}}}
 #endif
 
 // expected-note@-20 2 {{if you supply your own aligned allocation functions}}
@@ -146,7 +146,7 @@ OveralignedS2::~OveralignedS2() {}
 // expected-error@-12 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on watchOS 4 or newer}}}
 // expected-note@-13 {{if you supply your own aligned allocation functions}}
 #else
-// expected-error@-15 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on macOS 10.13 or newer}}}
+// expected-error@-15 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on macOS 10.14 or newer}}}
 // expected-note@-16 {{if you supply your own aligned allocation functions}}
 #endif
 #endif
-- 
cgit v1.2.3


From 72d635358db729a936c80b9be7316faac848d36c Mon Sep 17 00:00:00 2001
From: Dan Albert 
Date: Tue, 8 Jan 2019 22:31:19 +0000
Subject: Android is not GNU, so don't claim that it is.

Reviewers: pirama, srhines

Reviewed By: srhines

Subscribers: kristina, cfe-commits

Differential Revision: https://reviews.llvm.org/D55953

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350664 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/Basic/Targets/OSTargets.h | 3 ++-
 test/Preprocessor/init.c      | 2 ++
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/lib/Basic/Targets/OSTargets.h b/lib/Basic/Targets/OSTargets.h
index 42ce89669f..085efa02cc 100644
--- a/lib/Basic/Targets/OSTargets.h
+++ b/lib/Basic/Targets/OSTargets.h
@@ -345,7 +345,6 @@ protected:
     // Linux defines; list based off of gcc output
     DefineStd(Builder, "unix", Opts);
     DefineStd(Builder, "linux", Opts);
-    Builder.defineMacro("__gnu_linux__");
     Builder.defineMacro("__ELF__");
     if (Triple.isAndroid()) {
       Builder.defineMacro("__ANDROID__", "1");
@@ -355,6 +354,8 @@ protected:
       this->PlatformMinVersion = VersionTuple(Maj, Min, Rev);
       if (Maj)
         Builder.defineMacro("__ANDROID_API__", Twine(Maj));
+    } else {
+        Builder.defineMacro("__gnu_linux__");
     }
     if (Opts.POSIXThreads)
       Builder.defineMacro("_REENTRANT");
diff --git a/test/Preprocessor/init.c b/test/Preprocessor/init.c
index ff48b11868..940dddade3 100644
--- a/test/Preprocessor/init.c
+++ b/test/Preprocessor/init.c
@@ -9057,6 +9057,7 @@
 // RUN: %clang_cc1 -triple arm-linux-androideabi -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix ANDROID %s
 // ANDROID-NOT:#define __ANDROID_API__
 // ANDROID:#define __ANDROID__ 1
+// ANDROID-NOT:#define __gnu_linux__
 //
 // RUN: %clang_cc1 -x c++ -triple i686-linux-android -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix I386-ANDROID-CXX %s
 // I386-ANDROID-CXX:#define __STDCPP_DEFAULT_NEW_ALIGNMENT__ 8U
@@ -9067,6 +9068,7 @@
 // RUN: %clang_cc1 -triple arm-linux-androideabi20 -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix ANDROID20 %s
 // ANDROID20:#define __ANDROID_API__ 20
 // ANDROID20:#define __ANDROID__ 1
+// ANDROID-NOT:#define __gnu_linux__
 //
 // RUN: %clang_cc1 -triple lanai-unknown-unknown -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix LANAI %s
 // LANAI: #define __lanai__ 1
-- 
cgit v1.2.3


From 63beca62d94c0442c16aeb7d176ae93f5c90017f Mon Sep 17 00:00:00 2001
From: Stephen Kelly 
Date: Tue, 8 Jan 2019 22:32:48 +0000
Subject: Implement the TreeStructure interface through the TextNodeDumper

Summary:
This way, when the generic ASTTraverser is extracted from ASTDumper,
there can't be any problem related to ordering of class members, a
concern that was raised in https://reviews.llvm.org/D55337.

This will also preserve the property that the generic traverser does not
enforce any coupling between the NodeDumper and the TreeStructure.

 https://godbolt.org/z/PEtT1_

Reviewers: aaron.ballman, erichkeane

Subscribers: cfe-commits

Differential Revision: https://reviews.llvm.org/D56407

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350665 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/AST/ASTDumperUtils.h | 84 ------------------------------------
 include/clang/AST/TextNodeDumper.h | 87 +++++++++++++++++++++++++++++++++++++-
 lib/AST/ASTDumper.cpp              |  6 +--
 lib/AST/TextNodeDumper.cpp         |  4 +-
 4 files changed, 90 insertions(+), 91 deletions(-)

diff --git a/include/clang/AST/ASTDumperUtils.h b/include/clang/AST/ASTDumperUtils.h
index 129c40ce3e..71cf5c93bc 100644
--- a/include/clang/AST/ASTDumperUtils.h
+++ b/include/clang/AST/ASTDumperUtils.h
@@ -92,90 +92,6 @@ public:
   }
 };
 
-class TextTreeStructure {
-  raw_ostream &OS;
-  const bool ShowColors;
-
-  /// Pending[i] is an action to dump an entity at level i.
-  llvm::SmallVector, 32> Pending;
-
-  /// Indicates whether we're at the top level.
-  bool TopLevel = true;
-
-  /// Indicates if we're handling the first child after entering a new depth.
-  bool FirstChild = true;
-
-  /// Prefix for currently-being-dumped entity.
-  std::string Prefix;
-
-public:
-  /// Add a child of the current node.  Calls doAddChild without arguments
-  template  void addChild(Fn doAddChild) {
-    // If we're at the top level, there's nothing interesting to do; just
-    // run the dumper.
-    if (TopLevel) {
-      TopLevel = false;
-      doAddChild();
-      while (!Pending.empty()) {
-        Pending.back()(true);
-        Pending.pop_back();
-      }
-      Prefix.clear();
-      OS << "\n";
-      TopLevel = true;
-      return;
-    }
-
-    auto dumpWithIndent = [this, doAddChild](bool isLastChild) {
-      // Print out the appropriate tree structure and work out the prefix for
-      // children of this node. For instance:
-      //
-      //   A        Prefix = ""
-      //   |-B      Prefix = "| "
-      //   | `-C    Prefix = "|   "
-      //   `-D      Prefix = "  "
-      //     |-E    Prefix = "  | "
-      //     `-F    Prefix = "    "
-      //   G        Prefix = ""
-      //
-      // Note that the first level gets no prefix.
-      {
-        OS << '\n';
-        ColorScope Color(OS, ShowColors, IndentColor);
-        OS << Prefix << (isLastChild ? '`' : '|') << '-';
-        this->Prefix.push_back(isLastChild ? ' ' : '|');
-        this->Prefix.push_back(' ');
-      }
-
-      FirstChild = true;
-      unsigned Depth = Pending.size();
-
-      doAddChild();
-
-      // If any children are left, they're the last at their nesting level.
-      // Dump those ones out now.
-      while (Depth < Pending.size()) {
-        Pending.back()(true);
-        this->Pending.pop_back();
-      }
-
-      // Restore the old prefix.
-      this->Prefix.resize(Prefix.size() - 2);
-    };
-
-    if (FirstChild) {
-      Pending.push_back(std::move(dumpWithIndent));
-    } else {
-      Pending.back()(false);
-      Pending.back() = std::move(dumpWithIndent);
-    }
-    FirstChild = false;
-  }
-
-  TextTreeStructure(raw_ostream &OS, bool ShowColors)
-      : OS(OS), ShowColors(ShowColors) {}
-};
-
 } // namespace clang
 
 #endif // LLVM_CLANG_AST_ASTDUMPERUTILS_H
diff --git a/include/clang/AST/TextNodeDumper.h b/include/clang/AST/TextNodeDumper.h
index 5a1dbb40fa..3634d1c41f 100644
--- a/include/clang/AST/TextNodeDumper.h
+++ b/include/clang/AST/TextNodeDumper.h
@@ -22,9 +22,94 @@
 
 namespace clang {
 
+class TextTreeStructure {
+  raw_ostream &OS;
+  const bool ShowColors;
+
+  /// Pending[i] is an action to dump an entity at level i.
+  llvm::SmallVector, 32> Pending;
+
+  /// Indicates whether we're at the top level.
+  bool TopLevel = true;
+
+  /// Indicates if we're handling the first child after entering a new depth.
+  bool FirstChild = true;
+
+  /// Prefix for currently-being-dumped entity.
+  std::string Prefix;
+
+public:
+  /// Add a child of the current node.  Calls doAddChild without arguments
+  template  void addChild(Fn doAddChild) {
+    // If we're at the top level, there's nothing interesting to do; just
+    // run the dumper.
+    if (TopLevel) {
+      TopLevel = false;
+      doAddChild();
+      while (!Pending.empty()) {
+        Pending.back()(true);
+        Pending.pop_back();
+      }
+      Prefix.clear();
+      OS << "\n";
+      TopLevel = true;
+      return;
+    }
+
+    auto dumpWithIndent = [this, doAddChild](bool isLastChild) {
+      // Print out the appropriate tree structure and work out the prefix for
+      // children of this node. For instance:
+      //
+      //   A        Prefix = ""
+      //   |-B      Prefix = "| "
+      //   | `-C    Prefix = "|   "
+      //   `-D      Prefix = "  "
+      //     |-E    Prefix = "  | "
+      //     `-F    Prefix = "    "
+      //   G        Prefix = ""
+      //
+      // Note that the first level gets no prefix.
+      {
+        OS << '\n';
+        ColorScope Color(OS, ShowColors, IndentColor);
+        OS << Prefix << (isLastChild ? '`' : '|') << '-';
+        this->Prefix.push_back(isLastChild ? ' ' : '|');
+        this->Prefix.push_back(' ');
+      }
+
+      FirstChild = true;
+      unsigned Depth = Pending.size();
+
+      doAddChild();
+
+      // If any children are left, they're the last at their nesting level.
+      // Dump those ones out now.
+      while (Depth < Pending.size()) {
+        Pending.back()(true);
+        this->Pending.pop_back();
+      }
+
+      // Restore the old prefix.
+      this->Prefix.resize(Prefix.size() - 2);
+    };
+
+    if (FirstChild) {
+      Pending.push_back(std::move(dumpWithIndent));
+    } else {
+      Pending.back()(false);
+      Pending.back() = std::move(dumpWithIndent);
+    }
+    FirstChild = false;
+  }
+
+  TextTreeStructure(raw_ostream &OS, bool ShowColors)
+      : OS(OS), ShowColors(ShowColors) {}
+};
+
 class TextNodeDumper
     : public comments::ConstCommentVisitor {
+                                           const comments::FullComment *>,
+      public TextTreeStructure {
   raw_ostream &OS;
   const bool ShowColors;
 
diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp
index 43d8d7d38f..79c40dc554 100644
--- a/lib/AST/ASTDumper.cpp
+++ b/lib/AST/ASTDumper.cpp
@@ -44,7 +44,6 @@ namespace  {
         public ConstCommentVisitor,
         public TypeVisitor {
 
-    TextTreeStructure TreeStructure;
     TextNodeDumper NodeDumper;
 
     raw_ostream &OS;
@@ -60,7 +59,7 @@ namespace  {
 
     /// Dump a child of the current node.
     template void dumpChild(Fn doDumpChild) {
-      TreeStructure.addChild(doDumpChild);
+      NodeDumper.addChild(doDumpChild);
     }
 
   public:
@@ -75,8 +74,7 @@ namespace  {
     ASTDumper(raw_ostream &OS, const CommandTraits *Traits,
               const SourceManager *SM, bool ShowColors,
               const PrintingPolicy &PrintPolicy)
-        : TreeStructure(OS, ShowColors),
-          NodeDumper(OS, ShowColors, SM, PrintPolicy, Traits), OS(OS),
+        : NodeDumper(OS, ShowColors, SM, PrintPolicy, Traits), OS(OS),
           PrintPolicy(PrintPolicy), ShowColors(ShowColors) {}
 
     void setDeserialize(bool D) { Deserialize = D; }
diff --git a/lib/AST/TextNodeDumper.cpp b/lib/AST/TextNodeDumper.cpp
index 27d8f25393..d673b3bc82 100644
--- a/lib/AST/TextNodeDumper.cpp
+++ b/lib/AST/TextNodeDumper.cpp
@@ -19,8 +19,8 @@ TextNodeDumper::TextNodeDumper(raw_ostream &OS, bool ShowColors,
                                const SourceManager *SM,
                                const PrintingPolicy &PrintPolicy,
                                const comments::CommandTraits *Traits)
-    : OS(OS), ShowColors(ShowColors), SM(SM), PrintPolicy(PrintPolicy),
-      Traits(Traits) {}
+    : TextTreeStructure(OS, ShowColors), OS(OS), ShowColors(ShowColors), SM(SM),
+      PrintPolicy(PrintPolicy), Traits(Traits) {}
 
 void TextNodeDumper::Visit(const comments::Comment *C,
                            const comments::FullComment *FC) {
-- 
cgit v1.2.3


From 1551b66a72c6b7b669edb6807810556953511649 Mon Sep 17 00:00:00 2001
From: Alex Lorenz 
Date: Tue, 8 Jan 2019 22:32:51 +0000
Subject: [libclang] Recommit r336590 with a fix for the memory leak in the
 test

The original commit had a memory leak in the test has a leak as it doesn't
dispose of the evaluated cursor result.

This also contains the follow-up NFC refactoring commit r336591.

rdar://45893054

Original commit message:

[libclang] evalute compound statement cursors before trying to evaluate
the cursor like a declaration

This change fixes a bug in libclang in which it tries to evaluate a statement
cursor as a declaration cursor, because that statement still has a pointer to
the declaration parent.

rdar://38888477

Differential Revision: https://reviews.llvm.org/D49051


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350666 91177308-0d34-0410-b5e6-96231b3b80d8
---
 tools/libclang/CIndex.cpp           | 47 ++++++++++++++++++-------------------
 unittests/libclang/LibclangTest.cpp | 42 +++++++++++++++++++++++++++++++++
 2 files changed, 65 insertions(+), 24 deletions(-)

diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp
index bc791954fc..15b2df8493 100644
--- a/tools/libclang/CIndex.cpp
+++ b/tools/libclang/CIndex.cpp
@@ -3902,36 +3902,35 @@ static const ExprEvalResult* evaluateExpr(Expr *expr, CXCursor C) {
   return nullptr;
 }
 
-CXEvalResult clang_Cursor_Evaluate(CXCursor C) {
-  const Decl *D = getCursorDecl(C);
-  if (D) {
-    const Expr *expr = nullptr;
-    if (auto *Var = dyn_cast(D)) {
-      expr = Var->getInit();
-    } else if (auto *Field = dyn_cast(D)) {
-      expr = Field->getInClassInitializer();
-    }
-    if (expr)
-      return const_cast(reinterpret_cast(
-          evaluateExpr(const_cast(expr), C)));
+static const Expr *evaluateDeclExpr(const Decl *D) {
+  if (!D)
     return nullptr;
-  }
+  if (auto *Var = dyn_cast(D))
+    return Var->getInit();
+  else if (auto *Field = dyn_cast(D))
+    return Field->getInClassInitializer();
+  return nullptr;
+}
 
-  const CompoundStmt *compoundStmt = dyn_cast_or_null(getCursorStmt(C));
-  if (compoundStmt) {
-    Expr *expr = nullptr;
-    for (auto *bodyIterator : compoundStmt->body()) {
-      if ((expr = dyn_cast(bodyIterator))) {
-        break;
-      }
-    }
-    if (expr)
-      return const_cast(
-          reinterpret_cast(evaluateExpr(expr, C)));
+static const Expr *evaluateCompoundStmtExpr(const CompoundStmt *CS) {
+  assert(CS && "invalid compound statement");
+  for (auto *bodyIterator : CS->body()) {
+    if (const auto *E = dyn_cast(bodyIterator))
+      return E;
   }
   return nullptr;
 }
 
+CXEvalResult clang_Cursor_Evaluate(CXCursor C) {
+  if (const Expr *E =
+          clang_getCursorKind(C) == CXCursor_CompoundStmt
+              ? evaluateCompoundStmtExpr(cast(getCursorStmt(C)))
+              : evaluateDeclExpr(getCursorDecl(C)))
+    return const_cast(
+        reinterpret_cast(evaluateExpr(const_cast(E), C)));
+  return nullptr;
+}
+
 unsigned clang_Cursor_hasAttrs(CXCursor C) {
   const Decl *D = getCursorDecl(C);
   if (!D) {
diff --git a/unittests/libclang/LibclangTest.cpp b/unittests/libclang/LibclangTest.cpp
index 6fddcb2cbf..b88b88dac3 100644
--- a/unittests/libclang/LibclangTest.cpp
+++ b/unittests/libclang/LibclangTest.cpp
@@ -461,6 +461,48 @@ TEST_F(LibclangParseTest, AllSkippedRanges) {
   clang_disposeSourceRangeList(Ranges);
 }
 
+TEST_F(LibclangParseTest, EvaluateChildExpression) {
+  std::string Main = "main.m";
+  WriteFile(Main, "#define kFOO @\"foo\"\n"
+                  "void foobar(void) {\n"
+                  " {kFOO;}\n"
+                  "}\n");
+  ClangTU = clang_parseTranslationUnit(Index, Main.c_str(), nullptr, 0, nullptr,
+                                       0, TUFlags);
+
+  CXCursor C = clang_getTranslationUnitCursor(ClangTU);
+  clang_visitChildren(
+      C,
+      [](CXCursor cursor, CXCursor parent,
+         CXClientData client_data) -> CXChildVisitResult {
+        if (clang_getCursorKind(cursor) == CXCursor_FunctionDecl) {
+          int numberedStmt = 0;
+          clang_visitChildren(
+              cursor,
+              [](CXCursor cursor, CXCursor parent,
+                 CXClientData client_data) -> CXChildVisitResult {
+                int &numberedStmt = *((int *)client_data);
+                if (clang_getCursorKind(cursor) == CXCursor_CompoundStmt) {
+                  if (numberedStmt) {
+                    CXEvalResult RE = clang_Cursor_Evaluate(cursor);
+                    EXPECT_NE(RE, nullptr);
+                    EXPECT_EQ(clang_EvalResult_getKind(RE),
+                              CXEval_ObjCStrLiteral);
+                    clang_EvalResult_dispose(RE);
+                    return CXChildVisit_Break;
+                  }
+                  numberedStmt++;
+                }
+                return CXChildVisit_Recurse;
+              },
+              &numberedStmt);
+          EXPECT_EQ(numberedStmt, 1);
+        }
+        return CXChildVisit_Continue;
+      },
+      nullptr);
+}
+
 class LibclangReparseTest : public LibclangParseTest {
 public:
   void DisplayDiagnostics() {
-- 
cgit v1.2.3


From 52994f9d728ad5b739d22aa4e26328cbc34cead5 Mon Sep 17 00:00:00 2001
From: Dan Albert 
Date: Tue, 8 Jan 2019 22:33:59 +0000
Subject: [Driver] Default to -fno-addrsig on Android.

Summary: The Android NDK still uses GNU binutils by default.

Reviewers: srhines, pirama

Reviewed By: srhines

Subscribers: cfe-commits

Differential Revision: https://reviews.llvm.org/D56456

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350668 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/Driver/ToolChains/Clang.cpp | 1 +
 test/Driver/addrsig.c           | 1 +
 2 files changed, 2 insertions(+)

diff --git a/lib/Driver/ToolChains/Clang.cpp b/lib/Driver/ToolChains/Clang.cpp
index 10487a6d45..7df95649bd 100644
--- a/lib/Driver/ToolChains/Clang.cpp
+++ b/lib/Driver/ToolChains/Clang.cpp
@@ -5292,6 +5292,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
                       !TC.getTriple().isPS4() &&
                       !TC.getTriple().isOSNetBSD() &&
                       !Distro(D.getVFS()).IsGentoo() &&
+                      !TC.getTriple().isAndroid() &&
                        TC.useIntegratedAs()))
     CmdArgs.push_back("-faddrsig");
 
diff --git a/test/Driver/addrsig.c b/test/Driver/addrsig.c
index 556a908e30..684e351298 100644
--- a/test/Driver/addrsig.c
+++ b/test/Driver/addrsig.c
@@ -8,6 +8,7 @@
 // RUN: %clang -### -target x86_64-unknown-linux -fno-addrsig -c %s 2>&1 | FileCheck -check-prefix=NO-ADDRSIG %s
 // RUN: %clang -### -target x86_64-apple-darwin -c %s 2>&1 | FileCheck -check-prefix=NO-ADDRSIG %s
 // RUN: %clang -### -target x86_64-scei-ps4 -c %s 2>&1 | FileCheck -check-prefix=NO-ADDRSIG %s
+// RUN: %clang -### -target x86_64-linux-android21 -c %s 2>&1 | FileCheck -check-prefix=NO-ADDRSIG %s
 
 // ADDRSIG: -faddrsig
 // NO-ADDRSIG-NOT: -faddrsig
-- 
cgit v1.2.3


From 3aac3eb43a803d26eb5653d6bee6d437c1adfc85 Mon Sep 17 00:00:00 2001
From: Stephen Kelly 
Date: Tue, 8 Jan 2019 23:11:24 +0000
Subject: [ASTDump] NFC: Move dumpDeclRef to NodeDumper

Reviewers: aaron.ballman

Subscribers: cfe-commits

Differential Revision: https://reviews.llvm.org/D55337

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350677 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/AST/TextNodeDumper.h |  8 +++--
 lib/AST/ASTDumper.cpp              | 72 ++++++++++++++++----------------------
 lib/AST/TextNodeDumper.cpp         | 11 ++++++
 3 files changed, 46 insertions(+), 45 deletions(-)

diff --git a/include/clang/AST/TextNodeDumper.h b/include/clang/AST/TextNodeDumper.h
index 3634d1c41f..db8087c9aa 100644
--- a/include/clang/AST/TextNodeDumper.h
+++ b/include/clang/AST/TextNodeDumper.h
@@ -107,9 +107,9 @@ public:
 };
 
 class TextNodeDumper
-    : public comments::ConstCommentVisitor,
-      public TextTreeStructure {
+    : public TextTreeStructure,
+      public comments::ConstCommentVisitor {
   raw_ostream &OS;
   const bool ShowColors;
 
@@ -144,6 +144,8 @@ public:
   void dumpAccessSpecifier(AccessSpecifier AS);
   void dumpCXXTemporary(const CXXTemporary *Temporary);
 
+  void dumpDeclRef(const Decl *D, const char *Label = nullptr);
+
   void visitTextComment(const comments::TextComment *C,
                         const comments::FullComment *);
   void visitInlineCommandComment(const comments::InlineCommandComment *C,
diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp
index 79c40dc554..8d2e003504 100644
--- a/lib/AST/ASTDumper.cpp
+++ b/lib/AST/ASTDumper.cpp
@@ -86,7 +86,6 @@ namespace  {
     void dumpType(QualType T) { NodeDumper.dumpType(T); }
     void dumpTypeAsChild(QualType T);
     void dumpTypeAsChild(const Type *T);
-    void dumpDeclRef(const Decl *Node, const char *Label = nullptr);
     void dumpBareDeclRef(const Decl *Node) { NodeDumper.dumpBareDeclRef(Node); }
     void dumpDeclContext(const DeclContext *DC);
     void dumpLookups(const DeclContext *DC, bool DumpDecls);
@@ -215,10 +214,10 @@ namespace  {
         dumpChild([=] { OS << "..."; });
     }
     void VisitUnresolvedUsingType(const UnresolvedUsingType *T) {
-      dumpDeclRef(T->getDecl());
+      NodeDumper.dumpDeclRef(T->getDecl());
     }
     void VisitTypedefType(const TypedefType *T) {
-      dumpDeclRef(T->getDecl());
+      NodeDumper.dumpDeclRef(T->getDecl());
     }
     void VisitTypeOfExprType(const TypeOfExprType *T) {
       dumpStmt(T->getUnderlyingExpr());
@@ -235,7 +234,7 @@ namespace  {
       dumpTypeAsChild(T->getBaseType());
     }
     void VisitTagType(const TagType *T) {
-      dumpDeclRef(T->getDecl());
+      NodeDumper.dumpDeclRef(T->getDecl());
     }
     void VisitAttributedType(const AttributedType *T) {
       // FIXME: AttrKind
@@ -244,7 +243,7 @@ namespace  {
     void VisitTemplateTypeParmType(const TemplateTypeParmType *T) {
       OS << " depth " << T->getDepth() << " index " << T->getIndex();
       if (T->isParameterPack()) OS << " pack";
-      dumpDeclRef(T->getDecl());
+      NodeDumper.dumpDeclRef(T->getDecl());
     }
     void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) {
       dumpTypeAsChild(T->getReplacedParameter());
@@ -268,10 +267,10 @@ namespace  {
         dumpTypeAsChild(T->getAliasedType());
     }
     void VisitInjectedClassNameType(const InjectedClassNameType *T) {
-      dumpDeclRef(T->getDecl());
+      NodeDumper.dumpDeclRef(T->getDecl());
     }
     void VisitObjCInterfaceType(const ObjCInterfaceType *T) {
-      dumpDeclRef(T->getDecl());
+      NodeDumper.dumpDeclRef(T->getDecl());
     }
     void VisitObjCObjectPointerType(const ObjCObjectPointerType *T) {
       dumpTypeAsChild(T->getPointeeType());
@@ -506,17 +505,6 @@ void ASTDumper::dumpTypeAsChild(const Type *T) {
   });
 }
 
-void ASTDumper::dumpDeclRef(const Decl *D, const char *Label) {
-  if (!D)
-    return;
-
-  dumpChild([=]{
-    if (Label)
-      OS << Label << ' ';
-    dumpBareDeclRef(D);
-  });
-}
-
 void ASTDumper::dumpDeclContext(const DeclContext *DC) {
   if (!DC)
     return;
@@ -695,7 +683,7 @@ void ASTDumper::dumpTemplateArgument(const TemplateArgument &A, SourceRange R,
       NodeDumper.dumpSourceRange(R);
 
     if (From)
-      dumpDeclRef(From, Label);
+      NodeDumper.dumpDeclRef(From, Label);
 
     switch (A.getKind()) {
     case TemplateArgument::Null:
@@ -707,7 +695,7 @@ void ASTDumper::dumpTemplateArgument(const TemplateArgument &A, SourceRange R,
       break;
     case TemplateArgument::Declaration:
       OS << " decl";
-      dumpDeclRef(A.getAsDecl());
+      NodeDumper.dumpDeclRef(A.getAsDecl());
       break;
     case TemplateArgument::NullPtr:
       OS << " nullptr";
@@ -863,7 +851,7 @@ void ASTDumper::VisitIndirectFieldDecl(const IndirectFieldDecl *D) {
   NodeDumper.dumpType(D->getType());
 
   for (auto *Child : D->chain())
-    dumpDeclRef(Child);
+    NodeDumper.dumpDeclRef(Child);
 }
 
 void ASTDumper::VisitFunctionDecl(const FunctionDecl *D) {
@@ -1105,7 +1093,7 @@ void ASTDumper::VisitNamespaceDecl(const NamespaceDecl *D) {
   if (D->isInline())
     OS << " inline";
   if (!D->isOriginalNamespace())
-    dumpDeclRef(D->getOriginalNamespace(), "original");
+    NodeDumper.dumpDeclRef(D->getOriginalNamespace(), "original");
 }
 
 void ASTDumper::VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) {
@@ -1115,7 +1103,7 @@ void ASTDumper::VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) {
 
 void ASTDumper::VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) {
   NodeDumper.dumpName(D);
-  dumpDeclRef(D->getAliasedNamespace());
+  NodeDumper.dumpDeclRef(D->getAliasedNamespace());
 }
 
 void ASTDumper::VisitTypeAliasDecl(const TypeAliasDecl *D) {
@@ -1301,7 +1289,7 @@ void ASTDumper::dumpTemplateDeclSpecialization(const SpecializationDecl *D,
     case TSK_Undeclared:
     case TSK_ImplicitInstantiation:
       if (DumpRefOnly)
-        dumpDeclRef(Redecl);
+        NodeDumper.dumpDeclRef(Redecl);
       else
         dumpDecl(Redecl);
       DumpedAny = true;
@@ -1313,7 +1301,7 @@ void ASTDumper::dumpTemplateDeclSpecialization(const SpecializationDecl *D,
 
   // Ensure we dump at least one decl for each specialization.
   if (!DumpedAny)
-    dumpDeclRef(D);
+    NodeDumper.dumpDeclRef(D);
 }
 
 template 
@@ -1568,42 +1556,42 @@ void ASTDumper::VisitObjCTypeParamDecl(const ObjCTypeParamDecl *D) {
 
 void ASTDumper::VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {
   NodeDumper.dumpName(D);
-  dumpDeclRef(D->getClassInterface());
+  NodeDumper.dumpDeclRef(D->getClassInterface());
   dumpObjCTypeParamList(D->getTypeParamList());
-  dumpDeclRef(D->getImplementation());
+  NodeDumper.dumpDeclRef(D->getImplementation());
   for (ObjCCategoryDecl::protocol_iterator I = D->protocol_begin(),
                                            E = D->protocol_end();
        I != E; ++I)
-    dumpDeclRef(*I);
+    NodeDumper.dumpDeclRef(*I);
 }
 
 void ASTDumper::VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) {
   NodeDumper.dumpName(D);
-  dumpDeclRef(D->getClassInterface());
-  dumpDeclRef(D->getCategoryDecl());
+  NodeDumper.dumpDeclRef(D->getClassInterface());
+  NodeDumper.dumpDeclRef(D->getCategoryDecl());
 }
 
 void ASTDumper::VisitObjCProtocolDecl(const ObjCProtocolDecl *D) {
   NodeDumper.dumpName(D);
 
   for (auto *Child : D->protocols())
-    dumpDeclRef(Child);
+    NodeDumper.dumpDeclRef(Child);
 }
 
 void ASTDumper::VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
   NodeDumper.dumpName(D);
   dumpObjCTypeParamList(D->getTypeParamListAsWritten());
-  dumpDeclRef(D->getSuperClass(), "super");
+  NodeDumper.dumpDeclRef(D->getSuperClass(), "super");
 
-  dumpDeclRef(D->getImplementation());
+  NodeDumper.dumpDeclRef(D->getImplementation());
   for (auto *Child : D->protocols())
-    dumpDeclRef(Child);
+    NodeDumper.dumpDeclRef(Child);
 }
 
 void ASTDumper::VisitObjCImplementationDecl(const ObjCImplementationDecl *D) {
   NodeDumper.dumpName(D);
-  dumpDeclRef(D->getSuperClass(), "super");
-  dumpDeclRef(D->getClassInterface());
+  NodeDumper.dumpDeclRef(D->getSuperClass(), "super");
+  NodeDumper.dumpDeclRef(D->getClassInterface());
   for (ObjCImplementationDecl::init_const_iterator I = D->init_begin(),
                                                    E = D->init_end();
        I != E; ++I)
@@ -1612,7 +1600,7 @@ void ASTDumper::VisitObjCImplementationDecl(const ObjCImplementationDecl *D) {
 
 void ASTDumper::VisitObjCCompatibleAliasDecl(const ObjCCompatibleAliasDecl *D) {
   NodeDumper.dumpName(D);
-  dumpDeclRef(D->getClassInterface());
+  NodeDumper.dumpDeclRef(D->getClassInterface());
 }
 
 void ASTDumper::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
@@ -1649,9 +1637,9 @@ void ASTDumper::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
     if (Attrs & ObjCPropertyDecl::OBJC_PR_class)
       OS << " class";
     if (Attrs & ObjCPropertyDecl::OBJC_PR_getter)
-      dumpDeclRef(D->getGetterMethodDecl(), "getter");
+      NodeDumper.dumpDeclRef(D->getGetterMethodDecl(), "getter");
     if (Attrs & ObjCPropertyDecl::OBJC_PR_setter)
-      dumpDeclRef(D->getSetterMethodDecl(), "setter");
+      NodeDumper.dumpDeclRef(D->getSetterMethodDecl(), "setter");
   }
 }
 
@@ -1661,8 +1649,8 @@ void ASTDumper::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
     OS << " synthesize";
   else
     OS << " dynamic";
-  dumpDeclRef(D->getPropertyDecl());
-  dumpDeclRef(D->getPropertyIvarDecl());
+  NodeDumper.dumpDeclRef(D->getPropertyDecl());
+  NodeDumper.dumpDeclRef(D->getPropertyIvarDecl());
 }
 
 void ASTDumper::VisitBlockDecl(const BlockDecl *D) {
@@ -2153,7 +2141,7 @@ ASTDumper::VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *Node) {
 
 void ASTDumper::VisitExprWithCleanups(const ExprWithCleanups *Node) {
   for (unsigned i = 0, e = Node->getNumObjects(); i != e; ++i)
-    dumpDeclRef(Node->getObject(i), "cleanup");
+    NodeDumper.dumpDeclRef(Node->getObject(i), "cleanup");
 }
 
 void ASTDumper::VisitSizeOfPackExpr(const SizeOfPackExpr *Node) {
diff --git a/lib/AST/TextNodeDumper.cpp b/lib/AST/TextNodeDumper.cpp
index d673b3bc82..b04a3cfdc8 100644
--- a/lib/AST/TextNodeDumper.cpp
+++ b/lib/AST/TextNodeDumper.cpp
@@ -161,6 +161,17 @@ void TextNodeDumper::dumpCXXTemporary(const CXXTemporary *Temporary) {
   OS << ")";
 }
 
+void TextNodeDumper::dumpDeclRef(const Decl *D, const char *Label) {
+  if (!D)
+    return;
+
+  addChild([=] {
+    if (Label)
+      OS << Label << ' ';
+    dumpBareDeclRef(D);
+  });
+}
+
 const char *TextNodeDumper::getCommandName(unsigned CommandID) {
   if (Traits)
     return Traits->getCommandInfo(CommandID)->Name;
-- 
cgit v1.2.3


From c3ada736c34d204768d2b6a303a191401713a958 Mon Sep 17 00:00:00 2001
From: Alex Lorenz 
Date: Tue, 8 Jan 2019 23:28:37 +0000
Subject: [libclang] Fix the mismatched delete operator for ExprEvalResult

The '.stringVal' field in ExprEvalResult is allocated using new[],
but was freed using a regular delete. That caused memory leaks in
the test from r350666.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350680 91177308-0d34-0410-b5e6-96231b3b80d8
---
 tools/libclang/CIndex.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp
index 15b2df8493..a9c3077e5f 100644
--- a/tools/libclang/CIndex.cpp
+++ b/tools/libclang/CIndex.cpp
@@ -3694,7 +3694,7 @@ struct ExprEvalResult {
   ~ExprEvalResult() {
     if (EvalType != CXEval_UnExposed && EvalType != CXEval_Float &&
         EvalType != CXEval_Int) {
-      delete EvalData.stringVal;
+      delete[] EvalData.stringVal;
     }
   }
 };
-- 
cgit v1.2.3


From a1312e9156064555daacf6a2daa19b9060f5b980 Mon Sep 17 00:00:00 2001
From: Craig Topper 
Date: Wed, 9 Jan 2019 07:36:01 +0000
Subject: [X86] Make the pointer arguments to avx512 gather/scatter intrinsics
 'void*' to match gcc and Intel's documentation.

The avx2 gather intrinsics are documented to use 'int', 'long long', 'float', or 'double' *. So I'm leaving those. This matches gcc.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350696 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/Headers/avx512fintrin.h  | 64 ++++++++++++++---------------
 lib/Headers/avx512pfintrin.h | 32 +++++++--------
 lib/Headers/avx512vlintrin.h | 96 ++++++++++++++++++++++----------------------
 3 files changed, 96 insertions(+), 96 deletions(-)

diff --git a/lib/Headers/avx512fintrin.h b/lib/Headers/avx512fintrin.h
index 6fc7f9e8d6..1c19993ff1 100644
--- a/lib/Headers/avx512fintrin.h
+++ b/lib/Headers/avx512fintrin.h
@@ -7630,177 +7630,177 @@ _mm512_maskz_getexp_ps (__mmask16 __U, __m512 __A)
 
 #define _mm512_i64gather_ps(index, addr, scale) \
   (__m256)__builtin_ia32_gatherdiv16sf((__v8sf)_mm256_undefined_ps(), \
-                                       (float const *)(addr), \
+                                       (void const *)(addr), \
                                        (__v8di)(__m512i)(index), (__mmask8)-1, \
                                        (int)(scale))
 
 #define _mm512_mask_i64gather_ps(v1_old, mask, index, addr, scale) \
   (__m256)__builtin_ia32_gatherdiv16sf((__v8sf)(__m256)(v1_old),\
-                                       (float const *)(addr), \
+                                       (void const *)(addr), \
                                        (__v8di)(__m512i)(index), \
                                        (__mmask8)(mask), (int)(scale))
 
 #define _mm512_i64gather_epi32(index, addr, scale) \
   (__m256i)__builtin_ia32_gatherdiv16si((__v8si)_mm256_undefined_si256(), \
-                                        (int const *)(addr), \
+                                        (void const *)(addr), \
                                         (__v8di)(__m512i)(index), \
                                         (__mmask8)-1, (int)(scale))
 
 #define _mm512_mask_i64gather_epi32(v1_old, mask, index, addr, scale) \
   (__m256i)__builtin_ia32_gatherdiv16si((__v8si)(__m256i)(v1_old), \
-                                        (int const *)(addr), \
+                                        (void const *)(addr), \
                                         (__v8di)(__m512i)(index), \
                                         (__mmask8)(mask), (int)(scale))
 
 #define _mm512_i64gather_pd(index, addr, scale) \
   (__m512d)__builtin_ia32_gatherdiv8df((__v8df)_mm512_undefined_pd(), \
-                                       (double const *)(addr), \
+                                       (void const *)(addr), \
                                        (__v8di)(__m512i)(index), (__mmask8)-1, \
                                        (int)(scale))
 
 #define _mm512_mask_i64gather_pd(v1_old, mask, index, addr, scale) \
   (__m512d)__builtin_ia32_gatherdiv8df((__v8df)(__m512d)(v1_old), \
-                                       (double const *)(addr), \
+                                       (void const *)(addr), \
                                        (__v8di)(__m512i)(index), \
                                        (__mmask8)(mask), (int)(scale))
 
 #define _mm512_i64gather_epi64(index, addr, scale) \
   (__m512i)__builtin_ia32_gatherdiv8di((__v8di)_mm512_undefined_epi32(), \
-                                       (long long const *)(addr), \
+                                       (void const *)(addr), \
                                        (__v8di)(__m512i)(index), (__mmask8)-1, \
                                        (int)(scale))
 
 #define _mm512_mask_i64gather_epi64(v1_old, mask, index, addr, scale) \
   (__m512i)__builtin_ia32_gatherdiv8di((__v8di)(__m512i)(v1_old), \
-                                       (long long const *)(addr), \
+                                       (void const *)(addr), \
                                        (__v8di)(__m512i)(index), \
                                        (__mmask8)(mask), (int)(scale))
 
 #define _mm512_i32gather_ps(index, addr, scale) \
   (__m512)__builtin_ia32_gathersiv16sf((__v16sf)_mm512_undefined_ps(), \
-                                       (float const *)(addr), \
+                                       (void const *)(addr), \
                                        (__v16sf)(__m512)(index), \
                                        (__mmask16)-1, (int)(scale))
 
 #define _mm512_mask_i32gather_ps(v1_old, mask, index, addr, scale) \
   (__m512)__builtin_ia32_gathersiv16sf((__v16sf)(__m512)(v1_old), \
-                                       (float const *)(addr), \
+                                       (void const *)(addr), \
                                        (__v16sf)(__m512)(index), \
                                        (__mmask16)(mask), (int)(scale))
 
 #define _mm512_i32gather_epi32(index, addr, scale) \
   (__m512i)__builtin_ia32_gathersiv16si((__v16si)_mm512_undefined_epi32(), \
-                                        (int const *)(addr), \
+                                        (void const *)(addr), \
                                         (__v16si)(__m512i)(index), \
                                         (__mmask16)-1, (int)(scale))
 
 #define _mm512_mask_i32gather_epi32(v1_old, mask, index, addr, scale) \
   (__m512i)__builtin_ia32_gathersiv16si((__v16si)(__m512i)(v1_old), \
-                                        (int const *)(addr), \
+                                        (void const *)(addr), \
                                         (__v16si)(__m512i)(index), \
                                         (__mmask16)(mask), (int)(scale))
 
 #define _mm512_i32gather_pd(index, addr, scale) \
   (__m512d)__builtin_ia32_gathersiv8df((__v8df)_mm512_undefined_pd(), \
-                                       (double const *)(addr), \
+                                       (void const *)(addr), \
                                        (__v8si)(__m256i)(index), (__mmask8)-1, \
                                        (int)(scale))
 
 #define _mm512_mask_i32gather_pd(v1_old, mask, index, addr, scale) \
   (__m512d)__builtin_ia32_gathersiv8df((__v8df)(__m512d)(v1_old), \
-                                       (double const *)(addr), \
+                                       (void const *)(addr), \
                                        (__v8si)(__m256i)(index), \
                                        (__mmask8)(mask), (int)(scale))
 
 #define _mm512_i32gather_epi64(index, addr, scale) \
   (__m512i)__builtin_ia32_gathersiv8di((__v8di)_mm512_undefined_epi32(), \
-                                       (long long const *)(addr), \
+                                       (void const *)(addr), \
                                        (__v8si)(__m256i)(index), (__mmask8)-1, \
                                        (int)(scale))
 
 #define _mm512_mask_i32gather_epi64(v1_old, mask, index, addr, scale) \
   (__m512i)__builtin_ia32_gathersiv8di((__v8di)(__m512i)(v1_old), \
-                                       (long long const *)(addr), \
+                                       (void const *)(addr), \
                                        (__v8si)(__m256i)(index), \
                                        (__mmask8)(mask), (int)(scale))
 
 #define _mm512_i64scatter_ps(addr, index, v1, scale) \
-  __builtin_ia32_scatterdiv16sf((float *)(addr), (__mmask8)-1, \
+  __builtin_ia32_scatterdiv16sf((void *)(addr), (__mmask8)-1, \
                                 (__v8di)(__m512i)(index), \
                                 (__v8sf)(__m256)(v1), (int)(scale))
 
 #define _mm512_mask_i64scatter_ps(addr, mask, index, v1, scale) \
-  __builtin_ia32_scatterdiv16sf((float *)(addr), (__mmask8)(mask), \
+  __builtin_ia32_scatterdiv16sf((void *)(addr), (__mmask8)(mask), \
                                 (__v8di)(__m512i)(index), \
                                 (__v8sf)(__m256)(v1), (int)(scale))
 
 #define _mm512_i64scatter_epi32(addr, index, v1, scale) \
-  __builtin_ia32_scatterdiv16si((int *)(addr), (__mmask8)-1, \
+  __builtin_ia32_scatterdiv16si((void *)(addr), (__mmask8)-1, \
                                 (__v8di)(__m512i)(index), \
                                 (__v8si)(__m256i)(v1), (int)(scale))
 
 #define _mm512_mask_i64scatter_epi32(addr, mask, index, v1, scale) \
-  __builtin_ia32_scatterdiv16si((int *)(addr), (__mmask8)(mask), \
+  __builtin_ia32_scatterdiv16si((void *)(addr), (__mmask8)(mask), \
                                 (__v8di)(__m512i)(index), \
                                 (__v8si)(__m256i)(v1), (int)(scale))
 
 #define _mm512_i64scatter_pd(addr, index, v1, scale) \
-  __builtin_ia32_scatterdiv8df((double *)(addr), (__mmask8)-1, \
+  __builtin_ia32_scatterdiv8df((void *)(addr), (__mmask8)-1, \
                                (__v8di)(__m512i)(index), \
                                (__v8df)(__m512d)(v1), (int)(scale))
 
 #define _mm512_mask_i64scatter_pd(addr, mask, index, v1, scale) \
-  __builtin_ia32_scatterdiv8df((double *)(addr), (__mmask8)(mask), \
+  __builtin_ia32_scatterdiv8df((void *)(addr), (__mmask8)(mask), \
                                (__v8di)(__m512i)(index), \
                                (__v8df)(__m512d)(v1), (int)(scale))
 
 #define _mm512_i64scatter_epi64(addr, index, v1, scale) \
-  __builtin_ia32_scatterdiv8di((long long *)(addr), (__mmask8)-1, \
+  __builtin_ia32_scatterdiv8di((void *)(addr), (__mmask8)-1, \
                                (__v8di)(__m512i)(index), \
                                (__v8di)(__m512i)(v1), (int)(scale))
 
 #define _mm512_mask_i64scatter_epi64(addr, mask, index, v1, scale) \
-  __builtin_ia32_scatterdiv8di((long long *)(addr), (__mmask8)(mask), \
+  __builtin_ia32_scatterdiv8di((void *)(addr), (__mmask8)(mask), \
                                (__v8di)(__m512i)(index), \
                                (__v8di)(__m512i)(v1), (int)(scale))
 
 #define _mm512_i32scatter_ps(addr, index, v1, scale) \
-  __builtin_ia32_scattersiv16sf((float *)(addr), (__mmask16)-1, \
+  __builtin_ia32_scattersiv16sf((void *)(addr), (__mmask16)-1, \
                                 (__v16si)(__m512i)(index), \
                                 (__v16sf)(__m512)(v1), (int)(scale))
 
 #define _mm512_mask_i32scatter_ps(addr, mask, index, v1, scale) \
-  __builtin_ia32_scattersiv16sf((float *)(addr), (__mmask16)(mask), \
+  __builtin_ia32_scattersiv16sf((void *)(addr), (__mmask16)(mask), \
                                 (__v16si)(__m512i)(index), \
                                 (__v16sf)(__m512)(v1), (int)(scale))
 
 #define _mm512_i32scatter_epi32(addr, index, v1, scale) \
-  __builtin_ia32_scattersiv16si((int *)(addr), (__mmask16)-1, \
+  __builtin_ia32_scattersiv16si((void *)(addr), (__mmask16)-1, \
                                 (__v16si)(__m512i)(index), \
                                 (__v16si)(__m512i)(v1), (int)(scale))
 
 #define _mm512_mask_i32scatter_epi32(addr, mask, index, v1, scale) \
-  __builtin_ia32_scattersiv16si((int *)(addr), (__mmask16)(mask), \
+  __builtin_ia32_scattersiv16si((void *)(addr), (__mmask16)(mask), \
                                 (__v16si)(__m512i)(index), \
                                 (__v16si)(__m512i)(v1), (int)(scale))
 
 #define _mm512_i32scatter_pd(addr, index, v1, scale) \
-  __builtin_ia32_scattersiv8df((double *)(addr), (__mmask8)-1, \
+  __builtin_ia32_scattersiv8df((void *)(addr), (__mmask8)-1, \
                                (__v8si)(__m256i)(index), \
                                (__v8df)(__m512d)(v1), (int)(scale))
 
 #define _mm512_mask_i32scatter_pd(addr, mask, index, v1, scale) \
-  __builtin_ia32_scattersiv8df((double *)(addr), (__mmask8)(mask), \
+  __builtin_ia32_scattersiv8df((void *)(addr), (__mmask8)(mask), \
                                (__v8si)(__m256i)(index), \
                                (__v8df)(__m512d)(v1), (int)(scale))
 
 #define _mm512_i32scatter_epi64(addr, index, v1, scale) \
-  __builtin_ia32_scattersiv8di((long long *)(addr), (__mmask8)-1, \
+  __builtin_ia32_scattersiv8di((void *)(addr), (__mmask8)-1, \
                                (__v8si)(__m256i)(index), \
                                (__v8di)(__m512i)(v1), (int)(scale))
 
 #define _mm512_mask_i32scatter_epi64(addr, mask, index, v1, scale) \
-  __builtin_ia32_scattersiv8di((long long *)(addr), (__mmask8)(mask), \
+  __builtin_ia32_scattersiv8di((void *)(addr), (__mmask8)(mask), \
                                (__v8si)(__m256i)(index), \
                                (__v8di)(__m512i)(v1), (int)(scale))
 
diff --git a/lib/Headers/avx512pfintrin.h b/lib/Headers/avx512pfintrin.h
index 5b8260b77c..73b2234fb4 100644
--- a/lib/Headers/avx512pfintrin.h
+++ b/lib/Headers/avx512pfintrin.h
@@ -33,78 +33,78 @@
 
 #define _mm512_mask_prefetch_i32gather_pd(index, mask, addr, scale, hint) \
   __builtin_ia32_gatherpfdpd((__mmask8)(mask), (__v8si)(__m256i)(index), \
-                             (long long const *)(addr), (int)(scale), \
+                             (void const *)(addr), (int)(scale), \
                              (int)(hint))
 
 #define _mm512_prefetch_i32gather_pd(index, addr, scale, hint) \
   __builtin_ia32_gatherpfdpd((__mmask8) -1, (__v8si)(__m256i)(index), \
-                             (long long const *)(addr), (int)(scale), \
+                             (void const *)(addr), (int)(scale), \
                              (int)(hint))
 
 #define _mm512_mask_prefetch_i32gather_ps(index, mask, addr, scale, hint) \
   __builtin_ia32_gatherpfdps((__mmask16)(mask), \
-                             (__v16si)(__m512i)(index), (int const *)(addr), \
+                             (__v16si)(__m512i)(index), (void const *)(addr), \
                              (int)(scale), (int)(hint))
 
 #define _mm512_prefetch_i32gather_ps(index, addr, scale, hint) \
   __builtin_ia32_gatherpfdps((__mmask16) -1, \
-                             (__v16si)(__m512i)(index), (int const *)(addr), \
+                             (__v16si)(__m512i)(index), (void const *)(addr), \
                              (int)(scale), (int)(hint))
 
 #define _mm512_mask_prefetch_i64gather_pd(index, mask, addr, scale, hint) \
   __builtin_ia32_gatherpfqpd((__mmask8)(mask), (__v8di)(__m512i)(index), \
-                             (long long const *)(addr), (int)(scale), \
+                             (void const *)(addr), (int)(scale), \
                              (int)(hint))
 
 #define _mm512_prefetch_i64gather_pd(index, addr, scale, hint) \
   __builtin_ia32_gatherpfqpd((__mmask8) -1, (__v8di)(__m512i)(index), \
-                             (long long const *)(addr), (int)(scale), \
+                             (void const *)(addr), (int)(scale), \
                              (int)(hint))
 
 #define _mm512_mask_prefetch_i64gather_ps(index, mask, addr, scale, hint) \
   __builtin_ia32_gatherpfqps((__mmask8)(mask), (__v8di)(__m512i)(index), \
-                             (int const *)(addr), (int)(scale), (int)(hint))
+                             (void const *)(addr), (int)(scale), (int)(hint))
 
 #define _mm512_prefetch_i64gather_ps(index, addr, scale, hint) \
   __builtin_ia32_gatherpfqps((__mmask8) -1, (__v8di)(__m512i)(index), \
-                             (int const *)(addr), (int)(scale), (int)(hint))
+                             (void const *)(addr), (int)(scale), (int)(hint))
 
 #define _mm512_prefetch_i32scatter_pd(addr, index, scale, hint) \
   __builtin_ia32_scatterpfdpd((__mmask8)-1, (__v8si)(__m256i)(index), \
-                              (long long *)(addr), (int)(scale), \
+                              (void *)(addr), (int)(scale), \
                               (int)(hint))
 
 #define _mm512_mask_prefetch_i32scatter_pd(addr, mask, index, scale, hint) \
   __builtin_ia32_scatterpfdpd((__mmask8)(mask), (__v8si)(__m256i)(index), \
-                              (long long *)(addr), (int)(scale), \
+                              (void *)(addr), (int)(scale), \
                               (int)(hint))
 
 #define _mm512_prefetch_i32scatter_ps(addr, index, scale, hint) \
   __builtin_ia32_scatterpfdps((__mmask16)-1, (__v16si)(__m512i)(index), \
-                              (int *)(addr), (int)(scale), (int)(hint))
+                              (void *)(addr), (int)(scale), (int)(hint))
 
 #define _mm512_mask_prefetch_i32scatter_ps(addr, mask, index, scale, hint) \
   __builtin_ia32_scatterpfdps((__mmask16)(mask), \
-                              (__v16si)(__m512i)(index), (int *)(addr), \
+                              (__v16si)(__m512i)(index), (void *)(addr), \
                               (int)(scale), (int)(hint))
 
 #define _mm512_prefetch_i64scatter_pd(addr, index, scale, hint) \
   __builtin_ia32_scatterpfqpd((__mmask8)-1, (__v8di)(__m512i)(index), \
-                              (long long *)(addr), (int)(scale), \
+                              (void *)(addr), (int)(scale), \
                               (int)(hint))
 
 #define _mm512_mask_prefetch_i64scatter_pd(addr, mask, index, scale, hint) \
   __builtin_ia32_scatterpfqpd((__mmask8)(mask), (__v8di)(__m512i)(index), \
-                              (long long *)(addr), (int)(scale), \
+                              (void *)(addr), (int)(scale), \
                               (int)(hint))
 
 #define _mm512_prefetch_i64scatter_ps(addr, index, scale, hint) \
   __builtin_ia32_scatterpfqps((__mmask8)-1, (__v8di)(__m512i)(index), \
-                              (int *)(addr), (int)(scale), (int)(hint))
+                              (void *)(addr), (int)(scale), (int)(hint))
 
 #define _mm512_mask_prefetch_i64scatter_ps(addr, mask, index, scale, hint) \
   __builtin_ia32_scatterpfqps((__mmask8)(mask), (__v8di)(__m512i)(index), \
-                              (int *)(addr), (int)(scale), (int)(hint))
+                              (void *)(addr), (int)(scale), (int)(hint))
 
 #undef __DEFAULT_FN_ATTRS
 
diff --git a/lib/Headers/avx512vlintrin.h b/lib/Headers/avx512vlintrin.h
index c0ca297837..a2cdc0a96e 100644
--- a/lib/Headers/avx512vlintrin.h
+++ b/lib/Headers/avx512vlintrin.h
@@ -3484,162 +3484,162 @@ _mm256_maskz_scalef_ps (__mmask8 __U, __m256 __A, __m256 __B) {
 }
 
 #define _mm_i64scatter_pd(addr, index, v1, scale) \
-  __builtin_ia32_scatterdiv2df((double *)(addr), (__mmask8)-1, \
+  __builtin_ia32_scatterdiv2df((void *)(addr), (__mmask8)-1, \
                                (__v2di)(__m128i)(index), \
                                (__v2df)(__m128d)(v1), (int)(scale))
 
 #define _mm_mask_i64scatter_pd(addr, mask, index, v1, scale) \
-  __builtin_ia32_scatterdiv2df((double *)(addr), (__mmask8)(mask), \
+  __builtin_ia32_scatterdiv2df((void *)(addr), (__mmask8)(mask), \
                                (__v2di)(__m128i)(index), \
                                (__v2df)(__m128d)(v1), (int)(scale))
 
 #define _mm_i64scatter_epi64(addr, index, v1, scale) \
-  __builtin_ia32_scatterdiv2di((long long *)(addr), (__mmask8)-1, \
+  __builtin_ia32_scatterdiv2di((void *)(addr), (__mmask8)-1, \
                                (__v2di)(__m128i)(index), \
                                (__v2di)(__m128i)(v1), (int)(scale))
 
 #define _mm_mask_i64scatter_epi64(addr, mask, index, v1, scale) \
-  __builtin_ia32_scatterdiv2di((long long *)(addr), (__mmask8)(mask), \
+  __builtin_ia32_scatterdiv2di((void *)(addr), (__mmask8)(mask), \
                                (__v2di)(__m128i)(index), \
                                (__v2di)(__m128i)(v1), (int)(scale))
 
 #define _mm256_i64scatter_pd(addr, index, v1, scale) \
-  __builtin_ia32_scatterdiv4df((double *)(addr), (__mmask8)-1, \
+  __builtin_ia32_scatterdiv4df((void *)(addr), (__mmask8)-1, \
                                (__v4di)(__m256i)(index), \
                                (__v4df)(__m256d)(v1), (int)(scale))
 
 #define _mm256_mask_i64scatter_pd(addr, mask, index, v1, scale) \
-  __builtin_ia32_scatterdiv4df((double *)(addr), (__mmask8)(mask), \
+  __builtin_ia32_scatterdiv4df((void *)(addr), (__mmask8)(mask), \
                                (__v4di)(__m256i)(index), \
                                (__v4df)(__m256d)(v1), (int)(scale))
 
 #define _mm256_i64scatter_epi64(addr, index, v1, scale) \
-  __builtin_ia32_scatterdiv4di((long long *)(addr), (__mmask8)-1, \
+  __builtin_ia32_scatterdiv4di((void *)(addr), (__mmask8)-1, \
                                (__v4di)(__m256i)(index), \
                                (__v4di)(__m256i)(v1), (int)(scale))
 
 #define _mm256_mask_i64scatter_epi64(addr, mask, index, v1, scale) \
-  __builtin_ia32_scatterdiv4di((long long *)(addr), (__mmask8)(mask), \
+  __builtin_ia32_scatterdiv4di((void *)(addr), (__mmask8)(mask), \
                                (__v4di)(__m256i)(index), \
                                (__v4di)(__m256i)(v1), (int)(scale))
 
 #define _mm_i64scatter_ps(addr, index, v1, scale) \
-  __builtin_ia32_scatterdiv4sf((float *)(addr), (__mmask8)-1, \
+  __builtin_ia32_scatterdiv4sf((void *)(addr), (__mmask8)-1, \
                                (__v2di)(__m128i)(index), (__v4sf)(__m128)(v1), \
                                (int)(scale))
 
 #define _mm_mask_i64scatter_ps(addr, mask, index, v1, scale) \
-  __builtin_ia32_scatterdiv4sf((float *)(addr), (__mmask8)(mask), \
+  __builtin_ia32_scatterdiv4sf((void *)(addr), (__mmask8)(mask), \
                                (__v2di)(__m128i)(index), (__v4sf)(__m128)(v1), \
                                (int)(scale))
 
 #define _mm_i64scatter_epi32(addr, index, v1, scale) \
-  __builtin_ia32_scatterdiv4si((int *)(addr), (__mmask8)-1, \
+  __builtin_ia32_scatterdiv4si((void *)(addr), (__mmask8)-1, \
                                (__v2di)(__m128i)(index), \
                                (__v4si)(__m128i)(v1), (int)(scale))
 
 #define _mm_mask_i64scatter_epi32(addr, mask, index, v1, scale) \
-  __builtin_ia32_scatterdiv4si((int *)(addr), (__mmask8)(mask), \
+  __builtin_ia32_scatterdiv4si((void *)(addr), (__mmask8)(mask), \
                                (__v2di)(__m128i)(index), \
                                (__v4si)(__m128i)(v1), (int)(scale))
 
 #define _mm256_i64scatter_ps(addr, index, v1, scale) \
-  __builtin_ia32_scatterdiv8sf((float *)(addr), (__mmask8)-1, \
+  __builtin_ia32_scatterdiv8sf((void *)(addr), (__mmask8)-1, \
                                (__v4di)(__m256i)(index), (__v4sf)(__m128)(v1), \
                                (int)(scale))
 
 #define _mm256_mask_i64scatter_ps(addr, mask, index, v1, scale) \
-  __builtin_ia32_scatterdiv8sf((float *)(addr), (__mmask8)(mask), \
+  __builtin_ia32_scatterdiv8sf((void *)(addr), (__mmask8)(mask), \
                                (__v4di)(__m256i)(index), (__v4sf)(__m128)(v1), \
                                (int)(scale))
 
 #define _mm256_i64scatter_epi32(addr, index, v1, scale) \
-  __builtin_ia32_scatterdiv8si((int *)(addr), (__mmask8)-1, \
+  __builtin_ia32_scatterdiv8si((void *)(addr), (__mmask8)-1, \
                                (__v4di)(__m256i)(index), \
                                (__v4si)(__m128i)(v1), (int)(scale))
 
 #define _mm256_mask_i64scatter_epi32(addr, mask, index, v1, scale) \
-  __builtin_ia32_scatterdiv8si((int *)(addr), (__mmask8)(mask), \
+  __builtin_ia32_scatterdiv8si((void *)(addr), (__mmask8)(mask), \
                                (__v4di)(__m256i)(index), \
                                (__v4si)(__m128i)(v1), (int)(scale))
 
 #define _mm_i32scatter_pd(addr, index, v1, scale) \
-  __builtin_ia32_scattersiv2df((double *)(addr), (__mmask8)-1, \
+  __builtin_ia32_scattersiv2df((void *)(addr), (__mmask8)-1, \
                                (__v4si)(__m128i)(index), \
                                (__v2df)(__m128d)(v1), (int)(scale))
 
 #define _mm_mask_i32scatter_pd(addr, mask, index, v1, scale) \
-    __builtin_ia32_scattersiv2df((double *)(addr), (__mmask8)(mask), \
+    __builtin_ia32_scattersiv2df((void *)(addr), (__mmask8)(mask), \
                                  (__v4si)(__m128i)(index), \
                                  (__v2df)(__m128d)(v1), (int)(scale))
 
 #define _mm_i32scatter_epi64(addr, index, v1, scale) \
-    __builtin_ia32_scattersiv2di((long long *)(addr), (__mmask8)-1, \
+    __builtin_ia32_scattersiv2di((void *)(addr), (__mmask8)-1, \
                                  (__v4si)(__m128i)(index), \
                                  (__v2di)(__m128i)(v1), (int)(scale))
 
 #define _mm_mask_i32scatter_epi64(addr, mask, index, v1, scale) \
-    __builtin_ia32_scattersiv2di((long long *)(addr), (__mmask8)(mask), \
+    __builtin_ia32_scattersiv2di((void *)(addr), (__mmask8)(mask), \
                                  (__v4si)(__m128i)(index), \
                                  (__v2di)(__m128i)(v1), (int)(scale))
 
 #define _mm256_i32scatter_pd(addr, index, v1, scale) \
-    __builtin_ia32_scattersiv4df((double *)(addr), (__mmask8)-1, \
+    __builtin_ia32_scattersiv4df((void *)(addr), (__mmask8)-1, \
                                  (__v4si)(__m128i)(index), \
                                  (__v4df)(__m256d)(v1), (int)(scale))
 
 #define _mm256_mask_i32scatter_pd(addr, mask, index, v1, scale) \
-    __builtin_ia32_scattersiv4df((double *)(addr), (__mmask8)(mask), \
+    __builtin_ia32_scattersiv4df((void *)(addr), (__mmask8)(mask), \
                                  (__v4si)(__m128i)(index), \
                                  (__v4df)(__m256d)(v1), (int)(scale))
 
 #define _mm256_i32scatter_epi64(addr, index, v1, scale) \
-    __builtin_ia32_scattersiv4di((long long *)(addr), (__mmask8)-1, \
+    __builtin_ia32_scattersiv4di((void *)(addr), (__mmask8)-1, \
                                  (__v4si)(__m128i)(index), \
                                  (__v4di)(__m256i)(v1), (int)(scale))
 
 #define _mm256_mask_i32scatter_epi64(addr, mask, index, v1, scale) \
-    __builtin_ia32_scattersiv4di((long long *)(addr), (__mmask8)(mask), \
+    __builtin_ia32_scattersiv4di((void *)(addr), (__mmask8)(mask), \
                                  (__v4si)(__m128i)(index), \
                                  (__v4di)(__m256i)(v1), (int)(scale))
 
 #define _mm_i32scatter_ps(addr, index, v1, scale) \
-    __builtin_ia32_scattersiv4sf((float *)(addr), (__mmask8)-1, \
+    __builtin_ia32_scattersiv4sf((void *)(addr), (__mmask8)-1, \
                                  (__v4si)(__m128i)(index), (__v4sf)(__m128)(v1), \
                                  (int)(scale))
 
 #define _mm_mask_i32scatter_ps(addr, mask, index, v1, scale) \
-    __builtin_ia32_scattersiv4sf((float *)(addr), (__mmask8)(mask), \
+    __builtin_ia32_scattersiv4sf((void *)(addr), (__mmask8)(mask), \
                                  (__v4si)(__m128i)(index), (__v4sf)(__m128)(v1), \
                                  (int)(scale))
 
 #define _mm_i32scatter_epi32(addr, index, v1, scale) \
-    __builtin_ia32_scattersiv4si((int *)(addr), (__mmask8)-1, \
+    __builtin_ia32_scattersiv4si((void *)(addr), (__mmask8)-1, \
                                  (__v4si)(__m128i)(index), \
                                  (__v4si)(__m128i)(v1), (int)(scale))
 
 #define _mm_mask_i32scatter_epi32(addr, mask, index, v1, scale) \
-    __builtin_ia32_scattersiv4si((int *)(addr), (__mmask8)(mask), \
+    __builtin_ia32_scattersiv4si((void *)(addr), (__mmask8)(mask), \
                                  (__v4si)(__m128i)(index), \
                                  (__v4si)(__m128i)(v1), (int)(scale))
 
 #define _mm256_i32scatter_ps(addr, index, v1, scale) \
-    __builtin_ia32_scattersiv8sf((float *)(addr), (__mmask8)-1, \
+    __builtin_ia32_scattersiv8sf((void *)(addr), (__mmask8)-1, \
                                  (__v8si)(__m256i)(index), (__v8sf)(__m256)(v1), \
                                  (int)(scale))
 
 #define _mm256_mask_i32scatter_ps(addr, mask, index, v1, scale) \
-    __builtin_ia32_scattersiv8sf((float *)(addr), (__mmask8)(mask), \
+    __builtin_ia32_scattersiv8sf((void *)(addr), (__mmask8)(mask), \
                                  (__v8si)(__m256i)(index), (__v8sf)(__m256)(v1), \
                                  (int)(scale))
 
 #define _mm256_i32scatter_epi32(addr, index, v1, scale) \
-    __builtin_ia32_scattersiv8si((int *)(addr), (__mmask8)-1, \
+    __builtin_ia32_scattersiv8si((void *)(addr), (__mmask8)-1, \
                                  (__v8si)(__m256i)(index), \
                                  (__v8si)(__m256i)(v1), (int)(scale))
 
 #define _mm256_mask_i32scatter_epi32(addr, mask, index, v1, scale) \
-    __builtin_ia32_scattersiv8si((int *)(addr), (__mmask8)(mask), \
+    __builtin_ia32_scattersiv8si((void *)(addr), (__mmask8)(mask), \
                                  (__v8si)(__m256i)(index), \
                                  (__v8si)(__m256i)(v1), (int)(scale))
 
@@ -7984,97 +7984,97 @@ _mm256_mask_cvtepi64_storeu_epi16 (void * __P, __mmask8 __M, __m256i __A)
 
 #define _mm_mmask_i64gather_pd(v1_old, mask, index, addr, scale) \
   (__m128d)__builtin_ia32_gather3div2df((__v2df)(__m128d)(v1_old), \
-                                        (double const *)(addr), \
+                                        (void const *)(addr), \
                                         (__v2di)(__m128i)(index), \
                                         (__mmask8)(mask), (int)(scale))
 
 #define _mm_mmask_i64gather_epi64(v1_old, mask, index, addr, scale) \
   (__m128i)__builtin_ia32_gather3div2di((__v2di)(__m128i)(v1_old), \
-                                        (long long const *)(addr), \
+                                        (void const *)(addr), \
                                         (__v2di)(__m128i)(index), \
                                         (__mmask8)(mask), (int)(scale))
 
 #define _mm256_mmask_i64gather_pd(v1_old, mask, index, addr, scale) \
   (__m256d)__builtin_ia32_gather3div4df((__v4df)(__m256d)(v1_old), \
-                                        (double const *)(addr), \
+                                        (void const *)(addr), \
                                         (__v4di)(__m256i)(index), \
                                         (__mmask8)(mask), (int)(scale))
 
 #define _mm256_mmask_i64gather_epi64(v1_old, mask, index, addr, scale) \
   (__m256i)__builtin_ia32_gather3div4di((__v4di)(__m256i)(v1_old), \
-                                        (long long const *)(addr), \
+                                        (void const *)(addr), \
                                         (__v4di)(__m256i)(index), \
                                         (__mmask8)(mask), (int)(scale))
 
 #define _mm_mmask_i64gather_ps(v1_old, mask, index, addr, scale) \
   (__m128)__builtin_ia32_gather3div4sf((__v4sf)(__m128)(v1_old), \
-                                       (float const *)(addr), \
+                                       (void const *)(addr), \
                                        (__v2di)(__m128i)(index), \
                                        (__mmask8)(mask), (int)(scale))
 
 #define _mm_mmask_i64gather_epi32(v1_old, mask, index, addr, scale) \
   (__m128i)__builtin_ia32_gather3div4si((__v4si)(__m128i)(v1_old), \
-                                        (int const *)(addr), \
+                                        (void const *)(addr), \
                                         (__v2di)(__m128i)(index), \
                                         (__mmask8)(mask), (int)(scale))
 
 #define _mm256_mmask_i64gather_ps(v1_old, mask, index, addr, scale) \
   (__m128)__builtin_ia32_gather3div8sf((__v4sf)(__m128)(v1_old), \
-                                       (float const *)(addr), \
+                                       (void const *)(addr), \
                                        (__v4di)(__m256i)(index), \
                                        (__mmask8)(mask), (int)(scale))
 
 #define _mm256_mmask_i64gather_epi32(v1_old, mask, index, addr, scale) \
   (__m128i)__builtin_ia32_gather3div8si((__v4si)(__m128i)(v1_old), \
-                                        (int const *)(addr), \
+                                        (void const *)(addr), \
                                         (__v4di)(__m256i)(index), \
                                         (__mmask8)(mask), (int)(scale))
 
 #define _mm_mmask_i32gather_pd(v1_old, mask, index, addr, scale) \
   (__m128d)__builtin_ia32_gather3siv2df((__v2df)(__m128d)(v1_old), \
-                                        (double const *)(addr), \
+                                        (void const *)(addr), \
                                         (__v4si)(__m128i)(index), \
                                         (__mmask8)(mask), (int)(scale))
 
 #define _mm_mmask_i32gather_epi64(v1_old, mask, index, addr, scale) \
   (__m128i)__builtin_ia32_gather3siv2di((__v2di)(__m128i)(v1_old), \
-                                        (long long const *)(addr), \
+                                        (void const *)(addr), \
                                         (__v4si)(__m128i)(index), \
                                         (__mmask8)(mask), (int)(scale))
 
 #define _mm256_mmask_i32gather_pd(v1_old, mask, index, addr, scale) \
   (__m256d)__builtin_ia32_gather3siv4df((__v4df)(__m256d)(v1_old), \
-                                        (double const *)(addr), \
+                                        (void const *)(addr), \
                                         (__v4si)(__m128i)(index), \
                                         (__mmask8)(mask), (int)(scale))
 
 #define _mm256_mmask_i32gather_epi64(v1_old, mask, index, addr, scale) \
   (__m256i)__builtin_ia32_gather3siv4di((__v4di)(__m256i)(v1_old), \
-                                        (long long const *)(addr), \
+                                        (void const *)(addr), \
                                         (__v4si)(__m128i)(index), \
                                         (__mmask8)(mask), (int)(scale))
 
 #define _mm_mmask_i32gather_ps(v1_old, mask, index, addr, scale) \
   (__m128)__builtin_ia32_gather3siv4sf((__v4sf)(__m128)(v1_old), \
-                                       (float const *)(addr), \
+                                       (void const *)(addr), \
                                        (__v4si)(__m128i)(index), \
                                        (__mmask8)(mask), (int)(scale))
 
 #define _mm_mmask_i32gather_epi32(v1_old, mask, index, addr, scale) \
   (__m128i)__builtin_ia32_gather3siv4si((__v4si)(__m128i)(v1_old), \
-                                        (int const *)(addr), \
+                                        (void const *)(addr), \
                                         (__v4si)(__m128i)(index), \
                                         (__mmask8)(mask), (int)(scale))
 
 #define _mm256_mmask_i32gather_ps(v1_old, mask, index, addr, scale) \
   (__m256)__builtin_ia32_gather3siv8sf((__v8sf)(__m256)(v1_old), \
-                                       (float const *)(addr), \
+                                       (void const *)(addr), \
                                        (__v8si)(__m256i)(index), \
                                        (__mmask8)(mask), (int)(scale))
 
 #define _mm256_mmask_i32gather_epi32(v1_old, mask, index, addr, scale) \
   (__m256i)__builtin_ia32_gather3siv8si((__v8si)(__m256i)(v1_old), \
-                                        (int const *)(addr), \
+                                        (void const *)(addr), \
                                         (__v8si)(__m256i)(index), \
                                         (__mmask8)(mask), (int)(scale))
 
-- 
cgit v1.2.3


From 7f43dcfad8b0ba27dda9b1de50a9787f2473e928 Mon Sep 17 00:00:00 2001
From: Anastasia Stulova 
Date: Wed, 9 Jan 2019 11:25:09 +0000
Subject: Use DeclSpec for quals in DeclaratorChunk::FunctionTypeInfo.

Rather than duplicating data fields, use DeclSpec directly to store
the qualifiers for the functions/methods. This change doesn't handle
attributes yet and has to be extended further.

Differential revision: https://reviews.llvm.org/D55948



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350703 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/Sema/DeclSpec.h | 77 ++++++++++++++++++++++++++-----------------
 lib/Parse/ParseDecl.cpp       | 18 +++-------
 lib/Parse/ParseDeclCXX.cpp    | 34 +++++++------------
 lib/Parse/ParseExpr.cpp       |  4 ---
 lib/Parse/ParseExprCXX.cpp    | 12 ++-----
 lib/Sema/DeclSpec.cpp         | 53 +++++++++++++++++++++--------
 lib/Sema/SemaDecl.cpp         |  4 ---
 lib/Sema/SemaDeclCXX.cpp      | 32 +++++++-----------
 lib/Sema/SemaLambda.cpp       |  6 ++--
 lib/Sema/SemaType.cpp         | 27 ++++++++-------
 10 files changed, 135 insertions(+), 132 deletions(-)

diff --git a/include/clang/Sema/DeclSpec.h b/include/clang/Sema/DeclSpec.h
index b667e077f5..8d6f0bc914 100644
--- a/include/clang/Sema/DeclSpec.h
+++ b/include/clang/Sema/DeclSpec.h
@@ -593,6 +593,18 @@ public:
     FS_noreturnLoc = SourceLocation();
   }
 
+  /// This method calls the passed in handler on each CVRU qual being
+  /// set.
+  /// Handle - a handler to be invoked.
+  void forEachCVRUQualifier(
+      llvm::function_ref Handle);
+
+  /// This method calls the passed in handler on each qual being
+  /// set.
+  /// Handle - a handler to be invoked.
+  void forEachQualifier(
+      llvm::function_ref Handle);
+
   /// Return true if any type-specifier has been found.
   bool hasTypeSpecifier() const {
     return getTypeSpecType() != DeclSpec::TST_unspecified ||
@@ -683,6 +695,8 @@ public:
     ExprRep = Rep;
   }
 
+  bool SetTypeQual(TQ T, SourceLocation Loc);
+
   bool SetTypeQual(TQ T, SourceLocation Loc, const char *&PrevSpec,
                    unsigned &DiagID, const LangOptions &Lang);
 
@@ -1250,10 +1264,6 @@ struct DeclaratorChunk {
     /// Otherwise, it's an rvalue reference.
     unsigned RefQualifierIsLValueRef : 1;
 
-    /// The type qualifiers: const/volatile/restrict/__unaligned
-    /// The qualifier bitmask values are the same as in QualType.
-    unsigned TypeQuals : 4;
-
     /// ExceptionSpecType - An ExceptionSpecificationType value.
     unsigned ExceptionSpecType : 4;
 
@@ -1287,21 +1297,6 @@ struct DeclaratorChunk {
     /// If this is an invalid location, there is no ref-qualifier.
     unsigned RefQualifierLoc;
 
-    /// The location of the const-qualifier, if any.
-    ///
-    /// If this is an invalid location, there is no const-qualifier.
-    unsigned ConstQualifierLoc;
-
-    /// The location of the volatile-qualifier, if any.
-    ///
-    /// If this is an invalid location, there is no volatile-qualifier.
-    unsigned VolatileQualifierLoc;
-
-    /// The location of the restrict-qualifier, if any.
-    ///
-    /// If this is an invalid location, there is no restrict-qualifier.
-    unsigned RestrictQualifierLoc;
-
     /// The location of the 'mutable' qualifer in a lambda-declarator, if
     /// any.
     unsigned MutableLoc;
@@ -1317,6 +1312,12 @@ struct DeclaratorChunk {
     /// there are no parameters specified.
     ParamInfo *Params;
 
+    /// DeclSpec for the function with the qualifier related info.
+    DeclSpec *MethodQualifiers;
+
+    /// AtttibuteFactory for the MethodQualifiers.
+    AttributeFactory *QualAttrFactory;
+
     union {
       /// Pointer to a new[]'d array of TypeAndRange objects that
       /// contain the types in the function's dynamic exception specification
@@ -1356,6 +1357,8 @@ struct DeclaratorChunk {
 
     void destroy() {
       freeParams();
+      delete QualAttrFactory;
+      delete MethodQualifiers;
       switch (getExceptionSpecType()) {
       default:
         break;
@@ -1372,6 +1375,14 @@ struct DeclaratorChunk {
       }
     }
 
+    DeclSpec &getOrCreateMethodQualifiers() {
+      if (!MethodQualifiers) {
+        QualAttrFactory = new AttributeFactory();
+        MethodQualifiers = new DeclSpec(*QualAttrFactory);
+      }
+      return *MethodQualifiers;
+    }
+
     /// isKNRPrototype - Return true if this is a K&R style identifier list,
     /// like "void foo(a,b,c)".  In a function definition, this will be followed
     /// by the parameter type definitions.
@@ -1406,19 +1417,22 @@ struct DeclaratorChunk {
       return SourceLocation::getFromRawEncoding(RefQualifierLoc);
     }
 
-    /// Retrieve the location of the 'const' qualifier, if any.
+    /// Retrieve the location of the 'const' qualifier.
     SourceLocation getConstQualifierLoc() const {
-      return SourceLocation::getFromRawEncoding(ConstQualifierLoc);
+      assert(MethodQualifiers);
+      return MethodQualifiers->getConstSpecLoc();
     }
 
-    /// Retrieve the location of the 'volatile' qualifier, if any.
+    /// Retrieve the location of the 'volatile' qualifier.
     SourceLocation getVolatileQualifierLoc() const {
-      return SourceLocation::getFromRawEncoding(VolatileQualifierLoc);
+      assert(MethodQualifiers);
+      return MethodQualifiers->getVolatileSpecLoc();
     }
 
-    /// Retrieve the location of the 'restrict' qualifier, if any.
+    /// Retrieve the location of the 'restrict' qualifier.
     SourceLocation getRestrictQualifierLoc() const {
-      return SourceLocation::getFromRawEncoding(RestrictQualifierLoc);
+      assert(MethodQualifiers);
+      return MethodQualifiers->getRestrictSpecLoc();
     }
 
     /// Retrieve the location of the 'mutable' qualifier, if any.
@@ -1434,6 +1448,12 @@ struct DeclaratorChunk {
     /// qualifier.
     bool hasMutableQualifier() const { return getMutableLoc().isValid(); }
 
+    /// Determine whether this method has qualifiers.
+    bool hasMethodTypeQualifiers() const {
+      return MethodQualifiers && (MethodQualifiers->getTypeQualifiers() ||
+                                  MethodQualifiers->getAttributes().size());
+    }
+
     /// Get the type of exception specification this function has.
     ExceptionSpecificationType getExceptionSpecType() const {
       return static_cast(ExceptionSpecType);
@@ -1574,12 +1594,8 @@ struct DeclaratorChunk {
                                      ParamInfo *Params, unsigned NumParams,
                                      SourceLocation EllipsisLoc,
                                      SourceLocation RParenLoc,
-                                     unsigned TypeQuals,
                                      bool RefQualifierIsLvalueRef,
                                      SourceLocation RefQualifierLoc,
-                                     SourceLocation ConstQualifierLoc,
-                                     SourceLocation VolatileQualifierLoc,
-                                     SourceLocation RestrictQualifierLoc,
                                      SourceLocation MutableLoc,
                                      ExceptionSpecificationType ESpecType,
                                      SourceRange ESpecRange,
@@ -1593,7 +1609,8 @@ struct DeclaratorChunk {
                                      SourceLocation LocalRangeEnd,
                                      Declarator &TheDeclarator,
                                      TypeResult TrailingReturnType =
-                                                    TypeResult());
+                                                    TypeResult(),
+                                     DeclSpec *MethodQualifiers = nullptr);
 
   /// Return a DeclaratorChunk for a block.
   static DeclaratorChunk getBlockPointer(unsigned TypeQuals,
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 7538b635f0..298a2bad56 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -6072,9 +6072,6 @@ void Parser::ParseFunctionDeclarator(Declarator &D,
   DeclSpec DS(AttrFactory);
   bool RefQualifierIsLValueRef = true;
   SourceLocation RefQualifierLoc;
-  SourceLocation ConstQualifierLoc;
-  SourceLocation VolatileQualifierLoc;
-  SourceLocation RestrictQualifierLoc;
   ExceptionSpecificationType ESpecType = EST_None;
   SourceRange ESpecRange;
   SmallVector DynamicExceptions;
@@ -6137,9 +6134,6 @@ void Parser::ParseFunctionDeclarator(Declarator &D,
                                 }));
       if (!DS.getSourceRange().getEnd().isInvalid()) {
         EndLoc = DS.getSourceRange().getEnd();
-        ConstQualifierLoc = DS.getConstSpecLoc();
-        VolatileQualifierLoc = DS.getVolatileSpecLoc();
-        RestrictQualifierLoc = DS.getRestrictSpecLoc();
       }
 
       // Parse ref-qualifier[opt].
@@ -6239,15 +6233,13 @@ void Parser::ParseFunctionDeclarator(Declarator &D,
   D.AddTypeInfo(DeclaratorChunk::getFunction(
                     HasProto, IsAmbiguous, LParenLoc, ParamInfo.data(),
                     ParamInfo.size(), EllipsisLoc, RParenLoc,
-                    DS.getTypeQualifiers(), RefQualifierIsLValueRef,
-                    RefQualifierLoc, ConstQualifierLoc, VolatileQualifierLoc,
-                    RestrictQualifierLoc,
-                    /*MutableLoc=*/SourceLocation(), ESpecType, ESpecRange,
-                    DynamicExceptions.data(), DynamicExceptionRanges.data(),
-                    DynamicExceptions.size(),
+                    RefQualifierIsLValueRef, RefQualifierLoc,
+                    /*MutableLoc=*/SourceLocation(),
+                    ESpecType, ESpecRange, DynamicExceptions.data(),
+                    DynamicExceptionRanges.data(), DynamicExceptions.size(),
                     NoexceptExpr.isUsable() ? NoexceptExpr.get() : nullptr,
                     ExceptionSpecTokens, DeclsInPrototype, StartLoc,
-                    LocalEndLoc, D, TrailingReturnType),
+                    LocalEndLoc, D, TrailingReturnType, &DS),
                 std::move(FnAttrs), EndLoc);
 }
 
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp
index 02c73979ba..f8359f1e87 100644
--- a/lib/Parse/ParseDeclCXX.cpp
+++ b/lib/Parse/ParseDeclCXX.cpp
@@ -2346,32 +2346,22 @@ void Parser::MaybeParseAndDiagnoseDeclSpecAfterCXX11VirtSpecifierSeq(
   if (D.isFunctionDeclarator()) {
     auto &Function = D.getFunctionTypeInfo();
     if (DS.getTypeQualifiers() != DeclSpec::TQ_unspecified) {
-      auto DeclSpecCheck = [&] (DeclSpec::TQ TypeQual,
-                                const char *FixItName,
-                                SourceLocation SpecLoc,
-                                unsigned* QualifierLoc) {
+      auto DeclSpecCheck = [&](DeclSpec::TQ TypeQual, StringRef FixItName,
+                               SourceLocation SpecLoc) {
         FixItHint Insertion;
-        if (DS.getTypeQualifiers() & TypeQual) {
-          if (!(Function.TypeQuals & TypeQual)) {
-            std::string Name(FixItName);
-            Name += " ";
-            Insertion = FixItHint::CreateInsertion(VS.getFirstLocation(), Name);
-            Function.TypeQuals |= TypeQual;
-            *QualifierLoc = SpecLoc.getRawEncoding();
-          }
-          Diag(SpecLoc, diag::err_declspec_after_virtspec)
+        auto &MQ = Function.getOrCreateMethodQualifiers();
+        if (!(MQ.getTypeQualifiers() & TypeQual)) {
+          std::string Name(FixItName.data());
+          Name += " ";
+          Insertion = FixItHint::CreateInsertion(VS.getFirstLocation(), Name);
+          MQ.SetTypeQual(TypeQual, SpecLoc);
+        }
+        Diag(SpecLoc, diag::err_declspec_after_virtspec)
             << FixItName
             << VirtSpecifiers::getSpecifierName(VS.getLastSpecifier())
-            << FixItHint::CreateRemoval(SpecLoc)
-            << Insertion;
-        }
+            << FixItHint::CreateRemoval(SpecLoc) << Insertion;
       };
-      DeclSpecCheck(DeclSpec::TQ_const, "const", DS.getConstSpecLoc(),
-                    &Function.ConstQualifierLoc);
-      DeclSpecCheck(DeclSpec::TQ_volatile, "volatile", DS.getVolatileSpecLoc(),
-                    &Function.VolatileQualifierLoc);
-      DeclSpecCheck(DeclSpec::TQ_restrict, "restrict", DS.getRestrictSpecLoc(),
-                    &Function.RestrictQualifierLoc);
+      DS.forEachQualifier(DeclSpecCheck);
     }
 
     // Parse ref-qualifiers.
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index 194b07df46..4bcbebcbb4 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -3012,12 +3012,8 @@ ExprResult Parser::ParseBlockLiteralExpression() {
                                      /*NumArgs=*/0,
                                      /*EllipsisLoc=*/NoLoc,
                                      /*RParenLoc=*/NoLoc,
-                                     /*TypeQuals=*/0,
                                      /*RefQualifierIsLvalueRef=*/true,
                                      /*RefQualifierLoc=*/NoLoc,
-                                     /*ConstQualifierLoc=*/NoLoc,
-                                     /*VolatileQualifierLoc=*/NoLoc,
-                                     /*RestrictQualifierLoc=*/NoLoc,
                                      /*MutableLoc=*/NoLoc, EST_None,
                                      /*ESpecRange=*/SourceRange(),
                                      /*Exceptions=*/nullptr,
diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp
index 359bcf9e71..3caec6b4de 100644
--- a/lib/Parse/ParseExprCXX.cpp
+++ b/lib/Parse/ParseExprCXX.cpp
@@ -1206,12 +1206,8 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
                       /*hasProto=*/true,
                       /*isAmbiguous=*/false, LParenLoc, ParamInfo.data(),
                       ParamInfo.size(), EllipsisLoc, RParenLoc,
-                      DS.getTypeQualifiers(),
                       /*RefQualifierIsLValueRef=*/true,
-                      /*RefQualifierLoc=*/NoLoc,
-                      /*ConstQualifierLoc=*/NoLoc,
-                      /*VolatileQualifierLoc=*/NoLoc,
-                      /*RestrictQualifierLoc=*/NoLoc, MutableLoc, ESpecType,
+                      /*RefQualifierLoc=*/NoLoc, MutableLoc, ESpecType,
                       ESpecRange, DynamicExceptions.data(),
                       DynamicExceptionRanges.data(), DynamicExceptions.size(),
                       NoexceptExpr.isUsable() ? NoexceptExpr.get() : nullptr,
@@ -1273,12 +1269,8 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
                       /*NumParams=*/0,
                       /*EllipsisLoc=*/NoLoc,
                       /*RParenLoc=*/NoLoc,
-                      /*TypeQuals=*/0,
                       /*RefQualifierIsLValueRef=*/true,
-                      /*RefQualifierLoc=*/NoLoc,
-                      /*ConstQualifierLoc=*/NoLoc,
-                      /*VolatileQualifierLoc=*/NoLoc,
-                      /*RestrictQualifierLoc=*/NoLoc, MutableLoc, EST_None,
+                      /*RefQualifierLoc=*/NoLoc, MutableLoc, EST_None,
                       /*ESpecRange=*/SourceRange(),
                       /*Exceptions=*/nullptr,
                       /*ExceptionRanges=*/nullptr,
diff --git a/lib/Sema/DeclSpec.cpp b/lib/Sema/DeclSpec.cpp
index 2efa0a7fd1..8b002dac13 100644
--- a/lib/Sema/DeclSpec.cpp
+++ b/lib/Sema/DeclSpec.cpp
@@ -156,14 +156,8 @@ DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto,
                                              unsigned NumParams,
                                              SourceLocation EllipsisLoc,
                                              SourceLocation RParenLoc,
-                                             unsigned TypeQuals,
                                              bool RefQualifierIsLvalueRef,
                                              SourceLocation RefQualifierLoc,
-                                             SourceLocation ConstQualifierLoc,
-                                             SourceLocation
-                                                 VolatileQualifierLoc,
-                                             SourceLocation
-                                                 RestrictQualifierLoc,
                                              SourceLocation MutableLoc,
                                              ExceptionSpecificationType
                                                  ESpecType,
@@ -178,8 +172,9 @@ DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto,
                                              SourceLocation LocalRangeBegin,
                                              SourceLocation LocalRangeEnd,
                                              Declarator &TheDeclarator,
-                                             TypeResult TrailingReturnType) {
-  assert(!(TypeQuals & DeclSpec::TQ_atomic) &&
+                                             TypeResult TrailingReturnType,
+                                             DeclSpec *MethodQualifiers) {
+  assert(!(MethodQualifiers && MethodQualifiers->getTypeQualifiers() & DeclSpec::TQ_atomic) &&
          "function cannot have _Atomic qualifier");
 
   DeclaratorChunk I;
@@ -193,14 +188,10 @@ DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto,
   I.Fun.EllipsisLoc             = EllipsisLoc.getRawEncoding();
   I.Fun.RParenLoc               = RParenLoc.getRawEncoding();
   I.Fun.DeleteParams            = false;
-  I.Fun.TypeQuals               = TypeQuals;
   I.Fun.NumParams               = NumParams;
   I.Fun.Params                  = nullptr;
   I.Fun.RefQualifierIsLValueRef = RefQualifierIsLvalueRef;
   I.Fun.RefQualifierLoc         = RefQualifierLoc.getRawEncoding();
-  I.Fun.ConstQualifierLoc       = ConstQualifierLoc.getRawEncoding();
-  I.Fun.VolatileQualifierLoc    = VolatileQualifierLoc.getRawEncoding();
-  I.Fun.RestrictQualifierLoc    = RestrictQualifierLoc.getRawEncoding();
   I.Fun.MutableLoc              = MutableLoc.getRawEncoding();
   I.Fun.ExceptionSpecType       = ESpecType;
   I.Fun.ExceptionSpecLocBeg     = ESpecRange.getBegin().getRawEncoding();
@@ -211,8 +202,21 @@ DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto,
   I.Fun.HasTrailingReturnType   = TrailingReturnType.isUsable() ||
                                   TrailingReturnType.isInvalid();
   I.Fun.TrailingReturnType      = TrailingReturnType.get();
+  I.Fun.MethodQualifiers        = nullptr;
+  I.Fun.QualAttrFactory         = nullptr;
+
+  if (MethodQualifiers && (MethodQualifiers->getTypeQualifiers() ||
+                           MethodQualifiers->getAttributes().size())) {
+    auto &attrs = MethodQualifiers->getAttributes();
+    I.Fun.MethodQualifiers = new DeclSpec(attrs.getPool().getFactory());
+    MethodQualifiers->forEachCVRUQualifier(
+        [&](DeclSpec::TQ TypeQual, StringRef PrintName, SourceLocation SL) {
+          I.Fun.MethodQualifiers->SetTypeQual(TypeQual, SL);
+        });
+    I.Fun.MethodQualifiers->getAttributes().takeAllFrom(attrs);
+    I.Fun.MethodQualifiers->getAttributePool().takeAllFrom(attrs.getPool());
+  }
 
-  assert(I.Fun.TypeQuals == TypeQuals && "bitfield overflow");
   assert(I.Fun.ExceptionSpecType == ESpecType && "bitfield overflow");
 
   // new[] a parameter array if needed.
@@ -403,6 +407,24 @@ bool Declarator::isCtorOrDtor() {
          (getName().getKind() == UnqualifiedIdKind::IK_DestructorName);
 }
 
+void DeclSpec::forEachCVRUQualifier(
+    llvm::function_ref Handle) {
+  if (TypeQualifiers & TQ_const)
+    Handle(TQ_const, "const", TQ_constLoc);
+  if (TypeQualifiers & TQ_volatile)
+    Handle(TQ_volatile, "volatile", TQ_volatileLoc);
+  if (TypeQualifiers & TQ_restrict)
+    Handle(TQ_restrict, "restrict", TQ_restrictLoc);
+  if (TypeQualifiers & TQ_unaligned)
+    Handle(TQ_unaligned, "unaligned", TQ_unalignedLoc);
+}
+
+void DeclSpec::forEachQualifier(
+    llvm::function_ref Handle) {
+  forEachCVRUQualifier(Handle);
+  // FIXME: Add code below to iterate through the attributes and call Handle.
+}
+
 bool DeclSpec::hasTagDefinition() const {
   if (!TypeSpecOwned)
     return false;
@@ -862,6 +884,11 @@ bool DeclSpec::SetTypeQual(TQ T, SourceLocation Loc, const char *&PrevSpec,
       IsExtension = false;
     return BadSpecifier(T, T, PrevSpec, DiagID, IsExtension);
   }
+
+  return SetTypeQual(T, Loc);
+}
+
+bool DeclSpec::SetTypeQual(TQ T, SourceLocation Loc) {
   TypeQualifiers |= T;
 
   switch (T) {
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index f607873a73..2b88955285 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -13508,12 +13508,8 @@ NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc,
                                              /*NumParams=*/0,
                                              /*EllipsisLoc=*/NoLoc,
                                              /*RParenLoc=*/NoLoc,
-                                             /*TypeQuals=*/0,
                                              /*RefQualifierIsLvalueRef=*/true,
                                              /*RefQualifierLoc=*/NoLoc,
-                                             /*ConstQualifierLoc=*/NoLoc,
-                                             /*VolatileQualifierLoc=*/NoLoc,
-                                             /*RestrictQualifierLoc=*/NoLoc,
                                              /*MutableLoc=*/NoLoc, EST_None,
                                              /*ESpecRange=*/SourceRange(),
                                              /*Exceptions=*/nullptr,
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 4ab220fd03..e19b68718e 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -8174,16 +8174,12 @@ QualType Sema::CheckConstructorDeclarator(Declarator &D, QualType R,
   }
 
   DeclaratorChunk::FunctionTypeInfo &FTI = D.getFunctionTypeInfo();
-  if (FTI.TypeQuals != 0) {
-    if (FTI.TypeQuals & Qualifiers::Const)
-      Diag(D.getIdentifierLoc(), diag::err_invalid_qualified_constructor)
-        << "const" << SourceRange(D.getIdentifierLoc());
-    if (FTI.TypeQuals & Qualifiers::Volatile)
-      Diag(D.getIdentifierLoc(), diag::err_invalid_qualified_constructor)
-        << "volatile" << SourceRange(D.getIdentifierLoc());
-    if (FTI.TypeQuals & Qualifiers::Restrict)
-      Diag(D.getIdentifierLoc(), diag::err_invalid_qualified_constructor)
-        << "restrict" << SourceRange(D.getIdentifierLoc());
+  if (FTI.hasMethodTypeQualifiers()) {
+    FTI.MethodQualifiers->forEachQualifier(
+        [&](DeclSpec::TQ TypeQual, StringRef QualName, SourceLocation SL) {
+          Diag(SL, diag::err_invalid_qualified_constructor)
+              << QualName << SourceRange(SL);
+        });
     D.setInvalidType();
   }
 
@@ -8364,16 +8360,12 @@ QualType Sema::CheckDestructorDeclarator(Declarator &D, QualType R,
   }
 
   DeclaratorChunk::FunctionTypeInfo &FTI = D.getFunctionTypeInfo();
-  if (FTI.TypeQuals != 0 && !D.isInvalidType()) {
-    if (FTI.TypeQuals & Qualifiers::Const)
-      Diag(D.getIdentifierLoc(), diag::err_invalid_qualified_destructor)
-        << "const" << SourceRange(D.getIdentifierLoc());
-    if (FTI.TypeQuals & Qualifiers::Volatile)
-      Diag(D.getIdentifierLoc(), diag::err_invalid_qualified_destructor)
-        << "volatile" << SourceRange(D.getIdentifierLoc());
-    if (FTI.TypeQuals & Qualifiers::Restrict)
-      Diag(D.getIdentifierLoc(), diag::err_invalid_qualified_destructor)
-        << "restrict" << SourceRange(D.getIdentifierLoc());
+  if (FTI.hasMethodTypeQualifiers() && !D.isInvalidType()) {
+    FTI.MethodQualifiers->forEachQualifier(
+        [&](DeclSpec::TQ TypeQual, StringRef QualName, SourceLocation SL) {
+          Diag(SL, diag::err_invalid_qualified_destructor)
+              << QualName << SourceRange(SL);
+        });
     D.setInvalidType();
   }
 
diff --git a/lib/Sema/SemaLambda.cpp b/lib/Sema/SemaLambda.cpp
index c1c4572aa2..10f5e7b7bc 100644
--- a/lib/Sema/SemaLambda.cpp
+++ b/lib/Sema/SemaLambda.cpp
@@ -884,8 +884,10 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,
     //   This function call operator is declared const (9.3.1) if and only if
     //   the lambda-expression's parameter-declaration-clause is not followed
     //   by mutable. It is neither virtual nor declared volatile. [...]
-    if (!FTI.hasMutableQualifier())
-      FTI.TypeQuals |= DeclSpec::TQ_const;
+    if (!FTI.hasMutableQualifier()) {
+      FTI.getOrCreateMethodQualifiers().SetTypeQual(DeclSpec::TQ_const,
+                                                    SourceLocation());
+    }
 
     MethodTyInfo = GetTypeForDeclarator(ParamInfo, CurScope);
     assert(MethodTyInfo && "no type from lambda-declarator");
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index bd4a0e1407..bf2bfda9ce 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -724,12 +724,8 @@ static void maybeSynthesizeBlockSignature(TypeProcessingState &state,
       /*NumArgs=*/0,
       /*EllipsisLoc=*/NoLoc,
       /*RParenLoc=*/NoLoc,
-      /*TypeQuals=*/0,
       /*RefQualifierIsLvalueRef=*/true,
       /*RefQualifierLoc=*/NoLoc,
-      /*ConstQualifierLoc=*/NoLoc,
-      /*VolatileQualifierLoc=*/NoLoc,
-      /*RestrictQualifierLoc=*/NoLoc,
       /*MutableLoc=*/NoLoc, EST_None,
       /*ESpecRange=*/SourceRange(),
       /*Exceptions=*/nullptr,
@@ -737,8 +733,7 @@ static void maybeSynthesizeBlockSignature(TypeProcessingState &state,
       /*NumExceptions=*/0,
       /*NoexceptExpr=*/nullptr,
       /*ExceptionSpecTokens=*/nullptr,
-      /*DeclsInPrototype=*/None,
-      loc, loc, declarator));
+      /*DeclsInPrototype=*/None, loc, loc, declarator));
 
   // For consistency, make sure the state still has us as processing
   // the decl spec.
@@ -4460,7 +4455,8 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
       // does not have a K&R-style identifier list), then the arguments are part
       // of the type, otherwise the argument list is ().
       const DeclaratorChunk::FunctionTypeInfo &FTI = DeclType.Fun;
-      IsQualifiedFunction = FTI.TypeQuals || FTI.hasRefQualifier();
+      IsQualifiedFunction =
+          FTI.hasMethodTypeQualifiers() || FTI.hasRefQualifier();
 
       // Check for auto functions and trailing return type and adjust the
       // return type accordingly.
@@ -4698,7 +4694,9 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
         EPI.ExtInfo = EI;
         EPI.Variadic = FTI.isVariadic;
         EPI.HasTrailingReturn = FTI.hasTrailingReturnType();
-        EPI.TypeQuals.addCVRUQualifiers(FTI.TypeQuals);
+        EPI.TypeQuals.addCVRUQualifiers(
+            FTI.MethodQualifiers ? FTI.MethodQualifiers->getTypeQualifiers()
+                                 : 0);
         EPI.RefQualifier = !FTI.hasRefQualifier()? RQ_None
                     : FTI.RefQualifierIsLValueRef? RQ_LValue
                     : RQ_RValue;
@@ -5024,14 +5022,15 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
         SmallVector RemovalLocs;
         const DeclaratorChunk &Chunk = D.getTypeObject(I);
         assert(Chunk.Kind == DeclaratorChunk::Function);
+
         if (Chunk.Fun.hasRefQualifier())
           RemovalLocs.push_back(Chunk.Fun.getRefQualifierLoc());
-        if (Chunk.Fun.TypeQuals & Qualifiers::Const)
-          RemovalLocs.push_back(Chunk.Fun.getConstQualifierLoc());
-        if (Chunk.Fun.TypeQuals & Qualifiers::Volatile)
-          RemovalLocs.push_back(Chunk.Fun.getVolatileQualifierLoc());
-        if (Chunk.Fun.TypeQuals & Qualifiers::Restrict)
-          RemovalLocs.push_back(Chunk.Fun.getRestrictQualifierLoc());
+
+        if (Chunk.Fun.hasMethodTypeQualifiers())
+          Chunk.Fun.MethodQualifiers->forEachQualifier(
+              [&](DeclSpec::TQ TypeQual, StringRef QualName,
+                  SourceLocation SL) { RemovalLocs.push_back(SL); });
+
         if (!RemovalLocs.empty()) {
           llvm::sort(RemovalLocs,
                      BeforeThanCompare(S.getSourceManager()));
-- 
cgit v1.2.3


From 8db048138c2194434b3c69c8bddbb8340cac4ee1 Mon Sep 17 00:00:00 2001
From: Ilya Biryukov 
Date: Wed, 9 Jan 2019 13:08:11 +0000
Subject: [Driver] Fix libcxx detection on Darwin with clang run as ./clang

Summary:
By using '..' instead of fs::parent_path.

The intention of the code was to go from 'path/to/clang/bin' to
'path/to/clang/include'. In most cases parent_path works, however it
would fail when clang is run as './clang'.

This was noticed in Chromium's bug tracker, see
https://bugs.chromium.org/p/chromium/issues/detail?id=919761

Reviewers: arphaman, thakis, EricWF

Reviewed By: arphaman, thakis

Subscribers: christof, cfe-commits

Differential Revision: https://reviews.llvm.org/D56446

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350714 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/Driver/ToolChains/Darwin.cpp          | 9 +++++----
 test/Driver/darwin-stdlib.cpp             | 2 +-
 test/Tooling/Inputs/mock-libcxx/bin/clang | 1 +
 3 files changed, 7 insertions(+), 5 deletions(-)
 create mode 100644 test/Tooling/Inputs/mock-libcxx/bin/clang

diff --git a/lib/Driver/ToolChains/Darwin.cpp b/lib/Driver/ToolChains/Darwin.cpp
index 4e306fd960..50ecd13e69 100644
--- a/lib/Driver/ToolChains/Darwin.cpp
+++ b/lib/Driver/ToolChains/Darwin.cpp
@@ -1752,10 +1752,11 @@ void DarwinClang::AddClangCXXStdlibIncludeArgs(
       break;
     // On Darwin, libc++ may be installed alongside the compiler in
     // include/c++/v1.
-    // Get from 'foo/bin' to 'foo'.
-    SmallString<128> P = llvm::sys::path::parent_path(InstallDir);
-    // Get to 'foo/include/c++/v1'.
-    llvm::sys::path::append(P, "include", "c++", "v1");
+    // Get from 'foo/bin' to 'foo/include/c++/v1'.
+    SmallString<128> P = InstallDir;
+    // Note that InstallDir can be relative, so we have to '..' and not
+    // parent_path.
+    llvm::sys::path::append(P, "..", "include", "c++", "v1");
     addSystemInclude(DriverArgs, CC1Args, P);
     break;
   }
diff --git a/test/Driver/darwin-stdlib.cpp b/test/Driver/darwin-stdlib.cpp
index 3da92a26ee..3e89bd1ec9 100644
--- a/test/Driver/darwin-stdlib.cpp
+++ b/test/Driver/darwin-stdlib.cpp
@@ -14,7 +14,7 @@
 // optional absolute include for libc++ from InitHeaderSearch.cpp also fires.
 
 // CHECK-LIBCXX: "-stdlib=libc++"
-// CHECK-LIBCXX: "-internal-isystem" "{{[^"]*}}{{/|\\\\}}Inputs{{/|\\\\}}darwin_toolchain_tree{{/|\\\\}}bin{{/|\\\\}}include{{/|\\\\}}c++{{/|\\\\}}v1"
+// CHECK-LIBCXX: "-internal-isystem" "{{[^"]*}}{{/|\\\\}}Inputs{{/|\\\\}}darwin_toolchain_tree{{/|\\\\}}bin{{/|\\\\}}..{{/|\\\\}}include{{/|\\\\}}c++{{/|\\\\}}v1"
 
 // CHECK-LIBSTDCXX-NOT: -stdlib=libc++
 // CHECK-LIBSTDCXX-NOT: -stdlib=libstdc++
diff --git a/test/Tooling/Inputs/mock-libcxx/bin/clang b/test/Tooling/Inputs/mock-libcxx/bin/clang
new file mode 100644
index 0000000000..ed34c1f818
--- /dev/null
+++ b/test/Tooling/Inputs/mock-libcxx/bin/clang
@@ -0,0 +1 @@
+This file is a placeholder to keep its parent directory in git.
-- 
cgit v1.2.3


From 350d1e978c1c5c06f02adc1e1bbc82c1d653a6ad Mon Sep 17 00:00:00 2001
From: Florian Hahn 
Date: Wed, 9 Jan 2019 13:30:47 +0000
Subject: Revert r350648: "Fix clang for r350647: Missed a function rename"

The related commit r350647 breaks thread sanitizer on some macOS builders, e.g.
http://green.lab.llvm.org/green/job/clang-stage1-configure-RA/52725/


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350718 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/CodeGen/BackendUtil.cpp | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/lib/CodeGen/BackendUtil.cpp b/lib/CodeGen/BackendUtil.cpp
index 828ff2e66e..1311af9168 100644
--- a/lib/CodeGen/BackendUtil.cpp
+++ b/lib/CodeGen/BackendUtil.cpp
@@ -53,10 +53,9 @@
 #include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h"
 #include "llvm/Transforms/InstCombine/InstCombine.h"
 #include "llvm/Transforms/Instrumentation.h"
+#include "llvm/Transforms/Instrumentation/MemorySanitizer.h"
 #include "llvm/Transforms/Instrumentation/BoundsChecking.h"
 #include "llvm/Transforms/Instrumentation/GCOVProfiler.h"
-#include "llvm/Transforms/Instrumentation/MemorySanitizer.h"
-#include "llvm/Transforms/Instrumentation/ThreadSanitizer.h"
 #include "llvm/Transforms/ObjCARC.h"
 #include "llvm/Transforms/Scalar.h"
 #include "llvm/Transforms/Scalar/GVN.h"
@@ -306,7 +305,7 @@ static void addKernelMemorySanitizerPass(const PassManagerBuilder &Builder,
 
 static void addThreadSanitizerPass(const PassManagerBuilder &Builder,
                                    legacy::PassManagerBase &PM) {
-  PM.add(createThreadSanitizerLegacyPassPass());
+  PM.add(createThreadSanitizerPass());
 }
 
 static void addDataFlowSanitizerPass(const PassManagerBuilder &Builder,
-- 
cgit v1.2.3


From 6004d6a8927da10ed564c3b34c5340aa1ddb70b2 Mon Sep 17 00:00:00 2001
From: Nico Weber 
Date: Wed, 9 Jan 2019 14:19:16 +0000
Subject: Fix typo in comment

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350724 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/Sema/Sema.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index ab87704a40..c79ca74d32 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -4819,7 +4819,7 @@ public:
   ImplicitExceptionSpecification
   ComputeDefaultedCopyCtorExceptionSpec(CXXMethodDecl *MD);
 
-  /// Determine what sort of exception specification a defautled
+  /// Determine what sort of exception specification a defaulted
   /// copy assignment operator of a class will have, and whether the
   /// parameter will be const.
   ImplicitExceptionSpecification
-- 
cgit v1.2.3


From 51d9fdf26d5102dd92e18c0068c5f22662f30d35 Mon Sep 17 00:00:00 2001
From: Alexander Kornienko 
Date: Wed, 9 Jan 2019 15:00:06 +0000
Subject: Remove dependency-related arguments in clang-check.

This is the default behavior of clang tools, but clang-check overrides default
argument adjusters for some reason.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350727 91177308-0d34-0410-b5e6-96231b3b80d8
---
 tools/clang-check/ClangCheck.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tools/clang-check/ClangCheck.cpp b/tools/clang-check/ClangCheck.cpp
index 3e3d6763c1..66d865b749 100644
--- a/tools/clang-check/ClangCheck.cpp
+++ b/tools/clang-check/ClangCheck.cpp
@@ -167,6 +167,7 @@ int main(int argc, const char **argv) {
   // Clear adjusters because -fsyntax-only is inserted by the default chain.
   Tool.clearArgumentsAdjusters();
   Tool.appendArgumentsAdjuster(getClangStripOutputAdjuster());
+  Tool.appendArgumentsAdjuster(getClangStripDependencyFileAdjuster());
 
   // Running the analyzer requires --analyze. Other modes can work with the
   // -fsyntax-only option.
-- 
cgit v1.2.3


From 9cf7831cb862214a5c70ff20eed892222973b6ea Mon Sep 17 00:00:00 2001
From: Bruno Ricci 
Date: Wed, 9 Jan 2019 15:43:19 +0000
Subject: [AST] Store the results in OverloadExpr in a trailing array

Use the newly available space in the bit-fields of Stmt to pack
OverloadExpr, UnresolvedLookupExpr and UnresolvedMemberExpr.

Additionally store the results in the overload set in a trailing array.
This saves 1 pointer + 8 bytes per UnresolvedLookupExpr and
UnresolvedMemberExpr.

Differential Revision: https://reviews.llvm.org/D56368

Reviewed By: rjmccall



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350732 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/AST/ExprCXX.h         | 297 +++++++++++++++++++-----------------
 include/clang/AST/Stmt.h            |  58 +++++++
 lib/AST/ExprCXX.cpp                 | 234 +++++++++++++++-------------
 lib/Serialization/ASTReaderStmt.cpp |  58 ++++---
 lib/Serialization/ASTWriterStmt.cpp |  16 +-
 5 files changed, 388 insertions(+), 275 deletions(-)

diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index 15f2156418..2b75b68f11 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -2658,58 +2658,54 @@ public:
 /// A reference to an overloaded function set, either an
 /// \c UnresolvedLookupExpr or an \c UnresolvedMemberExpr.
 class OverloadExpr : public Expr {
+  friend class ASTStmtReader;
+  friend class ASTStmtWriter;
+
   /// The common name of these declarations.
   DeclarationNameInfo NameInfo;
 
   /// The nested-name-specifier that qualifies the name, if any.
   NestedNameSpecifierLoc QualifierLoc;
 
-  /// The results.  These are undesugared, which is to say, they may
-  /// include UsingShadowDecls.  Access is relative to the naming
-  /// class.
-  // FIXME: Allocate this data after the OverloadExpr subclass.
-  DeclAccessPair *Results = nullptr;
-
-  unsigned NumResults = 0;
-
 protected:
-  /// Whether the name includes info for explicit template
-  /// keyword and arguments.
-  bool HasTemplateKWAndArgsInfo = false;
-
-  OverloadExpr(StmtClass K, const ASTContext &C,
+  OverloadExpr(StmtClass SC, const ASTContext &Context,
                NestedNameSpecifierLoc QualifierLoc,
                SourceLocation TemplateKWLoc,
                const DeclarationNameInfo &NameInfo,
                const TemplateArgumentListInfo *TemplateArgs,
                UnresolvedSetIterator Begin, UnresolvedSetIterator End,
-               bool KnownDependent,
-               bool KnownInstantiationDependent,
+               bool KnownDependent, bool KnownInstantiationDependent,
                bool KnownContainsUnexpandedParameterPack);
 
-  OverloadExpr(StmtClass K, EmptyShell Empty) : Expr(K, Empty) {}
+  OverloadExpr(StmtClass SC, EmptyShell Empty, unsigned NumResults,
+               bool HasTemplateKWAndArgsInfo);
 
-  /// Return the optional template keyword and arguments info.
-  ASTTemplateKWAndArgsInfo *
-  getTrailingASTTemplateKWAndArgsInfo(); // defined far below.
+  /// Return the results. Defined after UnresolvedMemberExpr.
+  inline DeclAccessPair *getTrailingResults();
+  const DeclAccessPair *getTrailingResults() const {
+    return const_cast(this)->getTrailingResults();
+  }
 
   /// Return the optional template keyword and arguments info.
+  /// Defined after UnresolvedMemberExpr.
+  inline ASTTemplateKWAndArgsInfo *getTrailingASTTemplateKWAndArgsInfo();
   const ASTTemplateKWAndArgsInfo *getTrailingASTTemplateKWAndArgsInfo() const {
     return const_cast(this)
         ->getTrailingASTTemplateKWAndArgsInfo();
   }
 
-  /// Return the optional template arguments.
-  TemplateArgumentLoc *getTrailingTemplateArgumentLoc(); // defined far below
+  /// Return the optional template arguments. Defined after
+  /// UnresolvedMemberExpr.
+  inline TemplateArgumentLoc *getTrailingTemplateArgumentLoc();
+  const TemplateArgumentLoc *getTrailingTemplateArgumentLoc() const {
+    return const_cast(this)->getTrailingTemplateArgumentLoc();
+  }
 
-  void initializeResults(const ASTContext &C,
-                         UnresolvedSetIterator Begin,
-                         UnresolvedSetIterator End);
+  bool hasTemplateKWAndArgsInfo() const {
+    return OverloadExprBits.HasTemplateKWAndArgsInfo;
+  }
 
 public:
-  friend class ASTStmtReader;
-  friend class ASTStmtWriter;
-
   struct FindResult {
     OverloadExpr *Expression;
     bool IsAddressOfOperand;
@@ -2745,20 +2741,26 @@ public:
   }
 
   /// Gets the naming class of this lookup, if any.
-  CXXRecordDecl *getNamingClass() const;
+  /// Defined after UnresolvedMemberExpr.
+  inline CXXRecordDecl *getNamingClass();
+  const CXXRecordDecl *getNamingClass() const {
+    return const_cast(this)->getNamingClass();
+  }
 
   using decls_iterator = UnresolvedSetImpl::iterator;
 
-  decls_iterator decls_begin() const { return UnresolvedSetIterator(Results); }
+  decls_iterator decls_begin() const {
+    return UnresolvedSetIterator(getTrailingResults());
+  }
   decls_iterator decls_end() const {
-    return UnresolvedSetIterator(Results + NumResults);
+    return UnresolvedSetIterator(getTrailingResults() + getNumDecls());
   }
   llvm::iterator_range decls() const {
     return llvm::make_range(decls_begin(), decls_end());
   }
 
   /// Gets the number of declarations in the unresolved set.
-  unsigned getNumDecls() const { return NumResults; }
+  unsigned getNumDecls() const { return OverloadExprBits.NumResults; }
 
   /// Gets the full name info.
   const DeclarationNameInfo &getNameInfo() const { return NameInfo; }
@@ -2781,21 +2783,24 @@ public:
   /// Retrieve the location of the template keyword preceding
   /// this name, if any.
   SourceLocation getTemplateKeywordLoc() const {
-    if (!HasTemplateKWAndArgsInfo) return SourceLocation();
+    if (!hasTemplateKWAndArgsInfo())
+      return SourceLocation();
     return getTrailingASTTemplateKWAndArgsInfo()->TemplateKWLoc;
   }
 
   /// Retrieve the location of the left angle bracket starting the
   /// explicit template argument list following the name, if any.
   SourceLocation getLAngleLoc() const {
-    if (!HasTemplateKWAndArgsInfo) return SourceLocation();
+    if (!hasTemplateKWAndArgsInfo())
+      return SourceLocation();
     return getTrailingASTTemplateKWAndArgsInfo()->LAngleLoc;
   }
 
   /// Retrieve the location of the right angle bracket ending the
   /// explicit template argument list following the name, if any.
   SourceLocation getRAngleLoc() const {
-    if (!HasTemplateKWAndArgsInfo) return SourceLocation();
+    if (!hasTemplateKWAndArgsInfo())
+      return SourceLocation();
     return getTrailingASTTemplateKWAndArgsInfo()->RAngleLoc;
   }
 
@@ -2847,86 +2852,82 @@ public:
 /// members and therefore appear only in UnresolvedMemberLookupExprs.
 class UnresolvedLookupExpr final
     : public OverloadExpr,
-      private llvm::TrailingObjects<
-          UnresolvedLookupExpr, ASTTemplateKWAndArgsInfo, TemplateArgumentLoc> {
+      private llvm::TrailingObjects {
   friend class ASTStmtReader;
   friend class OverloadExpr;
   friend TrailingObjects;
 
-  /// True if these lookup results should be extended by
-  /// argument-dependent lookup if this is the operand of a function
-  /// call.
-  bool RequiresADL = false;
-
-  /// True if these lookup results are overloaded.  This is pretty
-  /// trivially rederivable if we urgently need to kill this field.
-  bool Overloaded = false;
-
   /// The naming class (C++ [class.access.base]p5) of the lookup, if
   /// any.  This can generally be recalculated from the context chain,
-  /// but that can be fairly expensive for unqualified lookups.  If we
-  /// want to improve memory use here, this could go in a union
-  /// against the qualified-lookup bits.
-  CXXRecordDecl *NamingClass = nullptr;
+  /// but that can be fairly expensive for unqualified lookups.
+  CXXRecordDecl *NamingClass;
 
-  UnresolvedLookupExpr(const ASTContext &C,
-                       CXXRecordDecl *NamingClass,
+  // UnresolvedLookupExpr is followed by several trailing objects.
+  // They are in order:
+  //
+  // * An array of getNumResults() DeclAccessPair for the results. These are
+  //   undesugared, which is to say, they may include UsingShadowDecls.
+  //   Access is relative to the naming class.
+  //
+  // * An optional ASTTemplateKWAndArgsInfo for the explicitly specified
+  //   template keyword and arguments. Present if and only if
+  //   hasTemplateKWAndArgsInfo().
+  //
+  // * An array of getNumTemplateArgs() TemplateArgumentLoc containing
+  //   location information for the explicitly specified template arguments.
+
+  UnresolvedLookupExpr(const ASTContext &Context, CXXRecordDecl *NamingClass,
                        NestedNameSpecifierLoc QualifierLoc,
                        SourceLocation TemplateKWLoc,
-                       const DeclarationNameInfo &NameInfo,
-                       bool RequiresADL, bool Overloaded,
+                       const DeclarationNameInfo &NameInfo, bool RequiresADL,
+                       bool Overloaded,
                        const TemplateArgumentListInfo *TemplateArgs,
-                       UnresolvedSetIterator Begin, UnresolvedSetIterator End)
-      : OverloadExpr(UnresolvedLookupExprClass, C, QualifierLoc, TemplateKWLoc,
-                     NameInfo, TemplateArgs, Begin, End, false, false, false),
-        RequiresADL(RequiresADL),
-        Overloaded(Overloaded), NamingClass(NamingClass) {}
+                       UnresolvedSetIterator Begin, UnresolvedSetIterator End);
 
-  UnresolvedLookupExpr(EmptyShell Empty)
-      : OverloadExpr(UnresolvedLookupExprClass, Empty) {}
+  UnresolvedLookupExpr(EmptyShell Empty, unsigned NumResults,
+                       bool HasTemplateKWAndArgsInfo);
 
-  size_t numTrailingObjects(OverloadToken) const {
-    return HasTemplateKWAndArgsInfo ? 1 : 0;
+  unsigned numTrailingObjects(OverloadToken) const {
+    return getNumDecls();
+  }
+
+  unsigned numTrailingObjects(OverloadToken) const {
+    return hasTemplateKWAndArgsInfo();
   }
 
 public:
-  static UnresolvedLookupExpr *Create(const ASTContext &C,
-                                      CXXRecordDecl *NamingClass,
-                                      NestedNameSpecifierLoc QualifierLoc,
-                                      const DeclarationNameInfo &NameInfo,
-                                      bool ADL, bool Overloaded,
-                                      UnresolvedSetIterator Begin,
-                                      UnresolvedSetIterator End) {
-    return new(C) UnresolvedLookupExpr(C, NamingClass, QualifierLoc,
-                                       SourceLocation(), NameInfo,
-                                       ADL, Overloaded, nullptr, Begin, End);
-  }
-
-  static UnresolvedLookupExpr *Create(const ASTContext &C,
-                                      CXXRecordDecl *NamingClass,
-                                      NestedNameSpecifierLoc QualifierLoc,
-                                      SourceLocation TemplateKWLoc,
-                                      const DeclarationNameInfo &NameInfo,
-                                      bool ADL,
-                                      const TemplateArgumentListInfo *Args,
-                                      UnresolvedSetIterator Begin,
-                                      UnresolvedSetIterator End);
-
-  static UnresolvedLookupExpr *CreateEmpty(const ASTContext &C,
+  static UnresolvedLookupExpr *
+  Create(const ASTContext &Context, CXXRecordDecl *NamingClass,
+         NestedNameSpecifierLoc QualifierLoc,
+         const DeclarationNameInfo &NameInfo, bool RequiresADL, bool Overloaded,
+         UnresolvedSetIterator Begin, UnresolvedSetIterator End);
+
+  static UnresolvedLookupExpr *
+  Create(const ASTContext &Context, CXXRecordDecl *NamingClass,
+         NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc,
+         const DeclarationNameInfo &NameInfo, bool RequiresADL,
+         const TemplateArgumentListInfo *Args, UnresolvedSetIterator Begin,
+         UnresolvedSetIterator End);
+
+  static UnresolvedLookupExpr *CreateEmpty(const ASTContext &Context,
+                                           unsigned NumResults,
                                            bool HasTemplateKWAndArgsInfo,
                                            unsigned NumTemplateArgs);
 
   /// True if this declaration should be extended by
   /// argument-dependent lookup.
-  bool requiresADL() const { return RequiresADL; }
+  bool requiresADL() const { return UnresolvedLookupExprBits.RequiresADL; }
 
   /// True if this lookup is overloaded.
-  bool isOverloaded() const { return Overloaded; }
+  bool isOverloaded() const { return UnresolvedLookupExprBits.Overloaded; }
 
   /// Gets the 'naming class' (in the sense of C++0x
   /// [class.access.base]p5) of the lookup.  This is the scope
   /// that was looked in to find these results.
-  CXXRecordDecl *getNamingClass() const { return NamingClass; }
+  CXXRecordDecl *getNamingClass() { return NamingClass; }
+  const CXXRecordDecl *getNamingClass() const { return NamingClass; }
 
   SourceLocation getBeginLoc() const LLVM_READONLY {
     if (NestedNameSpecifierLoc l = getQualifierLoc())
@@ -3561,25 +3562,18 @@ public:
 /// DeclRefExpr, depending on whether the member is static.
 class UnresolvedMemberExpr final
     : public OverloadExpr,
-      private llvm::TrailingObjects<
-          UnresolvedMemberExpr, ASTTemplateKWAndArgsInfo, TemplateArgumentLoc> {
+      private llvm::TrailingObjects {
   friend class ASTStmtReader;
   friend class OverloadExpr;
   friend TrailingObjects;
 
-  /// Whether this member expression used the '->' operator or
-  /// the '.' operator.
-  bool IsArrow : 1;
-
-  /// Whether the lookup results contain an unresolved using
-  /// declaration.
-  bool HasUnresolvedUsing : 1;
-
   /// The expression for the base pointer or class reference,
   /// e.g., the \c x in x.f.
   ///
   /// This can be null if this is an 'unbased' member expression.
-  Stmt *Base = nullptr;
+  Stmt *Base;
 
   /// The type of the base expression; never null.
   QualType BaseType;
@@ -3587,7 +3581,21 @@ class UnresolvedMemberExpr final
   /// The location of the '->' or '.' operator.
   SourceLocation OperatorLoc;
 
-  UnresolvedMemberExpr(const ASTContext &C, bool HasUnresolvedUsing,
+  // UnresolvedMemberExpr is followed by several trailing objects.
+  // They are in order:
+  //
+  // * An array of getNumResults() DeclAccessPair for the results. These are
+  //   undesugared, which is to say, they may include UsingShadowDecls.
+  //   Access is relative to the naming class.
+  //
+  // * An optional ASTTemplateKWAndArgsInfo for the explicitly specified
+  //   template keyword and arguments. Present if and only if
+  //   hasTemplateKWAndArgsInfo().
+  //
+  // * An array of getNumTemplateArgs() TemplateArgumentLoc containing
+  //   location information for the explicitly specified template arguments.
+
+  UnresolvedMemberExpr(const ASTContext &Context, bool HasUnresolvedUsing,
                        Expr *Base, QualType BaseType, bool IsArrow,
                        SourceLocation OperatorLoc,
                        NestedNameSpecifierLoc QualifierLoc,
@@ -3596,28 +3604,30 @@ class UnresolvedMemberExpr final
                        const TemplateArgumentListInfo *TemplateArgs,
                        UnresolvedSetIterator Begin, UnresolvedSetIterator End);
 
-  UnresolvedMemberExpr(EmptyShell Empty)
-      : OverloadExpr(UnresolvedMemberExprClass, Empty), IsArrow(false),
-        HasUnresolvedUsing(false) {}
+  UnresolvedMemberExpr(EmptyShell Empty, unsigned NumResults,
+                       bool HasTemplateKWAndArgsInfo);
 
-  size_t numTrailingObjects(OverloadToken) const {
-    return HasTemplateKWAndArgsInfo ? 1 : 0;
+  unsigned numTrailingObjects(OverloadToken) const {
+    return getNumDecls();
+  }
+
+  unsigned numTrailingObjects(OverloadToken) const {
+    return hasTemplateKWAndArgsInfo();
   }
 
 public:
   static UnresolvedMemberExpr *
-  Create(const ASTContext &C, bool HasUnresolvedUsing,
-         Expr *Base, QualType BaseType, bool IsArrow,
-         SourceLocation OperatorLoc,
-         NestedNameSpecifierLoc QualifierLoc,
-         SourceLocation TemplateKWLoc,
+  Create(const ASTContext &Context, bool HasUnresolvedUsing, Expr *Base,
+         QualType BaseType, bool IsArrow, SourceLocation OperatorLoc,
+         NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc,
          const DeclarationNameInfo &MemberNameInfo,
          const TemplateArgumentListInfo *TemplateArgs,
          UnresolvedSetIterator Begin, UnresolvedSetIterator End);
 
-  static UnresolvedMemberExpr *
-  CreateEmpty(const ASTContext &C, bool HasTemplateKWAndArgsInfo,
-              unsigned NumTemplateArgs);
+  static UnresolvedMemberExpr *CreateEmpty(const ASTContext &Context,
+                                           unsigned NumResults,
+                                           bool HasTemplateKWAndArgsInfo,
+                                           unsigned NumTemplateArgs);
 
   /// True if this is an implicit access, i.e., one in which the
   /// member being accessed was not written in the source.
@@ -3640,32 +3650,36 @@ public:
 
   /// Determine whether the lookup results contain an unresolved using
   /// declaration.
-  bool hasUnresolvedUsing() const { return HasUnresolvedUsing; }
+  bool hasUnresolvedUsing() const {
+    return UnresolvedMemberExprBits.HasUnresolvedUsing;
+  }
 
   /// Determine whether this member expression used the '->'
   /// operator; otherwise, it used the '.' operator.
-  bool isArrow() const { return IsArrow; }
+  bool isArrow() const { return UnresolvedMemberExprBits.IsArrow; }
 
   /// Retrieve the location of the '->' or '.' operator.
   SourceLocation getOperatorLoc() const { return OperatorLoc; }
 
   /// Retrieve the naming class of this lookup.
-  CXXRecordDecl *getNamingClass() const;
+  CXXRecordDecl *getNamingClass();
+  const CXXRecordDecl *getNamingClass() const {
+    return const_cast(this)->getNamingClass();
+  }
 
   /// Retrieve the full name info for the member that this expression
   /// refers to.
   const DeclarationNameInfo &getMemberNameInfo() const { return getNameInfo(); }
 
-  /// Retrieve the name of the member that this expression
-  /// refers to.
+  /// Retrieve the name of the member that this expression refers to.
   DeclarationName getMemberName() const { return getName(); }
 
-  // Retrieve the location of the name of the member that this
-  // expression refers to.
+  /// Retrieve the location of the name of the member that this
+  /// expression refers to.
   SourceLocation getMemberLoc() const { return getNameLoc(); }
 
-  // Return the preferred location (the member name) for the arrow when
-  // diagnosing a problem with this expression.
+  /// Return the preferred location (the member name) for the arrow when
+  /// diagnosing a problem with this expression.
   SourceLocation getExprLoc() const LLVM_READONLY { return getMemberLoc(); }
 
   SourceLocation getBeginLoc() const LLVM_READONLY {
@@ -3694,26 +3708,33 @@ public:
   }
 };
 
-inline ASTTemplateKWAndArgsInfo *
-OverloadExpr::getTrailingASTTemplateKWAndArgsInfo() {
-  if (!HasTemplateKWAndArgsInfo)
+DeclAccessPair *OverloadExpr::getTrailingResults() {
+  if (auto *ULE = dyn_cast(this))
+    return ULE->getTrailingObjects();
+  return cast(this)->getTrailingObjects();
+}
+
+ASTTemplateKWAndArgsInfo *OverloadExpr::getTrailingASTTemplateKWAndArgsInfo() {
+  if (!hasTemplateKWAndArgsInfo())
     return nullptr;
 
-  if (isa(this))
-    return cast(this)
-        ->getTrailingObjects();
-  else
-    return cast(this)
-        ->getTrailingObjects();
+  if (auto *ULE = dyn_cast(this))
+    return ULE->getTrailingObjects();
+  return cast(this)
+      ->getTrailingObjects();
+}
+
+TemplateArgumentLoc *OverloadExpr::getTrailingTemplateArgumentLoc() {
+  if (auto *ULE = dyn_cast(this))
+    return ULE->getTrailingObjects();
+  return cast(this)
+      ->getTrailingObjects();
 }
 
-inline TemplateArgumentLoc *OverloadExpr::getTrailingTemplateArgumentLoc() {
-  if (isa(this))
-    return cast(this)
-        ->getTrailingObjects();
-  else
-    return cast(this)
-        ->getTrailingObjects();
+CXXRecordDecl *OverloadExpr::getNamingClass() {
+  if (auto *ULE = dyn_cast(this))
+    return ULE->getNamingClass();
+  return cast(this)->getNamingClass();
 }
 
 /// Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]).
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index 162cfa52ed..2f33fec71b 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -769,6 +769,61 @@ protected:
     SourceLocation OperatorLoc;
   };
 
+  class OverloadExprBitfields {
+    friend class ASTStmtReader;
+    friend class OverloadExpr;
+
+    unsigned : NumExprBits;
+
+    /// Whether the name includes info for explicit template
+    /// keyword and arguments.
+    unsigned HasTemplateKWAndArgsInfo : 1;
+
+    /// Padding used by the derived classes to store various bits. If you
+    /// need to add some data here, shrink this padding and add your data
+    /// above. NumOverloadExprBits also needs to be updated.
+    unsigned : 32 - NumExprBits - 1;
+
+    /// The number of results.
+    unsigned NumResults;
+  };
+  enum { NumOverloadExprBits = NumExprBits + 1 };
+
+  class UnresolvedLookupExprBitfields {
+    friend class ASTStmtReader;
+    friend class UnresolvedLookupExpr;
+
+    unsigned : NumOverloadExprBits;
+
+    /// True if these lookup results should be extended by
+    /// argument-dependent lookup if this is the operand of a function call.
+    unsigned RequiresADL : 1;
+
+    /// True if these lookup results are overloaded.  This is pretty trivially
+    /// rederivable if we urgently need to kill this field.
+    unsigned Overloaded : 1;
+  };
+  static_assert(sizeof(UnresolvedLookupExprBitfields) <= 4,
+                "UnresolvedLookupExprBitfields must be <= than 4 bytes to"
+                "avoid trashing OverloadExprBitfields::NumResults!");
+
+  class UnresolvedMemberExprBitfields {
+    friend class ASTStmtReader;
+    friend class UnresolvedMemberExpr;
+
+    unsigned : NumOverloadExprBits;
+
+    /// Whether this member expression used the '->' operator or
+    /// the '.' operator.
+    unsigned IsArrow : 1;
+
+    /// Whether the lookup results contain an unresolved using declaration.
+    unsigned HasUnresolvedUsing : 1;
+  };
+  static_assert(sizeof(UnresolvedMemberExprBitfields) <= 4,
+                "UnresolvedMemberExprBitfields must be <= than 4 bytes to"
+                "avoid trashing OverloadExprBitfields::NumResults!");
+
   class CXXNoexceptExprBitfields {
     friend class ASTStmtReader;
     friend class CXXNoexceptExpr;
@@ -877,6 +932,9 @@ protected:
     ExprWithCleanupsBitfields ExprWithCleanupsBits;
     CXXUnresolvedConstructExprBitfields CXXUnresolvedConstructExprBits;
     CXXDependentScopeMemberExprBitfields CXXDependentScopeMemberExprBits;
+    OverloadExprBitfields OverloadExprBits;
+    UnresolvedLookupExprBitfields UnresolvedLookupExprBits;
+    UnresolvedMemberExprBitfields UnresolvedMemberExprBits;
     CXXNoexceptExprBitfields CXXNoexceptExprBits;
     SubstNonTypeTemplateParmExprBitfields SubstNonTypeTemplateParmExprBits;
 
diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp
index 9a724cd08e..699baa71f3 100644
--- a/lib/AST/ExprCXX.cpp
+++ b/lib/AST/ExprCXX.cpp
@@ -302,68 +302,95 @@ SourceLocation CXXPseudoDestructorExpr::getEndLoc() const {
 }
 
 // UnresolvedLookupExpr
-UnresolvedLookupExpr *
-UnresolvedLookupExpr::Create(const ASTContext &C,
-                             CXXRecordDecl *NamingClass,
-                             NestedNameSpecifierLoc QualifierLoc,
-                             SourceLocation TemplateKWLoc,
-                             const DeclarationNameInfo &NameInfo,
-                             bool ADL,
-                             const TemplateArgumentListInfo *Args,
-                             UnresolvedSetIterator Begin,
-                             UnresolvedSetIterator End) {
-  assert(Args || TemplateKWLoc.isValid());
-  unsigned num_args = Args ? Args->size() : 0;
+UnresolvedLookupExpr::UnresolvedLookupExpr(
+    const ASTContext &Context, CXXRecordDecl *NamingClass,
+    NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc,
+    const DeclarationNameInfo &NameInfo, bool RequiresADL, bool Overloaded,
+    const TemplateArgumentListInfo *TemplateArgs, UnresolvedSetIterator Begin,
+    UnresolvedSetIterator End)
+    : OverloadExpr(UnresolvedLookupExprClass, Context, QualifierLoc,
+                   TemplateKWLoc, NameInfo, TemplateArgs, Begin, End, false,
+                   false, false),
+      NamingClass(NamingClass) {
+  UnresolvedLookupExprBits.RequiresADL = RequiresADL;
+  UnresolvedLookupExprBits.Overloaded = Overloaded;
+}
+
+UnresolvedLookupExpr::UnresolvedLookupExpr(EmptyShell Empty,
+                                           unsigned NumResults,
+                                           bool HasTemplateKWAndArgsInfo)
+    : OverloadExpr(UnresolvedLookupExprClass, Empty, NumResults,
+                   HasTemplateKWAndArgsInfo) {}
+
+UnresolvedLookupExpr *UnresolvedLookupExpr::Create(
+    const ASTContext &Context, CXXRecordDecl *NamingClass,
+    NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo,
+    bool RequiresADL, bool Overloaded, UnresolvedSetIterator Begin,
+    UnresolvedSetIterator End) {
+  unsigned NumResults = End - Begin;
+  unsigned Size = totalSizeToAlloc(NumResults, 0, 0);
+  void *Mem = Context.Allocate(Size, alignof(UnresolvedLookupExpr));
+  return new (Mem) UnresolvedLookupExpr(Context, NamingClass, QualifierLoc,
+                                        SourceLocation(), NameInfo, RequiresADL,
+                                        Overloaded, nullptr, Begin, End);
+}
 
-  std::size_t Size =
-      totalSizeToAlloc(1,
-                                                                      num_args);
-  void *Mem = C.Allocate(Size, alignof(UnresolvedLookupExpr));
-  return new (Mem) UnresolvedLookupExpr(C, NamingClass, QualifierLoc,
-                                        TemplateKWLoc, NameInfo,
-                                        ADL, /*Overload*/ true, Args,
-                                        Begin, End);
-}
-
-UnresolvedLookupExpr *
-UnresolvedLookupExpr::CreateEmpty(const ASTContext &C,
-                                  bool HasTemplateKWAndArgsInfo,
-                                  unsigned NumTemplateArgs) {
+UnresolvedLookupExpr *UnresolvedLookupExpr::Create(
+    const ASTContext &Context, CXXRecordDecl *NamingClass,
+    NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc,
+    const DeclarationNameInfo &NameInfo, bool RequiresADL,
+    const TemplateArgumentListInfo *Args, UnresolvedSetIterator Begin,
+    UnresolvedSetIterator End) {
+  assert(Args || TemplateKWLoc.isValid());
+  unsigned NumResults = End - Begin;
+  unsigned NumTemplateArgs = Args ? Args->size() : 0;
+  unsigned Size =
+      totalSizeToAlloc(NumResults, 1, NumTemplateArgs);
+  void *Mem = Context.Allocate(Size, alignof(UnresolvedLookupExpr));
+  return new (Mem) UnresolvedLookupExpr(Context, NamingClass, QualifierLoc,
+                                        TemplateKWLoc, NameInfo, RequiresADL,
+                                        /*Overloaded*/ true, Args, Begin, End);
+}
+
+UnresolvedLookupExpr *UnresolvedLookupExpr::CreateEmpty(
+    const ASTContext &Context, unsigned NumResults,
+    bool HasTemplateKWAndArgsInfo, unsigned NumTemplateArgs) {
   assert(NumTemplateArgs == 0 || HasTemplateKWAndArgsInfo);
-  std::size_t Size =
-      totalSizeToAlloc(
-          HasTemplateKWAndArgsInfo, NumTemplateArgs);
-  void *Mem = C.Allocate(Size, alignof(UnresolvedLookupExpr));
-  auto *E = new (Mem) UnresolvedLookupExpr(EmptyShell());
-  E->HasTemplateKWAndArgsInfo = HasTemplateKWAndArgsInfo;
-  return E;
+  unsigned Size = totalSizeToAlloc(
+      NumResults, HasTemplateKWAndArgsInfo, NumTemplateArgs);
+  void *Mem = Context.Allocate(Size, alignof(UnresolvedLookupExpr));
+  return new (Mem)
+      UnresolvedLookupExpr(EmptyShell(), NumResults, HasTemplateKWAndArgsInfo);
 }
 
-OverloadExpr::OverloadExpr(StmtClass K, const ASTContext &C,
+OverloadExpr::OverloadExpr(StmtClass SC, const ASTContext &Context,
                            NestedNameSpecifierLoc QualifierLoc,
                            SourceLocation TemplateKWLoc,
                            const DeclarationNameInfo &NameInfo,
                            const TemplateArgumentListInfo *TemplateArgs,
                            UnresolvedSetIterator Begin,
-                           UnresolvedSetIterator End,
-                           bool KnownDependent,
+                           UnresolvedSetIterator End, bool KnownDependent,
                            bool KnownInstantiationDependent,
                            bool KnownContainsUnexpandedParameterPack)
-    : Expr(K, C.OverloadTy, VK_LValue, OK_Ordinary, KnownDependent,
-           KnownDependent,
-           (KnownInstantiationDependent ||
-            NameInfo.isInstantiationDependent() ||
-            (QualifierLoc &&
+    : Expr(
+          SC, Context.OverloadTy, VK_LValue, OK_Ordinary, KnownDependent,
+          KnownDependent,
+          (KnownInstantiationDependent || NameInfo.isInstantiationDependent() ||
+           (QualifierLoc &&
             QualifierLoc.getNestedNameSpecifier()->isInstantiationDependent())),
-           (KnownContainsUnexpandedParameterPack ||
-            NameInfo.containsUnexpandedParameterPack() ||
-            (QualifierLoc &&
-             QualifierLoc.getNestedNameSpecifier()
-                                        ->containsUnexpandedParameterPack()))),
-      NameInfo(NameInfo), QualifierLoc(QualifierLoc), NumResults(End - Begin),
-      HasTemplateKWAndArgsInfo(TemplateArgs != nullptr ||
-                               TemplateKWLoc.isValid()) {
-  NumResults = End - Begin;
+          (KnownContainsUnexpandedParameterPack ||
+           NameInfo.containsUnexpandedParameterPack() ||
+           (QualifierLoc && QualifierLoc.getNestedNameSpecifier()
+                                ->containsUnexpandedParameterPack()))),
+      NameInfo(NameInfo), QualifierLoc(QualifierLoc) {
+  unsigned NumResults = End - Begin;
+  OverloadExprBits.NumResults = NumResults;
+  OverloadExprBits.HasTemplateKWAndArgsInfo =
+      (TemplateArgs != nullptr ) || TemplateKWLoc.isValid();
+
   if (NumResults) {
     // Determine whether this expression is type-dependent.
     for (UnresolvedSetImpl::const_iterator I = Begin; I != End; ++I) {
@@ -375,8 +402,9 @@ OverloadExpr::OverloadExpr(StmtClass K, const ASTContext &C,
       }
     }
 
-    Results = static_cast(C.Allocate(
-        sizeof(DeclAccessPair) * NumResults, alignof(DeclAccessPair)));
+    // Copy the results to the trailing array past UnresolvedLookupExpr
+    // or UnresolvedMemberExpr.
+    DeclAccessPair *Results = getTrailingResults();
     memcpy(Results, Begin.I, NumResults * sizeof(DeclAccessPair));
   }
 
@@ -404,28 +432,14 @@ OverloadExpr::OverloadExpr(StmtClass K, const ASTContext &C,
   }
 
   if (isTypeDependent())
-    setType(C.DependentTy);
-}
-
-void OverloadExpr::initializeResults(const ASTContext &C,
-                                     UnresolvedSetIterator Begin,
-                                     UnresolvedSetIterator End) {
-  assert(!Results && "Results already initialized!");
-  NumResults = End - Begin;
-  if (NumResults) {
-    Results = static_cast(
-        C.Allocate(sizeof(DeclAccessPair) * NumResults,
-
-                   alignof(DeclAccessPair)));
-    memcpy(Results, Begin.I, NumResults * sizeof(DeclAccessPair));
-  }
+    setType(Context.DependentTy);
 }
 
-CXXRecordDecl *OverloadExpr::getNamingClass() const {
-  if (isa(this))
-    return cast(this)->getNamingClass();
-  else
-    return cast(this)->getNamingClass();
+OverloadExpr::OverloadExpr(StmtClass SC, EmptyShell Empty, unsigned NumResults,
+                           bool HasTemplateKWAndArgsInfo)
+    : Expr(SC, Empty) {
+  OverloadExprBits.NumResults = NumResults;
+  OverloadExprBits.HasTemplateKWAndArgsInfo = HasTemplateKWAndArgsInfo;
 }
 
 // DependentScopeDeclRefExpr
@@ -1401,19 +1415,15 @@ static bool hasOnlyNonStaticMemberFunctions(UnresolvedSetIterator begin,
   return true;
 }
 
-UnresolvedMemberExpr::UnresolvedMemberExpr(const ASTContext &C,
-                                           bool HasUnresolvedUsing,
-                                           Expr *Base, QualType BaseType,
-                                           bool IsArrow,
-                                           SourceLocation OperatorLoc,
-                                           NestedNameSpecifierLoc QualifierLoc,
-                                           SourceLocation TemplateKWLoc,
-                                   const DeclarationNameInfo &MemberNameInfo,
-                                   const TemplateArgumentListInfo *TemplateArgs,
-                                           UnresolvedSetIterator Begin,
-                                           UnresolvedSetIterator End)
+UnresolvedMemberExpr::UnresolvedMemberExpr(
+    const ASTContext &Context, bool HasUnresolvedUsing, Expr *Base,
+    QualType BaseType, bool IsArrow, SourceLocation OperatorLoc,
+    NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc,
+    const DeclarationNameInfo &MemberNameInfo,
+    const TemplateArgumentListInfo *TemplateArgs, UnresolvedSetIterator Begin,
+    UnresolvedSetIterator End)
     : OverloadExpr(
-          UnresolvedMemberExprClass, C, QualifierLoc, TemplateKWLoc,
+          UnresolvedMemberExprClass, Context, QualifierLoc, TemplateKWLoc,
           MemberNameInfo, TemplateArgs, Begin, End,
           // Dependent
           ((Base && Base->isTypeDependent()) || BaseType->isDependentType()),
@@ -1422,14 +1432,22 @@ UnresolvedMemberExpr::UnresolvedMemberExpr(const ASTContext &C,
           // Contains unexpanded parameter pack
           ((Base && Base->containsUnexpandedParameterPack()) ||
            BaseType->containsUnexpandedParameterPack())),
-      IsArrow(IsArrow), HasUnresolvedUsing(HasUnresolvedUsing), Base(Base),
-      BaseType(BaseType), OperatorLoc(OperatorLoc) {
+      Base(Base), BaseType(BaseType), OperatorLoc(OperatorLoc) {
+  UnresolvedMemberExprBits.IsArrow = IsArrow;
+  UnresolvedMemberExprBits.HasUnresolvedUsing = HasUnresolvedUsing;
+
   // Check whether all of the members are non-static member functions,
   // and if so, mark give this bound-member type instead of overload type.
   if (hasOnlyNonStaticMemberFunctions(Begin, End))
-    setType(C.BoundMemberTy);
+    setType(Context.BoundMemberTy);
 }
 
+UnresolvedMemberExpr::UnresolvedMemberExpr(EmptyShell Empty,
+                                           unsigned NumResults,
+                                           bool HasTemplateKWAndArgsInfo)
+    : OverloadExpr(UnresolvedMemberExprClass, Empty, NumResults,
+                   HasTemplateKWAndArgsInfo) {}
+
 bool UnresolvedMemberExpr::isImplicitAccess() const {
   if (!Base)
     return true;
@@ -1438,39 +1456,37 @@ bool UnresolvedMemberExpr::isImplicitAccess() const {
 }
 
 UnresolvedMemberExpr *UnresolvedMemberExpr::Create(
-    const ASTContext &C, bool HasUnresolvedUsing, Expr *Base, QualType BaseType,
-    bool IsArrow, SourceLocation OperatorLoc,
+    const ASTContext &Context, bool HasUnresolvedUsing, Expr *Base,
+    QualType BaseType, bool IsArrow, SourceLocation OperatorLoc,
     NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc,
     const DeclarationNameInfo &MemberNameInfo,
     const TemplateArgumentListInfo *TemplateArgs, UnresolvedSetIterator Begin,
     UnresolvedSetIterator End) {
+  unsigned NumResults = End - Begin;
   bool HasTemplateKWAndArgsInfo = TemplateArgs || TemplateKWLoc.isValid();
-  std::size_t Size =
-      totalSizeToAlloc(
-          HasTemplateKWAndArgsInfo, TemplateArgs ? TemplateArgs->size() : 0);
-
-  void *Mem = C.Allocate(Size, alignof(UnresolvedMemberExpr));
+  unsigned NumTemplateArgs = TemplateArgs ? TemplateArgs->size() : 0;
+  unsigned Size = totalSizeToAlloc(
+      NumResults, HasTemplateKWAndArgsInfo, NumTemplateArgs);
+  void *Mem = Context.Allocate(Size, alignof(UnresolvedMemberExpr));
   return new (Mem) UnresolvedMemberExpr(
-      C, HasUnresolvedUsing, Base, BaseType, IsArrow, OperatorLoc, QualifierLoc,
-      TemplateKWLoc, MemberNameInfo, TemplateArgs, Begin, End);
+      Context, HasUnresolvedUsing, Base, BaseType, IsArrow, OperatorLoc,
+      QualifierLoc, TemplateKWLoc, MemberNameInfo, TemplateArgs, Begin, End);
 }
 
-UnresolvedMemberExpr *
-UnresolvedMemberExpr::CreateEmpty(const ASTContext &C,
-                                  bool HasTemplateKWAndArgsInfo,
-                                  unsigned NumTemplateArgs) {
+UnresolvedMemberExpr *UnresolvedMemberExpr::CreateEmpty(
+    const ASTContext &Context, unsigned NumResults,
+    bool HasTemplateKWAndArgsInfo, unsigned NumTemplateArgs) {
   assert(NumTemplateArgs == 0 || HasTemplateKWAndArgsInfo);
-  std::size_t Size =
-      totalSizeToAlloc(
-          HasTemplateKWAndArgsInfo, NumTemplateArgs);
-
-  void *Mem = C.Allocate(Size, alignof(UnresolvedMemberExpr));
-  auto *E = new (Mem) UnresolvedMemberExpr(EmptyShell());
-  E->HasTemplateKWAndArgsInfo = HasTemplateKWAndArgsInfo;
-  return E;
+  unsigned Size = totalSizeToAlloc(
+      NumResults, HasTemplateKWAndArgsInfo, NumTemplateArgs);
+  void *Mem = Context.Allocate(Size, alignof(UnresolvedMemberExpr));
+  return new (Mem)
+      UnresolvedMemberExpr(EmptyShell(), NumResults, HasTemplateKWAndArgsInfo);
 }
 
-CXXRecordDecl *UnresolvedMemberExpr::getNamingClass() const {
+CXXRecordDecl *UnresolvedMemberExpr::getNamingClass() {
   // Unlike for UnresolvedLookupExpr, it is very easy to re-derive this.
 
   // If there was a nested name specifier, it names the naming class.
diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp
index b4b2965f12..60abea95bf 100644
--- a/lib/Serialization/ASTReaderStmt.cpp
+++ b/lib/Serialization/ASTReaderStmt.cpp
@@ -1648,19 +1648,33 @@ ASTStmtReader::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E) {
 void ASTStmtReader::VisitOverloadExpr(OverloadExpr *E) {
   VisitExpr(E);
 
-  if (Record.readInt()) // HasTemplateKWAndArgsInfo
+  unsigned NumResults = Record.readInt();
+  bool HasTemplateKWAndArgsInfo = Record.readInt();
+  assert((E->getNumDecls() == NumResults) && "Wrong NumResults!");
+  assert((E->hasTemplateKWAndArgsInfo() == HasTemplateKWAndArgsInfo) &&
+         "Wrong HasTemplateKWAndArgsInfo!");
+
+  if (HasTemplateKWAndArgsInfo) {
+    unsigned NumTemplateArgs = Record.readInt();
     ReadTemplateKWAndArgsInfo(*E->getTrailingASTTemplateKWAndArgsInfo(),
                               E->getTrailingTemplateArgumentLoc(),
-                              /*NumTemplateArgs=*/Record.readInt());
+                              NumTemplateArgs);
+    assert((E->getNumTemplateArgs() == NumTemplateArgs) &&
+           "Wrong NumTemplateArgs!");
+  }
 
-  unsigned NumDecls = Record.readInt();
   UnresolvedSet<8> Decls;
-  for (unsigned i = 0; i != NumDecls; ++i) {
+  for (unsigned I = 0; I != NumResults; ++I) {
     auto *D = ReadDeclAs();
     auto AS = (AccessSpecifier)Record.readInt();
     Decls.addDecl(D, AS);
   }
-  E->initializeResults(Record.getContext(), Decls.begin(), Decls.end());
+
+  DeclAccessPair *Results = E->getTrailingResults();
+  UnresolvedSetIterator Iter = Decls.begin();
+  for (unsigned I = 0; I != NumResults; ++I) {
+    Results[I] = (Iter + I).getPair();
+  }
 
   ReadDeclarationNameInfo(E->NameInfo);
   E->QualifierLoc = Record.readNestedNameSpecifierLoc();
@@ -1668,8 +1682,8 @@ void ASTStmtReader::VisitOverloadExpr(OverloadExpr *E) {
 
 void ASTStmtReader::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) {
   VisitOverloadExpr(E);
-  E->IsArrow = Record.readInt();
-  E->HasUnresolvedUsing = Record.readInt();
+  E->UnresolvedMemberExprBits.IsArrow = Record.readInt();
+  E->UnresolvedMemberExprBits.HasUnresolvedUsing = Record.readInt();
   E->Base = Record.readSubExpr();
   E->BaseType = Record.readType();
   E->OperatorLoc = ReadSourceLocation();
@@ -1677,8 +1691,8 @@ void ASTStmtReader::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) {
 
 void ASTStmtReader::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) {
   VisitOverloadExpr(E);
-  E->RequiresADL = Record.readInt();
-  E->Overloaded = Record.readInt();
+  E->UnresolvedLookupExprBits.RequiresADL = Record.readInt();
+  E->UnresolvedLookupExprBits.Overloaded = Record.readInt();
   E->NamingClass = ReadDeclAs();
 }
 
@@ -3261,19 +3275,25 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
       break;
 
     case EXPR_CXX_UNRESOLVED_MEMBER:
-      S = UnresolvedMemberExpr::CreateEmpty(Context,
-         /*HasTemplateKWAndArgsInfo=*/Record[ASTStmtReader::NumExprFields],
-                  /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields]
-                                   ? Record[ASTStmtReader::NumExprFields + 1]
-                                   : 0);
+      S = UnresolvedMemberExpr::CreateEmpty(
+          Context,
+          /*NumResults=*/Record[ASTStmtReader::NumExprFields],
+          /*HasTemplateKWAndArgsInfo=*/Record[ASTStmtReader::NumExprFields + 1],
+          /*NumTemplateArgs=*/
+          Record[ASTStmtReader::NumExprFields + 1]
+              ? Record[ASTStmtReader::NumExprFields + 2]
+              : 0);
       break;
 
     case EXPR_CXX_UNRESOLVED_LOOKUP:
-      S = UnresolvedLookupExpr::CreateEmpty(Context,
-         /*HasTemplateKWAndArgsInfo=*/Record[ASTStmtReader::NumExprFields],
-                  /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields]
-                                   ? Record[ASTStmtReader::NumExprFields + 1]
-                                   : 0);
+      S = UnresolvedLookupExpr::CreateEmpty(
+          Context,
+          /*NumResults=*/Record[ASTStmtReader::NumExprFields],
+          /*HasTemplateKWAndArgsInfo=*/Record[ASTStmtReader::NumExprFields + 1],
+          /*NumTemplateArgs=*/
+          Record[ASTStmtReader::NumExprFields + 1]
+              ? Record[ASTStmtReader::NumExprFields + 2]
+              : 0);
       break;
 
     case EXPR_TYPE_TRAIT:
diff --git a/lib/Serialization/ASTWriterStmt.cpp b/lib/Serialization/ASTWriterStmt.cpp
index b1908f7991..6f8b86edcd 100644
--- a/lib/Serialization/ASTWriterStmt.cpp
+++ b/lib/Serialization/ASTWriterStmt.cpp
@@ -1625,25 +1625,23 @@ ASTStmtWriter::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E) {
 void ASTStmtWriter::VisitOverloadExpr(OverloadExpr *E) {
   VisitExpr(E);
 
-  // Don't emit anything here, HasTemplateKWAndArgsInfo must be
-  // emitted first.
-
-  Record.push_back(E->HasTemplateKWAndArgsInfo);
-  if (E->HasTemplateKWAndArgsInfo) {
+  Record.push_back(E->getNumDecls());
+  Record.push_back(E->hasTemplateKWAndArgsInfo());
+  if (E->hasTemplateKWAndArgsInfo()) {
     const ASTTemplateKWAndArgsInfo &ArgInfo =
         *E->getTrailingASTTemplateKWAndArgsInfo();
     Record.push_back(ArgInfo.NumTemplateArgs);
     AddTemplateKWAndArgsInfo(ArgInfo, E->getTrailingTemplateArgumentLoc());
   }
 
-  Record.push_back(E->getNumDecls());
-  for (OverloadExpr::decls_iterator
-         OvI = E->decls_begin(), OvE = E->decls_end(); OvI != OvE; ++OvI) {
+  for (OverloadExpr::decls_iterator OvI = E->decls_begin(),
+                                    OvE = E->decls_end();
+       OvI != OvE; ++OvI) {
     Record.AddDeclRef(OvI.getDecl());
     Record.push_back(OvI.getAccess());
   }
 
-  Record.AddDeclarationNameInfo(E->NameInfo);
+  Record.AddDeclarationNameInfo(E->getNameInfo());
   Record.AddNestedNameSpecifierLoc(E->getQualifierLoc());
 }
 
-- 
cgit v1.2.3


From 67d5b9bcce8937abc8585534b856f50a9895af87 Mon Sep 17 00:00:00 2001
From: Alexey Bataev 
Date: Wed, 9 Jan 2019 15:58:05 +0000
Subject: Incorrect implicit data-sharing for nested tasks

Summary:
There is a minor issue in how the implicit data-sharings for nested tasks are computed.

For the following example:
```
int x;
#pragma omp task shared(x)
#pragma omp task
x++;
```
We compute an implicit data-sharing of shared for `x` in the second task although I think that it should be firstprivate. Below you can find the part of the OpenMP spec that covers this example:
- // In a task generating construct, if no default clause is present, a variable for which the data-sharing attribute is not determined by the rules above and that in the enclosing context is determined to be shared by all implicit tasks bound to the current team is shared.//
- //In a task generating construct, if no default clause is present, a variable for which the data-sharing attribute is not determined by the rules above is firstprivate.//

Since each implicit-task has its own copy of `x`, we shouldn't apply the first rule.

Reviewers: ABataev

Reviewed By: ABataev

Subscribers: cfe-commits, rogfer01

Tags: #openmp

Differential Revision: https://reviews.llvm.org/D56430

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350734 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/Sema/SemaOpenMP.cpp       | 20 ++++++++++++--------
 test/OpenMP/task_messages.cpp | 20 +++++++++++++++++++-
 2 files changed, 31 insertions(+), 9 deletions(-)

diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp
index 140ccd15bb..1166de752e 100644
--- a/lib/Sema/SemaOpenMP.cpp
+++ b/lib/Sema/SemaOpenMP.cpp
@@ -676,9 +676,13 @@ public:
   }
 
 };
-bool isParallelOrTaskRegion(OpenMPDirectiveKind DKind) {
-  return isOpenMPParallelDirective(DKind) || isOpenMPTaskingDirective(DKind) ||
-         isOpenMPTeamsDirective(DKind) || DKind == OMPD_unknown;
+
+bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) {
+  return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind);
+}
+
+bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) {
+  return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) || DKind == OMPD_unknown;
 }
 
 } // namespace
@@ -819,7 +823,7 @@ DSAStackTy::DSAVarData DSAStackTy::getDSA(iterator &Iter,
           DVar.CKind = OMPC_firstprivate;
           return DVar;
         }
-      } while (I != E && !isParallelOrTaskRegion(I->Directive));
+      } while (I != E && !isImplicitTaskingRegion(I->Directive));
       DVar.CKind =
           (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
       return DVar;
@@ -1066,7 +1070,7 @@ bool DSAStackTy::isOpenMPLocal(VarDecl *D, iterator Iter) const {
   if (!isStackEmpty()) {
     iterator I = Iter, E = Stack.back().first.rend();
     Scope *TopScope = nullptr;
-    while (I != E && !isParallelOrTaskRegion(I->Directive) &&
+    while (I != E && !isImplicitOrExplicitTaskingRegion(I->Directive) &&
            !isOpenMPTargetExecutionDirective(I->Directive))
       ++I;
     if (I == E)
@@ -1292,7 +1296,7 @@ DSAStackTy::hasDSA(ValueDecl *D,
   if (FromParent && I != EndI)
     std::advance(I, 1);
   for (; I != EndI; std::advance(I, 1)) {
-    if (!DPred(I->Directive) && !isParallelOrTaskRegion(I->Directive))
+    if (!DPred(I->Directive) && !isImplicitOrExplicitTaskingRegion(I->Directive))
       continue;
     iterator NewI = I;
     DSAVarData DVar = getDSA(NewI, D);
@@ -1636,7 +1640,7 @@ VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D) {
     auto &&Info = DSAStack->isLoopControlVariable(D);
     if (Info.first ||
         (VD && VD->hasLocalStorage() &&
-         isParallelOrTaskRegion(DSAStack->getCurrentDirective())) ||
+         isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) ||
         (VD && DSAStack->isForceVarCapturing()))
       return VD ? VD : Info.second;
     DSAStackTy::DSAVarData DVarPrivate =
@@ -2244,7 +2248,7 @@ public:
       // attribute, must have its data-sharing attribute explicitly determined
       // by being listed in a data-sharing attribute clause.
       if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none &&
-          isParallelOrTaskRegion(DKind) &&
+          isImplicitOrExplicitTaskingRegion(DKind) &&
           VarsWithInheritedDSA.count(VD) == 0) {
         VarsWithInheritedDSA[VD] = E;
         return;
diff --git a/test/OpenMP/task_messages.cpp b/test/OpenMP/task_messages.cpp
index 85072cb5b4..d490c7f8ea 100644
--- a/test/OpenMP/task_messages.cpp
+++ b/test/OpenMP/task_messages.cpp
@@ -8,7 +8,7 @@ void foo() {
 #pragma omp task // expected-error {{unexpected OpenMP directive '#pragma omp task'}}
 
 class S {
-  S(const S &s) { a = s.a + 12; } // expected-note 14 {{implicitly declared private here}}
+  S(const S &s) { a = s.a + 12; } // expected-note 16 {{implicitly declared private here}}
   int a;
 
 public:
@@ -50,6 +50,15 @@ int foo() {
   // expected-error@+1 {{calling a private constructor of class 'S'}}
   ++a; // expected-error {{calling a private constructor of class 'S'}}
 #pragma omp task default(shared)
+#pragma omp task
+  // expected-error@+1 {{calling a private constructor of class 'S'}}
+  ++a;
+#pragma omp parallel shared(a)
+#pragma omp task
+#pragma omp task
+  ++a;
+#pragma omp parallel shared(a)
+#pragma omp task default(shared)
 #pragma omp task
   ++a;
 #pragma omp task
@@ -204,6 +213,15 @@ L2:
   // expected-error@+1 {{calling a private constructor of class 'S'}}
   ++sa; // expected-error {{calling a private constructor of class 'S'}}
 #pragma omp task default(shared)
+#pragma omp task
+  // expected-error@+1 {{calling a private constructor of class 'S'}}
+  ++sa;
+#pragma omp parallel shared(sa)
+#pragma omp task
+#pragma omp task
+  ++sa;
+#pragma omp parallel shared(sa)
+#pragma omp task default(shared)
 #pragma omp task
   ++sa;
 #pragma omp task
-- 
cgit v1.2.3


From ac5aeb33f2780dfaea375c4da8d27f6d3eab520d Mon Sep 17 00:00:00 2001
From: Bruno Ricci 
Date: Wed, 9 Jan 2019 16:41:33 +0000
Subject: [AST] Move back BasePathSize to the bit-fields of CastExpr

The number of trailing CXXBaseSpecifiers in CastExpr was moved from
CastExprBitfields to a trailing object in r338489 (D50050). At this time these
bit-fields classes were only 32 bits wide. However later r345459 widened these
bit-field classes to 64 bits.

The reason for this change was that on 64 bit archs alignment requirements
caused 4 bytes of padding after the Stmt sub-object in nearly all expression
classes. Reusing this padding yielded an >10% reduction in the size used by all
statement/expressions when parsing all of Boost (on a 64 bit arch). This
increased the size of statement/expressions for 32 bits archs, but this can be
mitigated by moving more data to the bit-fields of Stmt (and moreover most
people now care about 64 bits archs as a host).

Therefore move back the number of CXXBaseSpecifiers in CastExpr to the
bit-fields of Stmt. This in effect mostly revert r338489 while keeping the
added test.

Differential Revision: https://reviews.llvm.org/D56358

Reviewed By: lebedev.ri

Reviewers: lebedev.ri, rjmccall



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350741 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/AST/Expr.h     | 49 ++++++++++----------------------------------
 include/clang/AST/ExprCXX.h  | 33 ++++-------------------------
 include/clang/AST/ExprObjC.h |  7 +------
 include/clang/AST/Stmt.h     |  5 ++++-
 lib/AST/Expr.cpp             | 31 ++++------------------------
 lib/AST/ExprCXX.cpp          | 32 ++++++++---------------------
 6 files changed, 32 insertions(+), 125 deletions(-)

diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index 1c757b5330..3de7342882 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -2996,28 +2996,15 @@ public:
 /// representation in the source code (ExplicitCastExpr's derived
 /// classes).
 class CastExpr : public Expr {
-public:
-  using BasePathSizeTy = unsigned int;
-  static_assert(std::numeric_limits::max() >= 16384,
-                "[implimits] Direct and indirect base classes [16384].");
-
-private:
   Stmt *Op;
 
   bool CastConsistency() const;
 
-  BasePathSizeTy *BasePathSize();
-
   const CXXBaseSpecifier * const *path_buffer() const {
     return const_cast(this)->path_buffer();
   }
   CXXBaseSpecifier **path_buffer();
 
-  void setBasePathSize(BasePathSizeTy basePathSize) {
-    assert(!path_empty() && basePathSize != 0);
-    *(BasePathSize()) = basePathSize;
-  }
-
 protected:
   CastExpr(StmtClass SC, QualType ty, ExprValueKind VK, const CastKind kind,
            Expr *op, unsigned BasePathSize)
@@ -3038,9 +3025,9 @@ protected:
         Op(op) {
     CastExprBits.Kind = kind;
     CastExprBits.PartOfExplicitCast = false;
-    CastExprBits.BasePathIsEmpty = BasePathSize == 0;
-    if (!path_empty())
-      setBasePathSize(BasePathSize);
+    CastExprBits.BasePathSize = BasePathSize;
+    assert((CastExprBits.BasePathSize == BasePathSize) &&
+           "BasePathSize overflow!");
     assert(CastConsistency());
   }
 
@@ -3048,9 +3035,9 @@ protected:
   CastExpr(StmtClass SC, EmptyShell Empty, unsigned BasePathSize)
     : Expr(SC, Empty) {
     CastExprBits.PartOfExplicitCast = false;
-    CastExprBits.BasePathIsEmpty = BasePathSize == 0;
-    if (!path_empty())
-      setBasePathSize(BasePathSize);
+    CastExprBits.BasePathSize = BasePathSize;
+    assert((CastExprBits.BasePathSize == BasePathSize) &&
+           "BasePathSize overflow!");
   }
 
 public:
@@ -3077,13 +3064,9 @@ public:
   NamedDecl *getConversionFunction() const;
 
   typedef CXXBaseSpecifier **path_iterator;
-  typedef const CXXBaseSpecifier * const *path_const_iterator;
-  bool path_empty() const { return CastExprBits.BasePathIsEmpty; }
-  unsigned path_size() const {
-    if (path_empty())
-      return 0U;
-    return *(const_cast(this)->BasePathSize());
-  }
+  typedef const CXXBaseSpecifier *const *path_const_iterator;
+  bool path_empty() const { return path_size() == 0; }
+  unsigned path_size() const { return CastExprBits.BasePathSize; }
   path_iterator path_begin() { return path_buffer(); }
   path_iterator path_end() { return path_buffer() + path_size(); }
   path_const_iterator path_begin() const { return path_buffer(); }
@@ -3131,13 +3114,8 @@ public:
 /// @endcode
 class ImplicitCastExpr final
     : public CastExpr,
-      private llvm::TrailingObjects {
-  size_t numTrailingObjects(OverloadToken) const {
-    return path_empty() ? 0 : 1;
-  }
+      private llvm::TrailingObjects {
 
-private:
   ImplicitCastExpr(QualType ty, CastKind kind, Expr *op,
                    unsigned BasePathLength, ExprValueKind VK)
     : CastExpr(ImplicitCastExprClass, ty, VK, kind, op, BasePathLength) { }
@@ -3245,8 +3223,7 @@ public:
 /// (Type)expr. For example: @c (int)f.
 class CStyleCastExpr final
     : public ExplicitCastExpr,
-      private llvm::TrailingObjects {
+      private llvm::TrailingObjects {
   SourceLocation LPLoc; // the location of the left paren
   SourceLocation RPLoc; // the location of the right paren
 
@@ -3260,10 +3237,6 @@ class CStyleCastExpr final
   explicit CStyleCastExpr(EmptyShell Shell, unsigned PathSize)
     : ExplicitCastExpr(CStyleCastExprClass, Shell, PathSize) { }
 
-  size_t numTrailingObjects(OverloadToken) const {
-    return path_empty() ? 0 : 1;
-  }
-
 public:
   static CStyleCastExpr *Create(const ASTContext &Context, QualType T,
                                 ExprValueKind VK, CastKind K,
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index 2b75b68f11..6ef837a2fc 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -325,8 +325,7 @@ public:
 /// \c static_cast(1.0).
 class CXXStaticCastExpr final
     : public CXXNamedCastExpr,
-      private llvm::TrailingObjects {
+      private llvm::TrailingObjects {
   CXXStaticCastExpr(QualType ty, ExprValueKind vk, CastKind kind, Expr *op,
                     unsigned pathSize, TypeSourceInfo *writtenTy,
                     SourceLocation l, SourceLocation RParenLoc,
@@ -337,10 +336,6 @@ class CXXStaticCastExpr final
   explicit CXXStaticCastExpr(EmptyShell Empty, unsigned PathSize)
       : CXXNamedCastExpr(CXXStaticCastExprClass, Empty, PathSize) {}
 
-  size_t numTrailingObjects(OverloadToken) const {
-    return path_empty() ? 0 : 1;
-  }
-
 public:
   friend class CastExpr;
   friend TrailingObjects;
@@ -366,8 +361,7 @@ public:
 /// check to determine how to perform the type conversion.
 class CXXDynamicCastExpr final
     : public CXXNamedCastExpr,
-      private llvm::TrailingObjects<
-          CXXDynamicCastExpr, CastExpr::BasePathSizeTy, CXXBaseSpecifier *> {
+      private llvm::TrailingObjects {
   CXXDynamicCastExpr(QualType ty, ExprValueKind VK, CastKind kind,
                      Expr *op, unsigned pathSize, TypeSourceInfo *writtenTy,
                      SourceLocation l, SourceLocation RParenLoc,
@@ -378,10 +372,6 @@ class CXXDynamicCastExpr final
   explicit CXXDynamicCastExpr(EmptyShell Empty, unsigned pathSize)
       : CXXNamedCastExpr(CXXDynamicCastExprClass, Empty, pathSize) {}
 
-  size_t numTrailingObjects(OverloadToken) const {
-    return path_empty() ? 0 : 1;
-  }
-
 public:
   friend class CastExpr;
   friend TrailingObjects;
@@ -414,7 +404,6 @@ public:
 class CXXReinterpretCastExpr final
     : public CXXNamedCastExpr,
       private llvm::TrailingObjects {
   CXXReinterpretCastExpr(QualType ty, ExprValueKind vk, CastKind kind,
                          Expr *op, unsigned pathSize,
@@ -427,10 +416,6 @@ class CXXReinterpretCastExpr final
   CXXReinterpretCastExpr(EmptyShell Empty, unsigned pathSize)
       : CXXNamedCastExpr(CXXReinterpretCastExprClass, Empty, pathSize) {}
 
-  size_t numTrailingObjects(OverloadToken) const {
-    return path_empty() ? 0 : 1;
-  }
-
 public:
   friend class CastExpr;
   friend TrailingObjects;
@@ -458,8 +443,7 @@ public:
 /// value.
 class CXXConstCastExpr final
     : public CXXNamedCastExpr,
-      private llvm::TrailingObjects {
+      private llvm::TrailingObjects {
   CXXConstCastExpr(QualType ty, ExprValueKind VK, Expr *op,
                    TypeSourceInfo *writtenTy, SourceLocation l,
                    SourceLocation RParenLoc, SourceRange AngleBrackets)
@@ -469,10 +453,6 @@ class CXXConstCastExpr final
   explicit CXXConstCastExpr(EmptyShell Empty)
       : CXXNamedCastExpr(CXXConstCastExprClass, Empty, 0) {}
 
-  size_t numTrailingObjects(OverloadToken) const {
-    return path_empty() ? 0 : 1;
-  }
-
 public:
   friend class CastExpr;
   friend TrailingObjects;
@@ -1538,8 +1518,7 @@ public:
 /// \endcode
 class CXXFunctionalCastExpr final
     : public ExplicitCastExpr,
-      private llvm::TrailingObjects<
-          CXXFunctionalCastExpr, CastExpr::BasePathSizeTy, CXXBaseSpecifier *> {
+      private llvm::TrailingObjects {
   SourceLocation LParenLoc;
   SourceLocation RParenLoc;
 
@@ -1554,10 +1533,6 @@ class CXXFunctionalCastExpr final
   explicit CXXFunctionalCastExpr(EmptyShell Shell, unsigned PathSize)
       : ExplicitCastExpr(CXXFunctionalCastExprClass, Shell, PathSize) {}
 
-  size_t numTrailingObjects(OverloadToken) const {
-    return path_empty() ? 0 : 1;
-  }
-
 public:
   friend class CastExpr;
   friend TrailingObjects;
diff --git a/include/clang/AST/ExprObjC.h b/include/clang/AST/ExprObjC.h
index ed3d3840b3..c7b305f330 100644
--- a/include/clang/AST/ExprObjC.h
+++ b/include/clang/AST/ExprObjC.h
@@ -1574,8 +1574,7 @@ public:
 /// \endcode
 class ObjCBridgedCastExpr final
     : public ExplicitCastExpr,
-      private llvm::TrailingObjects<
-          ObjCBridgedCastExpr, CastExpr::BasePathSizeTy, CXXBaseSpecifier *> {
+      private llvm::TrailingObjects {
   friend class ASTStmtReader;
   friend class ASTStmtWriter;
   friend class CastExpr;
@@ -1585,10 +1584,6 @@ class ObjCBridgedCastExpr final
   SourceLocation BridgeKeywordLoc;
   unsigned Kind : 2;
 
-  size_t numTrailingObjects(OverloadToken) const {
-    return path_empty() ? 0 : 1;
-  }
-
 public:
   ObjCBridgedCastExpr(SourceLocation LParenLoc, ObjCBridgeCastKind Kind,
                       CastKind CK, SourceLocation BridgeKeywordLoc,
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index 2f33fec71b..ff5baa21ad 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -481,7 +481,10 @@ protected:
 
     unsigned Kind : 6;
     unsigned PartOfExplicitCast : 1; // Only set for ImplicitCastExpr.
-    unsigned BasePathIsEmpty : 1;
+
+    /// The number of CXXBaseSpecifiers in the cast. 14 bits would be enough
+    /// here. ([implimits] Direct and indirect base classes [16384]).
+    unsigned BasePathSize;
   };
 
   class BinaryOperatorBitfields {
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 0775ff5773..7f6df179d4 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -1808,21 +1808,6 @@ NamedDecl *CastExpr::getConversionFunction() const {
   return nullptr;
 }
 
-CastExpr::BasePathSizeTy *CastExpr::BasePathSize() {
-  assert(!path_empty());
-  switch (getStmtClass()) {
-#define ABSTRACT_STMT(x)
-#define CASTEXPR(Type, Base)                                                   \
-  case Stmt::Type##Class:                                                      \
-    return static_cast(this)                                           \
-        ->getTrailingObjects();
-#define STMT(Type, Base)
-#include "clang/AST/StmtNodes.inc"
-  default:
-    llvm_unreachable("non-cast expressions not possible here");
-  }
-}
-
 CXXBaseSpecifier **CastExpr::path_buffer() {
   switch (getStmtClass()) {
 #define ABSTRACT_STMT(x)
@@ -1861,9 +1846,7 @@ ImplicitCastExpr *ImplicitCastExpr::Create(const ASTContext &C, QualType T,
                                            const CXXCastPath *BasePath,
                                            ExprValueKind VK) {
   unsigned PathSize = (BasePath ? BasePath->size() : 0);
-  void *Buffer =
-      C.Allocate(totalSizeToAlloc(
-          PathSize ? 1 : 0, PathSize));
+  void *Buffer = C.Allocate(totalSizeToAlloc(PathSize));
   ImplicitCastExpr *E =
     new (Buffer) ImplicitCastExpr(T, Kind, Operand, PathSize, VK);
   if (PathSize)
@@ -1874,9 +1857,7 @@ ImplicitCastExpr *ImplicitCastExpr::Create(const ASTContext &C, QualType T,
 
 ImplicitCastExpr *ImplicitCastExpr::CreateEmpty(const ASTContext &C,
                                                 unsigned PathSize) {
-  void *Buffer =
-      C.Allocate(totalSizeToAlloc(
-          PathSize ? 1 : 0, PathSize));
+  void *Buffer = C.Allocate(totalSizeToAlloc(PathSize));
   return new (Buffer) ImplicitCastExpr(EmptyShell(), PathSize);
 }
 
@@ -1887,9 +1868,7 @@ CStyleCastExpr *CStyleCastExpr::Create(const ASTContext &C, QualType T,
                                        TypeSourceInfo *WrittenTy,
                                        SourceLocation L, SourceLocation R) {
   unsigned PathSize = (BasePath ? BasePath->size() : 0);
-  void *Buffer =
-      C.Allocate(totalSizeToAlloc(
-          PathSize ? 1 : 0, PathSize));
+  void *Buffer = C.Allocate(totalSizeToAlloc(PathSize));
   CStyleCastExpr *E =
     new (Buffer) CStyleCastExpr(T, VK, K, Op, PathSize, WrittenTy, L, R);
   if (PathSize)
@@ -1900,9 +1879,7 @@ CStyleCastExpr *CStyleCastExpr::Create(const ASTContext &C, QualType T,
 
 CStyleCastExpr *CStyleCastExpr::CreateEmpty(const ASTContext &C,
                                             unsigned PathSize) {
-  void *Buffer =
-      C.Allocate(totalSizeToAlloc(
-          PathSize ? 1 : 0, PathSize));
+  void *Buffer = C.Allocate(totalSizeToAlloc(PathSize));
   return new (Buffer) CStyleCastExpr(EmptyShell(), PathSize);
 }
 
diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp
index 699baa71f3..3891f45c7f 100644
--- a/lib/AST/ExprCXX.cpp
+++ b/lib/AST/ExprCXX.cpp
@@ -694,9 +694,7 @@ CXXStaticCastExpr *CXXStaticCastExpr::Create(const ASTContext &C, QualType T,
                                              SourceLocation RParenLoc,
                                              SourceRange AngleBrackets) {
   unsigned PathSize = (BasePath ? BasePath->size() : 0);
-  void *Buffer =
-      C.Allocate(totalSizeToAlloc(
-          PathSize ? 1 : 0, PathSize));
+  void *Buffer = C.Allocate(totalSizeToAlloc(PathSize));
   auto *E =
       new (Buffer) CXXStaticCastExpr(T, VK, K, Op, PathSize, WrittenTy, L,
                                      RParenLoc, AngleBrackets);
@@ -708,9 +706,7 @@ CXXStaticCastExpr *CXXStaticCastExpr::Create(const ASTContext &C, QualType T,
 
 CXXStaticCastExpr *CXXStaticCastExpr::CreateEmpty(const ASTContext &C,
                                                   unsigned PathSize) {
-  void *Buffer =
-      C.Allocate(totalSizeToAlloc(
-          PathSize ? 1 : 0, PathSize));
+  void *Buffer = C.Allocate(totalSizeToAlloc(PathSize));
   return new (Buffer) CXXStaticCastExpr(EmptyShell(), PathSize);
 }
 
@@ -723,9 +719,7 @@ CXXDynamicCastExpr *CXXDynamicCastExpr::Create(const ASTContext &C, QualType T,
                                                SourceLocation RParenLoc,
                                                SourceRange AngleBrackets) {
   unsigned PathSize = (BasePath ? BasePath->size() : 0);
-  void *Buffer =
-      C.Allocate(totalSizeToAlloc(
-          PathSize ? 1 : 0, PathSize));
+  void *Buffer = C.Allocate(totalSizeToAlloc(PathSize));
   auto *E =
       new (Buffer) CXXDynamicCastExpr(T, VK, K, Op, PathSize, WrittenTy, L,
                                       RParenLoc, AngleBrackets);
@@ -737,9 +731,7 @@ CXXDynamicCastExpr *CXXDynamicCastExpr::Create(const ASTContext &C, QualType T,
 
 CXXDynamicCastExpr *CXXDynamicCastExpr::CreateEmpty(const ASTContext &C,
                                                     unsigned PathSize) {
-  void *Buffer =
-      C.Allocate(totalSizeToAlloc(
-          PathSize ? 1 : 0, PathSize));
+  void *Buffer = C.Allocate(totalSizeToAlloc(PathSize));
   return new (Buffer) CXXDynamicCastExpr(EmptyShell(), PathSize);
 }
 
@@ -784,9 +776,7 @@ CXXReinterpretCastExpr::Create(const ASTContext &C, QualType T,
                                SourceLocation RParenLoc,
                                SourceRange AngleBrackets) {
   unsigned PathSize = (BasePath ? BasePath->size() : 0);
-  void *Buffer =
-      C.Allocate(totalSizeToAlloc(
-          PathSize ? 1 : 0, PathSize));
+  void *Buffer = C.Allocate(totalSizeToAlloc(PathSize));
   auto *E =
       new (Buffer) CXXReinterpretCastExpr(T, VK, K, Op, PathSize, WrittenTy, L,
                                           RParenLoc, AngleBrackets);
@@ -798,9 +788,7 @@ CXXReinterpretCastExpr::Create(const ASTContext &C, QualType T,
 
 CXXReinterpretCastExpr *
 CXXReinterpretCastExpr::CreateEmpty(const ASTContext &C, unsigned PathSize) {
-  void *Buffer =
-      C.Allocate(totalSizeToAlloc(
-          PathSize ? 1 : 0, PathSize));
+  void *Buffer = C.Allocate(totalSizeToAlloc(PathSize));
   return new (Buffer) CXXReinterpretCastExpr(EmptyShell(), PathSize);
 }
 
@@ -823,9 +811,7 @@ CXXFunctionalCastExpr::Create(const ASTContext &C, QualType T, ExprValueKind VK,
                               const CXXCastPath *BasePath,
                               SourceLocation L, SourceLocation R) {
   unsigned PathSize = (BasePath ? BasePath->size() : 0);
-  void *Buffer =
-      C.Allocate(totalSizeToAlloc(
-          PathSize ? 1 : 0, PathSize));
+  void *Buffer = C.Allocate(totalSizeToAlloc(PathSize));
   auto *E =
       new (Buffer) CXXFunctionalCastExpr(T, VK, Written, K, Op, PathSize, L, R);
   if (PathSize)
@@ -836,9 +822,7 @@ CXXFunctionalCastExpr::Create(const ASTContext &C, QualType T, ExprValueKind VK,
 
 CXXFunctionalCastExpr *
 CXXFunctionalCastExpr::CreateEmpty(const ASTContext &C, unsigned PathSize) {
-  void *Buffer =
-      C.Allocate(totalSizeToAlloc(
-          PathSize ? 1 : 0, PathSize));
+  void *Buffer = C.Allocate(totalSizeToAlloc(PathSize));
   return new (Buffer) CXXFunctionalCastExpr(EmptyShell(), PathSize);
 }
 
-- 
cgit v1.2.3


From 10f093a07ea53c1b248948cca3cdbd8eae11d46a Mon Sep 17 00:00:00 2001
From: Shoaib Meenai 
Date: Wed, 9 Jan 2019 20:05:16 +0000
Subject: [CodeGen] Clarify comment about COFF common symbol alignment

After a discussion on the commit thread, it seems the 32 byte alignment
limitation is an MSVC toolchain artifact, not an inherent COFF
restriction. Clarify the comment accordingly, since saying COFF in the
comment but using isKnownWindowsMSVCEnvironment in the conditional is
confusing. Also add a newline before the comment, which is consistent
with the local style.

Differential Revision: https://reviews.llvm.org/D56466

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350754 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/CodeGen/CodeGenModule.cpp | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index ab0ac67d8e..244738042c 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -3761,8 +3761,12 @@ static bool isVarDeclStrongDefinition(const ASTContext &Context,
       }
     }
   }
-  // COFF doesn't support alignments greater than 32, so these cannot be
-  // in common.
+
+  // Microsoft's link.exe doesn't support alignments greater than 32 for common
+  // symbols, so symbols with greater alignment requirements cannot be common.
+  // Other COFF linkers (ld.bfd and LLD) support arbitrary power-of-two
+  // alignments for common symbols via the aligncomm directive, so this
+  // restriction only applies to MSVC environments.
   if (Context.getTargetInfo().getTriple().isKnownWindowsMSVCEnvironment() &&
       Context.getTypeAlignIfKnown(D->getType()) > 32)
     return true;
-- 
cgit v1.2.3


From 624b066af176c118bc1647fa4f0982ff7def24d5 Mon Sep 17 00:00:00 2001
From: Aaron Ballman 
Date: Wed, 9 Jan 2019 20:15:10 +0000
Subject: Removing an include that was not necessary; NFC.

The include also had a using namespace llvm in it, so this adds qualifiers where needed as well.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350756 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/AST/ASTDumperUtils.h | 38 +++++++++++++++++++-------------------
 1 file changed, 19 insertions(+), 19 deletions(-)

diff --git a/include/clang/AST/ASTDumperUtils.h b/include/clang/AST/ASTDumperUtils.h
index 71cf5c93bc..5e62e902b4 100644
--- a/include/clang/AST/ASTDumperUtils.h
+++ b/include/clang/AST/ASTDumperUtils.h
@@ -14,7 +14,6 @@
 #ifndef LLVM_CLANG_AST_ASTDUMPERUTILS_H
 #define LLVM_CLANG_AST_ASTDUMPERUTILS_H
 
-#include "clang/AST/ASTContext.h"
 #include "llvm/Support/raw_ostream.h"
 
 namespace clang {
@@ -23,7 +22,7 @@ namespace clang {
 // Do not use bold yellow for any text.  It is hard to read on white screens.
 
 struct TerminalColor {
-  raw_ostream::Colors Color;
+  llvm::raw_ostream::Colors Color;
   bool Bold;
 };
 
@@ -38,50 +37,51 @@ struct TerminalColor {
 // Bold Cyan     - ValueColor, DeclNameColor
 
 // Decl kind names (VarDecl, FunctionDecl, etc)
-static const TerminalColor DeclKindNameColor = {raw_ostream::GREEN, true};
+static const TerminalColor DeclKindNameColor = {llvm::raw_ostream::GREEN, true};
 // Attr names (CleanupAttr, GuardedByAttr, etc)
-static const TerminalColor AttrColor = {raw_ostream::BLUE, true};
+static const TerminalColor AttrColor = {llvm::raw_ostream::BLUE, true};
 // Statement names (DeclStmt, ImplicitCastExpr, etc)
-static const TerminalColor StmtColor = {raw_ostream::MAGENTA, true};
+static const TerminalColor StmtColor = {llvm::raw_ostream::MAGENTA, true};
 // Comment names (FullComment, ParagraphComment, TextComment, etc)
-static const TerminalColor CommentColor = {raw_ostream::BLUE, false};
+static const TerminalColor CommentColor = {llvm::raw_ostream::BLUE, false};
 
 // Type names (int, float, etc, plus user defined types)
-static const TerminalColor TypeColor = {raw_ostream::GREEN, false};
+static const TerminalColor TypeColor = {llvm::raw_ostream::GREEN, false};
 
 // Pointer address
-static const TerminalColor AddressColor = {raw_ostream::YELLOW, false};
+static const TerminalColor AddressColor = {llvm::raw_ostream::YELLOW, false};
 // Source locations
-static const TerminalColor LocationColor = {raw_ostream::YELLOW, false};
+static const TerminalColor LocationColor = {llvm::raw_ostream::YELLOW, false};
 
 // lvalue/xvalue
-static const TerminalColor ValueKindColor = {raw_ostream::CYAN, false};
+static const TerminalColor ValueKindColor = {llvm::raw_ostream::CYAN, false};
 // bitfield/objcproperty/objcsubscript/vectorcomponent
-static const TerminalColor ObjectKindColor = {raw_ostream::CYAN, false};
+static const TerminalColor ObjectKindColor = {llvm::raw_ostream::CYAN, false};
 
 // Null statements
-static const TerminalColor NullColor = {raw_ostream::BLUE, false};
+static const TerminalColor NullColor = {llvm::raw_ostream::BLUE, false};
 
 // Undeserialized entities
-static const TerminalColor UndeserializedColor = {raw_ostream::GREEN, true};
+static const TerminalColor UndeserializedColor = {llvm::raw_ostream::GREEN,
+                                                  true};
 
 // CastKind from CastExpr's
-static const TerminalColor CastColor = {raw_ostream::RED, false};
+static const TerminalColor CastColor = {llvm::raw_ostream::RED, false};
 
 // Value of the statement
-static const TerminalColor ValueColor = {raw_ostream::CYAN, true};
+static const TerminalColor ValueColor = {llvm::raw_ostream::CYAN, true};
 // Decl names
-static const TerminalColor DeclNameColor = {raw_ostream::CYAN, true};
+static const TerminalColor DeclNameColor = {llvm::raw_ostream::CYAN, true};
 
 // Indents ( `, -. | )
-static const TerminalColor IndentColor = {raw_ostream::BLUE, false};
+static const TerminalColor IndentColor = {llvm::raw_ostream::BLUE, false};
 
 class ColorScope {
-  raw_ostream &OS;
+  llvm::raw_ostream &OS;
   const bool ShowColors;
 
 public:
-  ColorScope(raw_ostream &OS, bool ShowColors, TerminalColor Color)
+  ColorScope(llvm::raw_ostream &OS, bool ShowColors, TerminalColor Color)
       : OS(OS), ShowColors(ShowColors) {
     if (ShowColors)
       OS.changeColor(Color.Color, Color.Bold);
-- 
cgit v1.2.3


From 0aa94314808bdeedcdecfc97444b0f96ef59b72c Mon Sep 17 00:00:00 2001
From: Alexey Bataev 
Date: Wed, 9 Jan 2019 20:32:56 +0000
Subject: [OPENMP][DOCS]Release notes/OpenMP support updates, NFC.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350757 91177308-0d34-0410-b5e6-96231b3b80d8
---
 docs/OpenMPSupport.rst |  5 +----
 docs/ReleaseNotes.rst  | 18 ++++++++++++++++++
 2 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/docs/OpenMPSupport.rst b/docs/OpenMPSupport.rst
index e8ec1e371b..5ca3613cde 100644
--- a/docs/OpenMPSupport.rst
+++ b/docs/OpenMPSupport.rst
@@ -66,12 +66,11 @@ Combined directives
 
 * #pragma omp target teams distribute parallel for [simd]: :good:`Complete`.
 
-Clang does not support any constructs/updates from upcoming OpenMP 5.0 except
+Clang does not support any constructs/updates from OpenMP 5.0 except
 for `reduction`-based clauses in the `task` and `target`-based directives.
 
 In addition, the LLVM OpenMP runtime `libomp` supports the OpenMP Tools
 Interface (OMPT) on x86, x86_64, AArch64, and PPC64 on Linux, Windows, and mac OS.
-ows, and mac OS.
 
 .. _basic support for Cuda devices:
 
@@ -112,8 +111,6 @@ between the threads in the parallel regions.
 Features not supported or with limited support for Cuda devices
 ---------------------------------------------------------------
 
-- Reductions across the teams are not supported yet.
-
 - Cancellation constructs are not supported.
 
 - Doacross loop nest is not supported.
diff --git a/docs/ReleaseNotes.rst b/docs/ReleaseNotes.rst
index 2948812dc0..64991343d9 100644
--- a/docs/ReleaseNotes.rst
+++ b/docs/ReleaseNotes.rst
@@ -233,6 +233,24 @@ ABI Changes in Clang
 OpenMP Support in Clang
 ----------------------------------
 
+- Support relational-op != (not-equal) as one of the canonical forms of random
+  access iterator.
+
+- Added support for mapping of the lambdas in target regions.
+
+- Added parsing/sema analysis for OpenMP 5.0 requires directive.
+
+- Various bugfixes and improvements.
+
+New features supported for Cuda devices:
+
+- Added support for the reductions across the teams.
+
+- Extended number of constructs that can be executed in SPMD mode.
+
+- Fixed support for lastprivate/reduction variables in SPMD constructs.
+
+- General performance improvement.
 
 CUDA Support in Clang
 ---------------------
-- 
cgit v1.2.3


From 8bc98c731f0aebcd14b5e78deeb9a8cbfa4b93e6 Mon Sep 17 00:00:00 2001
From: Gheorghe-Teodor Bercea 
Date: Wed, 9 Jan 2019 20:38:35 +0000
Subject: [OpenMP] Add flag for preventing the extension to 64 bits for the
 collapse loop counter

Summary: Introduce a compiler flag for cases when the user knows that the collapsed loop counter can be safely represented using at most 32 bits. This will prevent the emission of expensive mathematical operations (such as the div operation) on the iteration variable using 64 bits where 32 bit operations are sufficient.

Reviewers: ABataev, caomhin

Reviewed By: ABataev

Subscribers: hfinkel, kkwli0, guansong, cfe-commits

Differential Revision: https://reviews.llvm.org/D55928

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350758 91177308-0d34-0410-b5e6-96231b3b80d8
---
 docs/OpenMPSupport.rst                             | 10 +++++++++
 include/clang/Basic/LangOptions.def                |  1 +
 include/clang/Driver/Options.td                    |  4 ++++
 lib/Driver/ToolChains/Clang.cpp                    |  4 ++++
 lib/Frontend/CompilerInvocation.cpp                |  5 +++++
 lib/Sema/SemaOpenMP.cpp                            | 23 ++++++++++----------
 ...arget_teams_distribute_parallel_for_codegen.cpp | 25 +++++++++++++---------
 7 files changed, 51 insertions(+), 21 deletions(-)

diff --git a/docs/OpenMPSupport.rst b/docs/OpenMPSupport.rst
index 5ca3613cde..04a9648ca2 100644
--- a/docs/OpenMPSupport.rst
+++ b/docs/OpenMPSupport.rst
@@ -108,6 +108,16 @@ are stored in the global memory. In `Cuda` mode local variables are not shared
 between the threads and it is user responsibility to share the required data
 between the threads in the parallel regions.
 
+Collapsed loop nest counter
+---------------------------
+
+When using the collapse clause on a loop nest the default behaviour is to
+automatically extend the representation of the loop counter to 64 bits for
+the cases where the sizes of the collapsed loops are not known at compile
+time. To prevent this conservative choice and use at most 32 bits,
+compile your program with the `-fopenmp-optimistic-collapse`.
+
+
 Features not supported or with limited support for Cuda devices
 ---------------------------------------------------------------
 
diff --git a/include/clang/Basic/LangOptions.def b/include/clang/Basic/LangOptions.def
index 512baa463b..49961856c9 100644
--- a/include/clang/Basic/LangOptions.def
+++ b/include/clang/Basic/LangOptions.def
@@ -207,6 +207,7 @@ LANGOPT(OpenMPCUDAForceFullRuntime , 1, 0, "Force to use full runtime in all con
 LANGOPT(OpenMPHostCXXExceptions    , 1, 0, "C++ exceptions handling in the host code.")
 LANGOPT(OpenMPCUDANumSMs  , 32, 0, "Number of SMs for CUDA devices.")
 LANGOPT(OpenMPCUDABlocksPerSM  , 32, 0, "Number of blocks per SM for CUDA devices.")
+LANGOPT(OpenMPOptimisticCollapse  , 1, 0, "Use at most 32 bits to represent the collapsed loop nest counter.")
 LANGOPT(RenderScript      , 1, 0, "RenderScript")
 
 LANGOPT(CUDAIsDevice      , 1, 0, "compiling for CUDA device")
diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td
index 1c5cae683a..9e6b1afde4 100644
--- a/include/clang/Driver/Options.td
+++ b/include/clang/Driver/Options.td
@@ -1574,6 +1574,10 @@ def fopenmp_cuda_number_of_sm_EQ : Joined<["-"], "fopenmp-cuda-number-of-sm=">,
   Flags<[CC1Option, NoArgumentUnused, HelpHidden]>;
 def fopenmp_cuda_blocks_per_sm_EQ : Joined<["-"], "fopenmp-cuda-blocks-per-sm=">, Group,
   Flags<[CC1Option, NoArgumentUnused, HelpHidden]>;
+def fopenmp_optimistic_collapse : Flag<["-"], "fopenmp-optimistic-collapse">, Group,
+  Flags<[CC1Option, NoArgumentUnused, HelpHidden]>;
+def fno_openmp_optimistic_collapse : Flag<["-"], "fno-openmp-optimistic-collapse">, Group,
+  Flags<[NoArgumentUnused, HelpHidden]>;
 def fno_optimize_sibling_calls : Flag<["-"], "fno-optimize-sibling-calls">, Group;
 def foptimize_sibling_calls : Flag<["-"], "foptimize-sibling-calls">, Group;
 def fno_escaping_block_tail_calls : Flag<["-"], "fno-escaping-block-tail-calls">, Group, Flags<[CC1Option]>;
diff --git a/lib/Driver/ToolChains/Clang.cpp b/lib/Driver/ToolChains/Clang.cpp
index 7df95649bd..eb88a71e49 100644
--- a/lib/Driver/ToolChains/Clang.cpp
+++ b/lib/Driver/ToolChains/Clang.cpp
@@ -4434,6 +4434,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
       Args.AddAllArgs(CmdArgs, options::OPT_fopenmp_version_EQ);
       Args.AddAllArgs(CmdArgs, options::OPT_fopenmp_cuda_number_of_sm_EQ);
       Args.AddAllArgs(CmdArgs, options::OPT_fopenmp_cuda_blocks_per_sm_EQ);
+      if (Args.hasFlag(options::OPT_fopenmp_optimistic_collapse,
+                       options::OPT_fno_openmp_optimistic_collapse,
+                       /*Default=*/false))
+        CmdArgs.push_back("-fopenmp-optimistic-collapse");
 
       // When in OpenMP offloading mode with NVPTX target, forward
       // cuda-mode flag
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index 04105f0980..1e857355b3 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -2846,6 +2846,11 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
                            Opts.OpenMPCUDABlocksPerSM, Diags);
   }
 
+  // Prevent auto-widening the representation of loop counters during an
+  // OpenMP collapse clause.
+  Opts.OpenMPOptimisticCollapse =
+      Args.hasArg(options::OPT_fopenmp_optimistic_collapse) ? 1 : 0;
+
   // Get the OpenMP target triples if any.
   if (Arg *A = Args.getLastArg(options::OPT_fopenmp_targets_EQ)) {
 
diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp
index 1166de752e..89eb2e2645 100644
--- a/lib/Sema/SemaOpenMP.cpp
+++ b/lib/Sema/SemaOpenMP.cpp
@@ -4136,7 +4136,7 @@ bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) {
     if (!TestIsLessOp.hasValue())
       TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract);
     if (UB && (IsConstZero ||
-               (TestIsLessOp.getValue() ? 
+               (TestIsLessOp.getValue() ?
                   (IsConstNeg || (IsUnsigned && Subtract)) :
                   (IsConstPos || (IsUnsigned && !Subtract))))) {
       SemaRef.Diag(NewStep->getExprLoc(),
@@ -4311,7 +4311,7 @@ bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) {
                        Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
                        CE->getOperatorLoc());
         break;
-      case OO_ExclaimEqual: 
+      case OO_ExclaimEqual:
         return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ?
                      CE->getArg(1) : CE->getArg(0),
                      /*LessOp=*/llvm::None,
@@ -4569,7 +4569,7 @@ Expr *OpenMPIterationSpaceChecker::buildPreCond(
 
   ExprResult CondExpr =
       SemaRef.BuildBinOp(S, DefaultLoc,
-                         TestIsLessOp.getValue() ? 
+                         TestIsLessOp.getValue() ?
                            (TestIsStrictOp ? BO_LT : BO_LE) :
                            (TestIsStrictOp ? BO_GT : BO_GE),
                          NewLB.get(), NewUB.get());
@@ -5270,13 +5270,14 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
 
   // Choose either the 32-bit or 64-bit version.
   ExprResult LastIteration = LastIteration64;
-  if (LastIteration32.isUsable() &&
-      C.getTypeSize(LastIteration32.get()->getType()) == 32 &&
-      (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
-       fitsInto(
-           /*Bits=*/32,
-           LastIteration32.get()->getType()->hasSignedIntegerRepresentation(),
-           LastIteration64.get(), SemaRef)))
+  if (SemaRef.getLangOpts().OpenMPOptimisticCollapse ||
+      (LastIteration32.isUsable() &&
+       C.getTypeSize(LastIteration32.get()->getType()) == 32 &&
+       (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
+        fitsInto(
+            /*Bits=*/32,
+            LastIteration32.get()->getType()->hasSignedIntegerRepresentation(),
+            LastIteration64.get(), SemaRef))))
     LastIteration = LastIteration32;
   QualType VType = LastIteration.get()->getType();
   QualType RealVType = VType;
@@ -13116,7 +13117,7 @@ Sema::ActOnOpenMPMapClause(ArrayRef MapTypeModifiers,
       continue;
     }
     assert(Count < OMPMapClause::NumberOfModifiers &&
-           "Modifiers exceed the allowed number of map type modifiers"); 
+           "Modifiers exceed the allowed number of map type modifiers");
     Modifiers[Count] = MapTypeModifiers[I];
     ModifiersLoc[Count] = MapTypeModifiersLoc[I];
     ++Count;
diff --git a/test/OpenMP/nvptx_target_teams_distribute_parallel_for_codegen.cpp b/test/OpenMP/nvptx_target_teams_distribute_parallel_for_codegen.cpp
index c4df348329..fe0c8dfb63 100644
--- a/test/OpenMP/nvptx_target_teams_distribute_parallel_for_codegen.cpp
+++ b/test/OpenMP/nvptx_target_teams_distribute_parallel_for_codegen.cpp
@@ -1,6 +1,7 @@
 // Test target codegen - host bc file has to be created first.
 // RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -fopenmp-cuda-mode -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc
-// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -fopenmp-cuda-mode -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -fopenmp-cuda-mode -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64 --check-prefix CHECK-DIV64
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -fopenmp-cuda-mode -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -fopenmp-optimistic-collapse -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-DIV32
 // RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -fopenmp-cuda-mode -x c++ -triple i386-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm-bc %s -o %t-x86-host.bc
 // RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -fopenmp-cuda-mode -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
 // RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -fopenmp-cuda-mode -fexceptions -fcxx-exceptions -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
@@ -9,11 +10,12 @@
 #define HEADER
 
 // Check that the execution mode of all 5 target regions on the gpu is set to SPMD Mode.
-// CHECK-DAG: {{@__omp_offloading_.+l32}}_exec_mode = weak constant i8 0
-// CHECK-DAG: {{@__omp_offloading_.+l38}}_exec_mode = weak constant i8 0
-// CHECK-DAG: {{@__omp_offloading_.+l43}}_exec_mode = weak constant i8 0
-// CHECK-DAG: {{@__omp_offloading_.+l48}}_exec_mode = weak constant i8 0
-// CHECK-DAG: {{@__omp_offloading_.+l56}}_exec_mode = weak constant i8 0
+// CHECK-DAG: {{@__omp_offloading_.+l34}}_exec_mode = weak constant i8 0
+// CHECK-DAG: {{@__omp_offloading_.+l40}}_exec_mode = weak constant i8 0
+// CHECK-DAG: {{@__omp_offloading_.+l45}}_exec_mode = weak constant i8 0
+// CHECK-DAG: {{@__omp_offloading_.+l50}}_exec_mode = weak constant i8 0
+// CHECK-DAG: {{@__omp_offloading_.+l58}}_exec_mode = weak constant i8 0
+// CHECK-DAG: {{@__omp_offloading_.+l65}}_exec_mode = weak constant i8 0
 
 #define N 1000
 #define M 10
@@ -80,7 +82,7 @@ int bar(int n){
 // CHECK-DAG: [[KERNEL_SIZE:@.+]] = internal unnamed_addr constant i{{64|32}} 4
 // CHECK-DAG: [[KERNEL_SHARED:@.+]] = internal unnamed_addr constant i16 1
 
-// CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+}}_l32(
+// CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+}}_l34(
 // CHECK-DAG: [[THREAD_LIMIT:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
 // CHECK: call void @__kmpc_spmd_kernel_init(i32 [[THREAD_LIMIT]], i16 0, i16 0)
 // CHECK: call void @__kmpc_get_team_static_memory(i16 1, i8* addrspacecast (i8 addrspace(3)* getelementptr inbounds ([[MEM_TY]], [[MEM_TY]] addrspace(3)* [[SHARED_GLOBAL_RD]], i32 0, i32 0, i32 0) to i8*), i{{64|32}} 4, i16 1, i8** addrspacecast (i8* addrspace(3)* [[KERNEL_PTR]] to i8**))
@@ -214,16 +216,19 @@ int bar(int n){
 // CHECK: call void @__kmpc_spmd_kernel_deinit_v2(i16 0)
 // CHECK: ret void
 
-// CHECK: define internal void [[OUTL4]](
+// CHECK-32: define internal void [[OUTL4]](
+// CHECK-64: define internal void [[OUTL4]](
 // CHECK: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, {{.+}} 33,
 // CHECK: call void @__kmpc_for_static_fini(
 // CHECK: ret void
 
-// CHECK: define weak void @__omp_offloading_{{.*}}_l56(i[[SZ:64|32]] %{{[^,]+}}, [10 x [10 x i32]]* dereferenceable{{.*}})
+// CHECK: define weak void @__omp_offloading_{{.*}}_l58(i[[SZ:64|32]] %{{[^,]+}}, [10 x [10 x i32]]* dereferenceable{{.*}})
 // CHECK: call void [[OUTLINED:@__omp_outlined.*]](i32* %{{.+}}, i32* %{{.+}}, i[[SZ]] %{{.*}}, i[[SZ]] %{{.*}}, i[[SZ]] %{{.*}}, [10 x [10 x i32]]* %{{.*}})
 // CHECK: define internal void [[OUTLINED]](i32* noalias %{{.*}}, i32* noalias %{{.*}} i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, [10 x [10 x i32]]* dereferenceable{{.*}})
+// CHECK-DIV64: div i64
+// CHECK-DIV32-NO: div i64
 
-// CHECK: define weak void @__omp_offloading_{{.*}}_l63(i[[SZ:64|32]] %{{[^,]+}}, [1000 x i32]* dereferenceable{{.*}}, i32* %{{[^)]+}})
+// CHECK: define weak void @__omp_offloading_{{.*}}_l65(i[[SZ:64|32]] %{{[^,]+}}, [1000 x i32]* dereferenceable{{.*}}, i32* %{{[^)]+}})
 // CHECK: call void [[OUTLINED:@__omp_outlined.*]](i32* %{{.+}}, i32* %{{.+}}, i[[SZ]] %{{.*}}, i[[SZ]] %{{.*}}, i[[SZ]] %{{.*}}, [1000 x i32]* %{{.*}}, i32* %{{.*}})
 // CHECK: define internal void [[OUTLINED]](i32* noalias %{{.*}}, i32* noalias %{{.*}} i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, [1000 x i32]* dereferenceable{{.*}}, i32* %{{.*}})
 
-- 
cgit v1.2.3


From 05d16b5603d658446d6b5e1e31af924959d00026 Mon Sep 17 00:00:00 2001
From: Gheorghe-Teodor Bercea 
Date: Wed, 9 Jan 2019 20:45:26 +0000
Subject: [OpenMP] Avoid remainder operations for loop index values on a
 collapsed loop nest.

Summary: Change the strategy for computing loop index variables after collapsing a loop nest via the collapse clause by replacing the expensive remainder operation with multiplications and additions.

Reviewers: ABataev, caomhin

Reviewed By: ABataev

Subscribers: guansong, arphaman, cfe-commits

Differential Revision: https://reviews.llvm.org/D56413

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350759 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/Sema/SemaOpenMP.cpp                   | 76 +++++++++++++++++-------------
 test/OpenMP/for_codegen.cpp               |  1 -
 test/OpenMP/for_simd_codegen.cpp          | 73 ++++++++++++++++++++++++-----
 test/OpenMP/parallel_for_simd_codegen.cpp | 73 ++++++++++++++++++++++++-----
 test/OpenMP/simd_codegen.cpp              | 77 +++++++++++++++++++++++++------
 5 files changed, 232 insertions(+), 68 deletions(-)

diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp
index 89eb2e2645..36048a38b9 100644
--- a/lib/Sema/SemaOpenMP.cpp
+++ b/lib/Sema/SemaOpenMP.cpp
@@ -5579,31 +5579,59 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
   Built.Updates.resize(NestedLoopCount);
   Built.Finals.resize(NestedLoopCount);
   {
-    ExprResult Div;
-    // Go from inner nested loop to outer.
-    for (int Cnt = NestedLoopCount - 1; Cnt >= 0; --Cnt) {
+    // We implement the following algorithm for obtaining the
+    // original loop iteration variable values based on the
+    // value of the collapsed loop iteration variable IV.
+    //
+    // Let n+1 be the number of collapsed loops in the nest.
+    // Iteration variables (I0, I1, .... In)
+    // Iteration counts (N0, N1, ... Nn)
+    //
+    // Acc = IV;
+    //
+    // To compute Ik for loop k, 0 <= k <= n, generate:
+    //    Prod = N(k+1) * N(k+2) * ... * Nn;
+    //    Ik = Acc / Prod;
+    //    Acc -= Ik * Prod;
+    //
+    ExprResult Acc = IV;
+    for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
       LoopIterationSpace &IS = IterSpaces[Cnt];
       SourceLocation UpdLoc = IS.IncSrcRange.getBegin();
-      // Build: Iter = (IV / Div) % IS.NumIters
-      // where Div is product of previous iterations' IS.NumIters.
       ExprResult Iter;
-      if (Div.isUsable()) {
-        Iter =
-            SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, IV.get(), Div.get());
-      } else {
-        Iter = IV;
-        assert((Cnt == (int)NestedLoopCount - 1) &&
-               "unusable div expected on first iteration only");
-      }
 
-      if (Cnt != 0 && Iter.isUsable())
-        Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Rem, Iter.get(),
-                                  IS.NumIterations);
+      // Compute prod
+      ExprResult Prod =
+          SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
+      for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K)
+        Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(),
+                                  IterSpaces[K].NumIterations);
+
+      // Iter = Acc / Prod
+      // If there is at least one more inner loop to avoid
+      // multiplication by 1.
+      if (Cnt + 1 < NestedLoopCount)
+        Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div,
+                                  Acc.get(), Prod.get());
+      else
+        Iter = Acc;
       if (!Iter.isUsable()) {
         HasErrors = true;
         break;
       }
 
+      // Update Acc:
+      // Acc -= Iter * Prod
+      // Check if there is at least one more inner loop to avoid
+      // multiplication by 1.
+      if (Cnt + 1 < NestedLoopCount)
+        Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul,
+                                  Iter.get(), Prod.get());
+      else
+        Prod = Iter;
+      Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub,
+                               Acc.get(), Prod.get());
+
       // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step
       auto *VD = cast(cast(IS.CounterVar)->getDecl());
       DeclRefExpr *CounterVar = buildDeclRefExpr(
@@ -5632,22 +5660,6 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
         break;
       }
 
-      // Build Div for the next iteration: Div <- Div * IS.NumIters
-      if (Cnt != 0) {
-        if (Div.isUnset())
-          Div = IS.NumIterations;
-        else
-          Div = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Div.get(),
-                                   IS.NumIterations);
-
-        // Add parentheses (for debugging purposes only).
-        if (Div.isUsable())
-          Div = tryBuildCapture(SemaRef, Div.get(), Captures);
-        if (!Div.isUsable()) {
-          HasErrors = true;
-          break;
-        }
-      }
       if (!Update.isUsable() || !Final.isUsable()) {
         HasErrors = true;
         break;
diff --git a/test/OpenMP/for_codegen.cpp b/test/OpenMP/for_codegen.cpp
index aab6606d7a..2e44478b63 100644
--- a/test/OpenMP/for_codegen.cpp
+++ b/test/OpenMP/for_codegen.cpp
@@ -38,7 +38,6 @@ void loop_with_counter_collapse() {
   // LIFETIME: call void @llvm.lifetime.end
   // LIFETIME: call void @llvm.lifetime.end
   // LIFETIME: call void @llvm.lifetime.end
-  // LIFETIME: call void @llvm.lifetime.end
   #pragma omp for collapse(2)
   for (int i = 0; i < 4; i++) {
     for (int j = i; j < 4; j++) {
diff --git a/test/OpenMP/for_simd_codegen.cpp b/test/OpenMP/for_simd_codegen.cpp
index a4c148e7d2..c36f52704b 100644
--- a/test/OpenMP/for_simd_codegen.cpp
+++ b/test/OpenMP/for_simd_codegen.cpp
@@ -408,7 +408,10 @@ int templ1(T a, T *z) {
 // CHECK-NEXT: [[I_2:%.+]] = trunc i64 [[I_1_ADD0]] to i32
 // CHECK-NEXT: store i32 [[I_2]], i32*
 // CHECK: [[IV2:%.+]] = load i64, i64* [[T1_OMP_IV]]
-// CHECK-NEXT: [[J_1:%.+]] = srem i64 [[IV2]], 4
+// CHECK-NEXT: [[IV2_1:%.+]] = load i64, i64* [[T1_OMP_IV]]
+// CHECK-NEXT: [[DIV_2:%.+]] = sdiv i64 [[IV2_1]], 4
+// CHECK-NEXT: [[MUL_2:%.+]] = mul nsw i64 [[DIV_2]], 4
+// CHECK-NEXT: [[J_1:%.+]] = sub nsw i64 [[IV2]], [[MUL_2]]
 // CHECK-NEXT: [[J_2:%.+]] = mul nsw i64 [[J_1]], 2
 // CHECK-NEXT: [[J_2_ADD0:%.+]] = add nsw i64 0, [[J_2]]
 // CHECK-NEXT: store i64 [[J_2_ADD0]], i64*
@@ -556,22 +559,70 @@ void collapsed(float *a, float *b, float *c, float *d) {
 // CHECK-NEXT: [[CALC_I_1_MUL1:%.+]] = mul i32 [[CALC_I_1]], 1
 // CHECK-NEXT: [[CALC_I_2:%.+]] = add i32 1, [[CALC_I_1_MUL1]]
 // CHECK-NEXT: store i32 [[CALC_I_2]], i32* [[LC_I:.+]]
+
 // CHECK: [[IV1_2:%.+]] = load i32, i32* [[OMP_IV]]
-// CHECK-NEXT: [[CALC_J_1:%.+]] = udiv i32 [[IV1_2]], 20
-// CHECK-NEXT: [[CALC_J_2:%.+]] = urem i32 [[CALC_J_1]], 3
+// CHECK: [[IV1_2_1:%.+]] = load i32, i32* [[OMP_IV]]
+// CHECK-NEXT: [[CALC_J_1:%.+]] = udiv i32 [[IV1_2_1]], 60
+// CHECK-NEXT: [[MUL_1:%.+]] = mul i32 [[CALC_J_1]], 60
+// CHECK-NEXT: [[SUB_3:%.+]] = sub i32 [[IV1_2]], [[MUL_1]]
+// CHECK-NEXT: [[CALC_J_2:%.+]] = udiv i32 [[SUB_3]], 20
 // CHECK-NEXT: [[CALC_J_2_MUL1:%.+]] = mul i32 [[CALC_J_2]], 1
 // CHECK-NEXT: [[CALC_J_3:%.+]] = add i32 2, [[CALC_J_2_MUL1]]
 // CHECK-NEXT: store i32 [[CALC_J_3]], i32* [[LC_J:.+]]
+
 // CHECK: [[IV1_3:%.+]] = load i32, i32* [[OMP_IV]]
-// CHECK-NEXT: [[CALC_K_1:%.+]] = udiv i32 [[IV1_3]], 5
-// CHECK-NEXT: [[CALC_K_2:%.+]] = urem i32 [[CALC_K_1]], 4
-// CHECK-NEXT: [[CALC_K_2_MUL1:%.+]] = mul i32 [[CALC_K_2]], 1
-// CHECK-NEXT: [[CALC_K_3:%.+]] = add i32 3, [[CALC_K_2_MUL1]]
-// CHECK-NEXT: store i32 [[CALC_K_3]], i32* [[LC_K:.+]]
+// CHECK: [[IV1_3_1:%.+]] = load i32, i32* [[OMP_IV]]
+// CHECK-NEXT: [[DIV_1:%.+]] = udiv i32 [[IV1_3_1]], 60
+// CHECK-NEXT: [[MUL_2:%.+]] = mul i32 [[DIV_1]], 60
+// CHECK-NEXT: [[ADD_3:%.+]] = sub i32 [[IV1_3]], [[MUL_2]]
+
 // CHECK: [[IV1_4:%.+]] = load i32, i32* [[OMP_IV]]
-// CHECK-NEXT: [[CALC_L_1:%.+]] = urem i32 [[IV1_4]], 5
-// CHECK-NEXT: [[CALC_L_1_MUL1:%.+]] = mul i32 [[CALC_L_1]], 1
-// CHECK-NEXT: [[CALC_L_2:%.+]] = add i32 4, [[CALC_L_1_MUL1]]
+// CHECK: [[IV1_4_1:%.+]] = load i32, i32* [[OMP_IV]]
+// CHECK-NEXT: [[DIV_2:%.+]] = udiv i32 [[IV1_4_1]], 60
+// CHECK-NEXT: [[MUL_3:%.+]] = mul i32 [[DIV_2]], 60
+// CHECK-NEXT: [[SUB_6:%.+]] = sub i32 [[IV1_4]], [[MUL_3]]
+// CHECK-NEXT: [[DIV_3:%.+]] = udiv i32 [[SUB_6]], 20
+// CHECK-NEXT: [[MUL_4:%.+]] = mul i32 [[DIV_3]], 20
+// CHECK-NEXT: [[SUB_7:%.+]] = sub i32 [[ADD_3]], [[MUL_4]]
+// CHECK-NEXT: [[DIV_4:%.+]] = udiv i32 [[SUB_7]], 5
+// CHECK-NEXT: [[MUL_5:%.+]] = mul i32 [[DIV_4]], 1
+// CHECK-NEXT: [[ADD_6:%.+]] = add i32 3, [[MUL_5]]
+// CHECK-NEXT: store i32 [[ADD_6]], i32* [[LC_K:.+]]
+
+// CHECK: [[IV1_5:%.+]] = load i32, i32* [[OMP_IV]]
+// CHECK: [[IV1_5_1:%.+]] = load i32, i32* [[OMP_IV]]
+// CHECK-NEXT: [[DIV_5:%.+]] = udiv i32 [[IV1_5_1]], 60
+// CHECK-NEXT: [[MUL_6:%.+]] = mul i32 [[DIV_5]], 60
+// CHECK-NEXT: [[ADD_7:%.+]] = sub i32 [[IV1_5]], [[MUL_6]]
+
+// CHECK: [[IV1_6:%.+]] = load i32, i32* [[OMP_IV]]
+// CHECK: [[IV1_6_1:%.+]] = load i32, i32* [[OMP_IV]]
+// CHECK-NEXT: [[DIV_6:%.+]] = udiv i32 [[IV1_6_1]], 60
+// CHECK-NEXT: [[MUL_7:%.+]] = mul i32 [[DIV_6]], 60
+// CHECK-NEXT: [[SUB_10:%.+]] = sub i32 [[IV1_6]], [[MUL_7]]
+// CHECK-NEXT: [[DIV_7:%.+]] = udiv i32 [[SUB_10]], 20
+// CHECK-NEXT: [[MUL_8:%.+]] = mul i32 [[DIV_7]], 20
+// CHECK-NEXT: [[ADD_9:%.+]] = sub i32 [[ADD_7]], [[MUL_8]]
+
+// CHECK: [[IV1_7:%.+]] = load i32, i32* [[OMP_IV]]
+// CHECK: [[IV1_7_1:%.+]] = load i32, i32* [[OMP_IV]]
+// CHECK-NEXT: [[DIV_8:%.+]] = udiv i32 [[IV1_7_1]], 60
+// CHECK-NEXT: [[MUL_9:%.+]] = mul i32 [[DIV_8]], 60
+// CHECK-NEXT: [[ADD_10:%.+]] = sub i32 [[IV1_7]], [[MUL_9]]
+
+// CHECK: [[IV1_8:%.+]] = load i32, i32* [[OMP_IV]]
+// CHECK: [[IV1_8_1:%.+]] = load i32, i32* [[OMP_IV]]
+// CHECK-NEXT: [[DIV_3:%.+]] = udiv i32 [[IV1_8_1]], 60
+// CHECK-NEXT: [[MUL_4:%.+]] = mul i32 [[DIV_3]], 60
+// CHECK-NEXT: [[SUB_7:%.+]] = sub i32 [[IV1_8]], [[MUL_4]]
+// CHECK-NEXT: [[DIV_4:%.+]] = udiv i32 [[SUB_7]], 20
+// CHECK-NEXT: [[MUL_5:%.+]] = mul i32 [[DIV_4]], 20
+// CHECK-NEXT: [[SUB_8:%.+]] = sub i32 [[ADD_10]], [[MUL_5]]
+// CHECK-NEXT: [[DIV_5:%.+]] = udiv i32 [[SUB_8]], 5
+// CHECK-NEXT: [[MUL_6:%.+]] = mul i32 [[DIV_5]], 5
+// CHECK-NEXT: [[SUB_9:%.+]] = sub i32 [[ADD_9]], [[MUL_6]]
+// CHECK-NEXT: [[MUL_6:%.+]] = mul i32 [[SUB_9]], 1
+// CHECK-NEXT: [[CALC_L_2:%.+]] = add i32 4, [[MUL_6]]
 // CHECK-NEXT: [[CALC_L_3:%.+]] = trunc i32 [[CALC_L_2]] to i16
 // CHECK-NEXT: store i16 [[CALC_L_3]], i16* [[LC_L:.+]]
 // ... loop body ...
diff --git a/test/OpenMP/parallel_for_simd_codegen.cpp b/test/OpenMP/parallel_for_simd_codegen.cpp
index 680d7a3556..9585bf2936 100644
--- a/test/OpenMP/parallel_for_simd_codegen.cpp
+++ b/test/OpenMP/parallel_for_simd_codegen.cpp
@@ -513,22 +513,70 @@ void collapsed(float *a, float *b, float *c, float *d) {
 // CHECK-NEXT: [[CALC_I_1_MUL1:%.+]] = mul i32 [[CALC_I_1]], 1
 // CHECK-NEXT: [[CALC_I_2:%.+]] = add i32 1, [[CALC_I_1_MUL1]]
 // CHECK-NEXT: store i32 [[CALC_I_2]], i32* [[LC_I:.+]]
+
 // CHECK: [[IV1_2:%.+]] = load i32, i32* [[OMP_IV]]
-// CHECK-NEXT: [[CALC_J_1:%.+]] = udiv i32 [[IV1_2]], 20
-// CHECK-NEXT: [[CALC_J_2:%.+]] = urem i32 [[CALC_J_1]], 3
+// CHECK: [[IV1_2_1:%.+]] = load i32, i32* [[OMP_IV]]
+// CHECK-NEXT: [[CALC_J_1:%.+]] = udiv i32 [[IV1_2_1]], 60
+// CHECK-NEXT: [[MUL_1:%.+]] = mul i32 [[CALC_J_1]], 60
+// CHECK-NEXT: [[SUB_3:%.+]] = sub i32 [[IV1_2]], [[MUL_1]]
+// CHECK-NEXT: [[CALC_J_2:%.+]] = udiv i32 [[SUB_3]], 20
 // CHECK-NEXT: [[CALC_J_2_MUL1:%.+]] = mul i32 [[CALC_J_2]], 1
 // CHECK-NEXT: [[CALC_J_3:%.+]] = add i32 2, [[CALC_J_2_MUL1]]
 // CHECK-NEXT: store i32 [[CALC_J_3]], i32* [[LC_J:.+]]
+
 // CHECK: [[IV1_3:%.+]] = load i32, i32* [[OMP_IV]]
-// CHECK-NEXT: [[CALC_K_1:%.+]] = udiv i32 [[IV1_3]], 5
-// CHECK-NEXT: [[CALC_K_2:%.+]] = urem i32 [[CALC_K_1]], 4
-// CHECK-NEXT: [[CALC_K_2_MUL1:%.+]] = mul i32 [[CALC_K_2]], 1
-// CHECK-NEXT: [[CALC_K_3:%.+]] = add i32 3, [[CALC_K_2_MUL1]]
-// CHECK-NEXT: store i32 [[CALC_K_3]], i32* [[LC_K:.+]]
+// CHECK: [[IV1_3_1:%.+]] = load i32, i32* [[OMP_IV]]
+// CHECK-NEXT: [[DIV_1:%.+]] = udiv i32 [[IV1_3_1]], 60
+// CHECK-NEXT: [[MUL_2:%.+]] = mul i32 [[DIV_1]], 60
+// CHECK-NEXT: [[ADD_3:%.+]] = sub i32 [[IV1_3]], [[MUL_2]]
+
 // CHECK: [[IV1_4:%.+]] = load i32, i32* [[OMP_IV]]
-// CHECK-NEXT: [[CALC_L_1:%.+]] = urem i32 [[IV1_4]], 5
-// CHECK-NEXT: [[CALC_L_1_MUL1:%.+]] = mul i32 [[CALC_L_1]], 1
-// CHECK-NEXT: [[CALC_L_2:%.+]] = add i32 4, [[CALC_L_1_MUL1]]
+// CHECK: [[IV1_4_1:%.+]] = load i32, i32* [[OMP_IV]]
+// CHECK-NEXT: [[DIV_2:%.+]] = udiv i32 [[IV1_4_1]], 60
+// CHECK-NEXT: [[MUL_3:%.+]] = mul i32 [[DIV_2]], 60
+// CHECK-NEXT: [[SUB_6:%.+]] = sub i32 [[IV1_4]], [[MUL_3]]
+// CHECK-NEXT: [[DIV_3:%.+]] = udiv i32 [[SUB_6]], 20
+// CHECK-NEXT: [[MUL_4:%.+]] = mul i32 [[DIV_3]], 20
+// CHECK-NEXT: [[SUB_7:%.+]] = sub i32 [[ADD_3]], [[MUL_4]]
+// CHECK-NEXT: [[DIV_4:%.+]] = udiv i32 [[SUB_7]], 5
+// CHECK-NEXT: [[MUL_5:%.+]] = mul i32 [[DIV_4]], 1
+// CHECK-NEXT: [[ADD_6:%.+]] = add i32 3, [[MUL_5]]
+// CHECK-NEXT: store i32 [[ADD_6]], i32* [[LC_K:.+]]
+
+// CHECK: [[IV1_5:%.+]] = load i32, i32* [[OMP_IV]]
+// CHECK: [[IV1_5_1:%.+]] = load i32, i32* [[OMP_IV]]
+// CHECK-NEXT: [[DIV_5:%.+]] = udiv i32 [[IV1_5_1]], 60
+// CHECK-NEXT: [[MUL_6:%.+]] = mul i32 [[DIV_5]], 60
+// CHECK-NEXT: [[ADD_7:%.+]] = sub i32 [[IV1_5]], [[MUL_6]]
+
+// CHECK: [[IV1_6:%.+]] = load i32, i32* [[OMP_IV]]
+// CHECK: [[IV1_6_1:%.+]] = load i32, i32* [[OMP_IV]]
+// CHECK-NEXT: [[DIV_6:%.+]] = udiv i32 [[IV1_6_1]], 60
+// CHECK-NEXT: [[MUL_7:%.+]] = mul i32 [[DIV_6]], 60
+// CHECK-NEXT: [[SUB_10:%.+]] = sub i32 [[IV1_6]], [[MUL_7]]
+// CHECK-NEXT: [[DIV_7:%.+]] = udiv i32 [[SUB_10]], 20
+// CHECK-NEXT: [[MUL_8:%.+]] = mul i32 [[DIV_7]], 20
+// CHECK-NEXT: [[ADD_9:%.+]] = sub i32 [[ADD_7]], [[MUL_8]]
+
+// CHECK: [[IV1_7:%.+]] = load i32, i32* [[OMP_IV]]
+// CHECK: [[IV1_7_1:%.+]] = load i32, i32* [[OMP_IV]]
+// CHECK-NEXT: [[DIV_8:%.+]] = udiv i32 [[IV1_7_1]], 60
+// CHECK-NEXT: [[MUL_9:%.+]] = mul i32 [[DIV_8]], 60
+// CHECK-NEXT: [[ADD_10:%.+]] = sub i32 [[IV1_7]], [[MUL_9]]
+
+// CHECK: [[IV1_8:%.+]] = load i32, i32* [[OMP_IV]]
+// CHECK: [[IV1_8_1:%.+]] = load i32, i32* [[OMP_IV]]
+// CHECK-NEXT: [[DIV_3:%.+]] = udiv i32 [[IV1_8_1]], 60
+// CHECK-NEXT: [[MUL_4:%.+]] = mul i32 [[DIV_3]], 60
+// CHECK-NEXT: [[SUB_7:%.+]] = sub i32 [[IV1_8]], [[MUL_4]]
+// CHECK-NEXT: [[DIV_4:%.+]] = udiv i32 [[SUB_7]], 20
+// CHECK-NEXT: [[MUL_5:%.+]] = mul i32 [[DIV_4]], 20
+// CHECK-NEXT: [[SUB_8:%.+]] = sub i32 [[ADD_10]], [[MUL_5]]
+// CHECK-NEXT: [[DIV_5:%.+]] = udiv i32 [[SUB_8]], 5
+// CHECK-NEXT: [[MUL_6:%.+]] = mul i32 [[DIV_5]], 5
+// CHECK-NEXT: [[SUB_9:%.+]] = sub i32 [[ADD_9]], [[MUL_6]]
+// CHECK-NEXT: [[MUL_6:%.+]] = mul i32 [[SUB_9]], 1
+// CHECK-NEXT: [[CALC_L_2:%.+]] = add i32 4, [[MUL_6]]
 // CHECK-NEXT: [[CALC_L_3:%.+]] = trunc i32 [[CALC_L_2]] to i16
 // CHECK-NEXT: store i16 [[CALC_L_3]], i16* [[LC_L:.+]]
 // ... loop body ...
@@ -655,7 +703,10 @@ void widened(float *a, float *b, float *c, float *d) {
 // CHECK-NEXT: [[I_2:%.+]] = trunc i64 [[I_1_ADD0]] to i32
 // CHECK-NEXT: store i32 [[I_2]], i32*
 // CHECK: [[IV2:%.+]] = load i64, i64* [[T1_OMP_IV]]
-// CHECK-NEXT: [[J_1:%.+]] = srem i64 [[IV2]], 4
+// CHECK: [[IV2_1:%.+]] = load i64, i64* [[T1_OMP_IV]]
+// CHECK-NEXT: [[DIV_1:%.+]] = sdiv i64 [[IV2_1]], 4
+// CHECK-NEXT: [[MUL_1:%.+]] = mul nsw i64 [[DIV_1]], 4
+// CHECK-NEXT: [[J_1:%.+]] = sub nsw i64 [[IV2]], [[MUL_1]]
 // CHECK-NEXT: [[J_2:%.+]] = mul nsw i64 [[J_1]], 2
 // CHECK-NEXT: [[J_2_ADD0:%.+]] = add nsw i64 0, [[J_2]]
 // CHECK-NEXT: store i64 [[J_2_ADD0]], i64*
diff --git a/test/OpenMP/simd_codegen.cpp b/test/OpenMP/simd_codegen.cpp
index 9ac71b1dbb..8a636fba23 100644
--- a/test/OpenMP/simd_codegen.cpp
+++ b/test/OpenMP/simd_codegen.cpp
@@ -278,8 +278,11 @@ int templ1(T a, T *z) {
 // CHECK-NEXT: [[I_2:%.+]] = trunc i64 [[I_1_ADD0]] to i32
 // CHECK-NEXT: store i32 [[I_2]], i32* {{%.+}}{{.*}}!llvm.access.group
 // CHECK: [[IV2:%.+]] = load i64, i64* [[T1_OMP_IV]]{{.*}}!llvm.access.group
-// CHECK-NEXT: [[J_1:%.+]] = srem i64 [[IV2]], 4
-// CHECK-NEXT: [[J_2:%.+]] = mul nsw i64 [[J_1]], 2
+// CHECK: [[IV2_1:%.+]] = load i64, i64* [[T1_OMP_IV]]{{.*}}!llvm.access.group
+// CHECK-NEXT: [[J_1_DIV1:%.+]] = sdiv i64 [[IV2_1]], 4
+// CHECK-NEXT: [[J_1_MUL1:%.+]] = mul nsw i64 [[J_1_DIV1]], 4
+// CHECK-NEXT: [[J_1_SUB0:%.+]] = sub nsw i64 [[IV2]], [[J_1_MUL1]]
+// CHECK-NEXT: [[J_2:%.+]] = mul nsw i64 [[J_1_SUB0]], 2
 // CHECK-NEXT: [[J_2_ADD0:%.+]] = add nsw i64 0, [[J_2]]
 // CHECK-NEXT: store i64 [[J_2_ADD0]], i64* {{%.+}}{{.*}}!llvm.access.group
 // simd.for.inc:
@@ -393,22 +396,70 @@ void collapsed(float *a, float *b, float *c, float *d) {
 // CHECK-NEXT: [[CALC_I_1_MUL1:%.+]] = mul i32 [[CALC_I_1]], 1
 // CHECK-NEXT: [[CALC_I_2:%.+]] = add i32 1, [[CALC_I_1_MUL1]]
 // CHECK-NEXT: store i32 [[CALC_I_2]], i32* [[LC_I:.+]]
+
 // CHECK: [[IV1_2:%.+]] = load i32, i32* [[OMP_IV]]{{.+}}!llvm.access.group
-// CHECK-NEXT: [[CALC_J_1:%.+]] = udiv i32 [[IV1_2]], 20
-// CHECK-NEXT: [[CALC_J_2:%.+]] = urem i32 [[CALC_J_1]], 3
+// CHECK: [[IV1_2_1:%.+]] = load i32, i32* [[OMP_IV]]{{.+}}!llvm.access.group
+// CHECK-NEXT: [[CALC_J_1:%.+]] = udiv i32 [[IV1_2_1]], 60
+// CHECK-NEXT: [[MUL_1:%.+]] = mul i32 [[CALC_J_1]], 60
+// CHECK-NEXT: [[SUB_3:%.+]] = sub i32 [[IV1_2]], [[MUL_1]]
+// CHECK-NEXT: [[CALC_J_2:%.+]] = udiv i32 [[SUB_3]], 20
 // CHECK-NEXT: [[CALC_J_2_MUL1:%.+]] = mul i32 [[CALC_J_2]], 1
 // CHECK-NEXT: [[CALC_J_3:%.+]] = add i32 2, [[CALC_J_2_MUL1]]
 // CHECK-NEXT: store i32 [[CALC_J_3]], i32* [[LC_J:.+]]
+
 // CHECK: [[IV1_3:%.+]] = load i32, i32* [[OMP_IV]]{{.+}}!llvm.access.group
-// CHECK-NEXT: [[CALC_K_1:%.+]] = udiv i32 [[IV1_3]], 5
-// CHECK-NEXT: [[CALC_K_2:%.+]] = urem i32 [[CALC_K_1]], 4
-// CHECK-NEXT: [[CALC_K_2_MUL1:%.+]] = mul i32 [[CALC_K_2]], 1
-// CHECK-NEXT: [[CALC_K_3:%.+]] = add i32 3, [[CALC_K_2_MUL1]]
-// CHECK-NEXT: store i32 [[CALC_K_3]], i32* [[LC_K:.+]]
-// CHECK: [[IV1_4:%.+]] = load i32, i32* [[OMP_IV]]{{.+}}!llvm.access.group
-// CHECK-NEXT: [[CALC_L_1:%.+]] = urem i32 [[IV1_4]], 5
-// CHECK-NEXT: [[CALC_L_1_MUL1:%.+]] = mul i32 [[CALC_L_1]], 1
-// CHECK-NEXT: [[CALC_L_2:%.+]] = add i32 4, [[CALC_L_1_MUL1]]
+// CHECK: [[IV1_3_1:%.+]] = load i32, i32* [[OMP_IV]]{{.+}}!llvm.access.group
+// CHECK-NEXT: [[DIV_1:%.+]] = udiv i32 [[IV1_3_1]], 60
+// CHECK-NEXT: [[MUL_2:%.+]] = mul i32 [[DIV_1]], 60
+// CHECK-NEXT: [[ADD_3:%.+]] = sub i32 [[IV1_3]], [[MUL_2]]
+
+// CHECK: [[IV1_4:%.+]] = load i32, i32* [[OMP_IV]]
+// CHECK: [[IV1_4_1:%.+]] = load i32, i32* [[OMP_IV]]
+// CHECK-NEXT: [[DIV_2:%.+]] = udiv i32 [[IV1_4_1]], 60
+// CHECK-NEXT: [[MUL_3:%.+]] = mul i32 [[DIV_2]], 60
+// CHECK-NEXT: [[SUB_6:%.+]] = sub i32 [[IV1_4]], [[MUL_3]]
+// CHECK-NEXT: [[DIV_3:%.+]] = udiv i32 [[SUB_6]], 20
+// CHECK-NEXT: [[MUL_4:%.+]] = mul i32 [[DIV_3]], 20
+// CHECK-NEXT: [[ADD_5:%.+]] = sub i32 [[ADD_3]], [[MUL_4]]
+// CHECK-NEXT: [[DIV_4:%.+]] = udiv i32 [[ADD_5]], 5
+// CHECK-NEXT: [[MUL_5:%.+]] = mul i32 [[DIV_4]], 1
+// CHECK-NEXT: [[ADD_6:%.+]] = add i32 3, [[MUL_5]]
+// CHECK-NEXT: store i32 [[ADD_6]], i32* [[LC_K:.+]]
+
+// CHECK: [[IV1_5:%.+]] = load i32, i32* [[OMP_IV]]{{.+}}!llvm.access.group
+// CHECK: [[IV1_5_1:%.+]] = load i32, i32* [[OMP_IV]]{{.+}}!llvm.access.group
+// CHECK-NEXT: [[DIV_5:%.+]] = udiv i32 [[IV1_5_1]], 60
+// CHECK-NEXT: [[MUL_6:%.+]] = mul i32 [[DIV_5]], 60
+// CHECK-NEXT: [[SUB_7:%.+]] = sub i32 [[IV1_5]], [[MUL_6]]
+
+// CHECK: [[IV1_6:%.+]] = load i32, i32* [[OMP_IV]]
+// CHECK: [[IV1_6_1:%.+]] = load i32, i32* [[OMP_IV]]
+// CHECK-NEXT: [[DIV_6:%.+]] = udiv i32 [[IV1_6_1]], 60
+// CHECK-NEXT: [[MUL_7:%.+]] = mul i32 [[DIV_6]], 60
+// CHECK-NEXT: [[SUB_10:%.+]] = sub i32 [[IV1_6]], [[MUL_7]]
+// CHECK-NEXT: [[DIV_7:%.+]] = udiv i32 [[SUB_10]], 20
+// CHECK-NEXT: [[MUL_8:%.+]] = mul i32 [[DIV_7]], 20
+// CHECK-NEXT: [[SUB_11:%.+]] = sub i32 [[SUB_7]], [[MUL_8]]
+
+// CHECK: [[IV1_7:%.+]] = load i32, i32* [[OMP_IV]]
+// CHECK: [[IV1_7_1:%.+]] = load i32, i32* [[OMP_IV]]
+// CHECK-NEXT: [[DIV_8:%.+]] = udiv i32 [[IV1_7_1]], 60
+// CHECK-NEXT: [[MUL_9:%.+]] = mul i32 [[DIV_8]], 60
+// CHECK-NEXT: [[SUB_12:%.+]] = sub i32 [[IV1_7]], [[MUL_9]]
+
+// CHECK: [[IV1_8:%.+]] = load i32, i32* [[OMP_IV]]
+// CHECK: [[IV1_8_1:%.+]] = load i32, i32* [[OMP_IV]]
+// CHECK-NEXT: [[DIV_3:%.+]] = udiv i32 [[IV1_8_1]], 60
+// CHECK-NEXT: [[MUL_4:%.+]] = mul i32 [[DIV_3]], 60
+// CHECK-NEXT: [[SUB_7:%.+]] = sub i32 [[IV1_8]], [[MUL_4]]
+// CHECK-NEXT: [[DIV_4:%.+]] = udiv i32 [[SUB_7]], 20
+// CHECK-NEXT: [[MUL_5:%.+]] = mul i32 [[DIV_4]], 20
+// CHECK-NEXT: [[SUB_8:%.+]] = sub i32 [[SUB_12]], [[MUL_5]]
+// CHECK-NEXT: [[DIV_5:%.+]] = udiv i32 [[SUB_8]], 5
+// CHECK-NEXT: [[MUL_6:%.+]] = mul i32 [[DIV_5]], 5
+// CHECK-NEXT: [[SUB_9:%.+]] = sub i32 [[SUB_11]], [[MUL_6]]
+// CHECK-NEXT: [[MUL_6:%.+]] = mul i32 [[SUB_9]], 1
+// CHECK-NEXT: [[CALC_L_2:%.+]] = add i32 4, [[MUL_6]]
 // CHECK-NEXT: [[CALC_L_3:%.+]] = trunc i32 [[CALC_L_2]] to i16
 // CHECK-NEXT: store i16 [[CALC_L_3]], i16* [[LC_L:.+]]
 // ... loop body ...
-- 
cgit v1.2.3


From b01820327c555b8e32787e728892d4b89288e700 Mon Sep 17 00:00:00 2001
From: Alex Lorenz 
Date: Wed, 9 Jan 2019 22:31:37 +0000
Subject: [ObjC] Allow the use of implemented unavailable methods from within
 the @implementation context

In Objective-C, it's common for some frameworks to mark some methods like init
as unavailable in the @interface to prohibit their usage. However, these
frameworks then often implemented said method and refer to it in another method
that acts as a factory for that object. The recent change to how messages to
self are type checked in clang (r349841) introduced a regression which started
to prohibit this pattern with an X is unavailable error. This commit addresses
the aforementioned regression.

rdar://47134898

Differential Revision: https://reviews.llvm.org/D56469


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350768 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/Sema/SemaDeclAttr.cpp                     | 28 ++++++++---
 test/SemaObjC/call-unavailable-init-in-self.m | 68 +++++++++++++++++++++++++++
 2 files changed, 90 insertions(+), 6 deletions(-)
 create mode 100644 test/SemaObjC/call-unavailable-init-in-self.m

diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index d1db71838f..864c930136 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -7269,9 +7269,10 @@ ShouldDiagnoseAvailabilityOfDecl(Sema &S, const NamedDecl *D,
 /// whether we should emit a diagnostic for \c K and \c DeclVersion in
 /// the context of \c Ctx. For example, we should emit an unavailable diagnostic
 /// in a deprecated context, but not the other way around.
-static bool ShouldDiagnoseAvailabilityInContext(Sema &S, AvailabilityResult K,
-                                                VersionTuple DeclVersion,
-                                                Decl *Ctx) {
+static bool
+ShouldDiagnoseAvailabilityInContext(Sema &S, AvailabilityResult K,
+                                    VersionTuple DeclVersion, Decl *Ctx,
+                                    const NamedDecl *OffendingDecl) {
   assert(K != AR_Available && "Expected an unavailable declaration here!");
 
   // Checks if we should emit the availability diagnostic in the context of C.
@@ -7280,9 +7281,22 @@ static bool ShouldDiagnoseAvailabilityInContext(Sema &S, AvailabilityResult K,
       if (const AvailabilityAttr *AA = getAttrForPlatform(S.Context, C))
         if (AA->getIntroduced() >= DeclVersion)
           return true;
-    } else if (K == AR_Deprecated)
+    } else if (K == AR_Deprecated) {
       if (C->isDeprecated())
         return true;
+    } else if (K == AR_Unavailable) {
+      // It is perfectly fine to refer to an 'unavailable' Objective-C method
+      // when it's actually defined and is referenced from within the
+      // @implementation itself. In this context, we interpret unavailable as a
+      // form of access control.
+      if (const auto *MD = dyn_cast(OffendingDecl)) {
+        if (const auto *Impl = dyn_cast(C)) {
+          if (MD->getClassInterface() == Impl->getClassInterface() &&
+              MD->isDefined())
+            return true;
+        }
+      }
+    }
 
     if (C->isUnavailable())
       return true;
@@ -7471,7 +7485,8 @@ static void DoEmitAvailabilityWarning(Sema &S, AvailabilityResult K,
   if (const AvailabilityAttr *AA = getAttrForPlatform(S.Context, OffendingDecl))
     DeclVersion = AA->getIntroduced();
 
-  if (!ShouldDiagnoseAvailabilityInContext(S, K, DeclVersion, Ctx))
+  if (!ShouldDiagnoseAvailabilityInContext(S, K, DeclVersion, Ctx,
+                                           OffendingDecl))
     return;
 
   SourceLocation Loc = Locs.front();
@@ -7955,7 +7970,8 @@ void DiagnoseUnguardedAvailability::DiagnoseDeclAvailability(
 
     // If the context of this function is less available than D, we should not
     // emit a diagnostic.
-    if (!ShouldDiagnoseAvailabilityInContext(SemaRef, Result, Introduced, Ctx))
+    if (!ShouldDiagnoseAvailabilityInContext(SemaRef, Result, Introduced, Ctx,
+                                             OffendingDecl))
       return;
 
     // We would like to emit the diagnostic even if -Wunguarded-availability is
diff --git a/test/SemaObjC/call-unavailable-init-in-self.m b/test/SemaObjC/call-unavailable-init-in-self.m
new file mode 100644
index 0000000000..fa6f670cc9
--- /dev/null
+++ b/test/SemaObjC/call-unavailable-init-in-self.m
@@ -0,0 +1,68 @@
+// RUN: %clang_cc1 -x objective-c -verify -fobjc-arc %s
+
+@interface NSObject
+
++ (instancetype)new;
++ (instancetype)alloc;
+
+@end
+
+@interface Sub: NSObject
+
+- (instancetype)init __attribute__((unavailable)); // expected-note 4 {{'init' has been explicitly marked unavailable here}}
+
+- (void)notImplemented __attribute__((unavailable)); // expected-note {{'notImplemented' has been explicitly marked unavailable here}}
+
+@end
+
+@implementation Sub
+
++ (Sub *)create {
+  return [[self alloc] init];
+}
+
++ (Sub *)create2 {
+  return [self new];
+}
+
++ (Sub *)create3 {
+  return [Sub new];
+}
+
+- (instancetype) init {
+  return self;
+}
+
+- (void)reportUseOfUnimplemented {
+  [self notImplemented]; // expected-error {{'notImplemented' is unavailable}}
+}
+
+@end
+
+@interface SubClassContext: Sub
+@end
+
+@implementation SubClassContext
+
+- (void)subClassContext {
+  (void)[[Sub alloc] init]; // expected-error {{'init' is unavailable}}
+  (void)[Sub new]; // expected-error {{'new' is unavailable}}
+}
+
+@end
+
+void unrelatedContext() {
+  (void)[[Sub alloc] init]; // expected-error {{'init' is unavailable}}
+  (void)[Sub new]; // expected-error {{'new' is unavailable}}
+}
+
+@interface X @end
+
+@interface X (Foo)
+-(void)meth __attribute__((unavailable));
+@end
+
+@implementation X (Foo)
+-(void)meth {}
+-(void)call_it { [self meth]; }
+@end
-- 
cgit v1.2.3


From c5a37dd350a4e86e75ae49e3a4d6c55c0e803160 Mon Sep 17 00:00:00 2001
From: Nick Desaulniers 
Date: Wed, 9 Jan 2019 23:54:55 +0000
Subject: [Sema] Mark target of __attribute__((alias("target"))) used for C

Summary:
Prevents -Wunneeded-internal-delcaration warnings when the target has no
other references. This occurs frequently in device drivers in the Linux
kernel.

Sema would need to invoke the demangler on the target, since in C++ the
target name is mangled:

int f() { return 42; }
int g() __attribute__((alias("_Z1fv")));

Sema does not have the ability to demangle names at this time.

https://bugs.llvm.org/show_bug.cgi?id=39088
https://github.com/ClangBuiltLinux/linux/issues/232

Reviewers: rsmith, rjmccall

Reviewed By: rsmith

Subscribers: erik.pilkington, cfe-commits, pirama, srhines

Differential Revision: https://reviews.llvm.org/D54188

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350776 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/Sema/SemaDeclAttr.cpp | 11 ++++++++++-
 test/Sema/alias-unused.c  |  7 +++++++
 2 files changed, 17 insertions(+), 1 deletion(-)
 create mode 100644 test/Sema/alias-unused.c

diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index 864c930136..b5859d1fb7 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -1898,7 +1898,16 @@ static void handleAliasAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
     }
   }
 
-  // FIXME: check if target symbol exists in current file
+  // Mark target used to prevent unneeded-internal-declaration warnings.
+  if (!S.LangOpts.CPlusPlus) {
+    // FIXME: demangle Str for C++, as the attribute refers to the mangled
+    // linkage name, not the pre-mangled identifier.
+    const DeclarationNameInfo target(&S.Context.Idents.get(Str), AL.getLoc());
+    LookupResult LR(S, target, Sema::LookupOrdinaryName);
+    if (S.LookupQualifiedName(LR, S.getCurLexicalContext()))
+      for (NamedDecl *ND : LR)
+        ND->markUsed(S.Context);
+  }
 
   D->addAttr(::new (S.Context) AliasAttr(AL.getRange(), S.Context, Str,
                                          AL.getAttributeSpellingListIndex()));
diff --git a/test/Sema/alias-unused.c b/test/Sema/alias-unused.c
new file mode 100644
index 0000000000..5cedc93c29
--- /dev/null
+++ b/test/Sema/alias-unused.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -Wunneeded-internal-declaration -x c -verify %s
+// expected-no-diagnostics
+static int f() { return 42; }
+int g() __attribute__((alias("f")));
+
+static int foo [] = { 42, 0xDEAD };
+extern typeof(foo) bar __attribute__((unused, alias("foo")));
-- 
cgit v1.2.3


From 6e2340bf44dc6667ee701014db7a27374fb54c15 Mon Sep 17 00:00:00 2001
From: Richard Smith 
Date: Thu, 10 Jan 2019 00:03:29 +0000
Subject: In nothrow new-expressions, null-check the result if we're going to
 apply sanitizers to it.

This avoids a sanitizer false positive that we are initializing a null
pointer.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350779 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/CodeGen/CGExprCXX.cpp                |  5 ++--
 test/CodeGenCXX/catch-undef-behavior.cpp | 43 ++++++++++++++++++++++++++++++++
 2 files changed, 46 insertions(+), 2 deletions(-)

diff --git a/lib/CodeGen/CGExprCXX.cpp b/lib/CodeGen/CGExprCXX.cpp
index fabbb4ca54..884ce96859 100644
--- a/lib/CodeGen/CGExprCXX.cpp
+++ b/lib/CodeGen/CGExprCXX.cpp
@@ -1656,9 +1656,10 @@ llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) {
   // Emit a null check on the allocation result if the allocation
   // function is allowed to return null (because it has a non-throwing
   // exception spec or is the reserved placement new) and we have an
-  // interesting initializer.
+  // interesting initializer will be running sanitizers on the initialization.
   bool nullCheck = E->shouldNullCheckAllocation() &&
-                   (!allocType.isPODType(getContext()) || E->hasInitializer());
+                   (!allocType.isPODType(getContext()) || E->hasInitializer() ||
+                    sanitizePerformTypeCheck());
 
   llvm::BasicBlock *nullCheckBB = nullptr;
   llvm::BasicBlock *contBB = nullptr;
diff --git a/test/CodeGenCXX/catch-undef-behavior.cpp b/test/CodeGenCXX/catch-undef-behavior.cpp
index 50a05a06bf..0e8d4fa51a 100644
--- a/test/CodeGenCXX/catch-undef-behavior.cpp
+++ b/test/CodeGenCXX/catch-undef-behavior.cpp
@@ -520,6 +520,49 @@ void upcast_to_vbase() {
 }
 }
 
+struct nothrow {};
+void *operator new[](__SIZE_TYPE__, nothrow) noexcept;
+
+namespace NothrowNew {
+  struct X { X(); };
+
+  // CHECK-LABEL: define{{.*}}nothrow_new_trivial
+  void *nothrow_new_trivial() {
+    // CHECK: %[[is_null:.*]] = icmp eq i8*{{.*}}, null
+    // CHECK: br i1 %[[is_null]], label %[[null:.*]], label %[[nonnull:.*]]
+
+    // CHECK: [[nonnull]]:
+    // CHECK: llvm.objectsize
+    // CHECK: br i1
+    //
+    // CHECK: call {{.*}}__ubsan_handle_type_mismatch
+    //
+    // CHECK: [[null]]:
+    // CHECK-NOT: {{ }}br{{ }}
+    // CHECK: ret
+    return new (nothrow{}) char[123456];
+  }
+
+  // CHECK-LABEL: define{{.*}}nothrow_new_nontrivial
+  void *nothrow_new_nontrivial() {
+    // CHECK: %[[is_null:.*]] = icmp eq i8*{{.*}}, null
+    // CHECK: br i1 %[[is_null]], label %[[null:.*]], label %[[nonnull:.*]]
+
+    // CHECK: [[nonnull]]:
+    // CHECK: llvm.objectsize
+    // CHECK: br i1
+    //
+    // CHECK: call {{.*}}__ubsan_handle_type_mismatch
+    //
+    // CHECK: call {{.*}}_ZN10NothrowNew1XC1Ev
+    //
+    // CHECK: [[null]]:
+    // CHECK-NOT: {{ }}br{{ }}
+    // CHECK: ret
+    return new (nothrow{}) X[123456];
+  }
+}
+
 struct ThisAlign {
   void this_align_lambda();
   void this_align_lambda_2();
-- 
cgit v1.2.3


From d3e607dfe091644d2f5ded026b32e7617fd0eab3 Mon Sep 17 00:00:00 2001
From: Craig Topper 
Date: Thu, 10 Jan 2019 00:47:25 +0000
Subject: [X86] Really make the pointer arguments to avx512 gather/scatter
 intrinsics 'void*' to match gcc and Intel's documentation.

The avx2 gather intrinsics are documented to use 'int', 'long long', 'float', or 'double' *. So I'm leaving those. This matches gcc.

I tried to do this in r350696, but I only updated the header not the builtin definition.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350785 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/Basic/BuiltinsX86.def | 114 ++++++++++++++++++------------------
 1 file changed, 57 insertions(+), 57 deletions(-)

diff --git a/include/clang/Basic/BuiltinsX86.def b/include/clang/Basic/BuiltinsX86.def
index ccb5cd04d2..85c0c3e122 100644
--- a/include/clang/Basic/BuiltinsX86.def
+++ b/include/clang/Basic/BuiltinsX86.def
@@ -968,47 +968,47 @@ TARGET_BUILTIN(__builtin_ia32_vpdpwssds128, "V4iV4iV4iV4i", "ncV:128:", "avx512v
 TARGET_BUILTIN(__builtin_ia32_vpdpwssds256, "V8iV8iV8iV8i", "ncV:256:", "avx512vl,avx512vnni")
 TARGET_BUILTIN(__builtin_ia32_vpdpwssds512, "V16iV16iV16iV16i", "ncV:512:", "avx512vnni")
 
-TARGET_BUILTIN(__builtin_ia32_gather3div2df, "V2dV2ddC*V2LLiUcIi", "nV:128:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3div2di, "V2LLiV2LLiLLiC*V2LLiUcIi", "nV:128:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3div4df, "V4dV4ddC*V4LLiUcIi", "nV:256:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3div4di, "V4LLiV4LLiLLiC*V4LLiUcIi", "nV:256:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3div4sf, "V4fV4ffC*V2LLiUcIi", "nV:128:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3div4si, "V4iV4iiC*V2LLiUcIi", "nV:128:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3div8sf, "V4fV4ffC*V4LLiUcIi", "nV:256:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3div8si, "V4iV4iiC*V4LLiUcIi", "nV:256:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3siv2df, "V2dV2ddC*V4iUcIi", "nV:128:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3siv2di, "V2LLiV2LLiLLiC*V4iUcIi", "nV:128:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3siv4df, "V4dV4ddC*V4iUcIi", "nV:256:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3siv4di, "V4LLiV4LLiLLiC*V4iUcIi", "nV:256:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3siv4sf, "V4fV4ffC*V4iUcIi", "nV:128:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3siv4si, "V4iV4iiC*V4iUcIi", "nV:128:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3siv8sf, "V8fV8ffC*V8iUcIi", "nV:256:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3siv8si, "V8iV8iiC*V8iUcIi", "nV:256:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gathersiv8df, "V8dV8ddC*V8iUcIi", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_gathersiv16sf, "V16fV16ffC*V16fUsIi", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_gatherdiv8df, "V8dV8ddC*V8LLiUcIi", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_gatherdiv16sf, "V8fV8ffC*V8LLiUcIi", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_gathersiv8di, "V8LLiV8LLiLLiC*V8iUcIi", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_gathersiv16si, "V16iV16iiC*V16iUsIi", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_gatherdiv8di, "V8LLiV8LLiLLiC*V8LLiUcIi", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_gatherdiv16si, "V8iV8iiC*V8LLiUcIi", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_scattersiv8df, "vd*UcV8iV8dIi", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_scattersiv16sf, "vf*UsV16iV16fIi", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_scatterdiv8df,  "vd*UcV8LLiV8dIi", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_scatterdiv16sf, "vf*UcV8LLiV8fIi", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_scattersiv8di,  "vLLi*UcV8iV8LLiIi", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_scattersiv16si, "vi*UsV16iV16iIi", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_scatterdiv8di,  "vLLi*UcV8LLiV8LLiIi", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_scatterdiv16si, "vi*UcV8LLiV8iIi", "nV:512:", "avx512f")
-
-TARGET_BUILTIN(__builtin_ia32_gatherpfdpd,  "vUcV8iLLiC*IiIi", "nV:512:", "avx512pf")
-TARGET_BUILTIN(__builtin_ia32_gatherpfdps,  "vUsV16iiC*IiIi", "nV:512:", "avx512pf")
-TARGET_BUILTIN(__builtin_ia32_gatherpfqpd,  "vUcV8LLiLLiC*IiIi", "nV:512:", "avx512pf")
-TARGET_BUILTIN(__builtin_ia32_gatherpfqps,  "vUcV8LLiiC*IiIi", "nV:512:", "avx512pf")
-TARGET_BUILTIN(__builtin_ia32_scatterpfdpd, "vUcV8iLLi*IiIi", "nV:512:", "avx512pf")
-TARGET_BUILTIN(__builtin_ia32_scatterpfdps, "vUsV16ii*IiIi", "nV:512:", "avx512pf")
-TARGET_BUILTIN(__builtin_ia32_scatterpfqpd, "vUcV8LLiLLi*IiIi", "nV:512:", "avx512pf")
-TARGET_BUILTIN(__builtin_ia32_scatterpfqps, "vUcV8LLii*IiIi", "nV:512:", "avx512pf")
+TARGET_BUILTIN(__builtin_ia32_gather3div2df, "V2dV2dvC*V2LLiUcIi", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3div2di, "V2LLiV2LLivC*V2LLiUcIi", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3div4df, "V4dV4dvC*V4LLiUcIi", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3div4di, "V4LLiV4LLivC*V4LLiUcIi", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3div4sf, "V4fV4fvC*V2LLiUcIi", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3div4si, "V4iV4ivC*V2LLiUcIi", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3div8sf, "V4fV4fvC*V4LLiUcIi", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3div8si, "V4iV4ivC*V4LLiUcIi", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3siv2df, "V2dV2dvC*V4iUcIi", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3siv2di, "V2LLiV2LLivC*V4iUcIi", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3siv4df, "V4dV4dvC*V4iUcIi", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3siv4di, "V4LLiV4LLivC*V4iUcIi", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3siv4sf, "V4fV4fvC*V4iUcIi", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3siv4si, "V4iV4ivC*V4iUcIi", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3siv8sf, "V8fV8fvC*V8iUcIi", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3siv8si, "V8iV8ivC*V8iUcIi", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gathersiv8df, "V8dV8dvC*V8iUcIi", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_gathersiv16sf, "V16fV16fvC*V16fUsIi", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_gatherdiv8df, "V8dV8dvC*V8LLiUcIi", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_gatherdiv16sf, "V8fV8fvC*V8LLiUcIi", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_gathersiv8di, "V8LLiV8LLivC*V8iUcIi", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_gathersiv16si, "V16iV16ivC*V16iUsIi", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_gatherdiv8di, "V8LLiV8LLivC*V8LLiUcIi", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_gatherdiv16si, "V8iV8ivC*V8LLiUcIi", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_scattersiv8df, "vv*UcV8iV8dIi", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_scattersiv16sf, "vv*UsV16iV16fIi", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_scatterdiv8df,  "vv*UcV8LLiV8dIi", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_scatterdiv16sf, "vv*UcV8LLiV8fIi", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_scattersiv8di,  "vv*UcV8iV8LLiIi", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_scattersiv16si, "vv*UsV16iV16iIi", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_scatterdiv8di,  "vv*UcV8LLiV8LLiIi", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_scatterdiv16si, "vv*UcV8LLiV8iIi", "nV:512:", "avx512f")
+
+TARGET_BUILTIN(__builtin_ia32_gatherpfdpd,  "vUcV8ivC*IiIi", "nV:512:", "avx512pf")
+TARGET_BUILTIN(__builtin_ia32_gatherpfdps,  "vUsV16ivC*IiIi", "nV:512:", "avx512pf")
+TARGET_BUILTIN(__builtin_ia32_gatherpfqpd,  "vUcV8LLivC*IiIi", "nV:512:", "avx512pf")
+TARGET_BUILTIN(__builtin_ia32_gatherpfqps,  "vUcV8LLivC*IiIi", "nV:512:", "avx512pf")
+TARGET_BUILTIN(__builtin_ia32_scatterpfdpd, "vUcV8iv*IiIi", "nV:512:", "avx512pf")
+TARGET_BUILTIN(__builtin_ia32_scatterpfdps, "vUsV16iv*IiIi", "nV:512:", "avx512pf")
+TARGET_BUILTIN(__builtin_ia32_scatterpfqpd, "vUcV8LLiv*IiIi", "nV:512:", "avx512pf")
+TARGET_BUILTIN(__builtin_ia32_scatterpfqps, "vUcV8LLiv*IiIi", "nV:512:", "avx512pf")
 
 TARGET_BUILTIN(__builtin_ia32_knotqi, "UcUc", "nc", "avx512dq")
 TARGET_BUILTIN(__builtin_ia32_knothi, "UsUs", "nc", "avx512f")
@@ -1210,22 +1210,22 @@ TARGET_BUILTIN(__builtin_ia32_scalefpd256_mask, "V4dV4dV4dV4dUc", "ncV:256:", "a
 TARGET_BUILTIN(__builtin_ia32_scalefps128_mask, "V4fV4fV4fV4fUc", "ncV:128:", "avx512vl")
 TARGET_BUILTIN(__builtin_ia32_scalefps256_mask, "V8fV8fV8fV8fUc", "ncV:256:", "avx512vl")
 
-TARGET_BUILTIN(__builtin_ia32_scatterdiv2df, "vd*UcV2LLiV2dIi", "nV:128:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scatterdiv2di, "vLLi*UcV2LLiV2LLiIi", "nV:128:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scatterdiv4df, "vd*UcV4LLiV4dIi", "nV:256:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scatterdiv4di, "vLLi*UcV4LLiV4LLiIi", "nV:256:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scatterdiv4sf, "vf*UcV2LLiV4fIi", "nV:128:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scatterdiv4si, "vi*UcV2LLiV4iIi", "nV:128:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scatterdiv8sf, "vf*UcV4LLiV4fIi", "nV:256:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scatterdiv8si, "vi*UcV4LLiV4iIi", "nV:256:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scattersiv2df, "vd*UcV4iV2dIi", "nV:128:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scattersiv2di, "vLLi*UcV4iV2LLiIi", "nV:128:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scattersiv4df, "vd*UcV4iV4dIi", "nV:256:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scattersiv4di, "vLLi*UcV4iV4LLiIi", "nV:256:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scattersiv4sf, "vf*UcV4iV4fIi", "nV:128:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scattersiv4si, "vi*UcV4iV4iIi", "nV:128:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scattersiv8sf, "vf*UcV8iV8fIi", "nV:256:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scattersiv8si, "vi*UcV8iV8iIi", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_scatterdiv2df, "vv*UcV2LLiV2dIi", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_scatterdiv2di, "vv*UcV2LLiV2LLiIi", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_scatterdiv4df, "vv*UcV4LLiV4dIi", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_scatterdiv4di, "vv*UcV4LLiV4LLiIi", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_scatterdiv4sf, "vv*UcV2LLiV4fIi", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_scatterdiv4si, "vv*UcV2LLiV4iIi", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_scatterdiv8sf, "vv*UcV4LLiV4fIi", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_scatterdiv8si, "vv*UcV4LLiV4iIi", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_scattersiv2df, "vv*UcV4iV2dIi", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_scattersiv2di, "vv*UcV4iV2LLiIi", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_scattersiv4df, "vv*UcV4iV4dIi", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_scattersiv4di, "vv*UcV4iV4LLiIi", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_scattersiv4sf, "vv*UcV4iV4fIi", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_scattersiv4si, "vv*UcV4iV4iIi", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_scattersiv8sf, "vv*UcV8iV8fIi", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_scattersiv8si, "vv*UcV8iV8iIi", "nV:256:", "avx512vl")
 
 TARGET_BUILTIN(__builtin_ia32_vpermi2vard128, "V4iV4iV4iV4i", "ncV:128:", "avx512vl")
 TARGET_BUILTIN(__builtin_ia32_vpermi2vard256, "V8iV8iV8iV8i", "ncV:256:", "avx512vl")
-- 
cgit v1.2.3


From 9282bc528747fef1271c865083a207b2a415af33 Mon Sep 17 00:00:00 2001
From: Richard Trieu 
Date: Thu, 10 Jan 2019 03:23:25 +0000
Subject: Refactor declarations of ASTContext allocate functions into its own
 header.

Forward declarations of the allocate functions combine with the forward
declaration of the ASTContext class is enough information for some headers
without pulling in ASTContext.h in its entirety.  Pull the existing
declarations from AttrIterator.h into a new header.  Also place the default
alignment size into this header.  Previously, new had its default in
AttrIterator.h while new[] had its default in ASTContext.h.  Add new header
includes where it is needed.  Specifically to ASTVector.h to make it a
standalone header, unlike previously which it was standalone as long as
none of its functions were called.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350792 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/AST/ASTContext.h         |  9 ++++----
 include/clang/AST/ASTContextAllocate.h | 38 ++++++++++++++++++++++++++++++++++
 include/clang/AST/ASTVector.h          |  1 +
 include/clang/AST/Attr.h               |  1 +
 include/clang/AST/AttrIterator.h       | 19 -----------------
 include/clang/AST/Decl.h               |  1 +
 6 files changed, 46 insertions(+), 23 deletions(-)
 create mode 100644 include/clang/AST/ASTContextAllocate.h

diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index 7edf3b3fed..13870116c7 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -15,6 +15,7 @@
 #ifndef LLVM_CLANG_AST_ASTCONTEXT_H
 #define LLVM_CLANG_AST_ASTCONTEXT_H
 
+#include "clang/AST/ASTContextAllocate.h"
 #include "clang/AST/ASTTypeTraits.h"
 #include "clang/AST/CanonicalType.h"
 #include "clang/AST/CommentCommandTraits.h"
@@ -2969,8 +2970,8 @@ inline Selector GetUnarySelector(StringRef name, ASTContext &Ctx) {
 /// This placement form of operator new uses the ASTContext's allocator for
 /// obtaining memory.
 ///
-/// IMPORTANT: These are also declared in clang/AST/AttrIterator.h! Any changes
-/// here need to also be made there.
+/// IMPORTANT: These are also declared in clang/AST/ASTContextAllocate.h!
+/// Any changes here need to also be made there.
 ///
 /// We intentionally avoid using a nothrow specification here so that the calls
 /// to this operator will not perform a null check on the result -- the
@@ -2993,7 +2994,7 @@ inline Selector GetUnarySelector(StringRef name, ASTContext &Ctx) {
 ///                  allocator supports it).
 /// @return The allocated memory. Could be nullptr.
 inline void *operator new(size_t Bytes, const clang::ASTContext &C,
-                          size_t Alignment) {
+                          size_t Alignment /* = 8 */) {
   return C.Allocate(Bytes, Alignment);
 }
 
@@ -3031,7 +3032,7 @@ inline void operator delete(void *Ptr, const clang::ASTContext &C, size_t) {
 ///                  allocator supports it).
 /// @return The allocated memory. Could be nullptr.
 inline void *operator new[](size_t Bytes, const clang::ASTContext& C,
-                            size_t Alignment = 8) {
+                            size_t Alignment /* = 8 */) {
   return C.Allocate(Bytes, Alignment);
 }
 
diff --git a/include/clang/AST/ASTContextAllocate.h b/include/clang/AST/ASTContextAllocate.h
new file mode 100644
index 0000000000..5b9eed208a
--- /dev/null
+++ b/include/clang/AST/ASTContextAllocate.h
@@ -0,0 +1,38 @@
+//===- ASTContextAllocate.h - ASTContext allocate functions -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file declares ASTContext allocation functions separate from the main
+//  code in ASTContext.h.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_ASTCONTEXTALLOCATE_H
+#define LLVM_CLANG_AST_ASTCONTEXTALLOCATE_H
+
+#include 
+
+namespace clang {
+
+class ASTContext;
+
+} // namespace clang
+
+// Defined in ASTContext.h
+void *operator new(size_t Bytes, const clang::ASTContext &C,
+                   size_t Alignment = 8);
+void *operator new[](size_t Bytes, const clang::ASTContext &C,
+                     size_t Alignment = 8);
+
+// It is good practice to pair new/delete operators.  Also, MSVC gives many
+// warnings if a matching delete overload is not declared, even though the
+// throw() spec guarantees it will not be implicitly called.
+void operator delete(void *Ptr, const clang::ASTContext &C, size_t);
+void operator delete[](void *Ptr, const clang::ASTContext &C, size_t);
+
+#endif // LLVM_CLANG_AST_ASTCONTEXTALLOCATE_H
diff --git a/include/clang/AST/ASTVector.h b/include/clang/AST/ASTVector.h
index 80cd6b7007..51de119f08 100644
--- a/include/clang/AST/ASTVector.h
+++ b/include/clang/AST/ASTVector.h
@@ -18,6 +18,7 @@
 #ifndef LLVM_CLANG_AST_ASTVECTOR_H
 #define LLVM_CLANG_AST_ASTVECTOR_H
 
+#include "clang/AST/ASTContextAllocate.h"
 #include "llvm/ADT/PointerIntPair.h"
 #include 
 #include 
diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h
index 4ee083934c..3a319326d2 100644
--- a/include/clang/AST/Attr.h
+++ b/include/clang/AST/Attr.h
@@ -14,6 +14,7 @@
 #ifndef LLVM_CLANG_AST_ATTR_H
 #define LLVM_CLANG_AST_ATTR_H
 
+#include "clang/AST/ASTContextAllocate.h"  // For Attrs.inc
 #include "clang/AST/AttrIterator.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/Expr.h"
diff --git a/include/clang/AST/AttrIterator.h b/include/clang/AST/AttrIterator.h
index 2087ecc0e7..43ad1c9319 100644
--- a/include/clang/AST/AttrIterator.h
+++ b/include/clang/AST/AttrIterator.h
@@ -26,25 +26,6 @@ namespace clang {
 class ASTContext;
 class Attr;
 
-} // namespace clang
-
-// Defined in ASTContext.h
-void *operator new(size_t Bytes, const clang::ASTContext &C,
-                   size_t Alignment = 8);
-
-// FIXME: Being forced to not have a default argument here due to redeclaration
-//        rules on default arguments sucks
-void *operator new[](size_t Bytes, const clang::ASTContext &C,
-                     size_t Alignment);
-
-// It is good practice to pair new/delete operators.  Also, MSVC gives many
-// warnings if a matching delete overload is not declared, even though the
-// throw() spec guarantees it will not be implicitly called.
-void operator delete(void *Ptr, const clang::ASTContext &C, size_t);
-void operator delete[](void *Ptr, const clang::ASTContext &C, size_t);
-
-namespace clang {
-
 /// AttrVec - A vector of Attr, which is how they are stored on the AST.
 using AttrVec = SmallVector;
 
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index ac641881ae..de2765391f 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -15,6 +15,7 @@
 #define LLVM_CLANG_AST_DECL_H
 
 #include "clang/AST/APValue.h"
+#include "clang/AST/ASTContextAllocate.h"
 #include "clang/AST/DeclBase.h"
 #include "clang/AST/DeclarationName.h"
 #include "clang/AST/ExternalASTSource.h"
-- 
cgit v1.2.3


From ad0cb4e3a2d39c2afa7bead67d6707833ed4f603 Mon Sep 17 00:00:00 2001
From: Stanislav Mekhanoshin 
Date: Thu, 10 Jan 2019 03:25:47 +0000
Subject: [AMDGPU] Separate feature dot-insts

Differential Revision: https://reviews.llvm.org/D56525

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350794 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/Basic/BuiltinsAMDGPU.def             | 14 +++++------
 lib/Basic/Targets/AMDGPU.cpp                       |  1 +
 test/CodeGenOpenCL/amdgpu-features.cl              |  2 +-
 test/CodeGenOpenCL/builtins-amdgcn-dl-insts-err.cl | 28 +++++++++++-----------
 4 files changed, 23 insertions(+), 22 deletions(-)

diff --git a/include/clang/Basic/BuiltinsAMDGPU.def b/include/clang/Basic/BuiltinsAMDGPU.def
index 1ee43cb5ee..a25e45fe3f 100644
--- a/include/clang/Basic/BuiltinsAMDGPU.def
+++ b/include/clang/Basic/BuiltinsAMDGPU.def
@@ -135,13 +135,13 @@ TARGET_BUILTIN(__builtin_amdgcn_fmed3h, "hhhh", "nc", "gfx9-insts")
 // Deep learning builtins.
 //===----------------------------------------------------------------------===//
 
-TARGET_BUILTIN(__builtin_amdgcn_fdot2, "fV2hV2hfIb", "nc", "dl-insts")
-TARGET_BUILTIN(__builtin_amdgcn_sdot2, "SiV2SsV2SsSiIb", "nc", "dl-insts")
-TARGET_BUILTIN(__builtin_amdgcn_udot2, "UiV2UsV2UsUiIb", "nc", "dl-insts")
-TARGET_BUILTIN(__builtin_amdgcn_sdot4, "SiSiSiSiIb", "nc", "dl-insts")
-TARGET_BUILTIN(__builtin_amdgcn_udot4, "UiUiUiUiIb", "nc", "dl-insts")
-TARGET_BUILTIN(__builtin_amdgcn_sdot8, "SiSiSiSiIb", "nc", "dl-insts")
-TARGET_BUILTIN(__builtin_amdgcn_udot8, "UiUiUiUiIb", "nc", "dl-insts")
+TARGET_BUILTIN(__builtin_amdgcn_fdot2, "fV2hV2hfIb", "nc", "dot-insts")
+TARGET_BUILTIN(__builtin_amdgcn_sdot2, "SiV2SsV2SsSiIb", "nc", "dot-insts")
+TARGET_BUILTIN(__builtin_amdgcn_udot2, "UiV2UsV2UsUiIb", "nc", "dot-insts")
+TARGET_BUILTIN(__builtin_amdgcn_sdot4, "SiSiSiSiIb", "nc", "dot-insts")
+TARGET_BUILTIN(__builtin_amdgcn_udot4, "UiUiUiUiIb", "nc", "dot-insts")
+TARGET_BUILTIN(__builtin_amdgcn_sdot8, "SiSiSiSiIb", "nc", "dot-insts")
+TARGET_BUILTIN(__builtin_amdgcn_udot8, "UiUiUiUiIb", "nc", "dot-insts")
 
 //===----------------------------------------------------------------------===//
 // Special builtins.
diff --git a/lib/Basic/Targets/AMDGPU.cpp b/lib/Basic/Targets/AMDGPU.cpp
index 4f17b17ff4..7313a692f4 100644
--- a/lib/Basic/Targets/AMDGPU.cpp
+++ b/lib/Basic/Targets/AMDGPU.cpp
@@ -137,6 +137,7 @@ bool AMDGPUTargetInfo::initFeatureMap(
     switch (llvm::AMDGPU::parseArchAMDGCN(CPU)) {
     case GK_GFX906:
       Features["dl-insts"] = true;
+      Features["dot-insts"] = true;
       LLVM_FALLTHROUGH;
     case GK_GFX909:
     case GK_GFX904:
diff --git a/test/CodeGenOpenCL/amdgpu-features.cl b/test/CodeGenOpenCL/amdgpu-features.cl
index e24e2286df..7aac4d3a36 100644
--- a/test/CodeGenOpenCL/amdgpu-features.cl
+++ b/test/CodeGenOpenCL/amdgpu-features.cl
@@ -11,7 +11,7 @@
 // RUN: %clang_cc1 -triple amdgcn -target-cpu gfx601 -S -emit-llvm -o - %s | FileCheck --check-prefix=GFX601 %s
 
 // GFX904: "target-features"="+16-bit-insts,+ci-insts,+dpp,+fp32-denormals,+fp64-fp16-denormals,+gfx9-insts,+s-memrealtime,+vi-insts"
-// GFX906: "target-features"="+16-bit-insts,+ci-insts,+dl-insts,+dpp,+fp32-denormals,+fp64-fp16-denormals,+gfx9-insts,+s-memrealtime,+vi-insts"
+// GFX906: "target-features"="+16-bit-insts,+ci-insts,+dl-insts,+dot-insts,+dpp,+fp32-denormals,+fp64-fp16-denormals,+gfx9-insts,+s-memrealtime,+vi-insts"
 // GFX801: "target-features"="+16-bit-insts,+ci-insts,+dpp,+fp32-denormals,+fp64-fp16-denormals,+s-memrealtime,+vi-insts"
 // GFX700: "target-features"="+ci-insts,+fp64-fp16-denormals,-fp32-denormals"
 // GFX600: "target-features"="+fp64-fp16-denormals,-fp32-denormals"
diff --git a/test/CodeGenOpenCL/builtins-amdgcn-dl-insts-err.cl b/test/CodeGenOpenCL/builtins-amdgcn-dl-insts-err.cl
index ca3f4006e3..e2c03a471b 100644
--- a/test/CodeGenOpenCL/builtins-amdgcn-dl-insts-err.cl
+++ b/test/CodeGenOpenCL/builtins-amdgcn-dl-insts-err.cl
@@ -12,24 +12,24 @@ kernel void builtins_amdgcn_dl_insts_err(
     half2 v2hA, half2 v2hB, float fC,
     short2 v2ssA, short2 v2ssB, int siA, int siB, int siC,
     ushort2 v2usA, ushort2 v2usB, uint uiA, uint uiB, uint uiC) {
-  fOut[0] = __builtin_amdgcn_fdot2(v2hA, v2hB, fC, false);     // expected-error {{'__builtin_amdgcn_fdot2' needs target feature dl-insts}}
-  fOut[1] = __builtin_amdgcn_fdot2(v2hA, v2hB, fC, true);      // expected-error {{'__builtin_amdgcn_fdot2' needs target feature dl-insts}}
+  fOut[0] = __builtin_amdgcn_fdot2(v2hA, v2hB, fC, false);     // expected-error {{'__builtin_amdgcn_fdot2' needs target feature dot-insts}}
+  fOut[1] = __builtin_amdgcn_fdot2(v2hA, v2hB, fC, true);      // expected-error {{'__builtin_amdgcn_fdot2' needs target feature dot-insts}}
 
-  siOut[0] = __builtin_amdgcn_sdot2(v2ssA, v2ssB, siC, false); // expected-error {{'__builtin_amdgcn_sdot2' needs target feature dl-insts}}
-  siOut[1] = __builtin_amdgcn_sdot2(v2ssA, v2ssB, siC, true);  // expected-error {{'__builtin_amdgcn_sdot2' needs target feature dl-insts}}
+  siOut[0] = __builtin_amdgcn_sdot2(v2ssA, v2ssB, siC, false); // expected-error {{'__builtin_amdgcn_sdot2' needs target feature dot-insts}}
+  siOut[1] = __builtin_amdgcn_sdot2(v2ssA, v2ssB, siC, true);  // expected-error {{'__builtin_amdgcn_sdot2' needs target feature dot-insts}}
 
-  uiOut[0] = __builtin_amdgcn_udot2(v2usA, v2usB, uiC, false); // expected-error {{'__builtin_amdgcn_udot2' needs target feature dl-insts}}
-  uiOut[1] = __builtin_amdgcn_udot2(v2usA, v2usB, uiC, true);  // expected-error {{'__builtin_amdgcn_udot2' needs target feature dl-insts}}
+  uiOut[0] = __builtin_amdgcn_udot2(v2usA, v2usB, uiC, false); // expected-error {{'__builtin_amdgcn_udot2' needs target feature dot-insts}}
+  uiOut[1] = __builtin_amdgcn_udot2(v2usA, v2usB, uiC, true);  // expected-error {{'__builtin_amdgcn_udot2' needs target feature dot-insts}}
 
-  siOut[2] = __builtin_amdgcn_sdot4(siA, siB, siC, false);     // expected-error {{'__builtin_amdgcn_sdot4' needs target feature dl-insts}}
-  siOut[3] = __builtin_amdgcn_sdot4(siA, siB, siC, true);      // expected-error {{'__builtin_amdgcn_sdot4' needs target feature dl-insts}}
+  siOut[2] = __builtin_amdgcn_sdot4(siA, siB, siC, false);     // expected-error {{'__builtin_amdgcn_sdot4' needs target feature dot-insts}}
+  siOut[3] = __builtin_amdgcn_sdot4(siA, siB, siC, true);      // expected-error {{'__builtin_amdgcn_sdot4' needs target feature dot-insts}}
 
-  uiOut[2] = __builtin_amdgcn_udot4(uiA, uiB, uiC, false);     // expected-error {{'__builtin_amdgcn_udot4' needs target feature dl-insts}}
-  uiOut[3] = __builtin_amdgcn_udot4(uiA, uiB, uiC, true);      // expected-error {{'__builtin_amdgcn_udot4' needs target feature dl-insts}}
+  uiOut[2] = __builtin_amdgcn_udot4(uiA, uiB, uiC, false);     // expected-error {{'__builtin_amdgcn_udot4' needs target feature dot-insts}}
+  uiOut[3] = __builtin_amdgcn_udot4(uiA, uiB, uiC, true);      // expected-error {{'__builtin_amdgcn_udot4' needs target feature dot-insts}}
 
-  siOut[4] = __builtin_amdgcn_sdot8(siA, siB, siC, false);     // expected-error {{'__builtin_amdgcn_sdot8' needs target feature dl-insts}}
-  siOut[5] = __builtin_amdgcn_sdot8(siA, siB, siC, true);      // expected-error {{'__builtin_amdgcn_sdot8' needs target feature dl-insts}}
+  siOut[4] = __builtin_amdgcn_sdot8(siA, siB, siC, false);     // expected-error {{'__builtin_amdgcn_sdot8' needs target feature dot-insts}}
+  siOut[5] = __builtin_amdgcn_sdot8(siA, siB, siC, true);      // expected-error {{'__builtin_amdgcn_sdot8' needs target feature dot-insts}}
 
-  uiOut[4] = __builtin_amdgcn_udot8(uiA, uiB, uiC, false);     // expected-error {{'__builtin_amdgcn_udot8' needs target feature dl-insts}}
-  uiOut[5] = __builtin_amdgcn_udot8(uiA, uiB, uiC, true);      // expected-error {{'__builtin_amdgcn_udot8' needs target feature dl-insts}}
+  uiOut[4] = __builtin_amdgcn_udot8(uiA, uiB, uiC, false);     // expected-error {{'__builtin_amdgcn_udot8' needs target feature dot-insts}}
+  uiOut[5] = __builtin_amdgcn_udot8(uiA, uiB, uiC, true);      // expected-error {{'__builtin_amdgcn_udot8' needs target feature dot-insts}}
 }
-- 
cgit v1.2.3


From 5a120398929f7bbbc3edac565fb785ebee888949 Mon Sep 17 00:00:00 2001
From: Ivan Donchevskii 
Date: Thu, 10 Jan 2019 09:34:44 +0000
Subject: [libclang] Fix clang_Cursor_isAnonymous

Use the same logic as in TypePrinter::printTag to determine that the tag is anonymous and the separate check for namespaces.

Differential Revision: https://reviews.llvm.org/D54996

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350805 91177308-0d34-0410-b5e6-96231b3b80d8
---
 test/Index/print-type.cpp         | 16 ++++++++++++++++
 tools/c-index-test/c-index-test.c | 15 ++++++++-------
 tools/libclang/CXType.cpp         | 10 +++++++---
 3 files changed, 31 insertions(+), 10 deletions(-)

diff --git a/test/Index/print-type.cpp b/test/Index/print-type.cpp
index 654b456239..17bae2e9c3 100644
--- a/test/Index/print-type.cpp
+++ b/test/Index/print-type.cpp
@@ -79,6 +79,17 @@ auto autoTemplPointer = &autoTemplRefParam;
 
 outer::Foo parameter;
 outer::inner::Bar construct(¶meter);
+
+class X {
+  struct { int a; };
+  class { public: int b; };
+  union { int c; int d;};
+  enum { Test };
+};
+
+namespace {
+  int a;
+}
 // RUN: c-index-test -test-print-type %s -std=c++14 | FileCheck %s
 // CHECK: Namespace=outer:1:11 (Definition) [type=] [typekind=Invalid] [isPOD=0]
 // CHECK: ClassTemplate=Foo:4:8 (Definition) [type=] [typekind=Invalid] [isPOD=0]
@@ -188,3 +199,8 @@ outer::inner::Bar construct(¶meter);
 // CHECK: TypeAliasDecl=baz:76:7 (Definition) [type=baz] [typekind=Typedef] [templateargs/1= [type=A] [typekind=Unexposed]] [canonicaltype=A] [canonicaltypekind=Record] [canonicaltemplateargs/1= [type=void] [typekind=Void]] [isPOD=0]
 // CHECK: VarDecl=autoTemplPointer:78:6 (Definition) [type=Specialization &> *] [typekind=Auto] [canonicaltype=Specialization &> *] [canonicaltypekind=Pointer] [isPOD=1] [pointeetype=Specialization &>] [pointeekind=Record]
 // CHECK: CallExpr=Bar:17:3 [type=outer::inner::Bar] [typekind=Elaborated] [canonicaltype=outer::inner::Bar] [canonicaltypekind=Record] [args= [outer::Foo *] [Pointer]] [isPOD=0] [nbFields=3]
+// CHECK: StructDecl=:84:3 (Definition) [type=X::(anonymous struct at {{.*}}print-type.cpp:84:3)] [typekind=Record] [isPOD=1] [nbFields=1] [isAnon=1]
+// CHECK: ClassDecl=:85:3 (Definition) [type=X::(anonymous class at {{.*}}print-type.cpp:85:3)] [typekind=Record] [isPOD=1] [nbFields=1] [isAnon=1]
+// CHECK: UnionDecl=:86:3 (Definition) [type=X::(anonymous union at {{.*}}print-type.cpp:86:3)] [typekind=Record] [isPOD=1] [nbFields=2] [isAnon=1]
+// CHECK: EnumDecl=:87:3 (Definition) [type=X::(anonymous enum at {{.*}}print-type.cpp:87:3)] [typekind=Enum] [isPOD=1] [isAnon=1]
+// CHECK: Namespace=:90:11 (Definition) [type=] [typekind=Invalid] [isPOD=0] [isAnon=1]
diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c
index 7c88811a74..fc6ba46fd6 100644
--- a/tools/c-index-test/c-index-test.c
+++ b/tools/c-index-test/c-index-test.c
@@ -1654,13 +1654,14 @@ static enum CXChildVisitResult PrintType(CXCursor cursor, CXCursor p,
         if (numFields != 0) {
           printf(" [nbFields=%d]", numFields);
         }
-        /* Print if it is an anonymous record. */
-        {
-          unsigned isAnon = clang_Cursor_isAnonymous(cursor);
-          if (isAnon != 0) {
-            printf(" [isAnon=%d]", isAnon);
-          }
-        }
+      }
+    }
+
+    /* Print if it is an anonymous record or namespace. */
+    {
+      unsigned isAnon = clang_Cursor_isAnonymous(cursor);
+      if (isAnon != 0) {
+        printf(" [isAnon=%d]", isAnon);
       }
     }
 
diff --git a/tools/libclang/CXType.cpp b/tools/libclang/CXType.cpp
index b511046fe6..b8009ddc1c 100644
--- a/tools/libclang/CXType.cpp
+++ b/tools/libclang/CXType.cpp
@@ -1229,11 +1229,15 @@ unsigned clang_Cursor_isAnonymous(CXCursor C){
   if (!clang_isDeclaration(C.kind))
     return 0;
   const Decl *D = cxcursor::getCursorDecl(C);
-  if (const RecordDecl *FD = dyn_cast_or_null(D))
-    return FD->isAnonymousStructOrUnion();
+  if (const NamespaceDecl *ND = dyn_cast_or_null(D)) {
+    return ND->isAnonymousNamespace();
+  } else if (const TagDecl *TD = dyn_cast_or_null(D)) {
+    return TD->getTypedefNameForAnonDecl() == nullptr &&
+           TD->getIdentifier() == nullptr;
+  }
+
   return 0;
 }
-
 CXType clang_Type_getNamedType(CXType CT){
   QualType T = GetQualType(CT);
   const Type *TP = T.getTypePtrOrNull();
-- 
cgit v1.2.3


From c2686e43c2fcd01692c0f465d6ffc741afd7d939 Mon Sep 17 00:00:00 2001
From: Aaron Ballman 
Date: Thu, 10 Jan 2019 13:19:48 +0000
Subject: Correct the spelling of helpURI to helpUri.

JSON is case sensitive and the SARIF spec uses the corrected spelling.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350817 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/StaticAnalyzer/Core/SarifDiagnostics.cpp                          | 2 +-
 .../Inputs/expected-sarif/sarif-multi-diagnostic-test.c.sarif         | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/lib/StaticAnalyzer/Core/SarifDiagnostics.cpp b/lib/StaticAnalyzer/Core/SarifDiagnostics.cpp
index 9e9690ca0b..fecbc00010 100644
--- a/lib/StaticAnalyzer/Core/SarifDiagnostics.cpp
+++ b/lib/StaticAnalyzer/Core/SarifDiagnostics.cpp
@@ -285,7 +285,7 @@ static json::Object createRule(const PathDiagnostic &Diag) {
 
   std::string RuleURI = getRuleHelpURIStr(CheckName);
   if (!RuleURI.empty())
-    Ret["helpURI"] = RuleURI;
+    Ret["helpUri"] = RuleURI;
 
   return Ret;
 }
diff --git a/test/Analysis/diagnostics/Inputs/expected-sarif/sarif-multi-diagnostic-test.c.sarif b/test/Analysis/diagnostics/Inputs/expected-sarif/sarif-multi-diagnostic-test.c.sarif
index 15880baa4e..68e23642d3 100644
--- a/test/Analysis/diagnostics/Inputs/expected-sarif/sarif-multi-diagnostic-test.c.sarif
+++ b/test/Analysis/diagnostics/Inputs/expected-sarif/sarif-multi-diagnostic-test.c.sarif
@@ -29,7 +29,7 @@
             "fullDescription": {
               "text": "Check for logical errors for function calls and Objective-C message expressions (e.g., uninitialized arguments, null function pointers)"
             },
-            "helpURI": "https://clang-analyzer.llvm.org/available_checks.html#core.CallAndMessage",
+            "helpUri": "https://clang-analyzer.llvm.org/available_checks.html#core.CallAndMessage",
             "id": "core.CallAndMessage",
             "name": {
               "text": "core.CallAndMessage"
@@ -39,7 +39,7 @@
             "fullDescription": {
               "text": "Check for division by zero"
             },
-            "helpURI": "https://clang-analyzer.llvm.org/available_checks.html#core.DivideZero",
+            "helpUri": "https://clang-analyzer.llvm.org/available_checks.html#core.DivideZero",
             "id": "core.DivideZero",
             "name": {
               "text": "core.DivideZero"
-- 
cgit v1.2.3


From 97d939ee57f80d052d5b55dba51046f6aa459582 Mon Sep 17 00:00:00 2001
From: Rafael Stahl 
Date: Thu, 10 Jan 2019 17:44:04 +0000
Subject: [analyzer][CrossTU][NFC] Generalize to external definitions instead
 of external functions

Summary: This is just changing naming and documentation to be general about external definitions that can be imported for cross translation unit analysis. There is at least a plan to add VarDecls: D46421

Reviewers: NoQ, xazax.hun, martong, a.sidorin, george.karpenkov, serge-sans-paille

Reviewed By: xazax.hun, martong

Subscribers: mgorny, whisperity, baloghadamsoftware, szepet, rnkovacs, mikhail.ramalho, Szelethus, donat.nagy, dkrupp, cfe-commits

Differential Revision: https://reviews.llvm.org/D56441

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350852 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/Basic/DiagnosticCrossTUKinds.td      |   2 +-
 include/clang/CrossTU/CrossTranslationUnit.h       |   4 +-
 .../clang/StaticAnalyzer/Core/AnalyzerOptions.def  |   6 +-
 lib/CrossTU/CrossTranslationUnit.cpp               |  14 +--
 .../Analysis/Inputs/ctu-other.c.externalDefMap.txt |   6 ++
 test/Analysis/Inputs/ctu-other.c.externalFnMap.txt |   6 --
 .../Inputs/ctu-other.cpp.externalDefMap.txt        |  15 +++
 .../Inputs/ctu-other.cpp.externalFnMap.txt         |  15 ---
 test/Analysis/analyzer-config.c                    |   2 +-
 test/Analysis/ctu-different-triples.cpp            |   2 +-
 test/Analysis/ctu-main.c                           |   2 +-
 test/Analysis/ctu-main.cpp                         |   2 +-
 test/Analysis/ctu-unknown-parts-in-triples.cpp     |   2 +-
 test/Analysis/func-mapping-test.cpp                |   2 +-
 test/CMakeLists.txt                                |   2 +-
 test/lit.cfg.py                                    |   4 +-
 tools/CMakeLists.txt                               |   2 +-
 tools/clang-extdef-mapping/CMakeLists.txt          |  21 ++++
 tools/clang-extdef-mapping/ClangExtDefMapGen.cpp   | 118 +++++++++++++++++++++
 tools/clang-func-mapping/CMakeLists.txt            |  21 ----
 tools/clang-func-mapping/ClangFnMapGen.cpp         | 118 ---------------------
 tools/scan-build-py/README.md                      |   2 +-
 tools/scan-build-py/libscanbuild/__init__.py       |   2 +-
 tools/scan-build-py/libscanbuild/analyze.py        | 118 +++++++++++----------
 tools/scan-build-py/libscanbuild/arguments.py      |  28 ++---
 tools/scan-build-py/libscanbuild/clang.py          |   6 +-
 tools/scan-build-py/tests/unit/test_analyze.py     |  18 ++--
 tools/scan-build-py/tests/unit/test_clang.py       |   2 +-
 28 files changed, 272 insertions(+), 270 deletions(-)
 create mode 100644 test/Analysis/Inputs/ctu-other.c.externalDefMap.txt
 delete mode 100644 test/Analysis/Inputs/ctu-other.c.externalFnMap.txt
 create mode 100644 test/Analysis/Inputs/ctu-other.cpp.externalDefMap.txt
 delete mode 100644 test/Analysis/Inputs/ctu-other.cpp.externalFnMap.txt
 create mode 100644 tools/clang-extdef-mapping/CMakeLists.txt
 create mode 100644 tools/clang-extdef-mapping/ClangExtDefMapGen.cpp
 delete mode 100644 tools/clang-func-mapping/CMakeLists.txt
 delete mode 100644 tools/clang-func-mapping/ClangFnMapGen.cpp

diff --git a/include/clang/Basic/DiagnosticCrossTUKinds.td b/include/clang/Basic/DiagnosticCrossTUKinds.td
index 9c432457df..89e261c84b 100644
--- a/include/clang/Basic/DiagnosticCrossTUKinds.td
+++ b/include/clang/Basic/DiagnosticCrossTUKinds.td
@@ -12,7 +12,7 @@ let Component = "CrossTU" in {
 def err_ctu_error_opening : Error<
   "error opening '%0': required by the CrossTU functionality">;
 
-def err_fnmap_parsing : Error<
+def err_extdefmap_parsing : Error<
   "error parsing index file: '%0' line: %1 'UniqueID filename' format "
   "expected">;
 
diff --git a/include/clang/CrossTU/CrossTranslationUnit.h b/include/clang/CrossTU/CrossTranslationUnit.h
index 9b36fe653b..52e3ae2749 100644
--- a/include/clang/CrossTU/CrossTranslationUnit.h
+++ b/include/clang/CrossTU/CrossTranslationUnit.h
@@ -90,11 +90,11 @@ std::string createCrossTUIndexString(const llvm::StringMap &Index);
 /// This class is used for tools that requires cross translation
 ///        unit capability.
 ///
-/// This class can load function definitions from external AST files.
+/// This class can load definitions from external AST files.
 /// The loaded definition will be merged back to the original AST using the
 /// AST Importer.
 /// In order to use this class, an index file is required that describes
-/// the locations of the AST files for each function definition.
+/// the locations of the AST files for each definition.
 ///
 /// Note that this class also implements caching.
 class CrossTranslationUnitContext {
diff --git a/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def b/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def
index 8e5d8d3ad3..3cd54df7b1 100644
--- a/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def
+++ b/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def
@@ -275,7 +275,7 @@ ANALYZER_OPTION(
 ANALYZER_OPTION(
     bool, IsNaiveCTUEnabled, "experimental-enable-naive-ctu-analysis",
     "Whether naive cross translation unit analysis is enabled. This is an "
-    "experimental feature to inline functions from another translation units.",
+    "experimental feature to inline functions from other translation units.",
     false)
 
 ANALYZER_OPTION(bool, ShouldDisplayMacroExpansions, "expand-macros",
@@ -344,8 +344,8 @@ ANALYZER_OPTION(StringRef, CTUDir, "ctu-dir",
                 "The directory containing the CTU related files.", "")
 
 ANALYZER_OPTION(StringRef, CTUIndexName, "ctu-index-name",
-                "the name of the file containing the CTU index of functions.",
-                "externalFnMap.txt")
+                "the name of the file containing the CTU index of definitions.",
+                "externalDefMap.txt")
 
 ANALYZER_OPTION(
     StringRef, ModelPath, "model-path",
diff --git a/lib/CrossTU/CrossTranslationUnit.cpp b/lib/CrossTU/CrossTranslationUnit.cpp
index 915b5246c9..7c97beb498 100644
--- a/lib/CrossTU/CrossTranslationUnit.cpp
+++ b/lib/CrossTU/CrossTranslationUnit.cpp
@@ -120,26 +120,26 @@ std::error_code IndexError::convertToErrorCode() const {
 
 llvm::Expected>
 parseCrossTUIndex(StringRef IndexPath, StringRef CrossTUDir) {
-  std::ifstream ExternalFnMapFile(IndexPath);
-  if (!ExternalFnMapFile)
+  std::ifstream ExternalMapFile(IndexPath);
+  if (!ExternalMapFile)
     return llvm::make_error(index_error_code::missing_index_file,
                                         IndexPath.str());
 
   llvm::StringMap Result;
   std::string Line;
   unsigned LineNo = 1;
-  while (std::getline(ExternalFnMapFile, Line)) {
+  while (std::getline(ExternalMapFile, Line)) {
     const size_t Pos = Line.find(" ");
     if (Pos > 0 && Pos != std::string::npos) {
       StringRef LineRef{Line};
-      StringRef FunctionLookupName = LineRef.substr(0, Pos);
-      if (Result.count(FunctionLookupName))
+      StringRef LookupName = LineRef.substr(0, Pos);
+      if (Result.count(LookupName))
         return llvm::make_error(
             index_error_code::multiple_definitions, IndexPath.str(), LineNo);
       StringRef FileName = LineRef.substr(Pos + 1);
       SmallString<256> FilePath = CrossTUDir;
       llvm::sys::path::append(FilePath, FileName);
-      Result[FunctionLookupName] = FilePath.str().str();
+      Result[LookupName] = FilePath.str().str();
     } else
       return llvm::make_error(
           index_error_code::invalid_index_format, IndexPath.str(), LineNo);
@@ -250,7 +250,7 @@ void CrossTranslationUnitContext::emitCrossTUDiagnostics(const IndexError &IE) {
         << IE.getFileName();
     break;
   case index_error_code::invalid_index_format:
-    Context.getDiagnostics().Report(diag::err_fnmap_parsing)
+    Context.getDiagnostics().Report(diag::err_extdefmap_parsing)
         << IE.getFileName() << IE.getLineNum();
     break;
   case index_error_code::multiple_definitions:
diff --git a/test/Analysis/Inputs/ctu-other.c.externalDefMap.txt b/test/Analysis/Inputs/ctu-other.c.externalDefMap.txt
new file mode 100644
index 0000000000..9abaa501a4
--- /dev/null
+++ b/test/Analysis/Inputs/ctu-other.c.externalDefMap.txt
@@ -0,0 +1,6 @@
+c:@F@inlineAsm ctu-other.c.ast
+c:@F@g ctu-other.c.ast
+c:@F@f ctu-other.c.ast
+c:@F@enumCheck ctu-other.c.ast
+c:@F@identImplicit ctu-other.c.ast
+c:@F@structInProto ctu-other.c.ast
diff --git a/test/Analysis/Inputs/ctu-other.c.externalFnMap.txt b/test/Analysis/Inputs/ctu-other.c.externalFnMap.txt
deleted file mode 100644
index 9abaa501a4..0000000000
--- a/test/Analysis/Inputs/ctu-other.c.externalFnMap.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-c:@F@inlineAsm ctu-other.c.ast
-c:@F@g ctu-other.c.ast
-c:@F@f ctu-other.c.ast
-c:@F@enumCheck ctu-other.c.ast
-c:@F@identImplicit ctu-other.c.ast
-c:@F@structInProto ctu-other.c.ast
diff --git a/test/Analysis/Inputs/ctu-other.cpp.externalDefMap.txt b/test/Analysis/Inputs/ctu-other.cpp.externalDefMap.txt
new file mode 100644
index 0000000000..5461685dc6
--- /dev/null
+++ b/test/Analysis/Inputs/ctu-other.cpp.externalDefMap.txt
@@ -0,0 +1,15 @@
+c:@N@chns@F@chf1#I# ctu-other.cpp.ast
+c:@N@myns@N@embed_ns@F@fens#I# ctu-other.cpp.ast
+c:@F@g#I# ctu-other.cpp.ast
+c:@S@mycls@F@fscl#I#S ctu-other.cpp.ast
+c:@S@mycls@F@fcl#I# ctu-other.cpp.ast
+c:@N@myns@S@embed_cls@F@fecl#I# ctu-other.cpp.ast
+c:@S@mycls@S@embed_cls2@F@fecl2#I# ctu-other.cpp.ast
+c:@F@f#I# ctu-other.cpp.ast
+c:@N@myns@F@fns#I# ctu-other.cpp.ast
+c:@F@h#I# ctu-other.cpp.ast
+c:@F@h_chain#I# ctu-chain.cpp.ast
+c:@N@chns@S@chcls@F@chf4#I# ctu-chain.cpp.ast
+c:@N@chns@F@chf2#I# ctu-chain.cpp.ast
+c:@F@fun_using_anon_struct#I# ctu-other.cpp.ast
+c:@F@other_macro_diag#I# ctu-other.cpp.ast
diff --git a/test/Analysis/Inputs/ctu-other.cpp.externalFnMap.txt b/test/Analysis/Inputs/ctu-other.cpp.externalFnMap.txt
deleted file mode 100644
index 5461685dc6..0000000000
--- a/test/Analysis/Inputs/ctu-other.cpp.externalFnMap.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-c:@N@chns@F@chf1#I# ctu-other.cpp.ast
-c:@N@myns@N@embed_ns@F@fens#I# ctu-other.cpp.ast
-c:@F@g#I# ctu-other.cpp.ast
-c:@S@mycls@F@fscl#I#S ctu-other.cpp.ast
-c:@S@mycls@F@fcl#I# ctu-other.cpp.ast
-c:@N@myns@S@embed_cls@F@fecl#I# ctu-other.cpp.ast
-c:@S@mycls@S@embed_cls2@F@fecl2#I# ctu-other.cpp.ast
-c:@F@f#I# ctu-other.cpp.ast
-c:@N@myns@F@fns#I# ctu-other.cpp.ast
-c:@F@h#I# ctu-other.cpp.ast
-c:@F@h_chain#I# ctu-chain.cpp.ast
-c:@N@chns@S@chcls@F@chf4#I# ctu-chain.cpp.ast
-c:@N@chns@F@chf2#I# ctu-chain.cpp.ast
-c:@F@fun_using_anon_struct#I# ctu-other.cpp.ast
-c:@F@other_macro_diag#I# ctu-other.cpp.ast
diff --git a/test/Analysis/analyzer-config.c b/test/Analysis/analyzer-config.c
index ed13a85b59..50b5c2dcf6 100644
--- a/test/Analysis/analyzer-config.c
+++ b/test/Analysis/analyzer-config.c
@@ -20,7 +20,7 @@
 // CHECK-NEXT: cfg-temporary-dtors = true
 // CHECK-NEXT: crosscheck-with-z3 = false
 // CHECK-NEXT: ctu-dir = ""
-// CHECK-NEXT: ctu-index-name = externalFnMap.txt
+// CHECK-NEXT: ctu-index-name = externalDefMap.txt
 // CHECK-NEXT: display-ctu-progress = false
 // CHECK-NEXT: eagerly-assume = true
 // CHECK-NEXT: elide-constructors = true
diff --git a/test/Analysis/ctu-different-triples.cpp b/test/Analysis/ctu-different-triples.cpp
index 314bada0c2..dbfa82fb48 100644
--- a/test/Analysis/ctu-different-triples.cpp
+++ b/test/Analysis/ctu-different-triples.cpp
@@ -2,7 +2,7 @@
 // RUN: mkdir -p %t/ctudir
 // RUN: %clang_cc1 -triple x86_64-pc-linux-gnu \
 // RUN:   -emit-pch -o %t/ctudir/ctu-other.cpp.ast %S/Inputs/ctu-other.cpp
-// RUN: cp %S/Inputs/ctu-other.cpp.externalFnMap.txt %t/ctudir/externalFnMap.txt
+// RUN: cp %S/Inputs/ctu-other.cpp.externalDefMap.txt %t/ctudir/externalDefMap.txt
 // RUN: %clang_analyze_cc1 -triple powerpc64-montavista-linux-gnu \
 // RUN:   -analyzer-checker=core,debug.ExprInspection \
 // RUN:   -analyzer-config experimental-enable-naive-ctu-analysis=true \
diff --git a/test/Analysis/ctu-main.c b/test/Analysis/ctu-main.c
index 239d51ab49..114d694020 100644
--- a/test/Analysis/ctu-main.c
+++ b/test/Analysis/ctu-main.c
@@ -2,7 +2,7 @@
 // RUN: mkdir -p %t/ctudir2
 // RUN: %clang_cc1 -triple x86_64-pc-linux-gnu \
 // RUN:   -emit-pch -o %t/ctudir2/ctu-other.c.ast %S/Inputs/ctu-other.c
-// RUN: cp %S/Inputs/ctu-other.c.externalFnMap.txt %t/ctudir2/externalFnMap.txt
+// RUN: cp %S/Inputs/ctu-other.c.externalDefMap.txt %t/ctudir2/externalDefMap.txt
 // RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fsyntax-only -std=c89 -analyze \
 // RUN:   -analyzer-checker=core,debug.ExprInspection \
 // RUN:   -analyzer-config experimental-enable-naive-ctu-analysis=true \
diff --git a/test/Analysis/ctu-main.cpp b/test/Analysis/ctu-main.cpp
index 44c0c07603..35d1f52ad0 100644
--- a/test/Analysis/ctu-main.cpp
+++ b/test/Analysis/ctu-main.cpp
@@ -4,7 +4,7 @@
 // RUN:   -emit-pch -o %t/ctudir/ctu-other.cpp.ast %S/Inputs/ctu-other.cpp
 // RUN: %clang_cc1 -triple x86_64-pc-linux-gnu \
 // RUN:   -emit-pch -o %t/ctudir/ctu-chain.cpp.ast %S/Inputs/ctu-chain.cpp
-// RUN: cp %S/Inputs/ctu-other.cpp.externalFnMap.txt %t/ctudir/externalFnMap.txt
+// RUN: cp %S/Inputs/ctu-other.cpp.externalDefMap.txt %t/ctudir/externalDefMap.txt
 // RUN: %clang_analyze_cc1 -triple x86_64-pc-linux-gnu \
 // RUN:   -analyzer-checker=core,debug.ExprInspection \
 // RUN:   -analyzer-config experimental-enable-naive-ctu-analysis=true \
diff --git a/test/Analysis/ctu-unknown-parts-in-triples.cpp b/test/Analysis/ctu-unknown-parts-in-triples.cpp
index a632cfbb32..5e643c164d 100644
--- a/test/Analysis/ctu-unknown-parts-in-triples.cpp
+++ b/test/Analysis/ctu-unknown-parts-in-triples.cpp
@@ -5,7 +5,7 @@
 // RUN: mkdir -p %t/ctudir
 // RUN: %clang_cc1 -triple x86_64-pc-linux-gnu \
 // RUN:   -emit-pch -o %t/ctudir/ctu-other.cpp.ast %S/Inputs/ctu-other.cpp
-// RUN: cp %S/Inputs/ctu-other.cpp.externalFnMap.txt %t/ctudir/externalFnMap.txt
+// RUN: cp %S/Inputs/ctu-other.cpp.externalDefMap.txt %t/ctudir/externalDefMap.txt
 // RUN: %clang_analyze_cc1 -triple x86_64-unknown-linux-gnu \
 // RUN:   -analyzer-checker=core,debug.ExprInspection \
 // RUN:   -analyzer-config experimental-enable-naive-ctu-analysis=true \
diff --git a/test/Analysis/func-mapping-test.cpp b/test/Analysis/func-mapping-test.cpp
index 37e653882b..a5d7cfb449 100644
--- a/test/Analysis/func-mapping-test.cpp
+++ b/test/Analysis/func-mapping-test.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_func_map %s -- | FileCheck %s
+// RUN: %clang_extdef_map %s -- | FileCheck %s
 
 int f(int) {
   return 0;
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 2836aefada..7d9dc429a4 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -61,7 +61,7 @@ list(APPEND CLANG_TEST_DEPS
 if(CLANG_ENABLE_STATIC_ANALYZER)
   list(APPEND CLANG_TEST_DEPS
     clang-check
-    clang-func-mapping
+    clang-extdef-mapping
     )
 endif()
 
diff --git a/test/lit.cfg.py b/test/lit.cfg.py
index e61b4bb104..ace0b81081 100644
--- a/test/lit.cfg.py
+++ b/test/lit.cfg.py
@@ -63,8 +63,8 @@ tool_dirs = [config.clang_tools_dir, config.llvm_tools_dir]
 tools = [
     'c-index-test', 'clang-check', 'clang-diff', 'clang-format', 'clang-tblgen',
     'opt',
-    ToolSubst('%clang_func_map', command=FindTool(
-        'clang-func-mapping'), unresolved='ignore'),
+    ToolSubst('%clang_extdef_map', command=FindTool(
+        'clang-extdef-mapping'), unresolved='ignore'),
 ]
 
 if config.clang_examples:
diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt
index 9f76d36dba..43dfffe149 100644
--- a/tools/CMakeLists.txt
+++ b/tools/CMakeLists.txt
@@ -21,7 +21,7 @@ endif()
 
 if(CLANG_ENABLE_STATIC_ANALYZER)
   add_clang_subdirectory(clang-check)
-  add_clang_subdirectory(clang-func-mapping)
+  add_clang_subdirectory(clang-extdef-mapping)
   add_clang_subdirectory(scan-build)
   add_clang_subdirectory(scan-view)
 endif()
diff --git a/tools/clang-extdef-mapping/CMakeLists.txt b/tools/clang-extdef-mapping/CMakeLists.txt
new file mode 100644
index 0000000000..6c81689a83
--- /dev/null
+++ b/tools/clang-extdef-mapping/CMakeLists.txt
@@ -0,0 +1,21 @@
+set(LLVM_LINK_COMPONENTS
+  ${LLVM_TARGETS_TO_BUILD}
+  support
+  )
+
+add_clang_executable(clang-extdef-mapping
+  ClangExtDefMapGen.cpp
+  )
+
+target_link_libraries(clang-extdef-mapping
+  PRIVATE
+  clangAST
+  clangBasic
+  clangCrossTU
+  clangFrontend
+  clangSerialization
+  clangTooling
+  )
+
+install(TARGETS clang-extdef-mapping
+  RUNTIME DESTINATION bin)
diff --git a/tools/clang-extdef-mapping/ClangExtDefMapGen.cpp b/tools/clang-extdef-mapping/ClangExtDefMapGen.cpp
new file mode 100644
index 0000000000..7885f39018
--- /dev/null
+++ b/tools/clang-extdef-mapping/ClangExtDefMapGen.cpp
@@ -0,0 +1,118 @@
+//===- ClangFnMapGen.cpp -----------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--------------------------------------------------------------------===//
+//
+// Clang tool which creates a list of defined functions and the files in which
+// they are defined.
+//
+//===--------------------------------------------------------------------===//
+
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/CrossTU/CrossTranslationUnit.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Frontend/FrontendActions.h"
+#include "clang/Tooling/CommonOptionsParser.h"
+#include "clang/Tooling/Tooling.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Signals.h"
+#include 
+#include 
+
+using namespace llvm;
+using namespace clang;
+using namespace clang::cross_tu;
+using namespace clang::tooling;
+
+static cl::OptionCategory ClangExtDefMapGenCategory("clang-extdefmapgen options");
+
+class MapExtDefNamesConsumer : public ASTConsumer {
+public:
+  MapExtDefNamesConsumer(ASTContext &Context)
+      : SM(Context.getSourceManager()) {}
+
+  ~MapExtDefNamesConsumer() {
+    // Flush results to standard output.
+    llvm::outs() << createCrossTUIndexString(Index);
+  }
+
+  void HandleTranslationUnit(ASTContext &Ctx) override {
+    handleDecl(Ctx.getTranslationUnitDecl());
+  }
+
+private:
+  void handleDecl(const Decl *D);
+
+  SourceManager &SM;
+  llvm::StringMap Index;
+  std::string CurrentFileName;
+};
+
+void MapExtDefNamesConsumer::handleDecl(const Decl *D) {
+  if (!D)
+    return;
+
+  if (const auto *FD = dyn_cast(D)) {
+    if (FD->isThisDeclarationADefinition()) {
+      if (const Stmt *Body = FD->getBody()) {
+        if (CurrentFileName.empty()) {
+          CurrentFileName =
+              SM.getFileEntryForID(SM.getMainFileID())->tryGetRealPathName();
+          if (CurrentFileName.empty())
+            CurrentFileName = "invalid_file";
+        }
+
+        switch (FD->getLinkageInternal()) {
+        case ExternalLinkage:
+        case VisibleNoLinkage:
+        case UniqueExternalLinkage:
+          if (SM.isInMainFile(Body->getBeginLoc())) {
+            std::string LookupName =
+                CrossTranslationUnitContext::getLookupName(FD);
+            Index[LookupName] = CurrentFileName;
+          }
+          break;
+        default:
+          break;
+        }
+      }
+    }
+  }
+
+  if (const auto *DC = dyn_cast(D))
+    for (const Decl *D : DC->decls())
+      handleDecl(D);
+}
+
+class MapExtDefNamesAction : public ASTFrontendAction {
+protected:
+  std::unique_ptr CreateASTConsumer(CompilerInstance &CI,
+                                                 llvm::StringRef) {
+    return llvm::make_unique(CI.getASTContext());
+  }
+};
+
+static cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage);
+
+int main(int argc, const char **argv) {
+  // Print a stack trace if we signal out.
+  sys::PrintStackTraceOnErrorSignal(argv[0], false);
+  PrettyStackTraceProgram X(argc, argv);
+
+  const char *Overview = "\nThis tool collects the USR name and location "
+                         "of external definitions in the source files "
+                         "(excluding headers).\n";
+  CommonOptionsParser OptionsParser(argc, argv, ClangExtDefMapGenCategory,
+                                    cl::ZeroOrMore, Overview);
+
+  ClangTool Tool(OptionsParser.getCompilations(),
+                 OptionsParser.getSourcePathList());
+
+  return Tool.run(newFrontendActionFactory().get());
+}
diff --git a/tools/clang-func-mapping/CMakeLists.txt b/tools/clang-func-mapping/CMakeLists.txt
deleted file mode 100644
index 3544009a45..0000000000
--- a/tools/clang-func-mapping/CMakeLists.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-set(LLVM_LINK_COMPONENTS
-  ${LLVM_TARGETS_TO_BUILD}
-  support
-  )
-
-add_clang_executable(clang-func-mapping
-  ClangFnMapGen.cpp
-  )
-
-target_link_libraries(clang-func-mapping
-  PRIVATE
-  clangAST
-  clangBasic
-  clangCrossTU
-  clangFrontend
-  clangSerialization
-  clangTooling
-  )
-
-install(TARGETS clang-func-mapping
-  RUNTIME DESTINATION bin)
diff --git a/tools/clang-func-mapping/ClangFnMapGen.cpp b/tools/clang-func-mapping/ClangFnMapGen.cpp
deleted file mode 100644
index 635bb0296c..0000000000
--- a/tools/clang-func-mapping/ClangFnMapGen.cpp
+++ /dev/null
@@ -1,118 +0,0 @@
-//===- ClangFnMapGen.cpp -----------------------------------------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===--------------------------------------------------------------------===//
-//
-// Clang tool which creates a list of defined functions and the files in which
-// they are defined.
-//
-//===--------------------------------------------------------------------===//
-
-#include "clang/AST/ASTConsumer.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/CrossTU/CrossTranslationUnit.h"
-#include "clang/Frontend/CompilerInstance.h"
-#include "clang/Frontend/FrontendActions.h"
-#include "clang/Tooling/CommonOptionsParser.h"
-#include "clang/Tooling/Tooling.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Signals.h"
-#include 
-#include 
-
-using namespace llvm;
-using namespace clang;
-using namespace clang::cross_tu;
-using namespace clang::tooling;
-
-static cl::OptionCategory ClangFnMapGenCategory("clang-fnmapgen options");
-
-class MapFunctionNamesConsumer : public ASTConsumer {
-public:
-  MapFunctionNamesConsumer(ASTContext &Context)
-      : SM(Context.getSourceManager()) {}
-
-  ~MapFunctionNamesConsumer() {
-    // Flush results to standard output.
-    llvm::outs() << createCrossTUIndexString(Index);
-  }
-
-  void HandleTranslationUnit(ASTContext &Ctx) override {
-    handleDecl(Ctx.getTranslationUnitDecl());
-  }
-
-private:
-  void handleDecl(const Decl *D);
-
-  SourceManager &SM;
-  llvm::StringMap Index;
-  std::string CurrentFileName;
-};
-
-void MapFunctionNamesConsumer::handleDecl(const Decl *D) {
-  if (!D)
-    return;
-
-  if (const auto *FD = dyn_cast(D)) {
-    if (FD->isThisDeclarationADefinition()) {
-      if (const Stmt *Body = FD->getBody()) {
-        if (CurrentFileName.empty()) {
-          CurrentFileName =
-              SM.getFileEntryForID(SM.getMainFileID())->tryGetRealPathName();
-          if (CurrentFileName.empty())
-            CurrentFileName = "invalid_file";
-        }
-
-        switch (FD->getLinkageInternal()) {
-        case ExternalLinkage:
-        case VisibleNoLinkage:
-        case UniqueExternalLinkage:
-          if (SM.isInMainFile(Body->getBeginLoc())) {
-            std::string LookupName =
-                CrossTranslationUnitContext::getLookupName(FD);
-            Index[LookupName] = CurrentFileName;
-          }
-          break;
-        default:
-          break;
-        }
-      }
-    }
-  }
-
-  if (const auto *DC = dyn_cast(D))
-    for (const Decl *D : DC->decls())
-      handleDecl(D);
-}
-
-class MapFunctionNamesAction : public ASTFrontendAction {
-protected:
-  std::unique_ptr CreateASTConsumer(CompilerInstance &CI,
-                                                 llvm::StringRef) {
-    return llvm::make_unique(CI.getASTContext());
-  }
-};
-
-static cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage);
-
-int main(int argc, const char **argv) {
-  // Print a stack trace if we signal out.
-  sys::PrintStackTraceOnErrorSignal(argv[0], false);
-  PrettyStackTraceProgram X(argc, argv);
-
-  const char *Overview = "\nThis tool collects the USR name and location "
-                         "of all functions definitions in the source files "
-                         "(excluding headers).\n";
-  CommonOptionsParser OptionsParser(argc, argv, ClangFnMapGenCategory,
-                                    cl::ZeroOrMore, Overview);
-
-  ClangTool Tool(OptionsParser.getCompilations(),
-                 OptionsParser.getSourcePathList());
-
-  return Tool.run(newFrontendActionFactory().get());
-}
diff --git a/tools/scan-build-py/README.md b/tools/scan-build-py/README.md
index 720bde1cf3..01e3454bed 100644
--- a/tools/scan-build-py/README.md
+++ b/tools/scan-build-py/README.md
@@ -53,7 +53,7 @@ with CTU analysis enabled, execute:
     
     $ analyze-build --ctu
 
-For CTU analysis an additional (function-definition) collection-phase is required. 
+For CTU analysis an additional (external definition) collection-phase is required. 
 For debugging purposes, it is possible to separately execute the collection 
 and the analysis phase. By doing this, the intermediate files used for 
 the analysis are kept on the disk in `./ctu-dir`.
diff --git a/tools/scan-build-py/libscanbuild/__init__.py b/tools/scan-build-py/libscanbuild/__init__.py
index e7b7487916..903207c6be 100644
--- a/tools/scan-build-py/libscanbuild/__init__.py
+++ b/tools/scan-build-py/libscanbuild/__init__.py
@@ -20,7 +20,7 @@ ENVIRONMENT_KEY = 'INTERCEPT_BUILD'
 Execution = collections.namedtuple('Execution', ['pid', 'cwd', 'cmd'])
 
 CtuConfig = collections.namedtuple('CtuConfig', ['collect', 'analyze', 'dir',
-                                                 'func_map_cmd'])
+                                                 'extdef_map_cmd'])
 
 
 def duplicate_check(method):
diff --git a/tools/scan-build-py/libscanbuild/analyze.py b/tools/scan-build-py/libscanbuild/analyze.py
index ec2ffbb275..ab8ea62f46 100644
--- a/tools/scan-build-py/libscanbuild/analyze.py
+++ b/tools/scan-build-py/libscanbuild/analyze.py
@@ -42,8 +42,8 @@ __all__ = ['scan_build', 'analyze_build', 'analyze_compiler_wrapper']
 COMPILER_WRAPPER_CC = 'analyze-cc'
 COMPILER_WRAPPER_CXX = 'analyze-c++'
 
-CTU_FUNCTION_MAP_FILENAME = 'externalFnMap.txt'
-CTU_TEMP_FNMAP_FOLDER = 'tmpExternalFnMaps'
+CTU_EXTDEF_MAP_FILENAME = 'externalDefMap.txt'
+CTU_TEMP_DEFMAP_FOLDER = 'tmpExternalDefMaps'
 
 
 @command_entry_point
@@ -117,9 +117,9 @@ def get_ctu_config_from_args(args):
         CtuConfig(collect=args.ctu_phases.collect,
                   analyze=args.ctu_phases.analyze,
                   dir=args.ctu_dir,
-                  func_map_cmd=args.func_map_cmd)
+                  extdef_map_cmd=args.extdef_map_cmd)
         if hasattr(args, 'ctu_phases') and hasattr(args.ctu_phases, 'dir')
-        else CtuConfig(collect=False, analyze=False, dir='', func_map_cmd=''))
+        else CtuConfig(collect=False, analyze=False, dir='', extdef_map_cmd=''))
 
 
 def get_ctu_config_from_json(ctu_conf_json):
@@ -130,23 +130,24 @@ def get_ctu_config_from_json(ctu_conf_json):
     return CtuConfig(collect=ctu_config[0],
                      analyze=ctu_config[1],
                      dir=ctu_config[2],
-                     func_map_cmd=ctu_config[3])
+                     extdef_map_cmd=ctu_config[3])
 
 
-def create_global_ctu_function_map(func_map_lines):
-    """ Takes iterator of individual function maps and creates a global map
-    keeping only unique names. We leave conflicting names out of CTU.
+def create_global_ctu_extdef_map(extdef_map_lines):
+    """ Takes iterator of individual external definition maps and creates a
+    global map keeping only unique names. We leave conflicting names out of
+    CTU.
 
-    :param func_map_lines: Contains the id of a function (mangled name) and
+    :param extdef_map_lines: Contains the id of a definition (mangled name) and
     the originating source (the corresponding AST file) name.
-    :type func_map_lines: Iterator of str.
+    :type extdef_map_lines: Iterator of str.
     :returns: Mangled name - AST file pairs.
     :rtype: List of (str, str) tuples.
     """
 
     mangled_to_asts = defaultdict(set)
 
-    for line in func_map_lines:
+    for line in extdef_map_lines:
         mangled_name, ast_file = line.strip().split(' ', 1)
         mangled_to_asts[mangled_name].add(ast_file)
 
@@ -159,20 +160,20 @@ def create_global_ctu_function_map(func_map_lines):
     return mangled_ast_pairs
 
 
-def merge_ctu_func_maps(ctudir):
-    """ Merge individual function maps into a global one.
+def merge_ctu_extdef_maps(ctudir):
+    """ Merge individual external definition maps into a global one.
 
     As the collect phase runs parallel on multiple threads, all compilation
-    units are separately mapped into a temporary file in CTU_TEMP_FNMAP_FOLDER.
-    These function maps contain the mangled names of functions and the source
-    (AST generated from the source) which had them.
+    units are separately mapped into a temporary file in CTU_TEMP_DEFMAP_FOLDER.
+    These definition maps contain the mangled names and the source
+    (AST generated from the source) which had their definition.
     These files should be merged at the end into a global map file:
-    CTU_FUNCTION_MAP_FILENAME."""
+    CTU_EXTDEF_MAP_FILENAME."""
 
-    def generate_func_map_lines(fnmap_dir):
+    def generate_extdef_map_lines(extdefmap_dir):
         """ Iterate over all lines of input files in a determined order. """
 
-        files = glob.glob(os.path.join(fnmap_dir, '*'))
+        files = glob.glob(os.path.join(extdefmap_dir, '*'))
         files.sort()
         for filename in files:
             with open(filename, 'r') as in_file:
@@ -180,11 +181,11 @@ def merge_ctu_func_maps(ctudir):
                     yield line
 
     def write_global_map(arch, mangled_ast_pairs):
-        """ Write (mangled function name, ast file) pairs into final file. """
+        """ Write (mangled name, ast file) pairs into final file. """
 
-        extern_fns_map_file = os.path.join(ctudir, arch,
-                                           CTU_FUNCTION_MAP_FILENAME)
-        with open(extern_fns_map_file, 'w') as out_file:
+        extern_defs_map_file = os.path.join(ctudir, arch,
+                                           CTU_EXTDEF_MAP_FILENAME)
+        with open(extern_defs_map_file, 'w') as out_file:
             for mangled_name, ast_file in mangled_ast_pairs:
                 out_file.write('%s %s\n' % (mangled_name, ast_file))
 
@@ -192,15 +193,15 @@ def merge_ctu_func_maps(ctudir):
     for triple_path in triple_arches:
         if os.path.isdir(triple_path):
             triple_arch = os.path.basename(triple_path)
-            fnmap_dir = os.path.join(ctudir, triple_arch,
-                                     CTU_TEMP_FNMAP_FOLDER)
+            extdefmap_dir = os.path.join(ctudir, triple_arch,
+                                     CTU_TEMP_DEFMAP_FOLDER)
 
-            func_map_lines = generate_func_map_lines(fnmap_dir)
-            mangled_ast_pairs = create_global_ctu_function_map(func_map_lines)
+            extdef_map_lines = generate_extdef_map_lines(extdefmap_dir)
+            mangled_ast_pairs = create_global_ctu_extdef_map(extdef_map_lines)
             write_global_map(triple_arch, mangled_ast_pairs)
 
             # Remove all temporary files
-            shutil.rmtree(fnmap_dir, ignore_errors=True)
+            shutil.rmtree(extdefmap_dir, ignore_errors=True)
 
 
 def run_analyzer_parallel(args):
@@ -251,21 +252,21 @@ def govern_analyzer_runs(args):
     # left so multiple analyze runs can use the same data gathered by a single
     # collection run.
     if ctu_config.collect and ctu_config.analyze:
-        # CTU strings are coming from args.ctu_dir and func_map_cmd,
+        # CTU strings are coming from args.ctu_dir and extdef_map_cmd,
         # so we can leave it empty
         args.ctu_phases = CtuConfig(collect=True, analyze=False,
-                                    dir='', func_map_cmd='')
+                                    dir='', extdef_map_cmd='')
         run_analyzer_parallel(args)
-        merge_ctu_func_maps(ctu_config.dir)
+        merge_ctu_extdef_maps(ctu_config.dir)
         args.ctu_phases = CtuConfig(collect=False, analyze=True,
-                                    dir='', func_map_cmd='')
+                                    dir='', extdef_map_cmd='')
         run_analyzer_parallel(args)
         shutil.rmtree(ctu_config.dir, ignore_errors=True)
     else:
         # Single runs (collect or analyze) are launched from here.
         run_analyzer_parallel(args)
         if ctu_config.collect:
-            merge_ctu_func_maps(ctu_config.dir)
+            merge_ctu_extdef_maps(ctu_config.dir)
 
 
 def setup_environment(args):
@@ -544,20 +545,20 @@ def run_analyzer(opts, continuation=report_failure):
         return result
 
 
-def func_map_list_src_to_ast(func_src_list):
-    """ Turns textual function map list with source files into a
-    function map list with ast files. """
+def extdef_map_list_src_to_ast(extdef_src_list):
+    """ Turns textual external definition map list with source files into an
+    external definition map list with ast files. """
 
-    func_ast_list = []
-    for fn_src_txt in func_src_list:
-        mangled_name, path = fn_src_txt.split(" ", 1)
+    extdef_ast_list = []
+    for extdef_src_txt in extdef_src_list:
+        mangled_name, path = extdef_src_txt.split(" ", 1)
         # Normalize path on windows as well
         path = os.path.splitdrive(path)[1]
         # Make relative path out of absolute
         path = path[1:] if path[0] == os.sep else path
         ast_path = os.path.join("ast", path + ".ast")
-        func_ast_list.append(mangled_name + " " + ast_path)
-    return func_ast_list
+        extdef_ast_list.append(mangled_name + " " + ast_path)
+    return extdef_ast_list
 
 
 @require(['clang', 'directory', 'flags', 'direct_args', 'file', 'ctu'])
@@ -588,37 +589,38 @@ def ctu_collect_phase(opts):
         logging.debug("Generating AST using '%s'", ast_command)
         run_command(ast_command, cwd=opts['directory'])
 
-    def map_functions(triple_arch):
-        """ Generate function map file for the current source. """
+    def map_extdefs(triple_arch):
+        """ Generate external definition map file for the current source. """
 
         args = opts['direct_args'] + opts['flags']
-        funcmap_command = [opts['ctu'].func_map_cmd]
-        funcmap_command.append(opts['file'])
-        funcmap_command.append('--')
-        funcmap_command.extend(args)
-        logging.debug("Generating function map using '%s'", funcmap_command)
-        func_src_list = run_command(funcmap_command, cwd=opts['directory'])
-        func_ast_list = func_map_list_src_to_ast(func_src_list)
-        extern_fns_map_folder = os.path.join(opts['ctu'].dir, triple_arch,
-                                             CTU_TEMP_FNMAP_FOLDER)
-        if not os.path.isdir(extern_fns_map_folder):
+        extdefmap_command = [opts['ctu'].extdef_map_cmd]
+        extdefmap_command.append(opts['file'])
+        extdefmap_command.append('--')
+        extdefmap_command.extend(args)
+        logging.debug("Generating external definition map using '%s'",
+                      extdefmap_command)
+        extdef_src_list = run_command(extdefmap_command, cwd=opts['directory'])
+        extdef_ast_list = extdef_map_list_src_to_ast(extdef_src_list)
+        extern_defs_map_folder = os.path.join(opts['ctu'].dir, triple_arch,
+                                             CTU_TEMP_DEFMAP_FOLDER)
+        if not os.path.isdir(extern_defs_map_folder):
             try:
-                os.makedirs(extern_fns_map_folder)
+                os.makedirs(extern_defs_map_folder)
             except OSError:
                 # In case an other process already created it.
                 pass
-        if func_ast_list:
+        if extdef_ast_list:
             with tempfile.NamedTemporaryFile(mode='w',
-                                             dir=extern_fns_map_folder,
+                                             dir=extern_defs_map_folder,
                                              delete=False) as out_file:
-                out_file.write("\n".join(func_ast_list) + "\n")
+                out_file.write("\n".join(extdef_ast_list) + "\n")
 
     cwd = opts['directory']
     cmd = [opts['clang'], '--analyze'] + opts['direct_args'] + opts['flags'] \
         + [opts['file']]
     triple_arch = get_triple_arch(cmd, cwd)
     generate_ast(triple_arch)
-    map_functions(triple_arch)
+    map_extdefs(triple_arch)
 
 
 @require(['ctu'])
diff --git a/tools/scan-build-py/libscanbuild/arguments.py b/tools/scan-build-py/libscanbuild/arguments.py
index eb8ea0d9ff..58c56d2b6d 100644
--- a/tools/scan-build-py/libscanbuild/arguments.py
+++ b/tools/scan-build-py/libscanbuild/arguments.py
@@ -135,10 +135,10 @@ def validate_args_for_analyze(parser, args, from_build_command):
         if args.ctu_phases.analyze and not args.ctu_phases.collect \
                 and not os.path.exists(args.ctu_dir):
             parser.error(message='missing CTU directory')
-        # Check CTU capability via checking clang-func-mapping
-        if not is_ctu_capable(args.func_map_cmd):
+        # Check CTU capability via checking clang-extdef-mapping
+        if not is_ctu_capable(args.extdef_map_cmd):
             parser.error(message="""This version of clang does not support CTU
-            functionality or clang-func-mapping command not found.""")
+            functionality or clang-extdef-mapping command not found.""")
 
 
 def create_intercept_parser():
@@ -366,7 +366,7 @@ def create_analyze_parser(from_build_command):
             '--ctu',
             action='store_const',
             const=CtuConfig(collect=True, analyze=True,
-                            dir='', func_map_cmd=''),
+                            dir='', extdef_map_cmd=''),
             dest='ctu_phases',
             help="""Perform cross translation unit (ctu) analysis (both collect
             and analyze phases) using default  for temporary output.
@@ -382,7 +382,7 @@ def create_analyze_parser(from_build_command):
             '--ctu-collect-only',
             action='store_const',
             const=CtuConfig(collect=True, analyze=False,
-                            dir='', func_map_cmd=''),
+                            dir='', extdef_map_cmd=''),
             dest='ctu_phases',
             help="""Perform only the collect phase of ctu.
             Keep  for further use.""")
@@ -390,20 +390,20 @@ def create_analyze_parser(from_build_command):
             '--ctu-analyze-only',
             action='store_const',
             const=CtuConfig(collect=False, analyze=True,
-                            dir='', func_map_cmd=''),
+                            dir='', extdef_map_cmd=''),
             dest='ctu_phases',
             help="""Perform only the analyze phase of ctu.  should be
             present and will not be removed after analysis.""")
         ctu.add_argument(
-            '--use-func-map-cmd',
+            '--use-extdef-map-cmd',
             metavar='',
-            dest='func_map_cmd',
-            default='clang-func-mapping',
-            help="""'%(prog)s' uses the 'clang-func-mapping' executable
-            relative to itself for generating function maps for static
-            analysis. One can override this behavior with this option by using
-            the 'clang-func-mapping' packaged with Xcode (on OS X) or from the
-            PATH.""")
+            dest='extdef_map_cmd',
+            default='clang-extdef-mapping',
+            help="""'%(prog)s' uses the 'clang-extdef-mapping' executable
+            relative to itself for generating external definition maps for
+            static analysis. One can override this behavior with this option
+            by using the 'clang-extdef-mapping' packaged with Xcode (on OS X)
+            or from the PATH.""")
     return parser
 
 
diff --git a/tools/scan-build-py/libscanbuild/clang.py b/tools/scan-build-py/libscanbuild/clang.py
index ab422066ca..0cbfdb648f 100644
--- a/tools/scan-build-py/libscanbuild/clang.py
+++ b/tools/scan-build-py/libscanbuild/clang.py
@@ -156,12 +156,12 @@ def get_checkers(clang, plugins):
     return checkers
 
 
-def is_ctu_capable(func_map_cmd):
-    """ Detects if the current (or given) clang and function mapping
+def is_ctu_capable(extdef_map_cmd):
+    """ Detects if the current (or given) clang and external definition mapping
     executables are CTU compatible. """
 
     try:
-        run_command([func_map_cmd, '-version'])
+        run_command([extdef_map_cmd, '-version'])
     except (OSError, subprocess.CalledProcessError):
         return False
     return True
diff --git a/tools/scan-build-py/tests/unit/test_analyze.py b/tools/scan-build-py/tests/unit/test_analyze.py
index 9964a296b8..768a3b6910 100644
--- a/tools/scan-build-py/tests/unit/test_analyze.py
+++ b/tools/scan-build-py/tests/unit/test_analyze.py
@@ -349,14 +349,14 @@ class PrefixWithTest(unittest.TestCase):
 class MergeCtuMapTest(unittest.TestCase):
 
     def test_no_map_gives_empty(self):
-        pairs = sut.create_global_ctu_function_map([])
+        pairs = sut.create_global_ctu_extdef_map([])
         self.assertFalse(pairs)
 
     def test_multiple_maps_merged(self):
         concat_map = ['c:@F@fun1#I# ast/fun1.c.ast',
                       'c:@F@fun2#I# ast/fun2.c.ast',
                       'c:@F@fun3#I# ast/fun3.c.ast']
-        pairs = sut.create_global_ctu_function_map(concat_map)
+        pairs = sut.create_global_ctu_extdef_map(concat_map)
         self.assertTrue(('c:@F@fun1#I#', 'ast/fun1.c.ast') in pairs)
         self.assertTrue(('c:@F@fun2#I#', 'ast/fun2.c.ast') in pairs)
         self.assertTrue(('c:@F@fun3#I#', 'ast/fun3.c.ast') in pairs)
@@ -366,7 +366,7 @@ class MergeCtuMapTest(unittest.TestCase):
         concat_map = ['c:@F@fun1#I# ast/fun1.c.ast',
                       'c:@F@fun2#I# ast/fun2.c.ast',
                       'c:@F@fun1#I# ast/fun7.c.ast']
-        pairs = sut.create_global_ctu_function_map(concat_map)
+        pairs = sut.create_global_ctu_extdef_map(concat_map)
         self.assertFalse(('c:@F@fun1#I#', 'ast/fun1.c.ast') in pairs)
         self.assertFalse(('c:@F@fun1#I#', 'ast/fun7.c.ast') in pairs)
         self.assertTrue(('c:@F@fun2#I#', 'ast/fun2.c.ast') in pairs)
@@ -376,28 +376,28 @@ class MergeCtuMapTest(unittest.TestCase):
         concat_map = ['c:@F@fun1#I# ast/fun1.c.ast',
                       'c:@F@fun2#I# ast/fun2.c.ast',
                       'c:@F@fun1#I# ast/fun1.c.ast']
-        pairs = sut.create_global_ctu_function_map(concat_map)
+        pairs = sut.create_global_ctu_extdef_map(concat_map)
         self.assertTrue(('c:@F@fun1#I#', 'ast/fun1.c.ast') in pairs)
         self.assertTrue(('c:@F@fun2#I#', 'ast/fun2.c.ast') in pairs)
         self.assertEqual(2, len(pairs))
 
     def test_space_handled_in_source(self):
         concat_map = ['c:@F@fun1#I# ast/f un.c.ast']
-        pairs = sut.create_global_ctu_function_map(concat_map)
+        pairs = sut.create_global_ctu_extdef_map(concat_map)
         self.assertTrue(('c:@F@fun1#I#', 'ast/f un.c.ast') in pairs)
         self.assertEqual(1, len(pairs))
 
 
-class FuncMapSrcToAstTest(unittest.TestCase):
+class ExtdefMapSrcToAstTest(unittest.TestCase):
 
     def test_empty_gives_empty(self):
-        fun_ast_lst = sut.func_map_list_src_to_ast([])
+        fun_ast_lst = sut.extdef_map_list_src_to_ast([])
         self.assertFalse(fun_ast_lst)
 
     def test_sources_to_asts(self):
         fun_src_lst = ['c:@F@f1#I# ' + os.path.join(os.sep + 'path', 'f1.c'),
                        'c:@F@f2#I# ' + os.path.join(os.sep + 'path', 'f2.c')]
-        fun_ast_lst = sut.func_map_list_src_to_ast(fun_src_lst)
+        fun_ast_lst = sut.extdef_map_list_src_to_ast(fun_src_lst)
         self.assertTrue('c:@F@f1#I# ' +
                         os.path.join('ast', 'path', 'f1.c.ast')
                         in fun_ast_lst)
@@ -408,7 +408,7 @@ class FuncMapSrcToAstTest(unittest.TestCase):
 
     def test_spaces_handled(self):
         fun_src_lst = ['c:@F@f1#I# ' + os.path.join(os.sep + 'path', 'f 1.c')]
-        fun_ast_lst = sut.func_map_list_src_to_ast(fun_src_lst)
+        fun_ast_lst = sut.extdef_map_list_src_to_ast(fun_src_lst)
         self.assertTrue('c:@F@f1#I# ' +
                         os.path.join('ast', 'path', 'f 1.c.ast')
                         in fun_ast_lst)
diff --git a/tools/scan-build-py/tests/unit/test_clang.py b/tools/scan-build-py/tests/unit/test_clang.py
index 07ac4d9fb8..7d625c6c5b 100644
--- a/tools/scan-build-py/tests/unit/test_clang.py
+++ b/tools/scan-build-py/tests/unit/test_clang.py
@@ -96,7 +96,7 @@ class ClangGetCheckersTest(unittest.TestCase):
 
 class ClangIsCtuCapableTest(unittest.TestCase):
     def test_ctu_not_found(self):
-        is_ctu = sut.is_ctu_capable('not-found-clang-func-mapping')
+        is_ctu = sut.is_ctu_capable('not-found-clang-extdef-mapping')
         self.assertFalse(is_ctu)
 
 
-- 
cgit v1.2.3


From 1581cdda759fb5b516ff2de1eb2aabf38fe7a7a4 Mon Sep 17 00:00:00 2001
From: Erik Pilkington 
Date: Thu, 10 Jan 2019 18:03:07 +0000
Subject: Split -Wdelete-non-virtual-dtor into two groups

This group controls two diagnostics: deleting an abstract class with
a non-virtual dtor, which is a guaranteed crash, and deleting a
non-abstract polymorphic class with a non-virtual dtor, which is just
suspicious.

rdar://40380564

Differential revision: https://reviews.llvm.org/D56405

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350856 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/Basic/DiagnosticGroups.td    |  6 +++++-
 include/clang/Basic/DiagnosticSemaKinds.td |  4 ++--
 test/SemaCXX/delete-non-virtual-dtor.cpp   | 30 ++++++++++++++++++++++++++++++
 3 files changed, 37 insertions(+), 3 deletions(-)
 create mode 100644 test/SemaCXX/delete-non-virtual-dtor.cpp

diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td
index 6ba6c19a28..ddf206da06 100644
--- a/include/clang/Basic/DiagnosticGroups.td
+++ b/include/clang/Basic/DiagnosticGroups.td
@@ -104,7 +104,11 @@ def UndefinedFuncTemplate : DiagGroup<"undefined-func-template">;
 def MissingNoEscape : DiagGroup<"missing-noescape">;
 
 def DeleteIncomplete : DiagGroup<"delete-incomplete">;
-def DeleteNonVirtualDtor : DiagGroup<"delete-non-virtual-dtor">;
+def DeleteNonAbstractNonVirtualDtor : DiagGroup<"delete-non-abstract-non-virtual-dtor">;
+def DeleteAbstractNonVirtualDtor : DiagGroup<"delete-abstract-non-virtual-dtor">;
+def DeleteNonVirtualDtor : DiagGroup<"delete-non-virtual-dtor",
+                                     [DeleteNonAbstractNonVirtualDtor,
+                                      DeleteAbstractNonVirtualDtor]>;
 def AbstractFinalClass : DiagGroup<"abstract-final-class">;
 
 def CXX11CompatDeprecatedWritableStr :
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index c54fbc8b4c..2f77773ac8 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -6455,12 +6455,12 @@ def warn_non_virtual_dtor : Warning<
 def warn_delete_non_virtual_dtor : Warning<
   "%select{delete|destructor}0 called on non-final %1 that has "
   "virtual functions but non-virtual destructor">,
-  InGroup, DefaultIgnore, ShowInSystemHeader;
+  InGroup, DefaultIgnore, ShowInSystemHeader;
 def note_delete_non_virtual : Note<
   "qualify call to silence this warning">;
 def warn_delete_abstract_non_virtual_dtor : Warning<
   "%select{delete|destructor}0 called on %1 that is abstract but has "
-  "non-virtual destructor">, InGroup, ShowInSystemHeader;
+  "non-virtual destructor">, InGroup, ShowInSystemHeader;
 def warn_overloaded_virtual : Warning<
   "%q0 hides overloaded virtual %select{function|functions}1">,
   InGroup, DefaultIgnore;
diff --git a/test/SemaCXX/delete-non-virtual-dtor.cpp b/test/SemaCXX/delete-non-virtual-dtor.cpp
new file mode 100644
index 0000000000..b64eca3527
--- /dev/null
+++ b/test/SemaCXX/delete-non-virtual-dtor.cpp
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 %s -verify -DDIAG1
+// RUN: %clang_cc1 %s -verify -DDIAG1 -DDIAG2 -Wdelete-non-virtual-dtor
+// RUN: %clang_cc1 %s -verify -DDIAG1         -Wmost -Wno-delete-non-abstract-non-virtual-dtor
+// RUN: %clang_cc1 %s -verify         -DDIAG2 -Wmost -Wno-delete-abstract-non-virtual-dtor
+// RUN: %clang_cc1 %s -verify                 -Wmost -Wno-delete-non-virtual-dtor
+
+#ifndef DIAG1
+#ifndef DIAG2
+// expected-no-diagnostics
+#endif
+#endif
+
+struct S1 {
+  ~S1() {}
+  virtual void abs() = 0;
+};
+
+void f1(S1 *s1) { delete s1; }
+#ifdef DIAG1
+// expected-warning@-2 {{delete called on 'S1' that is abstract but has non-virtual destructor}}
+#endif
+
+struct S2 {
+  ~S2() {}
+  virtual void real() {}
+};
+void f2(S2 *s2) { delete s2; }
+#ifdef DIAG2
+// expected-warning@-2 {{delete called on non-final 'S2' that has virtual functions but non-virtual destructor}}
+#endif
-- 
cgit v1.2.3


From 6c6bd3ce01117d7c975f2d847e71764f7cf96f75 Mon Sep 17 00:00:00 2001
From: George Karpenkov 
Date: Thu, 10 Jan 2019 18:13:46 +0000
Subject: [analyzer] [NFC] Move ObjKind into a separate top-level enum in
 RetainSummaryManager.

Allows using it in future outside of RetEffect.

Differential Revision: https://reviews.llvm.org/D56039

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350857 91177308-0d34-0410-b5e6-96231b3b80d8
---
 .../StaticAnalyzer/Core/RetainSummaryManager.h     | 43 +++++++++++-----------
 lib/ARCMigrate/ObjCMT.cpp                          | 14 +++----
 .../RetainCountChecker/RetainCountChecker.cpp      | 20 +++++-----
 .../RetainCountChecker/RetainCountChecker.h        | 12 +++---
 .../RetainCountChecker/RetainCountDiagnostics.cpp  |  8 ++--
 lib/StaticAnalyzer/Core/RetainSummaryManager.cpp   | 42 ++++++++++-----------
 6 files changed, 70 insertions(+), 69 deletions(-)

diff --git a/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h b/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
index 9540f01c70..98aad57517 100644
--- a/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
+++ b/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
@@ -36,6 +36,22 @@ using namespace ento;
 namespace clang {
 namespace ento {
 
+/// Determines the object kind of a tracked object.
+enum class ObjKind {
+  /// Indicates that the tracked object is a CF object.  This is
+  /// important between GC and non-GC code.
+  CF,
+  /// Indicates that the tracked object is an Objective-C object.
+  ObjC,
+  /// Indicates that the tracked object could be a CF or Objective-C object.
+  AnyObj,
+  /// Indicates that the tracked object is a generalized object.
+  Generalized,
+
+  /// A descendant of OSObject.
+  OS
+};
+
 /// An ArgEffect summarizes the retain count behavior on an argument or receiver
 /// to a function or method.
 enum ArgEffect {
@@ -144,27 +160,12 @@ public:
     NoRetHard
   };
 
-  /// Determines the object kind of a tracked object.
-  enum ObjKind {
-    /// Indicates that the tracked object is a CF object.  This is
-    /// important between GC and non-GC code.
-    CF,
-    /// Indicates that the tracked object is an Objective-C object.
-    ObjC,
-    /// Indicates that the tracked object could be a CF or Objective-C object.
-    AnyObj,
-    /// Indicates that the tracked object is a generalized object.
-    Generalized,
-
-    /// A descendant of OSObject.
-    OS
-  };
 
 private:
   Kind K;
   ObjKind O;
 
-  RetEffect(Kind k, ObjKind o = AnyObj) : K(k), O(o) {}
+  RetEffect(Kind k, ObjKind o = ObjKind::AnyObj) : K(k), O(o) {}
 
 public:
   Kind getKind() const { return K; }
@@ -184,7 +185,7 @@ public:
   }
 
   static RetEffect MakeOwnedWhenTrackedReceiver() {
-    return RetEffect(OwnedWhenTrackedReceiver, ObjC);
+    return RetEffect(OwnedWhenTrackedReceiver, ObjKind::ObjC);
   }
 
   static RetEffect MakeOwned(ObjKind o) {
@@ -194,7 +195,7 @@ public:
     return RetEffect(NotOwnedSymbol, o);
   }
   static RetEffect MakeGCNotOwned() {
-    return RetEffect(GCNotOwnedSymbol, ObjC);
+    return RetEffect(GCNotOwnedSymbol, ObjKind::ObjC);
   }
   static RetEffect MakeNoRet() {
     return RetEffect(NoRet);
@@ -659,9 +660,9 @@ public:
      TrackObjCAndCFObjects(trackObjCAndCFObjects),
      TrackOSObjects(trackOSObjects),
      AF(BPAlloc),
-     ObjCAllocRetE(usesARC ? RetEffect::MakeNotOwned(RetEffect::ObjC)
-                               : RetEffect::MakeOwned(RetEffect::ObjC)),
-     ObjCInitRetE(usesARC ? RetEffect::MakeNotOwned(RetEffect::ObjC)
+     ObjCAllocRetE(usesARC ? RetEffect::MakeNotOwned(ObjKind::ObjC)
+                               : RetEffect::MakeOwned(ObjKind::ObjC)),
+     ObjCInitRetE(usesARC ? RetEffect::MakeNotOwned(ObjKind::ObjC)
                                : RetEffect::MakeOwnedWhenTrackedReceiver()) {
     InitializeClassMethodSummaries();
     InitializeMethodSummaries();
diff --git a/lib/ARCMigrate/ObjCMT.cpp b/lib/ARCMigrate/ObjCMT.cpp
index d202411429..b349434907 100644
--- a/lib/ARCMigrate/ObjCMT.cpp
+++ b/lib/ARCMigrate/ObjCMT.cpp
@@ -1460,14 +1460,14 @@ void ObjCMigrateASTConsumer::AddCFAnnotations(ASTContext &Ctx,
   if (!ResultAnnotated) {
     RetEffect Ret = CE.getReturnValue();
     const char *AnnotationString = nullptr;
-    if (Ret.getObjKind() == RetEffect::CF) {
+    if (Ret.getObjKind() == ObjKind::CF) {
       if (Ret.isOwned() && NSAPIObj->isMacroDefined("CF_RETURNS_RETAINED"))
         AnnotationString = " CF_RETURNS_RETAINED";
       else if (Ret.notOwned() &&
                NSAPIObj->isMacroDefined("CF_RETURNS_NOT_RETAINED"))
         AnnotationString = " CF_RETURNS_NOT_RETAINED";
     }
-    else if (Ret.getObjKind() == RetEffect::ObjC) {
+    else if (Ret.getObjKind() == ObjKind::ObjC) {
       if (Ret.isOwned() && NSAPIObj->isMacroDefined("NS_RETURNS_RETAINED"))
         AnnotationString = " NS_RETURNS_RETAINED";
     }
@@ -1520,7 +1520,7 @@ ObjCMigrateASTConsumer::CF_BRIDGING_KIND
   bool ReturnCFAudited = false;
   if (!FuncIsReturnAnnotated) {
     RetEffect Ret = CE.getReturnValue();
-    if (Ret.getObjKind() == RetEffect::CF &&
+    if (Ret.getObjKind() == ObjKind::CF &&
         (Ret.isOwned() || Ret.notOwned()))
       ReturnCFAudited = true;
     else if (!AuditedType(FuncDecl->getReturnType()))
@@ -1574,14 +1574,14 @@ void ObjCMigrateASTConsumer::AddCFAnnotations(ASTContext &Ctx,
   if (!ResultAnnotated) {
     RetEffect Ret = CE.getReturnValue();
     const char *AnnotationString = nullptr;
-    if (Ret.getObjKind() == RetEffect::CF) {
+    if (Ret.getObjKind() == ObjKind::CF) {
       if (Ret.isOwned() && NSAPIObj->isMacroDefined("CF_RETURNS_RETAINED"))
         AnnotationString = " CF_RETURNS_RETAINED";
       else if (Ret.notOwned() &&
                NSAPIObj->isMacroDefined("CF_RETURNS_NOT_RETAINED"))
         AnnotationString = " CF_RETURNS_NOT_RETAINED";
     }
-    else if (Ret.getObjKind() == RetEffect::ObjC) {
+    else if (Ret.getObjKind() == ObjKind::ObjC) {
       ObjCMethodFamily OMF = MethodDecl->getMethodFamily();
       switch (OMF) {
         case clang::OMF_alloc:
@@ -1649,8 +1649,8 @@ void ObjCMigrateASTConsumer::migrateAddMethodAnnotation(
 
   if (!MethodIsReturnAnnotated) {
     RetEffect Ret = CE.getReturnValue();
-    if ((Ret.getObjKind() == RetEffect::CF ||
-         Ret.getObjKind() == RetEffect::ObjC) &&
+    if ((Ret.getObjKind() == ObjKind::CF ||
+         Ret.getObjKind() == ObjKind::ObjC) &&
         (Ret.isOwned() || Ret.notOwned())) {
       AddCFAnnotations(Ctx, CE, MethodDecl, false);
       return;
diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
index 87c1ad9edb..a9b6d6839d 100644
--- a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
@@ -299,12 +299,12 @@ void RetainCountChecker::processObjCLiterals(CheckerContext &C,
   }
 
   // Return the object as autoreleased.
-  //  RetEffect RE = RetEffect::MakeNotOwned(RetEffect::ObjC);
+  //  RetEffect RE = RetEffect::MakeNotOwned(ObjKind::ObjC);
   if (SymbolRef sym =
         state->getSVal(Ex, pred->getLocationContext()).getAsSymbol()) {
     QualType ResultTy = Ex->getType();
     state = setRefBinding(state, sym,
-                          RefVal::makeNotOwned(RetEffect::ObjC, ResultTy));
+                          RefVal::makeNotOwned(ObjKind::ObjC, ResultTy));
   }
 
   C.addTransition(state);
@@ -330,7 +330,7 @@ void RetainCountChecker::checkPostStmt(const ObjCBoxedExpr *Ex,
   if (SymbolRef Sym = Pred->getSVal(Ex).getAsSymbol()) {
     QualType ResultTy = Ex->getType();
     State = setRefBinding(State, Sym,
-                          RefVal::makeNotOwned(RetEffect::ObjC, ResultTy));
+                          RefVal::makeNotOwned(ObjKind::ObjC, ResultTy));
   }
 
   C.addTransition(State);
@@ -351,11 +351,11 @@ void RetainCountChecker::checkPostStmt(const ObjCIvarRefExpr *IRE,
   // forgiving about what the surrounding code is allowed to do.
 
   QualType Ty = Sym->getType();
-  RetEffect::ObjKind Kind;
+  ObjKind Kind;
   if (Ty->isObjCRetainableType())
-    Kind = RetEffect::ObjC;
+    Kind = ObjKind::ObjC;
   else if (coreFoundation::isCFObjectRef(Ty))
-    Kind = RetEffect::CF;
+    Kind = ObjKind::CF;
   else
     return;
 
@@ -514,7 +514,7 @@ static bool isPointerToObject(QualType QT) {
 /// OSObjects are escaped when passed to void * / etc.
 static bool shouldEscapeArgumentOnCall(const CallEvent &CE, unsigned ArgIdx,
                                        const RefVal *TrackedValue) {
-  if (TrackedValue->getObjKind() != RetEffect::OS)
+  if (TrackedValue->getObjKind() != ObjKind::OS)
     return false;
   if (ArgIdx >= CE.parameters().size())
     return false;
@@ -583,7 +583,7 @@ static ProgramStateRef updateOutParameter(ProgramStateRef State,
   switch (Effect) {
   case UnretainedOutParameter:
     State = setRefBinding(State, Pointee,
-                          RefVal::makeNotOwned(RetEffect::CF, PointeeTy));
+                          RefVal::makeNotOwned(ObjKind::CF, PointeeTy));
     break;
   case RetainedOutParameter:
     // Do nothing. Retained out parameters will either point to a +1 reference
@@ -1407,11 +1407,11 @@ void RetainCountChecker::checkBeginFunction(CheckerContext &Ctx) const {
     const ArgEffect *AE = CalleeSideArgEffects.lookup(idx);
     if (AE && *AE == DecRef && isISLObjectRef(Ty)) {
       state = setRefBinding(
-          state, Sym, RefVal::makeOwned(RetEffect::ObjKind::Generalized, Ty));
+          state, Sym, RefVal::makeOwned(ObjKind::Generalized, Ty));
     } else if (isISLObjectRef(Ty)) {
       state = setRefBinding(
           state, Sym,
-          RefVal::makeNotOwned(RetEffect::ObjKind::Generalized, Ty));
+          RefVal::makeNotOwned(ObjKind::Generalized, Ty));
     }
   }
 
diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h
index 151aa49ed4..d8bbe6fcdd 100644
--- a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h
+++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h
@@ -94,7 +94,7 @@ private:
 
   /// The kind of object being tracked (CF or ObjC or OSObject), if known.
   ///
-  /// See the RetEffect::ObjKind enum for possible values.
+  /// See the ObjKind enum for possible values.
   unsigned RawObjectKind : 3;
 
   /// True if the current state and/or retain count may turn out to not be the
@@ -108,7 +108,7 @@ private:
   /// them.
   unsigned RawIvarAccessHistory : 2;
 
-  RefVal(Kind k, RetEffect::ObjKind o, unsigned cnt, unsigned acnt, QualType t,
+  RefVal(Kind k, ObjKind o, unsigned cnt, unsigned acnt, QualType t,
          IvarAccessHistory IvarAccess)
     : Cnt(cnt), ACnt(acnt), T(t), RawKind(static_cast(k)),
       RawObjectKind(static_cast(o)),
@@ -121,8 +121,8 @@ private:
 public:
   Kind getKind() const { return static_cast(RawKind); }
 
-  RetEffect::ObjKind getObjKind() const {
-    return static_cast(RawObjectKind);
+  ObjKind getObjKind() const {
+    return static_cast(RawObjectKind);
   }
 
   unsigned getCount() const { return Cnt; }
@@ -170,7 +170,7 @@ public:
   /// current function, at least partially.
   ///
   /// Most commonly, this is an owned object with a retain count of +1.
-  static RefVal makeOwned(RetEffect::ObjKind o, QualType t) {
+  static RefVal makeOwned(ObjKind o, QualType t) {
     return RefVal(Owned, o, /*Count=*/1, 0, t, IvarAccessHistory::None);
   }
 
@@ -178,7 +178,7 @@ public:
   /// the current function.
   ///
   /// Most commonly, this is an unowned object with a retain count of +0.
-  static RefVal makeNotOwned(RetEffect::ObjKind o, QualType t) {
+  static RefVal makeNotOwned(ObjKind o, QualType t) {
     return RefVal(NotOwned, o, /*Count=*/0, 0, t, IvarAccessHistory::None);
   }
 
diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
index 74dd1e149e..44cb7553c0 100644
--- a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
+++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
@@ -156,17 +156,17 @@ static void generateDiagnosticsForCallLike(ProgramStateRef CurrSt,
     }
   }
 
-  if (CurrV.getObjKind() == RetEffect::CF) {
+  if (CurrV.getObjKind() == ObjKind::CF) {
     os << " returns a Core Foundation object of type "
        << Sym->getType().getAsString() << " with a ";
-  } else if (CurrV.getObjKind() == RetEffect::OS) {
+  } else if (CurrV.getObjKind() == ObjKind::OS) {
     os << " returns an OSObject of type " << getPrettyTypeName(Sym->getType())
        << " with a ";
-  } else if (CurrV.getObjKind() == RetEffect::Generalized) {
+  } else if (CurrV.getObjKind() == ObjKind::Generalized) {
     os << " returns an object of type " << Sym->getType().getAsString()
        << " with a ";
   } else {
-    assert(CurrV.getObjKind() == RetEffect::ObjC);
+    assert(CurrV.getObjKind() == ObjKind::ObjC);
     QualType T = Sym->getType();
     if (!isa(T)) {
       os << " returns an Objective-C object with a ";
diff --git a/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp b/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
index 13955b5e50..465449b150 100644
--- a/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
+++ b/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
@@ -199,7 +199,7 @@ const RetainSummary *RetainSummaryManager::getSummaryForObjCOrCFObject(
   } else if (FName == "CMBufferQueueDequeueAndRetain" ||
              FName == "CMBufferQueueDequeueIfDataReadyAndRetain") {
     // Part of: .
-    return getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF),
+    return getPersistentSummary(RetEffect::MakeOwned(ObjKind::CF),
                                 ScratchArgs,
                                 DoNothing,
                                 DoNothing);
@@ -213,7 +213,7 @@ const RetainSummary *RetainSummaryManager::getSummaryForObjCOrCFObject(
                FName == "IOOpenFirmwarePathMatching"))) {
     // Part of . (IOKit)
     // This should be addressed using a API table.
-    return getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF),
+    return getPersistentSummary(RetEffect::MakeOwned(ObjKind::CF),
                                 ScratchArgs, DoNothing, DoNothing);
   } else if (FName == "IOServiceGetMatchingService" ||
              FName == "IOServiceGetMatchingServices") {
@@ -249,7 +249,7 @@ const RetainSummary *RetainSummaryManager::getSummaryForObjCOrCFObject(
     // passed to CGBitmapContextCreateWithData is released via
     // a callback and doing full IPA to make sure this is done correctly.
     ScratchArgs = AF.add(ScratchArgs, 8, StopTracking);
-    return getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF),
+    return getPersistentSummary(RetEffect::MakeOwned(ObjKind::CF),
                                 ScratchArgs, DoNothing, DoNothing);
   } else if (FName == "CVPixelBufferCreateWithPlanarBytes") {
     // FIXES: 
@@ -702,25 +702,25 @@ RetainSummaryManager::getOSSummaryFreeRule(const FunctionDecl *FD) {
 
 const RetainSummary *
 RetainSummaryManager::getOSSummaryCreateRule(const FunctionDecl *FD) {
-  return getPersistentSummary(RetEffect::MakeOwned(RetEffect::OS),
+  return getPersistentSummary(RetEffect::MakeOwned(ObjKind::OS),
                               AF.getEmptyMap());
 }
 
 const RetainSummary *
 RetainSummaryManager::getOSSummaryGetRule(const FunctionDecl *FD) {
-  return getPersistentSummary(RetEffect::MakeNotOwned(RetEffect::OS),
+  return getPersistentSummary(RetEffect::MakeNotOwned(ObjKind::OS),
                               AF.getEmptyMap());
 }
 
 const RetainSummary *
 RetainSummaryManager::getCFSummaryCreateRule(const FunctionDecl *FD) {
-  return getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF),
+  return getPersistentSummary(RetEffect::MakeOwned(ObjKind::CF),
                               ArgEffects(AF.getEmptyMap()));
 }
 
 const RetainSummary *
 RetainSummaryManager::getCFSummaryGetRule(const FunctionDecl *FD) {
-  return getPersistentSummary(RetEffect::MakeNotOwned(RetEffect::CF),
+  return getPersistentSummary(RetEffect::MakeNotOwned(ObjKind::CF),
                               ArgEffects(AF.getEmptyMap()),
                               DoNothing, DoNothing);
 }
@@ -741,26 +741,26 @@ RetainSummaryManager::getRetEffectFromAnnotations(QualType RetTy,
 
     if (D->hasAttr() ||
         D->hasAttr())
-      return RetEffect::MakeNotOwned(RetEffect::ObjC);
+      return RetEffect::MakeNotOwned(ObjKind::ObjC);
 
   } else if (!RetTy->isPointerType()) {
     return None;
   }
 
   if (hasEnabledAttr(D)) {
-    return RetEffect::MakeOwned(RetEffect::CF);
+    return RetEffect::MakeOwned(ObjKind::CF);
   } else if (hasEnabledAttr(D)) {
-    return RetEffect::MakeOwned(RetEffect::OS);
+    return RetEffect::MakeOwned(ObjKind::OS);
   } else if (hasRCAnnotation(D, "rc_ownership_returns_retained")) {
-    return RetEffect::MakeOwned(RetEffect::Generalized);
+    return RetEffect::MakeOwned(ObjKind::Generalized);
   }
 
   if (hasEnabledAttr(D)) {
-    return RetEffect::MakeNotOwned(RetEffect::CF);
+    return RetEffect::MakeNotOwned(ObjKind::CF);
   } else if (hasEnabledAttr(D)) {
-    return RetEffect::MakeNotOwned(RetEffect::OS);
+    return RetEffect::MakeNotOwned(ObjKind::OS);
   } else if (hasRCAnnotation(D, "rc_ownership_returns_not_retained")) {
-    return RetEffect::MakeNotOwned(RetEffect::Generalized);
+    return RetEffect::MakeNotOwned(ObjKind::Generalized);
   }
 
   if (const auto *MD = dyn_cast(D))
@@ -893,7 +893,7 @@ RetainSummaryManager::getStandardMethodSummary(const ObjCMethodDecl *MD,
       // FIXME: Does the non-threaded performSelector family really belong here?
       // The selector could be, say, @selector(copy).
       if (cocoa::isCocoaObjectRef(RetTy))
-        ResultEff = RetEffect::MakeNotOwned(RetEffect::ObjC);
+        ResultEff = RetEffect::MakeNotOwned(ObjKind::ObjC);
       else if (coreFoundation::isCFObjectRef(RetTy)) {
         // ObjCMethodDecl currently doesn't consider CF objects as valid return
         // values for alloc, new, copy, or mutableCopy, so we have to
@@ -905,14 +905,14 @@ RetainSummaryManager::getStandardMethodSummary(const ObjCMethodDecl *MD,
           case OMF_new:
           case OMF_copy:
           case OMF_mutableCopy:
-            ResultEff = RetEffect::MakeOwned(RetEffect::CF);
+            ResultEff = RetEffect::MakeOwned(ObjKind::CF);
             break;
           default:
-            ResultEff = RetEffect::MakeNotOwned(RetEffect::CF);
+            ResultEff = RetEffect::MakeNotOwned(ObjKind::CF);
             break;
           }
         } else {
-          ResultEff = RetEffect::MakeNotOwned(RetEffect::CF);
+          ResultEff = RetEffect::MakeNotOwned(ObjKind::CF);
         }
       }
       break;
@@ -927,7 +927,7 @@ RetainSummaryManager::getStandardMethodSummary(const ObjCMethodDecl *MD,
       if (cocoa::isCocoaObjectRef(RetTy))
         ResultEff = ObjCAllocRetE;
       else if (coreFoundation::isCFObjectRef(RetTy))
-        ResultEff = RetEffect::MakeOwned(RetEffect::CF);
+        ResultEff = RetEffect::MakeOwned(ObjKind::CF);
       break;
     case OMF_autorelease:
       ReceiverEff = Autorelease;
@@ -1033,7 +1033,7 @@ void RetainSummaryManager::InitializeClassMethodSummaries() {
 
   // Create the [NSAssertionHandler currentHander] summary.
   addClassMethSummary("NSAssertionHandler", "currentHandler",
-                getPersistentSummary(RetEffect::MakeNotOwned(RetEffect::ObjC),
+                getPersistentSummary(RetEffect::MakeNotOwned(ObjKind::ObjC),
                                      ScratchArgs));
 
   // Create the [NSAutoreleasePool addObject:] summary.
@@ -1063,7 +1063,7 @@ void RetainSummaryManager::InitializeMethodSummaries() {
   const RetainSummary *AllocSumm = getPersistentSummary(ObjCAllocRetE,
                                                         ScratchArgs);
   const RetainSummary *CFAllocSumm =
-    getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF), ScratchArgs);
+    getPersistentSummary(RetEffect::MakeOwned(ObjKind::CF), ScratchArgs);
 
   // Create the "retain" selector.
   RetEffect NoRet = RetEffect::MakeNoRet();
-- 
cgit v1.2.3


From 1aa49324a9eba39191d8d5b739f0088474ed7d18 Mon Sep 17 00:00:00 2001
From: George Karpenkov 
Date: Thu, 10 Jan 2019 18:13:59 +0000
Subject: [analyzer] [NFC] Track object type with ArgEffect in
 RetainCountChecker.

This would be needed in the future.

https://reviews.llvm.org/D56040

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350858 91177308-0d34-0410-b5e6-96231b3b80d8
---
 .../StaticAnalyzer/Core/RetainSummaryManager.h     |  59 +++++--
 lib/ARCMigrate/ObjCMT.cpp                          |  35 ++--
 .../RetainCountChecker/RetainCountChecker.cpp      |  27 +--
 .../RetainCountChecker/RetainCountChecker.h        |   2 +-
 .../RetainCountChecker/RetainCountDiagnostics.cpp  |   4 +-
 lib/StaticAnalyzer/Core/RetainSummaryManager.cpp   | 194 +++++++++++----------
 6 files changed, 180 insertions(+), 141 deletions(-)

diff --git a/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h b/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
index 98aad57517..5461716f9d 100644
--- a/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
+++ b/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
@@ -52,9 +52,7 @@ enum class ObjKind {
   OS
 };
 
-/// An ArgEffect summarizes the retain count behavior on an argument or receiver
-/// to a function or method.
-enum ArgEffect {
+enum ArgEffectKind {
   /// There is no effect.
   DoNothing,
 
@@ -133,6 +131,27 @@ enum ArgEffect {
   DecRefMsgAndStopTrackingHard
 };
 
+/// An ArgEffect summarizes the retain count behavior on an argument or receiver
+/// to a function or method.
+class ArgEffect {
+  ArgEffectKind K;
+  ObjKind O;
+public:
+  explicit ArgEffect(ArgEffectKind K = DoNothing, ObjKind O = ObjKind::AnyObj)
+      : K(K), O(O) {}
+
+  ArgEffectKind getKind() const { return K; }
+  ObjKind getObjKind() const { return O; }
+
+  ArgEffect withKind(ArgEffectKind NewK) {
+    return ArgEffect(NewK, O);
+  }
+
+  bool operator==(const ArgEffect &Other) const {
+    return K == Other.K && O == Other.O;
+  }
+};
+
 /// RetEffect summarizes a call's retain/release behavior with respect
 /// to its return value.
 class RetEffect {
@@ -218,7 +237,9 @@ class CallEffects {
   RetEffect Ret;
   ArgEffect Receiver;
 
-  CallEffects(const RetEffect &R) : Ret(R) {}
+  CallEffects(const RetEffect &R,
+              ArgEffect Receiver = ArgEffect(DoNothing, ObjKind::AnyObj))
+      : Ret(R), Receiver(Receiver) {}
 
 public:
   /// Returns the argument effects for a call.
@@ -263,7 +284,8 @@ namespace llvm {
 
 template <> struct FoldingSetTrait {
 static inline void Profile(const ArgEffect X, FoldingSetNodeID &ID) {
-  ID.AddInteger((unsigned) X);
+  ID.AddInteger((unsigned) X.getKind());
+  ID.AddInteger((unsigned) X.getObjKind());
 }
 };
 template <> struct FoldingSetTrait {
@@ -377,8 +399,8 @@ public:
   void setThisEffect(ArgEffect e) { This = e; }
 
   bool isNoop() const {
-    return Ret == RetEffect::MakeNoRet() && Receiver == DoNothing
-      && DefaultArgEffect == MayEscape && This == DoNothing
+    return Ret == RetEffect::MakeNoRet() && Receiver.getKind() == DoNothing
+      && DefaultArgEffect.getKind() == MayEscape && This.getKind() == DoNothing
       && Args.isEmpty();
   }
 
@@ -547,32 +569,31 @@ class RetainSummaryManager {
 
   const RetainSummary *getPersistentSummary(const RetainSummary &OldSumm);
 
-  const RetainSummary *getPersistentSummary(RetEffect RetEff,
-                                            ArgEffects ScratchArgs,
-                                            ArgEffect ReceiverEff = DoNothing,
-                                            ArgEffect DefaultEff = MayEscape,
-                                            ArgEffect ThisEff = DoNothing) {
-    RetainSummary Summ(ScratchArgs, RetEff, DefaultEff, ReceiverEff,
-                       ThisEff);
+  const RetainSummary *
+  getPersistentSummary(RetEffect RetEff, ArgEffects ScratchArgs,
+                       ArgEffect ReceiverEff = ArgEffect(DoNothing),
+                       ArgEffect DefaultEff = ArgEffect(MayEscape),
+                       ArgEffect ThisEff = ArgEffect(DoNothing)) {
+    RetainSummary Summ(ScratchArgs, RetEff, DefaultEff, ReceiverEff, ThisEff);
     return getPersistentSummary(Summ);
   }
 
   const RetainSummary *getDoNothingSummary() {
     return getPersistentSummary(RetEffect::MakeNoRet(),
                                 ArgEffects(AF.getEmptyMap()),
-                                DoNothing, DoNothing);
+                                ArgEffect(DoNothing), ArgEffect(DoNothing));
   }
 
   const RetainSummary *getDefaultSummary() {
     return getPersistentSummary(RetEffect::MakeNoRet(),
                                 ArgEffects(AF.getEmptyMap()),
-                                DoNothing, MayEscape);
+                                ArgEffect(DoNothing), ArgEffect(MayEscape));
   }
 
   const RetainSummary *getPersistentStopSummary() {
-    return getPersistentSummary(RetEffect::MakeNoRet(),
-                                ArgEffects(AF.getEmptyMap()),
-                                StopTracking, StopTracking);
+    return getPersistentSummary(
+        RetEffect::MakeNoRet(), ArgEffects(AF.getEmptyMap()),
+        ArgEffect(StopTracking), ArgEffect(StopTracking));
   }
 
   void InitializeClassMethodSummaries();
diff --git a/lib/ARCMigrate/ObjCMT.cpp b/lib/ARCMigrate/ObjCMT.cpp
index b349434907..c3f849b7fa 100644
--- a/lib/ARCMigrate/ObjCMT.cpp
+++ b/lib/ARCMigrate/ObjCMT.cpp
@@ -1484,13 +1484,13 @@ void ObjCMigrateASTConsumer::AddCFAnnotations(ASTContext &Ctx,
        pe = FuncDecl->param_end(); pi != pe; ++pi, ++i) {
     const ParmVarDecl *pd = *pi;
     ArgEffect AE = AEArgs[i];
-    if (AE == DecRef && !pd->hasAttr() &&
+    if (AE.getKind() == DecRef && !pd->hasAttr() &&
         NSAPIObj->isMacroDefined("CF_CONSUMED")) {
       edit::Commit commit(*Editor);
       commit.insertBefore(pd->getLocation(), "CF_CONSUMED ");
       Editor->commit(commit);
     }
-    else if (AE == DecRefMsg && !pd->hasAttr() &&
+    else if (AE.getKind() == DecRefMsg && !pd->hasAttr() &&
              NSAPIObj->isMacroDefined("NS_CONSUMED")) {
       edit::Commit commit(*Editor);
       commit.insertBefore(pd->getLocation(), "NS_CONSUMED ");
@@ -1536,13 +1536,13 @@ ObjCMigrateASTConsumer::CF_BRIDGING_KIND
        pe = FuncDecl->param_end(); pi != pe; ++pi, ++i) {
     const ParmVarDecl *pd = *pi;
     ArgEffect AE = AEArgs[i];
-    if (AE == DecRef /*CFConsumed annotated*/ || AE == IncRef) {
-      if (AE == DecRef && !pd->hasAttr())
+    if (AE.getKind() == DecRef /*CFConsumed annotated*/ ||
+        AE.getKind() == IncRef) {
+      if (AE.getKind() == DecRef && !pd->hasAttr())
         ArgCFAudited = true;
-      else if (AE == IncRef)
+      else if (AE.getKind() == IncRef)
         ArgCFAudited = true;
-    }
-    else {
+    } else {
       QualType AT = pd->getType();
       if (!AuditedType(AT)) {
         AddCFAnnotations(Ctx, CE, FuncDecl, FuncIsReturnAnnotated);
@@ -1610,7 +1610,7 @@ void ObjCMigrateASTConsumer::AddCFAnnotations(ASTContext &Ctx,
        pe = MethodDecl->param_end(); pi != pe; ++pi, ++i) {
     const ParmVarDecl *pd = *pi;
     ArgEffect AE = AEArgs[i];
-    if (AE == DecRef && !pd->hasAttr() &&
+    if (AE.getKind() == DecRef && !pd->hasAttr() &&
         NSAPIObj->isMacroDefined("CF_CONSUMED")) {
       edit::Commit commit(*Editor);
       commit.insertBefore(pd->getLocation(), "CF_CONSUMED ");
@@ -1626,13 +1626,14 @@ void ObjCMigrateASTConsumer::migrateAddMethodAnnotation(
     return;
 
   CallEffects CE  = CallEffects::getEffect(MethodDecl);
-  bool MethodIsReturnAnnotated = (MethodDecl->hasAttr() ||
-                                  MethodDecl->hasAttr() ||
-                                  MethodDecl->hasAttr() ||
-                                  MethodDecl->hasAttr() ||
-                                  MethodDecl->hasAttr());
-
-  if (CE.getReceiver() == DecRefMsg &&
+  bool MethodIsReturnAnnotated =
+      (MethodDecl->hasAttr() ||
+       MethodDecl->hasAttr() ||
+       MethodDecl->hasAttr() ||
+       MethodDecl->hasAttr() ||
+       MethodDecl->hasAttr());
+
+  if (CE.getReceiver().getKind() == DecRefMsg &&
       !MethodDecl->hasAttr() &&
       MethodDecl->getMethodFamily() != OMF_init &&
       MethodDecl->getMethodFamily() != OMF_release &&
@@ -1666,8 +1667,8 @@ void ObjCMigrateASTConsumer::migrateAddMethodAnnotation(
        pe = MethodDecl->param_end(); pi != pe; ++pi, ++i) {
     const ParmVarDecl *pd = *pi;
     ArgEffect AE = AEArgs[i];
-    if ((AE == DecRef && !pd->hasAttr()) || AE == IncRef ||
-        !AuditedType(pd->getType())) {
+    if ((AE.getKind() == DecRef && !pd->hasAttr()) ||
+        AE.getKind() == IncRef || !AuditedType(pd->getType())) {
       AddCFAnnotations(Ctx, CE, MethodDecl, MethodIsReturnAnnotated);
       return;
     }
diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
index a9b6d6839d..4e5fac815e 100644
--- a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
@@ -248,7 +248,7 @@ void RetainCountChecker::checkPostStmt(const CastExpr *CE,
   if (!BE)
     return;
 
-  ArgEffect AE = IncRef;
+  ArgEffectKind AE = IncRef;
 
   switch (BE->getBridgeKind()) {
     case OBC_Bridge:
@@ -534,7 +534,7 @@ void RetainCountChecker::processSummaryOfInlined(const RetainSummary &Summ,
     SVal V = CallOrMsg.getArgSVal(idx);
 
     if (SymbolRef Sym = V.getAsLocSymbol()) {
-      bool ShouldRemoveBinding = Summ.getArg(idx) == StopTrackingHard;
+      bool ShouldRemoveBinding = Summ.getArg(idx).getKind() == StopTrackingHard;
       if (const RefVal *T = getRefBinding(state, Sym))
         if (shouldEscapeArgumentOnCall(CallOrMsg, idx, T))
           ShouldRemoveBinding = true;
@@ -547,7 +547,7 @@ void RetainCountChecker::processSummaryOfInlined(const RetainSummary &Summ,
   // Evaluate the effect on the message receiver.
   if (const auto *MsgInvocation = dyn_cast(&CallOrMsg)) {
     if (SymbolRef Sym = MsgInvocation->getReceiverSVal().getAsLocSymbol()) {
-      if (Summ.getReceiverEffect() == StopTrackingHard) {
+      if (Summ.getReceiverEffect().getKind() == StopTrackingHard) {
         state = removeRefBinding(state, Sym);
       }
     }
@@ -566,7 +566,7 @@ void RetainCountChecker::processSummaryOfInlined(const RetainSummary &Summ,
 
 static ProgramStateRef updateOutParameter(ProgramStateRef State,
                                           SVal ArgVal,
-                                          ArgEffect Effect) {
+                                          ArgEffectKind Effect) {
   auto *ArgRegion = dyn_cast_or_null(ArgVal.getAsRegion());
   if (!ArgRegion)
     return State;
@@ -611,7 +611,7 @@ void RetainCountChecker::checkSummary(const RetainSummary &Summ,
   for (unsigned idx = 0, e = CallOrMsg.getNumArgs(); idx != e; ++idx) {
     SVal V = CallOrMsg.getArgSVal(idx);
 
-    ArgEffect Effect = Summ.getArg(idx);
+    ArgEffectKind Effect = Summ.getArg(idx).getKind();
     if (Effect == RetainedOutParameter || Effect == UnretainedOutParameter) {
       state = updateOutParameter(state, V, Effect);
     } else if (SymbolRef Sym = V.getAsLocSymbol()) {
@@ -637,8 +637,8 @@ void RetainCountChecker::checkSummary(const RetainSummary &Summ,
       if (SymbolRef Sym = MsgInvocation->getReceiverSVal().getAsLocSymbol()) {
         if (const RefVal *T = getRefBinding(state, Sym)) {
           ReceiverIsTracked = true;
-          state = updateSymbol(state, Sym, *T, Summ.getReceiverEffect(),
-                                 hasErr, C);
+          state = updateSymbol(state, Sym, *T,
+                               Summ.getReceiverEffect().getKind(), hasErr, C);
           if (hasErr) {
             ErrorRange = MsgInvocation->getOriginExpr()->getReceiverRange();
             ErrorSym = Sym;
@@ -648,7 +648,7 @@ void RetainCountChecker::checkSummary(const RetainSummary &Summ,
     } else if (const auto *MCall = dyn_cast(&CallOrMsg)) {
       if (SymbolRef Sym = MCall->getCXXThisVal().getAsLocSymbol()) {
         if (const RefVal *T = getRefBinding(state, Sym)) {
-          state = updateSymbol(state, Sym, *T, Summ.getThisEffect(),
+          state = updateSymbol(state, Sym, *T, Summ.getThisEffect().getKind(),
                                hasErr, C);
           if (hasErr) {
             ErrorRange = MCall->getOriginExpr()->getSourceRange();
@@ -707,10 +707,11 @@ void RetainCountChecker::checkSummary(const RetainSummary &Summ,
   }
 }
 
-ProgramStateRef
-RetainCountChecker::updateSymbol(ProgramStateRef state, SymbolRef sym,
-                                 RefVal V, ArgEffect E, RefVal::Kind &hasErr,
-                                 CheckerContext &C) const {
+ProgramStateRef RetainCountChecker::updateSymbol(ProgramStateRef state,
+                                                 SymbolRef sym, RefVal V,
+                                                 ArgEffectKind E,
+                                                 RefVal::Kind &hasErr,
+                                                 CheckerContext &C) const {
   bool IgnoreRetainMsg = (bool)C.getASTContext().getLangOpts().ObjCAutoRefCount;
   switch (E) {
   default:
@@ -1405,7 +1406,7 @@ void RetainCountChecker::checkBeginFunction(CheckerContext &Ctx) const {
 
     QualType Ty = Param->getType();
     const ArgEffect *AE = CalleeSideArgEffects.lookup(idx);
-    if (AE && *AE == DecRef && isISLObjectRef(Ty)) {
+    if (AE && AE->getKind() == DecRef && isISLObjectRef(Ty)) {
       state = setRefBinding(
           state, Sym, RefVal::makeOwned(ObjKind::Generalized, Ty));
     } else if (isISLObjectRef(Ty)) {
diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h
index d8bbe6fcdd..80d1b0573c 100644
--- a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h
+++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h
@@ -347,7 +347,7 @@ public:
   void checkEndFunction(const ReturnStmt *RS, CheckerContext &C) const;
 
   ProgramStateRef updateSymbol(ProgramStateRef state, SymbolRef sym,
-                               RefVal V, ArgEffect E, RefVal::Kind &hasErr,
+                               RefVal V, ArgEffectKind E, RefVal::Kind &hasErr,
                                CheckerContext &C) const;
 
   void processNonLeakError(ProgramStateRef St, SourceRange ErrorRange,
diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
index 44cb7553c0..5a687ef8d1 100644
--- a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
+++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
@@ -48,7 +48,9 @@ static bool shouldGenerateNote(llvm::raw_string_ostream &os,
   RefVal PrevV = *PrevT;
 
   // Specially handle -dealloc.
-  if (std::find(AEffects.begin(), AEffects.end(), Dealloc) != AEffects.end()) {
+  if (std::find_if(AEffects.begin(), AEffects.end(), [](ArgEffect &E) {
+        return E.getKind() == Dealloc;
+      }) != AEffects.end()) {
     // Determine if the object's reference count was pushed to zero.
     assert(!PrevV.hasSameState(CurrV) && "The state should have changed.");
     // We may not have transitioned to 'release' if we hit an error.
diff --git a/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp b/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
index 465449b150..9f0e60ec3e 100644
--- a/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
+++ b/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
@@ -201,8 +201,8 @@ const RetainSummary *RetainSummaryManager::getSummaryForObjCOrCFObject(
     // Part of: .
     return getPersistentSummary(RetEffect::MakeOwned(ObjKind::CF),
                                 ScratchArgs,
-                                DoNothing,
-                                DoNothing);
+                                ArgEffect(DoNothing),
+                                ArgEffect(DoNothing));
   } else if (FName == "CFPlugInInstanceCreate") {
     return getPersistentSummary(RetEffect::MakeNoRet(), ScratchArgs);
   } else if (FName == "IORegistryEntrySearchCFProperty" ||
@@ -213,25 +213,25 @@ const RetainSummary *RetainSummaryManager::getSummaryForObjCOrCFObject(
                FName == "IOOpenFirmwarePathMatching"))) {
     // Part of . (IOKit)
     // This should be addressed using a API table.
-    return getPersistentSummary(RetEffect::MakeOwned(ObjKind::CF),
-                                ScratchArgs, DoNothing, DoNothing);
+    return getPersistentSummary(RetEffect::MakeOwned(ObjKind::CF), ScratchArgs,
+                                ArgEffect(DoNothing), ArgEffect(DoNothing));
   } else if (FName == "IOServiceGetMatchingService" ||
              FName == "IOServiceGetMatchingServices") {
     // FIXES: 
     // This should be addressed using a API table.  This strcmp is also
     // a little gross, but there is no need to super optimize here.
-    ScratchArgs = AF.add(ScratchArgs, 1, DecRef);
+    ScratchArgs = AF.add(ScratchArgs, 1, ArgEffect(DecRef, ObjKind::CF));
     return getPersistentSummary(RetEffect::MakeNoRet(),
                                 ScratchArgs,
-                                DoNothing, DoNothing);
+                                ArgEffect(DoNothing), ArgEffect(DoNothing));
   } else if (FName == "IOServiceAddNotification" ||
              FName == "IOServiceAddMatchingNotification") {
     // Part of . (IOKit)
     // This should be addressed using a API table.
-    ScratchArgs = AF.add(ScratchArgs, 2, DecRef);
+    ScratchArgs = AF.add(ScratchArgs, 2, ArgEffect(DecRef, ObjKind::CF));
     return getPersistentSummary(RetEffect::MakeNoRet(),
                                 ScratchArgs,
-                                DoNothing, DoNothing);
+                                ArgEffect(DoNothing), ArgEffect(DoNothing));
   } else if (FName == "CVPixelBufferCreateWithBytes") {
     // FIXES: 
     // Eventually this can be improved by recognizing that the pixel
@@ -239,38 +239,38 @@ const RetainSummary *RetainSummaryManager::getSummaryForObjCOrCFObject(
     // a callback and doing full IPA to make sure this is done correctly.
     // FIXME: This function has an out parameter that returns an
     // allocated object.
-    ScratchArgs = AF.add(ScratchArgs, 7, StopTracking);
+    ScratchArgs = AF.add(ScratchArgs, 7, ArgEffect(StopTracking));
     return getPersistentSummary(RetEffect::MakeNoRet(),
                                 ScratchArgs,
-                                DoNothing, DoNothing);
+                                ArgEffect(DoNothing), ArgEffect(DoNothing));
   } else if (FName == "CGBitmapContextCreateWithData") {
     // FIXES: 
     // Eventually this can be improved by recognizing that 'releaseInfo'
     // passed to CGBitmapContextCreateWithData is released via
     // a callback and doing full IPA to make sure this is done correctly.
-    ScratchArgs = AF.add(ScratchArgs, 8, StopTracking);
-    return getPersistentSummary(RetEffect::MakeOwned(ObjKind::CF),
-                                ScratchArgs, DoNothing, DoNothing);
+    ScratchArgs = AF.add(ScratchArgs, 8, ArgEffect(ArgEffect(StopTracking)));
+    return getPersistentSummary(RetEffect::MakeOwned(ObjKind::CF), ScratchArgs,
+                                ArgEffect(DoNothing), ArgEffect(DoNothing));
   } else if (FName == "CVPixelBufferCreateWithPlanarBytes") {
     // FIXES: 
     // Eventually this can be improved by recognizing that the pixel
     // buffer passed to CVPixelBufferCreateWithPlanarBytes is released
     // via a callback and doing full IPA to make sure this is done
     // correctly.
-    ScratchArgs = AF.add(ScratchArgs, 12, StopTracking);
+    ScratchArgs = AF.add(ScratchArgs, 12, ArgEffect(StopTracking));
     return getPersistentSummary(RetEffect::MakeNoRet(),
                                 ScratchArgs,
-                                DoNothing, DoNothing);
+                                ArgEffect(DoNothing), ArgEffect(DoNothing));
   } else if (FName == "VTCompressionSessionEncodeFrame") {
     // The context argument passed to VTCompressionSessionEncodeFrame()
     // is passed to the callback specified when creating the session
     // (e.g. with VTCompressionSessionCreate()) which can release it.
     // To account for this possibility, conservatively stop tracking
     // the context.
-    ScratchArgs = AF.add(ScratchArgs, 5, StopTracking);
+    ScratchArgs = AF.add(ScratchArgs, 5, ArgEffect(StopTracking));
     return getPersistentSummary(RetEffect::MakeNoRet(),
                                 ScratchArgs,
-                                DoNothing, DoNothing);
+                                ArgEffect(DoNothing), ArgEffect(DoNothing));
   } else if (FName == "dispatch_set_context" ||
              FName == "xpc_connection_set_context") {
     //  - The analyzer currently doesn't have
@@ -279,20 +279,21 @@ const RetainSummary *RetainSummaryManager::getSummaryForObjCOrCFObject(
     //  - Same problem, but for XPC.
     // FIXME: this hack should possibly go away once we can handle
     // libdispatch and XPC finalizers.
-    ScratchArgs = AF.add(ScratchArgs, 1, StopTracking);
+    ScratchArgs = AF.add(ScratchArgs, 1, ArgEffect(StopTracking));
     return getPersistentSummary(RetEffect::MakeNoRet(),
                                 ScratchArgs,
-                                DoNothing, DoNothing);
+                                ArgEffect(DoNothing), ArgEffect(DoNothing));
   } else if (FName.startswith("NSLog")) {
     return getDoNothingSummary();
   } else if (FName.startswith("NS") &&
              (FName.find("Insert") != StringRef::npos)) {
     // Whitelist NSXXInsertXX, for example NSMapInsertIfAbsent, since they can
     // be deallocated by NSMapRemove. (radar://11152419)
-    ScratchArgs = AF.add(ScratchArgs, 1, StopTracking);
-    ScratchArgs = AF.add(ScratchArgs, 2, StopTracking);
+    ScratchArgs = AF.add(ScratchArgs, 1, ArgEffect(StopTracking));
+    ScratchArgs = AF.add(ScratchArgs, 2, ArgEffect(StopTracking));
     return getPersistentSummary(RetEffect::MakeNoRet(),
-                                ScratchArgs, DoNothing, DoNothing);
+                                ScratchArgs, ArgEffect(DoNothing),
+                                ArgEffect(DoNothing));
   }
 
   if (RetTy->isPointerType()) {
@@ -367,16 +368,17 @@ const RetainSummary *RetainSummaryManager::getSummaryForObjCOrCFObject(
       // "AppendValue", or "SetAttribute", then we assume that arguments may
       // "escape."  This means that something else holds on to the object,
       // allowing it be used even after its local retain count drops to 0.
-      ArgEffect E = (StrInStrNoCase(FName, "InsertValue") != StringRef::npos ||
-                     StrInStrNoCase(FName, "AddValue") != StringRef::npos ||
-                     StrInStrNoCase(FName, "SetValue") != StringRef::npos ||
-                     StrInStrNoCase(FName, "AppendValue") != StringRef::npos ||
-                     StrInStrNoCase(FName, "SetAttribute") != StringRef::npos)
-                        ? MayEscape
-                        : DoNothing;
+      ArgEffectKind E =
+          (StrInStrNoCase(FName, "InsertValue") != StringRef::npos ||
+           StrInStrNoCase(FName, "AddValue") != StringRef::npos ||
+           StrInStrNoCase(FName, "SetValue") != StringRef::npos ||
+           StrInStrNoCase(FName, "AppendValue") != StringRef::npos ||
+           StrInStrNoCase(FName, "SetAttribute") != StringRef::npos)
+              ? MayEscape
+              : DoNothing;
 
       return getPersistentSummary(RetEffect::MakeNoRet(), ScratchArgs,
-                                  DoNothing, E);
+                                  ArgEffect(DoNothing), ArgEffect(E, ObjKind::CF));
     }
   }
 
@@ -415,8 +417,9 @@ RetainSummaryManager::generateSummary(const FunctionDecl *FD,
     if (!(TrackOSObjects && isOSObjectRelated(MD)))
       return getPersistentSummary(RetEffect::MakeNoRet(),
                                   ArgEffects(AF.getEmptyMap()),
-                                  DoNothing, StopTracking,
-                                  DoNothing);
+                                  ArgEffect(DoNothing),
+                                  ArgEffect(StopTracking),
+                                  ArgEffect(DoNothing));
 
   return getDefaultSummary();
 }
@@ -449,7 +452,7 @@ RetainSummaryManager::getFunctionSummary(const FunctionDecl *FD) {
 //===----------------------------------------------------------------------===//
 
 static ArgEffect getStopTrackingHardEquivalent(ArgEffect E) {
-  switch (E) {
+  switch (E.getKind()) {
   case DoNothing:
   case Autorelease:
   case DecRefBridgedTransferred:
@@ -461,15 +464,15 @@ static ArgEffect getStopTrackingHardEquivalent(ArgEffect E) {
   case MayEscape:
   case StopTracking:
   case StopTrackingHard:
-    return StopTrackingHard;
+    return E.withKind(StopTrackingHard);
   case DecRef:
   case DecRefAndStopTrackingHard:
-    return DecRefAndStopTrackingHard;
+    return E.withKind(DecRefAndStopTrackingHard);
   case DecRefMsg:
   case DecRefMsgAndStopTrackingHard:
-    return DecRefMsgAndStopTrackingHard;
+    return E.withKind(DecRefMsgAndStopTrackingHard);
   case Dealloc:
-    return Dealloc;
+    return E.withKind(Dealloc);
   }
 
   llvm_unreachable("Unknown ArgEffect kind");
@@ -489,7 +492,7 @@ void RetainSummaryManager::updateSummaryForCall(const RetainSummary *&S,
                               E = CustomArgEffects.end();
          I != E; ++I) {
       ArgEffect Translated = getStopTrackingHardEquivalent(I->second);
-      if (Translated != DefEffect)
+      if (Translated.getKind() != DefEffect.getKind())
         ScratchArgs = AF.add(ScratchArgs, I->first, Translated);
     }
 
@@ -535,7 +538,7 @@ void RetainSummaryManager::updateSummaryForCall(const RetainSummary *&S,
       ParentMap &PM = LCtx->getAnalysisDeclContext()->getParentMap();
       if (!PM.isConsumedExpr(ME)) {
         RetainSummaryTemplate ModifiableSummaryTemplate(S, *this);
-        ModifiableSummaryTemplate->setReceiverEffect(DoNothing);
+        ModifiableSummaryTemplate->setReceiverEffect(ArgEffect(DoNothing));
         ModifiableSummaryTemplate->setRetEffect(RetEffect::MakeNoRet());
       }
     }
@@ -661,43 +664,43 @@ RetainSummaryManager::getUnarySummary(const FunctionType* FT,
 
   ArgEffect Effect;
   switch (func) {
-  case cfretain: Effect = IncRef; break;
-  case cfrelease: Effect = DecRef; break;
-  case cfautorelease: Effect = Autorelease; break;
-  case cfmakecollectable: Effect = MakeCollectable; break;
+  case cfretain: Effect = Effect.withKind(IncRef); break;
+  case cfrelease: Effect = Effect.withKind(DecRef); break;
+  case cfautorelease: Effect = Effect.withKind(Autorelease); break;
+  case cfmakecollectable: Effect = Effect.withKind(MakeCollectable); break;
   }
 
   ScratchArgs = AF.add(ScratchArgs, 0, Effect);
   return getPersistentSummary(RetEffect::MakeNoRet(),
                               ScratchArgs,
-                              DoNothing, DoNothing);
+                              ArgEffect(DoNothing), ArgEffect(DoNothing));
 }
 
 const RetainSummary *
 RetainSummaryManager::getOSSummaryRetainRule(const FunctionDecl *FD) {
   return getPersistentSummary(RetEffect::MakeNoRet(),
                               AF.getEmptyMap(),
-                              /*ReceiverEff=*/DoNothing,
-                              /*DefaultEff=*/DoNothing,
-                              /*ThisEff=*/IncRef);
+                              /*ReceiverEff=*/ArgEffect(DoNothing),
+                              /*DefaultEff=*/ArgEffect(DoNothing),
+                              /*ThisEff=*/ArgEffect(IncRef, ObjKind::OS));
 }
 
 const RetainSummary *
 RetainSummaryManager::getOSSummaryReleaseRule(const FunctionDecl *FD) {
   return getPersistentSummary(RetEffect::MakeNoRet(),
                               AF.getEmptyMap(),
-                              /*ReceiverEff=*/DoNothing,
-                              /*DefaultEff=*/DoNothing,
-                              /*ThisEff=*/DecRef);
+                              /*ReceiverEff=*/ArgEffect(DoNothing),
+                              /*DefaultEff=*/ArgEffect(DoNothing),
+                              /*ThisEff=*/ArgEffect(DecRef, ObjKind::OS));
 }
 
 const RetainSummary *
 RetainSummaryManager::getOSSummaryFreeRule(const FunctionDecl *FD) {
   return getPersistentSummary(RetEffect::MakeNoRet(),
                               AF.getEmptyMap(),
-                              /*ReceiverEff=*/DoNothing,
-                              /*DefaultEff=*/DoNothing,
-                              /*ThisEff=*/Dealloc);
+                              /*ReceiverEff=*/ArgEffect(DoNothing),
+                              /*DefaultEff=*/ArgEffect(DoNothing),
+                              /*ThisEff=*/ArgEffect(Dealloc, ObjKind::OS));
 }
 
 const RetainSummary *
@@ -722,7 +725,7 @@ const RetainSummary *
 RetainSummaryManager::getCFSummaryGetRule(const FunctionDecl *FD) {
   return getPersistentSummary(RetEffect::MakeNotOwned(ObjKind::CF),
                               ArgEffects(AF.getEmptyMap()),
-                              DoNothing, DoNothing);
+                              ArgEffect(DoNothing), ArgEffect(DoNothing));
 }
 
 
@@ -775,19 +778,24 @@ bool RetainSummaryManager::applyFunctionParamAnnotationEffect(
     const ParmVarDecl *pd, unsigned parm_idx, const FunctionDecl *FD,
     RetainSummaryTemplate &Template) {
   if (hasEnabledAttr(pd)) {
-    Template->addArg(AF, parm_idx, DecRefMsg);
+    Template->addArg(AF, parm_idx, ArgEffect(DecRefMsg, ObjKind::ObjC));
+    return true;
+  } else if (hasEnabledAttr(pd)) {
+    Template->addArg(AF, parm_idx, ArgEffect(DecRef, ObjKind::CF));
     return true;
-  } else if (hasEnabledAttr(pd) ||
-             hasEnabledAttr(pd) ||
-             hasRCAnnotation(pd, "rc_ownership_consumed")) {
-    Template->addArg(AF, parm_idx, DecRef);
+  } else if (hasEnabledAttr(pd)) {
+    Template->addArg(AF, parm_idx, ArgEffect(DecRef, ObjKind::OS));
+    return true;
+  } else if (hasRCAnnotation(pd, "rc_ownership_consumed")) {
+    Template->addArg(AF, parm_idx, ArgEffect(DecRef, ObjKind::Generalized));
     return true;
   } else if (hasEnabledAttr(pd) ||
              hasRCAnnotation(pd, "rc_ownership_returns_retained")) {
     QualType PointeeTy = pd->getType()->getPointeeType();
     if (!PointeeTy.isNull()) {
       if (coreFoundation::isCFObjectRef(PointeeTy)) {
-        Template->addArg(AF, parm_idx, RetainedOutParameter);
+        Template->addArg(AF, parm_idx, ArgEffect(RetainedOutParameter,
+                                                 ObjKind::CF));
         return true;
       }
     }
@@ -795,7 +803,8 @@ bool RetainSummaryManager::applyFunctionParamAnnotationEffect(
     QualType PointeeTy = pd->getType()->getPointeeType();
     if (!PointeeTy.isNull()) {
       if (coreFoundation::isCFObjectRef(PointeeTy)) {
-        Template->addArg(AF, parm_idx, UnretainedOutParameter);
+        Template->addArg(AF, parm_idx, ArgEffect(UnretainedOutParameter,
+                                                 ObjKind::CF));
         return true;
       }
     }
@@ -834,7 +843,7 @@ RetainSummaryManager::updateSummaryFromAnnotations(const RetainSummary *&Summ,
     Template->setRetEffect(*RetE);
 
   if (hasEnabledAttr(FD))
-    Template->setThisEffect(DecRef);
+    Template->setThisEffect(ArgEffect(DecRef, ObjKind::OS));
 }
 
 void
@@ -848,7 +857,7 @@ RetainSummaryManager::updateSummaryFromAnnotations(const RetainSummary *&Summ,
 
   // Effects on the receiver.
   if (MD->hasAttr())
-    Template->setReceiverEffect(DecRefMsg);
+    Template->setReceiverEffect(ArgEffect(DecRefMsg, ObjKind::ObjC));
 
   // Effects on the parameters.
   unsigned parm_idx = 0;
@@ -856,19 +865,23 @@ RetainSummaryManager::updateSummaryFromAnnotations(const RetainSummary *&Summ,
        pi != pe; ++pi, ++parm_idx) {
     const ParmVarDecl *pd = *pi;
     if (pd->hasAttr()) {
-      Template->addArg(AF, parm_idx, DecRefMsg);
-    } else if (pd->hasAttr() || pd->hasAttr()) {
-      Template->addArg(AF, parm_idx, DecRef);
+      Template->addArg(AF, parm_idx, ArgEffect(DecRefMsg, ObjKind::ObjC));
+    } else if (pd->hasAttr()) {
+      Template->addArg(AF, parm_idx, ArgEffect(DecRef, ObjKind::CF));
+    } else if (pd->hasAttr()) {
+      Template->addArg(AF, parm_idx, ArgEffect(DecRef, ObjKind::OS));
     } else if (pd->hasAttr()) {
       QualType PointeeTy = pd->getType()->getPointeeType();
       if (!PointeeTy.isNull())
         if (coreFoundation::isCFObjectRef(PointeeTy))
-          Template->addArg(AF, parm_idx, RetainedOutParameter);
+          Template->addArg(AF, parm_idx,
+                           ArgEffect(RetainedOutParameter, ObjKind::CF));
     } else if (pd->hasAttr()) {
       QualType PointeeTy = pd->getType()->getPointeeType();
       if (!PointeeTy.isNull())
         if (coreFoundation::isCFObjectRef(PointeeTy))
-          Template->addArg(AF, parm_idx, UnretainedOutParameter);
+          Template->addArg(AF, parm_idx, ArgEffect(UnretainedOutParameter,
+                                                   ObjKind::CF));
     }
   }
 
@@ -881,7 +894,7 @@ const RetainSummary *
 RetainSummaryManager::getStandardMethodSummary(const ObjCMethodDecl *MD,
                                                Selector S, QualType RetTy) {
   // Any special effects?
-  ArgEffect ReceiverEff = DoNothing;
+  ArgEffect ReceiverEff = ArgEffect(DoNothing, ObjKind::ObjC);
   RetEffect ResultEff = RetEffect::MakeNoRet();
 
   // Check the method family, and apply any default annotations.
@@ -918,7 +931,7 @@ RetainSummaryManager::getStandardMethodSummary(const ObjCMethodDecl *MD,
       break;
     case OMF_init:
       ResultEff = ObjCInitRetE;
-      ReceiverEff = DecRefMsg;
+      ReceiverEff = ArgEffect(DecRefMsg, ObjKind::ObjC);
       break;
     case OMF_alloc:
     case OMF_new:
@@ -930,16 +943,16 @@ RetainSummaryManager::getStandardMethodSummary(const ObjCMethodDecl *MD,
         ResultEff = RetEffect::MakeOwned(ObjKind::CF);
       break;
     case OMF_autorelease:
-      ReceiverEff = Autorelease;
+      ReceiverEff = ArgEffect(Autorelease, ObjKind::ObjC);
       break;
     case OMF_retain:
-      ReceiverEff = IncRefMsg;
+      ReceiverEff = ArgEffect(IncRefMsg, ObjKind::ObjC);
       break;
     case OMF_release:
-      ReceiverEff = DecRefMsg;
+      ReceiverEff = ArgEffect(DecRefMsg, ObjKind::ObjC);
       break;
     case OMF_dealloc:
-      ReceiverEff = Dealloc;
+      ReceiverEff = ArgEffect(Dealloc, ObjKind::ObjC);
       break;
     case OMF_self:
       // -self is handled specially by the ExprEngine to propagate the receiver.
@@ -961,17 +974,17 @@ RetainSummaryManager::getStandardMethodSummary(const ObjCMethodDecl *MD,
         if (ResultEff == ObjCInitRetE)
           ResultEff = RetEffect::MakeNoRetHard();
         else
-          ReceiverEff = StopTrackingHard;
+          ReceiverEff = ArgEffect(StopTrackingHard, ObjKind::ObjC);
       }
     }
   }
 
-  if (ReceiverEff == DoNothing &&
+  if (ReceiverEff.getKind() == DoNothing &&
       ResultEff.getKind() == RetEffect::NoRet)
     return getDefaultSummary();
 
   return getPersistentSummary(ResultEff, ArgEffects(AF.getEmptyMap()),
-                              ReceiverEff, MayEscape);
+                              ArgEffect(ReceiverEff), ArgEffect(MayEscape));
 }
 
 const RetainSummary *RetainSummaryManager::getInstanceMethodSummary(
@@ -1037,11 +1050,11 @@ void RetainSummaryManager::InitializeClassMethodSummaries() {
                                      ScratchArgs));
 
   // Create the [NSAutoreleasePool addObject:] summary.
-  ScratchArgs = AF.add(ScratchArgs, 0, Autorelease);
+  ScratchArgs = AF.add(ScratchArgs, 0, ArgEffect(Autorelease));
   addClassMethSummary("NSAutoreleasePool", "addObject",
-                      getPersistentSummary(RetEffect::MakeNoRet(),
-                                           ScratchArgs,
-                                           DoNothing, Autorelease));
+                      getPersistentSummary(RetEffect::MakeNoRet(), ScratchArgs,
+                                           ArgEffect(DoNothing),
+                                           ArgEffect(Autorelease)));
 }
 
 void RetainSummaryManager::InitializeMethodSummaries() {
@@ -1051,7 +1064,7 @@ void RetainSummaryManager::InitializeMethodSummaries() {
   // receiver.
   const RetainSummary *InitSumm = getPersistentSummary(ObjCInitRetE,
                                                        ScratchArgs,
-                                                       DecRefMsg);
+                                                       ArgEffect(DecRefMsg));
   addNSObjectMethSummary(GetNullarySelector("init", Ctx), InitSumm);
 
   // awakeAfterUsingCoder: behaves basically like an 'init' method.  It
@@ -1067,19 +1080,20 @@ void RetainSummaryManager::InitializeMethodSummaries() {
 
   // Create the "retain" selector.
   RetEffect NoRet = RetEffect::MakeNoRet();
-  const RetainSummary *Summ = getPersistentSummary(NoRet, ScratchArgs, IncRefMsg);
+  const RetainSummary *Summ =
+      getPersistentSummary(NoRet, ScratchArgs, ArgEffect(IncRefMsg));
   addNSObjectMethSummary(GetNullarySelector("retain", Ctx), Summ);
 
   // Create the "release" selector.
-  Summ = getPersistentSummary(NoRet, ScratchArgs, DecRefMsg);
+  Summ = getPersistentSummary(NoRet, ScratchArgs, ArgEffect(DecRefMsg));
   addNSObjectMethSummary(GetNullarySelector("release", Ctx), Summ);
 
   // Create the -dealloc summary.
-  Summ = getPersistentSummary(NoRet, ScratchArgs, Dealloc);
+  Summ = getPersistentSummary(NoRet, ScratchArgs, ArgEffect(Dealloc));
   addNSObjectMethSummary(GetNullarySelector("dealloc", Ctx), Summ);
 
   // Create the "autorelease" selector.
-  Summ = getPersistentSummary(NoRet, ScratchArgs, Autorelease);
+  Summ = getPersistentSummary(NoRet, ScratchArgs, ArgEffect(Autorelease));
   addNSObjectMethSummary(GetNullarySelector("autorelease", Ctx), Summ);
 
   // For NSWindow, allocated objects are (initially) self-owned.
@@ -1088,8 +1102,9 @@ void RetainSummaryManager::InitializeMethodSummaries() {
   //  Thus, we need to track an NSWindow's display status.
   //  This is tracked in .
   //  See also http://llvm.org/bugs/show_bug.cgi?id=3714.
-  const RetainSummary *NoTrackYet = getPersistentSummary(
-      RetEffect::MakeNoRet(), ScratchArgs, StopTracking, StopTracking);
+  const RetainSummary *NoTrackYet =
+      getPersistentSummary(RetEffect::MakeNoRet(), ScratchArgs,
+                           ArgEffect(StopTracking), ArgEffect(StopTracking));
 
   addClassMethSummary("NSWindow", "alloc", NoTrackYet);
 
@@ -1130,8 +1145,7 @@ CallEffects CallEffects::getEffect(const ObjCMethodDecl *MD) {
                          /*TrackNSAndCFObjects=*/true,
                          /*TrackOSObjects=*/false);
   const RetainSummary *S = M.getMethodSummary(MD);
-  CallEffects CE(S->getRetEffect());
-  CE.Receiver = S->getReceiverEffect();
+  CallEffects CE(S->getRetEffect(), S->getReceiverEffect());
   unsigned N = MD->param_size();
   for (unsigned i = 0; i < N; ++i) {
     CE.Args.push_back(S->getArg(i));
-- 
cgit v1.2.3


From 08e4f3dd6e207579c04e631cd07aa93b4178daab Mon Sep 17 00:00:00 2001
From: George Karpenkov 
Date: Thu, 10 Jan 2019 18:14:12 +0000
Subject: [analyzer] [RetainCountChecker] [NFC] Remove redundant enum items
 *Msg, as the object type is already communicated by a separate field

Differential Revision: https://reviews.llvm.org/D56070

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350859 91177308-0d34-0410-b5e6-96231b3b80d8
---
 .../StaticAnalyzer/Core/RetainSummaryManager.h     | 17 -----
 lib/ARCMigrate/ObjCMT.cpp                          | 19 +++---
 .../RetainCountChecker/RetainCountChecker.cpp      | 75 +++++++++++-----------
 .../RetainCountChecker/RetainCountChecker.h        |  2 +-
 lib/StaticAnalyzer/Core/RetainSummaryManager.cpp   | 38 +++++------
 5 files changed, 69 insertions(+), 82 deletions(-)

diff --git a/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h b/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
index 5461716f9d..099b20f611 100644
--- a/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
+++ b/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
@@ -68,20 +68,10 @@ enum ArgEffectKind {
   /// if CFRelease has been called on the argument.
   DecRef,
 
-  /// The argument has its reference count decreased by 1.  This is as
-  /// if a -release message has been sent to the argument.  This differs
-  /// in behavior from DecRef when ARC is enabled.
-  DecRefMsg,
-
   /// The argument has its reference count decreased by 1 to model
   /// a transferred bridge cast under ARC.
   DecRefBridgedTransferred,
 
-  /// The argument has its reference count increased by 1.  This is as
-  /// if a -retain message has been sent to the argument.  This differs
-  /// in behavior from IncRef when ARC is enabled.
-  IncRefMsg,
-
   /// The argument has its reference count increased by 1.  This is as
   /// if CFRetain has been called on the argument.
   IncRef,
@@ -122,13 +112,6 @@ enum ArgEffectKind {
   /// count of the argument and all typestate tracking on that argument
   /// should cease.
   DecRefAndStopTrackingHard,
-
-  /// Performs the combined functionality of DecRefMsg and StopTrackingHard.
-  ///
-  /// The models the effect that the called function decrements the reference
-  /// count of the argument and all typestate tracking on that argument
-  /// should cease.
-  DecRefMsgAndStopTrackingHard
 };
 
 /// An ArgEffect summarizes the retain count behavior on an argument or receiver
diff --git a/lib/ARCMigrate/ObjCMT.cpp b/lib/ARCMigrate/ObjCMT.cpp
index c3f849b7fa..6950ce0e12 100644
--- a/lib/ARCMigrate/ObjCMT.cpp
+++ b/lib/ARCMigrate/ObjCMT.cpp
@@ -1484,14 +1484,15 @@ void ObjCMigrateASTConsumer::AddCFAnnotations(ASTContext &Ctx,
        pe = FuncDecl->param_end(); pi != pe; ++pi, ++i) {
     const ParmVarDecl *pd = *pi;
     ArgEffect AE = AEArgs[i];
-    if (AE.getKind() == DecRef && !pd->hasAttr() &&
+    if (AE.getKind() == DecRef && AE.getObjKind() == ObjKind::CF &&
+        !pd->hasAttr() &&
         NSAPIObj->isMacroDefined("CF_CONSUMED")) {
       edit::Commit commit(*Editor);
       commit.insertBefore(pd->getLocation(), "CF_CONSUMED ");
       Editor->commit(commit);
-    }
-    else if (AE.getKind() == DecRefMsg && !pd->hasAttr() &&
-             NSAPIObj->isMacroDefined("NS_CONSUMED")) {
+    } else if (AE.getKind() == DecRef && AE.getObjKind() == ObjKind::ObjC &&
+               !pd->hasAttr() &&
+               NSAPIObj->isMacroDefined("NS_CONSUMED")) {
       edit::Commit commit(*Editor);
       commit.insertBefore(pd->getLocation(), "NS_CONSUMED ");
       Editor->commit(commit);
@@ -1536,8 +1537,8 @@ ObjCMigrateASTConsumer::CF_BRIDGING_KIND
        pe = FuncDecl->param_end(); pi != pe; ++pi, ++i) {
     const ParmVarDecl *pd = *pi;
     ArgEffect AE = AEArgs[i];
-    if (AE.getKind() == DecRef /*CFConsumed annotated*/ ||
-        AE.getKind() == IncRef) {
+    if ((AE.getKind() == DecRef /*CFConsumed annotated*/ ||
+         AE.getKind() == IncRef) && AE.getObjKind() == ObjKind::CF) {
       if (AE.getKind() == DecRef && !pd->hasAttr())
         ArgCFAudited = true;
       else if (AE.getKind() == IncRef)
@@ -1610,7 +1611,9 @@ void ObjCMigrateASTConsumer::AddCFAnnotations(ASTContext &Ctx,
        pe = MethodDecl->param_end(); pi != pe; ++pi, ++i) {
     const ParmVarDecl *pd = *pi;
     ArgEffect AE = AEArgs[i];
-    if (AE.getKind() == DecRef && !pd->hasAttr() &&
+    if (AE.getKind() == DecRef
+        && AE.getObjKind() == ObjKind::CF
+        && !pd->hasAttr() &&
         NSAPIObj->isMacroDefined("CF_CONSUMED")) {
       edit::Commit commit(*Editor);
       commit.insertBefore(pd->getLocation(), "CF_CONSUMED ");
@@ -1633,7 +1636,7 @@ void ObjCMigrateASTConsumer::migrateAddMethodAnnotation(
        MethodDecl->hasAttr() ||
        MethodDecl->hasAttr());
 
-  if (CE.getReceiver().getKind() == DecRefMsg &&
+  if (CE.getReceiver().getKind() == DecRef &&
       !MethodDecl->hasAttr() &&
       MethodDecl->getMethodFamily() != OMF_init &&
       MethodDecl->getMethodFamily() != OMF_release &&
diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
index 4e5fac815e..73de9f5b50 100644
--- a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
@@ -248,17 +248,17 @@ void RetainCountChecker::checkPostStmt(const CastExpr *CE,
   if (!BE)
     return;
 
-  ArgEffectKind AE = IncRef;
+  ArgEffect AE = ArgEffect(IncRef, ObjKind::ObjC);
 
   switch (BE->getBridgeKind()) {
     case OBC_Bridge:
       // Do nothing.
       return;
     case OBC_BridgeRetained:
-      AE = IncRef;
+      AE = AE.withKind(IncRef);
       break;
     case OBC_BridgeTransfer:
-      AE = DecRefBridgedTransferred;
+      AE = AE.withKind(DecRefBridgedTransferred);
       break;
   }
 
@@ -290,7 +290,8 @@ void RetainCountChecker::processObjCLiterals(CheckerContext &C,
     if (SymbolRef sym = V.getAsSymbol())
       if (const RefVal* T = getRefBinding(state, sym)) {
         RefVal::Kind hasErr = (RefVal::Kind) 0;
-        state = updateSymbol(state, sym, *T, MayEscape, hasErr, C);
+        state = updateSymbol(state, sym, *T,
+                             ArgEffect(MayEscape, ObjKind::ObjC), hasErr, C);
         if (hasErr) {
           processNonLeakError(state, Child->getSourceRange(), hasErr, sym, C);
           return;
@@ -512,7 +513,7 @@ static bool isPointerToObject(QualType QT) {
 
 /// Whether the tracked value should be escaped on a given call.
 /// OSObjects are escaped when passed to void * / etc.
-static bool shouldEscapeArgumentOnCall(const CallEvent &CE, unsigned ArgIdx,
+static bool shouldEscapeOSArgumentOnCall(const CallEvent &CE, unsigned ArgIdx,
                                        const RefVal *TrackedValue) {
   if (TrackedValue->getObjKind() != ObjKind::OS)
     return false;
@@ -536,7 +537,7 @@ void RetainCountChecker::processSummaryOfInlined(const RetainSummary &Summ,
     if (SymbolRef Sym = V.getAsLocSymbol()) {
       bool ShouldRemoveBinding = Summ.getArg(idx).getKind() == StopTrackingHard;
       if (const RefVal *T = getRefBinding(state, Sym))
-        if (shouldEscapeArgumentOnCall(CallOrMsg, idx, T))
+        if (shouldEscapeOSArgumentOnCall(CallOrMsg, idx, T))
           ShouldRemoveBinding = true;
 
       if (ShouldRemoveBinding)
@@ -611,14 +612,15 @@ void RetainCountChecker::checkSummary(const RetainSummary &Summ,
   for (unsigned idx = 0, e = CallOrMsg.getNumArgs(); idx != e; ++idx) {
     SVal V = CallOrMsg.getArgSVal(idx);
 
-    ArgEffectKind Effect = Summ.getArg(idx).getKind();
-    if (Effect == RetainedOutParameter || Effect == UnretainedOutParameter) {
-      state = updateOutParameter(state, V, Effect);
+    ArgEffect Effect = Summ.getArg(idx);
+    if (Effect.getKind() == RetainedOutParameter ||
+        Effect.getKind() == UnretainedOutParameter) {
+      state = updateOutParameter(state, V, Effect.getKind());
     } else if (SymbolRef Sym = V.getAsLocSymbol()) {
       if (const RefVal *T = getRefBinding(state, Sym)) {
 
-        if (shouldEscapeArgumentOnCall(CallOrMsg, idx, T))
-          Effect = StopTrackingHard;
+        if (shouldEscapeOSArgumentOnCall(CallOrMsg, idx, T))
+          Effect = ArgEffect(StopTrackingHard, ObjKind::OS);
 
         state = updateSymbol(state, Sym, *T, Effect, hasErr, C);
         if (hasErr) {
@@ -638,7 +640,7 @@ void RetainCountChecker::checkSummary(const RetainSummary &Summ,
         if (const RefVal *T = getRefBinding(state, Sym)) {
           ReceiverIsTracked = true;
           state = updateSymbol(state, Sym, *T,
-                               Summ.getReceiverEffect().getKind(), hasErr, C);
+                               Summ.getReceiverEffect(), hasErr, C);
           if (hasErr) {
             ErrorRange = MsgInvocation->getOriginExpr()->getReceiverRange();
             ErrorSym = Sym;
@@ -648,7 +650,7 @@ void RetainCountChecker::checkSummary(const RetainSummary &Summ,
     } else if (const auto *MCall = dyn_cast(&CallOrMsg)) {
       if (SymbolRef Sym = MCall->getCXXThisVal().getAsLocSymbol()) {
         if (const RefVal *T = getRefBinding(state, Sym)) {
-          state = updateSymbol(state, Sym, *T, Summ.getThisEffect().getKind(),
+          state = updateSymbol(state, Sym, *T, Summ.getThisEffect(),
                                hasErr, C);
           if (hasErr) {
             ErrorRange = MCall->getOriginExpr()->getSourceRange();
@@ -709,25 +711,27 @@ void RetainCountChecker::checkSummary(const RetainSummary &Summ,
 
 ProgramStateRef RetainCountChecker::updateSymbol(ProgramStateRef state,
                                                  SymbolRef sym, RefVal V,
-                                                 ArgEffectKind E,
+                                                 ArgEffect AE,
                                                  RefVal::Kind &hasErr,
                                                  CheckerContext &C) const {
   bool IgnoreRetainMsg = (bool)C.getASTContext().getLangOpts().ObjCAutoRefCount;
-  switch (E) {
-  default:
-    break;
-  case IncRefMsg:
-    E = IgnoreRetainMsg ? DoNothing : IncRef;
-    break;
-  case DecRefMsg:
-    E = IgnoreRetainMsg ? DoNothing: DecRef;
-    break;
-  case DecRefMsgAndStopTrackingHard:
-    E = IgnoreRetainMsg ? StopTracking : DecRefAndStopTrackingHard;
-    break;
-  case MakeCollectable:
-    E = DoNothing;
+  if (AE.getObjKind() == ObjKind::ObjC && IgnoreRetainMsg) {
+    switch (AE.getKind()) {
+    default:
+      break;
+    case IncRef:
+      AE = AE.withKind(DoNothing);
+      break;
+    case DecRef:
+      AE = AE.withKind(DoNothing);
+      break;
+    case DecRefAndStopTrackingHard:
+      AE = AE.withKind(StopTracking);
+      break;
+    }
   }
+  if (AE.getKind() == MakeCollectable)
+    AE = AE.withKind(DoNothing);
 
   // Handle all use-after-releases.
   if (V.getKind() == RefVal::Released) {
@@ -736,12 +740,9 @@ ProgramStateRef RetainCountChecker::updateSymbol(ProgramStateRef state,
     return setRefBinding(state, sym, V);
   }
 
-  switch (E) {
-    case DecRefMsg:
-    case IncRefMsg:
+  switch (AE.getKind()) {
     case MakeCollectable:
-    case DecRefMsgAndStopTrackingHard:
-      llvm_unreachable("DecRefMsg/IncRefMsg/MakeCollectable already converted");
+      llvm_unreachable("MakeCollectable already converted");
 
     case UnretainedOutParameter:
     case RetainedOutParameter:
@@ -806,13 +807,13 @@ ProgramStateRef RetainCountChecker::updateSymbol(ProgramStateRef state,
         case RefVal::Owned:
           assert(V.getCount() > 0);
           if (V.getCount() == 1) {
-            if (E == DecRefBridgedTransferred ||
+            if (AE.getKind() == DecRefBridgedTransferred ||
                 V.getIvarAccessHistory() ==
                   RefVal::IvarAccessHistory::AccessedDirectly)
               V = V ^ RefVal::NotOwned;
             else
               V = V ^ RefVal::Released;
-          } else if (E == DecRefAndStopTrackingHard) {
+          } else if (AE.getKind() == DecRefAndStopTrackingHard) {
             return removeRefBinding(state, sym);
           }
 
@@ -821,14 +822,14 @@ ProgramStateRef RetainCountChecker::updateSymbol(ProgramStateRef state,
 
         case RefVal::NotOwned:
           if (V.getCount() > 0) {
-            if (E == DecRefAndStopTrackingHard)
+            if (AE.getKind() == DecRefAndStopTrackingHard)
               return removeRefBinding(state, sym);
             V = V - 1;
           } else if (V.getIvarAccessHistory() ==
                        RefVal::IvarAccessHistory::AccessedDirectly) {
             // Assume that the instance variable was holding on the object at
             // +1, and we just didn't know.
-            if (E == DecRefAndStopTrackingHard)
+            if (AE.getKind() == DecRefAndStopTrackingHard)
               return removeRefBinding(state, sym);
             V = V.releaseViaIvar() ^ RefVal::Released;
           } else {
diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h
index 80d1b0573c..d8bbe6fcdd 100644
--- a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h
+++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h
@@ -347,7 +347,7 @@ public:
   void checkEndFunction(const ReturnStmt *RS, CheckerContext &C) const;
 
   ProgramStateRef updateSymbol(ProgramStateRef state, SymbolRef sym,
-                               RefVal V, ArgEffectKind E, RefVal::Kind &hasErr,
+                               RefVal V, ArgEffect E, RefVal::Kind &hasErr,
                                CheckerContext &C) const;
 
   void processNonLeakError(ProgramStateRef St, SourceRange ErrorRange,
diff --git a/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp b/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
index 9f0e60ec3e..20dc900e25 100644
--- a/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
+++ b/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
@@ -457,7 +457,6 @@ static ArgEffect getStopTrackingHardEquivalent(ArgEffect E) {
   case Autorelease:
   case DecRefBridgedTransferred:
   case IncRef:
-  case IncRefMsg:
   case MakeCollectable:
   case UnretainedOutParameter:
   case RetainedOutParameter:
@@ -468,9 +467,6 @@ static ArgEffect getStopTrackingHardEquivalent(ArgEffect E) {
   case DecRef:
   case DecRefAndStopTrackingHard:
     return E.withKind(DecRefAndStopTrackingHard);
-  case DecRefMsg:
-  case DecRefMsgAndStopTrackingHard:
-    return E.withKind(DecRefMsgAndStopTrackingHard);
   case Dealloc:
     return E.withKind(Dealloc);
   }
@@ -649,6 +645,8 @@ RetainSummaryManager::canEval(const CallExpr *CE, const FunctionDecl *FD,
   return None;
 }
 
+// TODO: UnaryFuncKind is a very funny enum, it really should not exist:
+// just pass the needed effect directly!
 const RetainSummary *
 RetainSummaryManager::getUnarySummary(const FunctionType* FT,
                                       UnaryFuncKind func) {
@@ -662,7 +660,7 @@ RetainSummaryManager::getUnarySummary(const FunctionType* FT,
   if (!FTP || FTP->getNumParams() != 1)
     return getPersistentStopSummary();
 
-  ArgEffect Effect;
+  ArgEffect Effect(DoNothing, ObjKind::CF);
   switch (func) {
   case cfretain: Effect = Effect.withKind(IncRef); break;
   case cfrelease: Effect = Effect.withKind(DecRef); break;
@@ -778,7 +776,7 @@ bool RetainSummaryManager::applyFunctionParamAnnotationEffect(
     const ParmVarDecl *pd, unsigned parm_idx, const FunctionDecl *FD,
     RetainSummaryTemplate &Template) {
   if (hasEnabledAttr(pd)) {
-    Template->addArg(AF, parm_idx, ArgEffect(DecRefMsg, ObjKind::ObjC));
+    Template->addArg(AF, parm_idx, ArgEffect(DecRef, ObjKind::ObjC));
     return true;
   } else if (hasEnabledAttr(pd)) {
     Template->addArg(AF, parm_idx, ArgEffect(DecRef, ObjKind::CF));
@@ -857,7 +855,7 @@ RetainSummaryManager::updateSummaryFromAnnotations(const RetainSummary *&Summ,
 
   // Effects on the receiver.
   if (MD->hasAttr())
-    Template->setReceiverEffect(ArgEffect(DecRefMsg, ObjKind::ObjC));
+    Template->setReceiverEffect(ArgEffect(DecRef, ObjKind::ObjC));
 
   // Effects on the parameters.
   unsigned parm_idx = 0;
@@ -865,7 +863,7 @@ RetainSummaryManager::updateSummaryFromAnnotations(const RetainSummary *&Summ,
        pi != pe; ++pi, ++parm_idx) {
     const ParmVarDecl *pd = *pi;
     if (pd->hasAttr()) {
-      Template->addArg(AF, parm_idx, ArgEffect(DecRefMsg, ObjKind::ObjC));
+      Template->addArg(AF, parm_idx, ArgEffect(DecRef, ObjKind::ObjC));
     } else if (pd->hasAttr()) {
       Template->addArg(AF, parm_idx, ArgEffect(DecRef, ObjKind::CF));
     } else if (pd->hasAttr()) {
@@ -931,7 +929,7 @@ RetainSummaryManager::getStandardMethodSummary(const ObjCMethodDecl *MD,
       break;
     case OMF_init:
       ResultEff = ObjCInitRetE;
-      ReceiverEff = ArgEffect(DecRefMsg, ObjKind::ObjC);
+      ReceiverEff = ArgEffect(DecRef, ObjKind::ObjC);
       break;
     case OMF_alloc:
     case OMF_new:
@@ -946,10 +944,10 @@ RetainSummaryManager::getStandardMethodSummary(const ObjCMethodDecl *MD,
       ReceiverEff = ArgEffect(Autorelease, ObjKind::ObjC);
       break;
     case OMF_retain:
-      ReceiverEff = ArgEffect(IncRefMsg, ObjKind::ObjC);
+      ReceiverEff = ArgEffect(IncRef, ObjKind::ObjC);
       break;
     case OMF_release:
-      ReceiverEff = ArgEffect(DecRefMsg, ObjKind::ObjC);
+      ReceiverEff = ArgEffect(DecRef, ObjKind::ObjC);
       break;
     case OMF_dealloc:
       ReceiverEff = ArgEffect(Dealloc, ObjKind::ObjC);
@@ -1062,9 +1060,8 @@ void RetainSummaryManager::InitializeMethodSummaries() {
   ArgEffects ScratchArgs = AF.getEmptyMap();
   // Create the "init" selector.  It just acts as a pass-through for the
   // receiver.
-  const RetainSummary *InitSumm = getPersistentSummary(ObjCInitRetE,
-                                                       ScratchArgs,
-                                                       ArgEffect(DecRefMsg));
+  const RetainSummary *InitSumm = getPersistentSummary(
+      ObjCInitRetE, ScratchArgs, ArgEffect(DecRef, ObjKind::ObjC));
   addNSObjectMethSummary(GetNullarySelector("init", Ctx), InitSumm);
 
   // awakeAfterUsingCoder: behaves basically like an 'init' method.  It
@@ -1080,20 +1077,23 @@ void RetainSummaryManager::InitializeMethodSummaries() {
 
   // Create the "retain" selector.
   RetEffect NoRet = RetEffect::MakeNoRet();
-  const RetainSummary *Summ =
-      getPersistentSummary(NoRet, ScratchArgs, ArgEffect(IncRefMsg));
+  const RetainSummary *Summ = getPersistentSummary(
+      NoRet, ScratchArgs, ArgEffect(IncRef, ObjKind::ObjC));
   addNSObjectMethSummary(GetNullarySelector("retain", Ctx), Summ);
 
   // Create the "release" selector.
-  Summ = getPersistentSummary(NoRet, ScratchArgs, ArgEffect(DecRefMsg));
+  Summ = getPersistentSummary(NoRet, ScratchArgs,
+                              ArgEffect(DecRef, ObjKind::ObjC));
   addNSObjectMethSummary(GetNullarySelector("release", Ctx), Summ);
 
   // Create the -dealloc summary.
-  Summ = getPersistentSummary(NoRet, ScratchArgs, ArgEffect(Dealloc));
+  Summ = getPersistentSummary(NoRet, ScratchArgs, ArgEffect(Dealloc,
+                                                            ObjKind::ObjC));
   addNSObjectMethSummary(GetNullarySelector("dealloc", Ctx), Summ);
 
   // Create the "autorelease" selector.
-  Summ = getPersistentSummary(NoRet, ScratchArgs, ArgEffect(Autorelease));
+  Summ = getPersistentSummary(NoRet, ScratchArgs, ArgEffect(Autorelease,
+                                                            ObjKind::ObjC));
   addNSObjectMethSummary(GetNullarySelector("autorelease", Ctx), Summ);
 
   // For NSWindow, allocated objects are (initially) self-owned.
-- 
cgit v1.2.3


From 61ebd71625b5146e235c51856b038dfea43207fb Mon Sep 17 00:00:00 2001
From: George Karpenkov 
Date: Thu, 10 Jan 2019 18:14:25 +0000
Subject: [analyzer] [RetainCountChecker] Remove obsolete "MakeCollectable"
 enum value

Differential Revision: https://reviews.llvm.org/D56071

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350860 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/StaticAnalyzer/Core/RetainSummaryManager.h             | 4 ----
 .../Checkers/RetainCountChecker/RetainCountChecker.cpp               | 5 -----
 lib/StaticAnalyzer/Core/RetainSummaryManager.cpp                     | 3 +--
 3 files changed, 1 insertion(+), 11 deletions(-)

diff --git a/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h b/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
index 099b20f611..e03a17067c 100644
--- a/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
+++ b/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
@@ -76,10 +76,6 @@ enum ArgEffectKind {
   /// if CFRetain has been called on the argument.
   IncRef,
 
-  /// The argument acts as if has been passed to CFMakeCollectable, which
-  /// transfers the object to the Garbage Collector under GC.
-  MakeCollectable,
-
   /// The argument is a pointer to a retain-counted object; on exit, the new
   /// value of the pointer is a +0 value or NULL.
   UnretainedOutParameter,
diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
index 73de9f5b50..4e6fd8490d 100644
--- a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
@@ -730,8 +730,6 @@ ProgramStateRef RetainCountChecker::updateSymbol(ProgramStateRef state,
       break;
     }
   }
-  if (AE.getKind() == MakeCollectable)
-    AE = AE.withKind(DoNothing);
 
   // Handle all use-after-releases.
   if (V.getKind() == RefVal::Released) {
@@ -741,9 +739,6 @@ ProgramStateRef RetainCountChecker::updateSymbol(ProgramStateRef state,
   }
 
   switch (AE.getKind()) {
-    case MakeCollectable:
-      llvm_unreachable("MakeCollectable already converted");
-
     case UnretainedOutParameter:
     case RetainedOutParameter:
       llvm_unreachable("Applies to pointer-to-pointer parameters, which should "
diff --git a/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp b/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
index 20dc900e25..6f0a71bdd7 100644
--- a/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
+++ b/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
@@ -457,7 +457,6 @@ static ArgEffect getStopTrackingHardEquivalent(ArgEffect E) {
   case Autorelease:
   case DecRefBridgedTransferred:
   case IncRef:
-  case MakeCollectable:
   case UnretainedOutParameter:
   case RetainedOutParameter:
   case MayEscape:
@@ -665,7 +664,7 @@ RetainSummaryManager::getUnarySummary(const FunctionType* FT,
   case cfretain: Effect = Effect.withKind(IncRef); break;
   case cfrelease: Effect = Effect.withKind(DecRef); break;
   case cfautorelease: Effect = Effect.withKind(Autorelease); break;
-  case cfmakecollectable: Effect = Effect.withKind(MakeCollectable); break;
+  case cfmakecollectable: Effect = Effect.withKind(DoNothing); break;
   }
 
   ScratchArgs = AF.add(ScratchArgs, 0, Effect);
-- 
cgit v1.2.3


From a8a2d77577f444f69f48b356e0616cc19887b2d1 Mon Sep 17 00:00:00 2001
From: George Karpenkov 
Date: Thu, 10 Jan 2019 18:14:38 +0000
Subject: [analyzer] [RetainCountChecker] Remove redundant enum
 UnarySummaryKind

Differential Revision: https://reviews.llvm.org/D56072

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350861 91177308-0d34-0410-b5e6-96231b3b80d8
---
 .../StaticAnalyzer/Core/RetainSummaryManager.h     |  4 +---
 lib/StaticAnalyzer/Core/RetainSummaryManager.cpp   | 24 ++++++++--------------
 2 files changed, 9 insertions(+), 19 deletions(-)

diff --git a/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h b/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
index e03a17067c..809789c231 100644
--- a/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
+++ b/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
@@ -537,10 +537,8 @@ class RetainSummaryManager {
   /// Free the OS object.
   const RetainSummary *getOSSummaryFreeRule(const FunctionDecl *FD);
 
-  enum UnaryFuncKind { cfretain, cfrelease, cfautorelease, cfmakecollectable };
-
   const RetainSummary *getUnarySummary(const FunctionType* FT,
-                                       UnaryFuncKind func);
+                                       ArgEffectKind AE);
 
   const RetainSummary *getCFSummaryCreateRule(const FunctionDecl *FD);
   const RetainSummary *getCFSummaryGetRule(const FunctionDecl *FD);
diff --git a/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp b/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
index 6f0a71bdd7..51fa760ab5 100644
--- a/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
+++ b/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
@@ -194,7 +194,7 @@ const RetainSummary *RetainSummaryManager::getSummaryForObjCOrCFObject(
   } else if(FName == "NSMakeCollectable") {
     // Handle: id NSMakeCollectable(CFTypeRef)
     AllowAnnotations = false;
-    return RetTy->isObjCIdType() ? getUnarySummary(FT, cfmakecollectable)
+    return RetTy->isObjCIdType() ? getUnarySummary(FT, DoNothing)
                                  : getPersistentStopSummary();
   } else if (FName == "CMBufferQueueDequeueAndRetain" ||
              FName == "CMBufferQueueDequeueIfDataReadyAndRetain") {
@@ -307,16 +307,16 @@ const RetainSummary *RetainSummaryManager::getSummaryForObjCOrCFObject(
         // We want to ignore such annotation.
         AllowAnnotations = false;
 
-        return getUnarySummary(FT, cfretain);
+        return getUnarySummary(FT, IncRef);
       } else if (isAutorelease(FD, FName)) {
         // The headers use cf_consumed, but we can fully model CFAutorelease
         // ourselves.
         AllowAnnotations = false;
 
-        return getUnarySummary(FT, cfautorelease);
+        return getUnarySummary(FT, Autorelease);
       } else if (isMakeCollectable(FName)) {
         AllowAnnotations = false;
-        return getUnarySummary(FT, cfmakecollectable);
+        return getUnarySummary(FT, DoNothing);
       } else {
         return getCFCreateGetRuleSummary(FD);
       }
@@ -326,7 +326,7 @@ const RetainSummary *RetainSummaryManager::getSummaryForObjCOrCFObject(
     if (cocoa::isRefType(RetTy, "CG", FName) ||
         cocoa::isRefType(RetTy, "CV", FName)) {
       if (isRetain(FD, FName))
-        return getUnarySummary(FT, cfretain);
+        return getUnarySummary(FT, IncRef);
       else
         return getCFCreateGetRuleSummary(FD);
     }
@@ -350,7 +350,7 @@ const RetainSummary *RetainSummaryManager::getSummaryForObjCOrCFObject(
     FName = FName.substr(FName.startswith("CGCF") ? 4 : 2);
 
     if (isRelease(FD, FName))
-      return getUnarySummary(FT, cfrelease);
+      return getUnarySummary(FT, DecRef);
     else {
       assert(ScratchArgs.isEmpty());
       // Remaining CoreFoundation and CoreGraphics functions.
@@ -644,11 +644,9 @@ RetainSummaryManager::canEval(const CallExpr *CE, const FunctionDecl *FD,
   return None;
 }
 
-// TODO: UnaryFuncKind is a very funny enum, it really should not exist:
-// just pass the needed effect directly!
 const RetainSummary *
 RetainSummaryManager::getUnarySummary(const FunctionType* FT,
-                                      UnaryFuncKind func) {
+                                      ArgEffectKind AE) {
 
   // Unary functions have no arg effects by definition.
   ArgEffects ScratchArgs(AF.getEmptyMap());
@@ -659,13 +657,7 @@ RetainSummaryManager::getUnarySummary(const FunctionType* FT,
   if (!FTP || FTP->getNumParams() != 1)
     return getPersistentStopSummary();
 
-  ArgEffect Effect(DoNothing, ObjKind::CF);
-  switch (func) {
-  case cfretain: Effect = Effect.withKind(IncRef); break;
-  case cfrelease: Effect = Effect.withKind(DecRef); break;
-  case cfautorelease: Effect = Effect.withKind(Autorelease); break;
-  case cfmakecollectable: Effect = Effect.withKind(DoNothing); break;
-  }
+  ArgEffect Effect(AE, ObjKind::CF);
 
   ScratchArgs = AF.add(ScratchArgs, 0, Effect);
   return getPersistentSummary(RetEffect::MakeNoRet(),
-- 
cgit v1.2.3


From 343a38646a56b7167a779489ac5f01875609ef02 Mon Sep 17 00:00:00 2001
From: George Karpenkov 
Date: Thu, 10 Jan 2019 18:14:51 +0000
Subject: [analyzer] [RetainCountChecker] [NFC] Refactor the way attributes are
 handled

Make sure all checks for attributes go through a centralized function,
which checks whether attribute handling is enabled, and performs
validation.  The type of the attribute is returned.

Sadly, metaprogramming is required as attributes have no sensible static
getters.

Differential Revision: https://reviews.llvm.org/D56222

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350862 91177308-0d34-0410-b5e6-96231b3b80d8
---
 .../StaticAnalyzer/Core/RetainSummaryManager.h     |  18 +-
 lib/StaticAnalyzer/Core/RetainSummaryManager.cpp   | 186 ++++++++++++---------
 2 files changed, 113 insertions(+), 91 deletions(-)

diff --git a/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h b/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
index 809789c231..65648e44d4 100644
--- a/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
+++ b/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
@@ -741,16 +741,18 @@ public:
 
   RetEffect getObjAllocRetEffect() const { return ObjCAllocRetE; }
 
-  /// \return True if the declaration has an attribute {@code T},
-  /// AND we are tracking that attribute. False otherwise.
+  /// Determine whether a declaration {@code D} of correspondent type (return
+  /// type for functions/methods) {@code QT} has any of the given attributes,
+  /// provided they pass necessary validation checks AND tracking the given
+  /// attribute is enabled.
+  /// Returns the object kind corresponding to the present attribute, or None,
+  /// if none of the specified attributes are present.
+  /// Crashes if passed an attribute which is not explicitly handled.
   template 
-  bool hasEnabledAttr(const Decl *D) {
-    return isAttrEnabled() && D->hasAttr();
-  }
+  Optional hasAnyEnabledAttrOf(const Decl *D, QualType QT);
 
-  /// Check whether we are tracking properties specified by the attributes.
-  template 
-  bool isAttrEnabled();
+  template 
+  Optional hasAnyEnabledAttrOf(const Decl *D, QualType QT);
 
   friend class RetainSummaryTemplate;
 };
diff --git a/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp b/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
index 51fa760ab5..a0fe2fefde 100644
--- a/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
+++ b/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
@@ -36,17 +36,79 @@ constexpr static bool isOneOf() {
   return std::is_same::value || isOneOf();
 }
 
-template  bool RetainSummaryManager::isAttrEnabled() {
+namespace {
+
+struct GeneralizedReturnsRetainedAttr {
+  static bool classof(const Attr *A) {
+    if (auto AA = dyn_cast(A))
+      return AA->getAnnotation() == "rc_ownership_returns_retained";
+    return false;
+  }
+};
+
+struct GeneralizedReturnsNotRetainedAttr {
+  static bool classof(const Attr *A) {
+    if (auto AA = dyn_cast(A))
+      return AA->getAnnotation() == "rc_ownership_returns_not_retained";
+    return false;
+  }
+};
+
+struct GeneralizedConsumedAttr {
+  static bool classof(const Attr *A) {
+    if (auto AA = dyn_cast(A))
+      return AA->getAnnotation() == "rc_ownership_consumed";
+    return false;
+  }
+};
+
+}
+
+template 
+Optional RetainSummaryManager::hasAnyEnabledAttrOf(const Decl *D,
+                                                            QualType QT) {
+  ObjKind K;
   if (isOneOf()) {
-    return TrackObjCAndCFObjects;
+              CFReturnsNotRetainedAttr>()) {
+    if (!TrackObjCAndCFObjects)
+      return None;
+
+    K = ObjKind::CF;
+  } else if (isOneOf()) {
+
+    if (!TrackObjCAndCFObjects)
+      return None;
+
+    if (isOneOf() &&
+        !cocoa::isCocoaObjectRef(QT))
+      return None;
+    K = ObjKind::ObjC;
   } else if (isOneOf()) {
-    return TrackOSObjects;
+    if (!TrackOSObjects)
+      return None;
+    K = ObjKind::OS;
+  } else if (isOneOf()) {
+    K = ObjKind::Generalized;
+  } else {
+    llvm_unreachable("Unexpected attribute");
   }
-  llvm_unreachable("Unexpected attribute passed");
+  if (D->hasAttr())
+    return K;
+  return None;
+}
+
+template 
+Optional RetainSummaryManager::hasAnyEnabledAttrOf(const Decl *D,
+                                                            QualType QT) {
+  if (auto Out = hasAnyEnabledAttrOf(D, QT))
+    return Out;
+  return hasAnyEnabledAttrOf(D, QT);
 }
 
 const RetainSummary *
@@ -727,33 +789,18 @@ RetainSummaryManager::getCFSummaryGetRule(const FunctionDecl *FD) {
 Optional
 RetainSummaryManager::getRetEffectFromAnnotations(QualType RetTy,
                                                   const Decl *D) {
-  if (TrackObjCAndCFObjects && cocoa::isCocoaObjectRef(RetTy)) {
-    if (D->hasAttr())
-      return ObjCAllocRetE;
-
-    if (D->hasAttr() ||
-        D->hasAttr())
-      return RetEffect::MakeNotOwned(ObjKind::ObjC);
-
-  } else if (!RetTy->isPointerType()) {
-    return None;
-  }
+  if (hasAnyEnabledAttrOf(D, RetTy))
+    return ObjCAllocRetE;
 
-  if (hasEnabledAttr(D)) {
-    return RetEffect::MakeOwned(ObjKind::CF);
-  } else if (hasEnabledAttr(D)) {
-    return RetEffect::MakeOwned(ObjKind::OS);
-  } else if (hasRCAnnotation(D, "rc_ownership_returns_retained")) {
-    return RetEffect::MakeOwned(ObjKind::Generalized);
-  }
+  if (auto K = hasAnyEnabledAttrOf(D, RetTy))
+    return RetEffect::MakeOwned(*K);
 
-  if (hasEnabledAttr(D)) {
-    return RetEffect::MakeNotOwned(ObjKind::CF);
-  } else if (hasEnabledAttr(D)) {
-    return RetEffect::MakeNotOwned(ObjKind::OS);
-  } else if (hasRCAnnotation(D, "rc_ownership_returns_not_retained")) {
-    return RetEffect::MakeNotOwned(ObjKind::Generalized);
-  }
+  if (auto K = hasAnyEnabledAttrOf<
+          CFReturnsNotRetainedAttr, OSReturnsNotRetainedAttr,
+          GeneralizedReturnsNotRetainedAttr, NSReturnsNotRetainedAttr,
+          NSReturnsAutoreleasedAttr>(D, RetTy))
+    return RetEffect::MakeNotOwned(*K);
 
   if (const auto *MD = dyn_cast(D))
     for (const auto *PD : MD->overridden_methods())
@@ -766,37 +813,20 @@ RetainSummaryManager::getRetEffectFromAnnotations(QualType RetTy,
 bool RetainSummaryManager::applyFunctionParamAnnotationEffect(
     const ParmVarDecl *pd, unsigned parm_idx, const FunctionDecl *FD,
     RetainSummaryTemplate &Template) {
-  if (hasEnabledAttr(pd)) {
-    Template->addArg(AF, parm_idx, ArgEffect(DecRef, ObjKind::ObjC));
+  QualType QT = pd->getType();
+  if (auto K =
+          hasAnyEnabledAttrOf(pd, QT)) {
+    Template->addArg(AF, parm_idx, ArgEffect(DecRef, *K));
     return true;
-  } else if (hasEnabledAttr(pd)) {
-    Template->addArg(AF, parm_idx, ArgEffect(DecRef, ObjKind::CF));
+  } else if (auto K =
+                 hasAnyEnabledAttrOf(pd, QT)) {
+    Template->addArg(AF, parm_idx, ArgEffect(RetainedOutParameter, *K));
     return true;
-  } else if (hasEnabledAttr(pd)) {
-    Template->addArg(AF, parm_idx, ArgEffect(DecRef, ObjKind::OS));
+  } else if (auto K = hasAnyEnabledAttrOf(pd, QT)) {
+    Template->addArg(AF, parm_idx, ArgEffect(UnretainedOutParameter, *K));
     return true;
-  } else if (hasRCAnnotation(pd, "rc_ownership_consumed")) {
-    Template->addArg(AF, parm_idx, ArgEffect(DecRef, ObjKind::Generalized));
-    return true;
-  } else if (hasEnabledAttr(pd) ||
-             hasRCAnnotation(pd, "rc_ownership_returns_retained")) {
-    QualType PointeeTy = pd->getType()->getPointeeType();
-    if (!PointeeTy.isNull()) {
-      if (coreFoundation::isCFObjectRef(PointeeTy)) {
-        Template->addArg(AF, parm_idx, ArgEffect(RetainedOutParameter,
-                                                 ObjKind::CF));
-        return true;
-      }
-    }
-  } else if (hasEnabledAttr(pd)) {
-    QualType PointeeTy = pd->getType()->getPointeeType();
-    if (!PointeeTy.isNull()) {
-      if (coreFoundation::isCFObjectRef(PointeeTy)) {
-        Template->addArg(AF, parm_idx, ArgEffect(UnretainedOutParameter,
-                                                 ObjKind::CF));
-        return true;
-      }
-    }
   } else {
     if (const auto *MD = dyn_cast(FD)) {
       for (const auto *OD : MD->overridden_methods()) {
@@ -831,7 +861,7 @@ RetainSummaryManager::updateSummaryFromAnnotations(const RetainSummary *&Summ,
   if (Optional RetE = getRetEffectFromAnnotations(RetTy, FD))
     Template->setRetEffect(*RetE);
 
-  if (hasEnabledAttr(FD))
+  if (hasAnyEnabledAttrOf(FD, RetTy))
     Template->setThisEffect(ArgEffect(DecRef, ObjKind::OS));
 }
 
@@ -845,35 +875,25 @@ RetainSummaryManager::updateSummaryFromAnnotations(const RetainSummary *&Summ,
   RetainSummaryTemplate Template(Summ, *this);
 
   // Effects on the receiver.
-  if (MD->hasAttr())
+  if (hasAnyEnabledAttrOf(MD, MD->getReturnType()))
     Template->setReceiverEffect(ArgEffect(DecRef, ObjKind::ObjC));
 
   // Effects on the parameters.
   unsigned parm_idx = 0;
-  for (auto pi=MD->param_begin(), pe=MD->param_end();
-       pi != pe; ++pi, ++parm_idx) {
+  for (auto pi = MD->param_begin(), pe = MD->param_end(); pi != pe;
+       ++pi, ++parm_idx) {
     const ParmVarDecl *pd = *pi;
-    if (pd->hasAttr()) {
-      Template->addArg(AF, parm_idx, ArgEffect(DecRef, ObjKind::ObjC));
-    } else if (pd->hasAttr()) {
-      Template->addArg(AF, parm_idx, ArgEffect(DecRef, ObjKind::CF));
-    } else if (pd->hasAttr()) {
-      Template->addArg(AF, parm_idx, ArgEffect(DecRef, ObjKind::OS));
-    } else if (pd->hasAttr()) {
-      QualType PointeeTy = pd->getType()->getPointeeType();
-      if (!PointeeTy.isNull())
-        if (coreFoundation::isCFObjectRef(PointeeTy))
-          Template->addArg(AF, parm_idx,
-                           ArgEffect(RetainedOutParameter, ObjKind::CF));
-    } else if (pd->hasAttr()) {
-      QualType PointeeTy = pd->getType()->getPointeeType();
-      if (!PointeeTy.isNull())
-        if (coreFoundation::isCFObjectRef(PointeeTy))
-          Template->addArg(AF, parm_idx, ArgEffect(UnretainedOutParameter,
-                                                   ObjKind::CF));
+    QualType QT = pd->getType();
+    if (auto K =
+            hasAnyEnabledAttrOf(
+                pd, QT)) {
+      Template->addArg(AF, parm_idx, ArgEffect(DecRef, *K));
+    } else if (auto K = hasAnyEnabledAttrOf(pd, QT)) {
+      Template->addArg(AF, parm_idx, ArgEffect(RetainedOutParameter, *K));
+    } else if (auto K = hasAnyEnabledAttrOf(pd, QT)) {
+      Template->addArg(AF, parm_idx, ArgEffect(UnretainedOutParameter, *K));
     }
   }
-
   QualType RetTy = MD->getReturnType();
   if (Optional RetE = getRetEffectFromAnnotations(RetTy, MD))
     Template->setRetEffect(*RetE);
-- 
cgit v1.2.3


From 3c7cc149a65a6025c4dbc611426cc4c922c2a85d Mon Sep 17 00:00:00 2001
From: George Karpenkov 
Date: Thu, 10 Jan 2019 18:15:04 +0000
Subject: [analyzer] [RetainCountChecker] [NFC] Another minor cleanup

Differential Revision: https://reviews.llvm.org/D56224

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350863 91177308-0d34-0410-b5e6-96231b3b80d8
---
 .../StaticAnalyzer/Core/RetainSummaryManager.h     | 30 ++++++++++------------
 lib/StaticAnalyzer/Core/RetainSummaryManager.cpp   |  1 +
 2 files changed, 15 insertions(+), 16 deletions(-)

diff --git a/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h b/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
index 65648e44d4..04e5d6a0ba 100644
--- a/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
+++ b/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
@@ -38,17 +38,20 @@ namespace ento {
 
 /// Determines the object kind of a tracked object.
 enum class ObjKind {
-  /// Indicates that the tracked object is a CF object.  This is
-  /// important between GC and non-GC code.
+  /// Indicates that the tracked object is a CF object.
   CF,
+
   /// Indicates that the tracked object is an Objective-C object.
   ObjC,
+
   /// Indicates that the tracked object could be a CF or Objective-C object.
   AnyObj,
+
   /// Indicates that the tracked object is a generalized object.
   Generalized,
 
-  /// A descendant of OSObject.
+  /// Indicates that the tracking object is a descendant of a
+  /// referenced-counted OSObject, used in the Darwin kernel.
   OS
 };
 
@@ -60,20 +63,17 @@ enum ArgEffectKind {
   /// the referenced object.
   Autorelease,
 
-  /// The argument is treated as if an -dealloc message had been sent to
-  /// the referenced object.
+  /// The argument is treated as if the referenced object was deallocated.
   Dealloc,
 
-  /// The argument has its reference count decreased by 1.  This is as
-  /// if CFRelease has been called on the argument.
+  /// The argument has its reference count decreased by 1.
   DecRef,
 
   /// The argument has its reference count decreased by 1 to model
   /// a transferred bridge cast under ARC.
   DecRefBridgedTransferred,
 
-  /// The argument has its reference count increased by 1.  This is as
-  /// if CFRetain has been called on the argument.
+  /// The argument has its reference count increased by 1.
   IncRef,
 
   /// The argument is a pointer to a retain-counted object; on exit, the new
@@ -139,18 +139,19 @@ public:
     /// Indicates that no retain count information is tracked for
     /// the return value.
     NoRet,
+
     /// Indicates that the returned value is an owned (+1) symbol.
     OwnedSymbol,
+
     /// Indicates that the returned value is an object with retain count
     /// semantics but that it is not owned (+0).  This is the default
     /// for getters, etc.
     NotOwnedSymbol,
-    /// Indicates that the object is not owned and controlled by the
-    /// Garbage collector.
-    GCNotOwnedSymbol,
+
     /// Indicates that the return value is an owned object when the
     /// receiver is also a tracked object.
     OwnedWhenTrackedReceiver,
+
     // Treat this function as returning a non-tracked symbol even if
     // the function has been inlined. This is used where the call
     // site summary is more precise than the summary indirectly produced
@@ -158,7 +159,6 @@ public:
     NoRetHard
   };
 
-
 private:
   Kind K;
   ObjKind O;
@@ -192,9 +192,6 @@ public:
   static RetEffect MakeNotOwned(ObjKind o) {
     return RetEffect(NotOwnedSymbol, o);
   }
-  static RetEffect MakeGCNotOwned() {
-    return RetEffect(GCNotOwnedSymbol, ObjKind::ObjC);
-  }
   static RetEffect MakeNoRet() {
     return RetEffect(NoRet);
   }
@@ -372,6 +369,7 @@ public:
   ArgEffect getReceiverEffect() const { return Receiver; }
 
   /// \return the effect on the "this" receiver of the method call.
+  /// This is only meaningful if the summary applies to CXXMethodDecl*.
   ArgEffect getThisEffect() const { return This; }
 
   /// Set the effect of the method on "this".
diff --git a/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp b/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
index a0fe2fefde..d50601f524 100644
--- a/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
+++ b/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
@@ -38,6 +38,7 @@ constexpr static bool isOneOf() {
 
 namespace {
 
+/// Fake attribute class for RC* attributes.
 struct GeneralizedReturnsRetainedAttr {
   static bool classof(const Attr *A) {
     if (auto AA = dyn_cast(A))
-- 
cgit v1.2.3


From 9795d231a76be469687e236d7d3ff8526fd194b1 Mon Sep 17 00:00:00 2001
From: George Karpenkov 
Date: Thu, 10 Jan 2019 18:15:17 +0000
Subject: [analyzer] [RetainCountChecker] [NFC] Remove SummaryLog

The complicated machinery for passing the summary log around is actually
only used for one thing! To figure out whether the "dealloc" message was
sent.

Since I have tried to extend it for other uses and failed (it's actually
very hard to use), I think it's much better to simply use a tag and
remove the summary log altogether.

Differential Revision: https://reviews.llvm.org/D56228

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350864 91177308-0d34-0410-b5e6-96231b3b80d8
---
 .../RetainCountChecker/RetainCountChecker.cpp      | 82 ++++++----------------
 .../RetainCountChecker/RetainCountChecker.h        | 11 +--
 .../RetainCountChecker/RetainCountDiagnostics.cpp  | 47 ++++++-------
 .../RetainCountChecker/RetainCountDiagnostics.h    |  9 +--
 4 files changed, 46 insertions(+), 103 deletions(-)

diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
index 4e6fd8490d..28873a465f 100644
--- a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
@@ -414,42 +414,6 @@ void RetainCountChecker::checkPostCall(const CallEvent &Call,
   checkSummary(*Summ, Call, C);
 }
 
-void RetainCountChecker::checkEndAnalysis(ExplodedGraph &G, BugReporter &BR,
-                                          ExprEngine &Eng) const {
-  // FIXME: This is a hack to make sure the summary log gets cleared between
-  // analyses of different code bodies.
-  //
-  // Why is this necessary? Because a checker's lifetime is tied to a
-  // translation unit, but an ExplodedGraph's lifetime is just a code body.
-  // Once in a blue moon, a new ExplodedNode will have the same address as an
-  // old one with an associated summary, and the bug report visitor gets very
-  // confused. (To make things worse, the summary lifetime is currently also
-  // tied to a code body, so we get a crash instead of incorrect results.)
-  //
-  // Why is this a bad solution? Because if the lifetime of the ExplodedGraph
-  // changes, things will start going wrong again. Really the lifetime of this
-  // log needs to be tied to either the specific nodes in it or the entire
-  // ExplodedGraph, not to a specific part of the code being analyzed.
-  //
-  // (Also, having stateful local data means that the same checker can't be
-  // used from multiple threads, but a lot of checkers have incorrect
-  // assumptions about that anyway. So that wasn't a priority at the time of
-  // this fix.)
-  //
-  // This happens at the end of analysis, but bug reports are emitted /after/
-  // this point. So we can't just clear the summary log now. Instead, we mark
-  // that the next time we access the summary log, it should be cleared.
-
-  // If we never reset the summary log during /this/ code body analysis,
-  // there were no new summaries. There might still have been summaries from
-  // the /last/ analysis, so clear them out to make sure the bug report
-  // visitors don't get confused.
-  if (ShouldResetSummaryLog)
-    SummaryLog.clear();
-
-  ShouldResetSummaryLog = !SummaryLog.empty();
-}
-
 CFRefBug *
 RetainCountChecker::getLeakWithinFunctionBug(const LangOptions &LOpts) const {
   if (!leakWithinFunction)
@@ -609,6 +573,11 @@ void RetainCountChecker::checkSummary(const RetainSummary &Summ,
   SourceRange ErrorRange;
   SymbolRef ErrorSym = nullptr;
 
+  // Helper tag for providing diagnostics: indicate whether dealloc was sent
+  // at this location.
+  static CheckerProgramPointTag DeallocSentTag(this, DeallocTagDescription);
+  bool DeallocSent = false;
+
   for (unsigned idx = 0, e = CallOrMsg.getNumArgs(); idx != e; ++idx) {
     SVal V = CallOrMsg.getArgSVal(idx);
 
@@ -627,6 +596,8 @@ void RetainCountChecker::checkSummary(const RetainSummary &Summ,
           ErrorRange = CallOrMsg.getArgSourceRange(idx);
           ErrorSym = Sym;
           break;
+        } else if (Effect.getKind() == Dealloc) {
+          DeallocSent = true;
         }
       }
     }
@@ -644,6 +615,8 @@ void RetainCountChecker::checkSummary(const RetainSummary &Summ,
           if (hasErr) {
             ErrorRange = MsgInvocation->getOriginExpr()->getReceiverRange();
             ErrorSym = Sym;
+          } else if (Summ.getReceiverEffect().getKind() == Dealloc) {
+            DeallocSent = true;
           }
         }
       }
@@ -688,24 +661,10 @@ void RetainCountChecker::checkSummary(const RetainSummary &Summ,
       state = setRefBinding(state, Sym, *updatedRefVal);
   }
 
-  // This check is actually necessary; otherwise the statement builder thinks
-  // we've hit a previously-found path.
-  // Normally addTransition takes care of this, but we want the node pointer.
-  ExplodedNode *NewNode;
-  if (state == C.getState()) {
-    NewNode = C.getPredecessor();
+  if (DeallocSent) {
+    C.addTransition(state, C.getPredecessor(), &DeallocSentTag);
   } else {
-    NewNode = C.addTransition(state);
-  }
-
-  // Annotate the node with summary we used.
-  if (NewNode) {
-    // FIXME: This is ugly. See checkEndAnalysis for why it's necessary.
-    if (ShouldResetSummaryLog) {
-      SummaryLog.clear();
-      ShouldResetSummaryLog = false;
-    }
-    SummaryLog[NewNode] = &Summ;
+    C.addTransition(state);
   }
 }
 
@@ -744,7 +703,7 @@ ProgramStateRef RetainCountChecker::updateSymbol(ProgramStateRef state,
       llvm_unreachable("Applies to pointer-to-pointer parameters, which should "
                        "not have ref state.");
 
-    case Dealloc:
+    case Dealloc: // NB. we only need to add a note in a non-error case.
       switch (V.getKind()) {
         default:
           llvm_unreachable("Invalid RefVal state for an explicit dealloc.");
@@ -880,7 +839,7 @@ void RetainCountChecker::processNonLeakError(ProgramStateRef St,
 
   assert(BT);
   auto report = llvm::make_unique(
-      *BT, C.getASTContext().getLangOpts(), SummaryLog, N, Sym);
+      *BT, C.getASTContext().getLangOpts(), N, Sym);
   report->addRange(ErrorRange);
   C.emitReport(std::move(report));
 }
@@ -1084,7 +1043,7 @@ ExplodedNode * RetainCountChecker::checkReturnWithRetEffect(const ReturnStmt *S,
         if (N) {
           const LangOptions &LOpts = C.getASTContext().getLangOpts();
           auto R = llvm::make_unique(
-              *getLeakAtReturnBug(LOpts), LOpts, SummaryLog, N, Sym, C);
+              *getLeakAtReturnBug(LOpts), LOpts, N, Sym, C);
           C.emitReport(std::move(R));
         }
         return N;
@@ -1112,8 +1071,7 @@ ExplodedNode * RetainCountChecker::checkReturnWithRetEffect(const ReturnStmt *S,
             returnNotOwnedForOwned.reset(new ReturnedNotOwnedForOwned(this));
 
           auto R = llvm::make_unique(
-              *returnNotOwnedForOwned, C.getASTContext().getLangOpts(),
-              SummaryLog, N, Sym);
+              *returnNotOwnedForOwned, C.getASTContext().getLangOpts(), N, Sym);
           C.emitReport(std::move(R));
         }
         return N;
@@ -1316,8 +1274,8 @@ RetainCountChecker::handleAutoreleaseCounts(ProgramStateRef state,
       overAutorelease.reset(new OverAutorelease(this));
 
     const LangOptions &LOpts = Ctx.getASTContext().getLangOpts();
-    auto R = llvm::make_unique(*overAutorelease, LOpts, SummaryLog,
-                                            N, Sym, os.str());
+    auto R = llvm::make_unique(*overAutorelease, LOpts, N, Sym,
+                                            os.str());
     Ctx.emitReport(std::move(R));
   }
 
@@ -1369,8 +1327,8 @@ RetainCountChecker::processLeaks(ProgramStateRef state,
                           : getLeakAtReturnBug(LOpts);
       assert(BT && "BugType not initialized.");
 
-      Ctx.emitReport(llvm::make_unique(
-          *BT, LOpts, SummaryLog, N, *I, Ctx));
+      Ctx.emitReport(
+          llvm::make_unique(*BT, LOpts, N, *I, Ctx));
     }
   }
 
diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h
index d8bbe6fcdd..0c233f72dd 100644
--- a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h
+++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h
@@ -239,7 +239,6 @@ public:
 class RetainCountChecker
   : public Checker< check::Bind,
                     check::DeadSymbols,
-                    check::EndAnalysis,
                     check::BeginFunction,
                     check::EndFunction,
                     check::PostStmt,
@@ -263,11 +262,8 @@ class RetainCountChecker
   mutable SymbolTagMap DeadSymbolTags;
 
   mutable std::unique_ptr Summaries;
-  mutable SummaryLogTy SummaryLog;
-
-  mutable bool ShouldResetSummaryLog;
-
 public:
+  static constexpr const char *DeallocTagDescription = "DeallocSent";
 
   /// Track Objective-C and CoreFoundation objects.
   bool TrackObjCAndCFObjects = false;
@@ -275,13 +271,10 @@ public:
   /// Track sublcasses of OSObject.
   bool TrackOSObjects = false;
 
-  RetainCountChecker() : ShouldResetSummaryLog(false) {}
+  RetainCountChecker() {}
 
   ~RetainCountChecker() override { DeleteContainerSeconds(DeadSymbolTags); }
 
-  void checkEndAnalysis(ExplodedGraph &G, BugReporter &BR,
-                        ExprEngine &Eng) const;
-
   CFRefBug *getLeakWithinFunctionBug(const LangOptions &LOpts) const;
 
   CFRefBug *getLeakAtReturnBug(const LangOptions &LOpts) const;
diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
index 5a687ef8d1..0f01d9a995 100644
--- a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
+++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
@@ -43,14 +43,12 @@ static std::string getPrettyTypeName(QualType QT) {
 /// return whether the note should be generated.
 static bool shouldGenerateNote(llvm::raw_string_ostream &os,
                                const RefVal *PrevT, const RefVal &CurrV,
-                               SmallVector &AEffects) {
+                               bool DeallocSent) {
   // Get the previous type state.
   RefVal PrevV = *PrevT;
 
   // Specially handle -dealloc.
-  if (std::find_if(AEffects.begin(), AEffects.end(), [](ArgEffect &E) {
-        return E.getKind() == Dealloc;
-      }) != AEffects.end()) {
+  if (DeallocSent) {
     // Determine if the object's reference count was pushed to zero.
     assert(!PrevV.hasSameState(CurrV) && "The state should have changed.");
     // We may not have transitioned to 'release' if we hit an error.
@@ -194,11 +192,9 @@ namespace retaincountchecker {
 class CFRefReportVisitor : public BugReporterVisitor {
 protected:
   SymbolRef Sym;
-  const SummaryLogTy &SummaryLog;
 
 public:
-  CFRefReportVisitor(SymbolRef sym, const SummaryLogTy &log)
-      : Sym(sym), SummaryLog(log) {}
+  CFRefReportVisitor(SymbolRef sym) : Sym(sym) {}
 
   void Profile(llvm::FoldingSetNodeID &ID) const override {
     static int x = 0;
@@ -217,9 +213,7 @@ public:
 
 class CFRefLeakReportVisitor : public CFRefReportVisitor {
 public:
-  CFRefLeakReportVisitor(SymbolRef sym,
-                         const SummaryLogTy &log)
-     : CFRefReportVisitor(sym, log) {}
+  CFRefLeakReportVisitor(SymbolRef sym) : CFRefReportVisitor(sym) {}
 
   std::shared_ptr getEndPath(BugReporterContext &BRC,
                                                   const ExplodedNode *N,
@@ -311,6 +305,7 @@ annotateConsumedSummaryMismatch(const ExplodedNode *N,
 std::shared_ptr
 CFRefReportVisitor::VisitNode(const ExplodedNode *N,
                               BugReporterContext &BRC, BugReport &BR) {
+
   const SourceManager &SM = BRC.getSourceManager();
   CallEventManager &CEMgr = BRC.getStateManager().getCallEventManager();
   if (auto CE = N->getLocationAs())
@@ -383,9 +378,11 @@ CFRefReportVisitor::VisitNode(const ExplodedNode *N,
 
   // Gather up the effects that were performed on the object at this
   // program point
-  SmallVector AEffects;
-  const ExplodedNode *OrigNode = BRC.getNodeResolver().getOriginalNode(N);
-  if (const RetainSummary *Summ = SummaryLog.lookup(OrigNode)) {
+  bool DeallocSent = false;
+
+  if (N->getLocation().getTag() &&
+      N->getLocation().getTag()->getTagDescription().contains(
+          RetainCountChecker::DeallocTagDescription)) {
     // We only have summaries attached to nodes after evaluating CallExpr and
     // ObjCMessageExprs.
     const Stmt *S = N->getLocation().castAs().getStmt();
@@ -403,20 +400,20 @@ CFRefReportVisitor::VisitNode(const ExplodedNode *N,
           continue;
 
         // We have an argument.  Get the effect!
-        AEffects.push_back(Summ->getArg(i));
+        DeallocSent = true;
       }
     } else if (const ObjCMessageExpr *ME = dyn_cast(S)) {
       if (const Expr *receiver = ME->getInstanceReceiver()) {
         if (CurrSt->getSValAsScalarOrLoc(receiver, LCtx)
               .getAsLocSymbol() == Sym) {
           // The symbol we are tracking is the receiver.
-          AEffects.push_back(Summ->getReceiverEffect());
+          DeallocSent = true;
         }
       }
     }
   }
 
-  if (!shouldGenerateNote(os, PrevT, CurrV, AEffects))
+  if (!shouldGenerateNote(os, PrevT, CurrV, DeallocSent))
     return nullptr;
 
   if (os.str().empty())
@@ -639,20 +636,18 @@ CFRefLeakReportVisitor::getEndPath(BugReporterContext &BRC,
   return std::make_shared(L, os.str());
 }
 
-CFRefReport::CFRefReport(CFRefBug &D, const LangOptions &LOpts,
-                         const SummaryLogTy &Log, ExplodedNode *n,
+CFRefReport::CFRefReport(CFRefBug &D, const LangOptions &LOpts, ExplodedNode *n,
                          SymbolRef sym, bool registerVisitor)
     : BugReport(D, D.getDescription(), n), Sym(sym) {
   if (registerVisitor)
-    addVisitor(llvm::make_unique(sym, Log));
+    addVisitor(llvm::make_unique(sym));
 }
 
-CFRefReport::CFRefReport(CFRefBug &D, const LangOptions &LOpts,
-                         const SummaryLogTy &Log, ExplodedNode *n,
+CFRefReport::CFRefReport(CFRefBug &D, const LangOptions &LOpts, ExplodedNode *n,
                          SymbolRef sym, StringRef endText)
     : BugReport(D, D.getDescription(), endText, n) {
 
-  addVisitor(llvm::make_unique(sym, Log));
+  addVisitor(llvm::make_unique(sym));
 }
 
 void CFRefLeakReport::deriveParamLocation(CheckerContext &Ctx, SymbolRef sym) {
@@ -665,7 +660,8 @@ void CFRefLeakReport::deriveParamLocation(CheckerContext &Ctx, SymbolRef sym) {
   if (Region) {
     const Decl *PDecl = Region->getDecl();
     if (PDecl && isa(PDecl)) {
-      PathDiagnosticLocation ParamLocation = PathDiagnosticLocation::create(PDecl, SMgr);
+      PathDiagnosticLocation ParamLocation =
+          PathDiagnosticLocation::create(PDecl, SMgr);
       Location = ParamLocation;
       UniqueingLocation = ParamLocation;
       UniqueingDecl = Ctx.getLocationContext()->getDecl();
@@ -733,10 +729,9 @@ void CFRefLeakReport::createDescription(CheckerContext &Ctx) {
 }
 
 CFRefLeakReport::CFRefLeakReport(CFRefBug &D, const LangOptions &LOpts,
-                                 const SummaryLogTy &Log,
                                  ExplodedNode *n, SymbolRef sym,
                                  CheckerContext &Ctx)
-  : CFRefReport(D, LOpts, Log, n, sym, false) {
+  : CFRefReport(D, LOpts, n, sym, false) {
 
   deriveAllocLocation(Ctx, sym);
   if (!AllocBinding)
@@ -744,5 +739,5 @@ CFRefLeakReport::CFRefLeakReport(CFRefBug &D, const LangOptions &LOpts,
 
   createDescription(Ctx);
 
-  addVisitor(llvm::make_unique(sym, Log));
+  addVisitor(llvm::make_unique(sym));
 }
diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h
index a30f62ac34..f27027ab62 100644
--- a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h
+++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h
@@ -37,20 +37,17 @@ public:
   virtual bool isLeak() const { return false; }
 };
 
-typedef ::llvm::DenseMap
-  SummaryLogTy;
-
 class CFRefReport : public BugReport {
 protected:
   SymbolRef Sym;
 
 public:
   CFRefReport(CFRefBug &D, const LangOptions &LOpts,
-              const SummaryLogTy &Log, ExplodedNode *n, SymbolRef sym,
+              ExplodedNode *n, SymbolRef sym,
               bool registerVisitor = true);
 
   CFRefReport(CFRefBug &D, const LangOptions &LOpts,
-              const SummaryLogTy &Log, ExplodedNode *n, SymbolRef sym,
+              ExplodedNode *n, SymbolRef sym,
               StringRef endText);
 
   llvm::iterator_range getRanges() override {
@@ -75,7 +72,7 @@ class CFRefLeakReport : public CFRefReport {
 
 public:
   CFRefLeakReport(CFRefBug &D, const LangOptions &LOpts,
-                  const SummaryLogTy &Log, ExplodedNode *n, SymbolRef sym,
+                  ExplodedNode *n, SymbolRef sym,
                   CheckerContext &Ctx);
 
   PathDiagnosticLocation getLocation(const SourceManager &SM) const override {
-- 
cgit v1.2.3


From a805cd9c50f196efef7207301d09b069501dcc49 Mon Sep 17 00:00:00 2001
From: George Karpenkov 
Date: Thu, 10 Jan 2019 18:15:30 +0000
Subject: [analyzer] [NFC] Reduce redundancy in RetainSummaryManager by using a
 function

Differential Revision: https://reviews.llvm.org/D56282

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350865 91177308-0d34-0410-b5e6-96231b3b80d8
---
 .../StaticAnalyzer/Core/RetainSummaryManager.h     |  7 +++---
 lib/StaticAnalyzer/Core/RetainSummaryManager.cpp   | 28 +++++++---------------
 2 files changed, 11 insertions(+), 24 deletions(-)

diff --git a/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h b/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
index 04e5d6a0ba..62b8fa6cf8 100644
--- a/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
+++ b/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
@@ -641,10 +641,9 @@ class RetainSummaryManager {
   /// Apply the annotation of {@code pd} in function {@code FD}
   /// to the resulting summary stored in out-parameter {@code Template}.
   /// \return whether an annotation was applied.
-  bool applyFunctionParamAnnotationEffect(const ParmVarDecl *pd,
-                                        unsigned parm_idx,
-                                        const FunctionDecl *FD,
-                                        RetainSummaryTemplate &Template);
+  bool applyParamAnnotationEffect(const ParmVarDecl *pd, unsigned parm_idx,
+                                  const NamedDecl *FD,
+                                  RetainSummaryTemplate &Template);
 
 public:
   RetainSummaryManager(ASTContext &ctx,
diff --git a/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp b/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
index d50601f524..bc43b8f897 100644
--- a/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
+++ b/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
@@ -811,8 +811,8 @@ RetainSummaryManager::getRetEffectFromAnnotations(QualType RetTy,
   return None;
 }
 
-bool RetainSummaryManager::applyFunctionParamAnnotationEffect(
-    const ParmVarDecl *pd, unsigned parm_idx, const FunctionDecl *FD,
+bool RetainSummaryManager::applyParamAnnotationEffect(
+    const ParmVarDecl *pd, unsigned parm_idx, const NamedDecl *FD,
     RetainSummaryTemplate &Template) {
   QualType QT = pd->getType();
   if (auto K =
@@ -832,7 +832,7 @@ bool RetainSummaryManager::applyFunctionParamAnnotationEffect(
     if (const auto *MD = dyn_cast(FD)) {
       for (const auto *OD : MD->overridden_methods()) {
         const ParmVarDecl *OP = OD->parameters()[parm_idx];
-        if (applyFunctionParamAnnotationEffect(OP, parm_idx, OD, Template))
+        if (applyParamAnnotationEffect(OP, parm_idx, OD, Template))
           return true;
       }
     }
@@ -853,10 +853,8 @@ RetainSummaryManager::updateSummaryFromAnnotations(const RetainSummary *&Summ,
   // Effects on the parameters.
   unsigned parm_idx = 0;
   for (auto pi = FD->param_begin(),
-         pe = FD->param_end(); pi != pe; ++pi, ++parm_idx) {
-    const ParmVarDecl *pd = *pi;
-    applyFunctionParamAnnotationEffect(pd, parm_idx, FD, Template);
-  }
+         pe = FD->param_end(); pi != pe; ++pi, ++parm_idx)
+    applyParamAnnotationEffect(*pi, parm_idx, FD, Template);
 
   QualType RetTy = FD->getReturnType();
   if (Optional RetE = getRetEffectFromAnnotations(RetTy, FD))
@@ -882,19 +880,9 @@ RetainSummaryManager::updateSummaryFromAnnotations(const RetainSummary *&Summ,
   // Effects on the parameters.
   unsigned parm_idx = 0;
   for (auto pi = MD->param_begin(), pe = MD->param_end(); pi != pe;
-       ++pi, ++parm_idx) {
-    const ParmVarDecl *pd = *pi;
-    QualType QT = pd->getType();
-    if (auto K =
-            hasAnyEnabledAttrOf(
-                pd, QT)) {
-      Template->addArg(AF, parm_idx, ArgEffect(DecRef, *K));
-    } else if (auto K = hasAnyEnabledAttrOf(pd, QT)) {
-      Template->addArg(AF, parm_idx, ArgEffect(RetainedOutParameter, *K));
-    } else if (auto K = hasAnyEnabledAttrOf(pd, QT)) {
-      Template->addArg(AF, parm_idx, ArgEffect(UnretainedOutParameter, *K));
-    }
-  }
+       ++pi, ++parm_idx)
+    applyParamAnnotationEffect(*pi, parm_idx, MD, Template);
+
   QualType RetTy = MD->getReturnType();
   if (Optional RetE = getRetEffectFromAnnotations(RetTy, MD))
     Template->setRetEffect(*RetE);
-- 
cgit v1.2.3


From 386cde02aee5b29319c3f0e6d0447ad6df5ce29d Mon Sep 17 00:00:00 2001
From: George Karpenkov 
Date: Thu, 10 Jan 2019 18:15:44 +0000
Subject: [analyzer] [NFC] Reverse the argument order for "diff" in tests

The current argument order has "expected" and "actual" the wrong way around,
so that the diff shows the change from expected to actual, not from actual to expected.

Namely, if the expected diagnostics contains the string "foo", but the analyzer emits "bar",
we really want to see:

```
- foo
+ bar
```

not

```
- bar
+ foo
```

since adapting to most changes would require applying that diff to the expected output.

Differential Revision: https://reviews.llvm.org/D56340

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350866 91177308-0d34-0410-b5e6-96231b3b80d8
---
 test/Analysis/NewDelete-path-notes.cpp                                | 2 +-
 test/Analysis/conditional-path-notes.c                                | 2 +-
 test/Analysis/copypaste/plist-diagnostics-notes-as-events.cpp         | 2 +-
 test/Analysis/copypaste/plist-diagnostics.cpp                         | 2 +-
 test/Analysis/cxx-for-range.cpp                                       | 2 +-
 .../Inputs/expected-sarif/sarif-diagnostics-taint-test.c.sarif        | 2 +-
 .../Inputs/expected-sarif/sarif-multi-diagnostic-test.c.sarif         | 2 +-
 test/Analysis/diagnostics/deref-track-symbolic-region.c               | 2 +-
 test/Analysis/diagnostics/report-issues-within-main-file.cpp          | 2 +-
 test/Analysis/diagnostics/sarif-diagnostics-taint-test.c              | 2 +-
 test/Analysis/diagnostics/sarif-multi-diagnostic-test.c               | 2 +-
 test/Analysis/diagnostics/undef-value-caller.c                        | 2 +-
 test/Analysis/diagnostics/undef-value-param.c                         | 2 +-
 test/Analysis/diagnostics/undef-value-param.m                         | 2 +-
 test/Analysis/edges-new.mm                                            | 2 +-
 test/Analysis/generics.m                                              | 2 +-
 test/Analysis/inline-plist.c                                          | 2 +-
 test/Analysis/inline-unique-reports.c                                 | 2 +-
 test/Analysis/inlining/eager-reclamation-path-notes.c                 | 2 +-
 test/Analysis/inlining/eager-reclamation-path-notes.cpp               | 2 +-
 test/Analysis/inlining/path-notes.c                                   | 2 +-
 test/Analysis/inlining/path-notes.cpp                                 | 2 +-
 test/Analysis/inlining/path-notes.m                                   | 2 +-
 test/Analysis/lit.local.cfg                                           | 4 ++--
 test/Analysis/method-call-path-notes.cpp                              | 2 +-
 test/Analysis/model-file.cpp                                          | 2 +-
 test/Analysis/null-deref-path-notes.m                                 | 2 +-
 test/Analysis/nullability-notes.m                                     | 2 +-
 test/Analysis/objc-arc.m                                              | 2 +-
 test/Analysis/plist-macros-with-expansion.cpp                         | 2 +-
 test/Analysis/plist-macros.cpp                                        | 2 +-
 test/Analysis/plist-output-alternate.m                                | 2 +-
 test/Analysis/plist-output.m                                          | 2 +-
 test/Analysis/retain-release-path-notes.m                             | 2 +-
 test/Analysis/unix-fns.c                                              | 2 +-
 35 files changed, 36 insertions(+), 36 deletions(-)

diff --git a/test/Analysis/NewDelete-path-notes.cpp b/test/Analysis/NewDelete-path-notes.cpp
index d9fe1976b8..2195b9d42a 100644
--- a/test/Analysis/NewDelete-path-notes.cpp
+++ b/test/Analysis/NewDelete-path-notes.cpp
@@ -1,7 +1,7 @@
 // RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus.NewDelete,unix.Malloc -analyzer-output=text -verify %s
 // RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus.NewDelete,unix.Malloc -analyzer-output=text -analyzer-config c++-allocator-inlining=true -verify %s
 // RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus.NewDelete,unix.Malloc -analyzer-output=plist %s -o %t.plist
-// RUN: cat %t.plist | %diff_plist %S/Inputs/expected-plists/NewDelete-path-notes.cpp.plist
+// RUN: cat %t.plist | %diff_plist %S/Inputs/expected-plists/NewDelete-path-notes.cpp.plist -
 
 void test() {
   int *p = new int;
diff --git a/test/Analysis/conditional-path-notes.c b/test/Analysis/conditional-path-notes.c
index 77744e3998..fb2dd9f2ca 100644
--- a/test/Analysis/conditional-path-notes.c
+++ b/test/Analysis/conditional-path-notes.c
@@ -1,6 +1,6 @@
 // RUN: %clang_analyze_cc1 %s -analyzer-checker=core.NullDereference -analyzer-output=text -verify
 // RUN: %clang_analyze_cc1 %s -analyzer-checker=core.NullDereference -analyzer-output=plist -o %t
-// RUN: cat %t | %diff_plist %S/Inputs/expected-plists/conditional-path-notes.c.plist
+// RUN: cat %t | %diff_plist %S/Inputs/expected-plists/conditional-path-notes.c.plist -
 
 void testCondOp(int *p) {
   int *x = p ? p : p;
diff --git a/test/Analysis/copypaste/plist-diagnostics-notes-as-events.cpp b/test/Analysis/copypaste/plist-diagnostics-notes-as-events.cpp
index 0a61c6c776..301a30b1c1 100644
--- a/test/Analysis/copypaste/plist-diagnostics-notes-as-events.cpp
+++ b/test/Analysis/copypaste/plist-diagnostics-notes-as-events.cpp
@@ -1,5 +1,5 @@
 // RUN: %clang_analyze_cc1 -analyzer-output=plist -analyzer-config notes-as-events=true -o %t.plist -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:MinimumCloneComplexity=10 -verify %s
-// RUN: cat %t.plist | %diff_plist %S/Inputs/expected-plists/plist-diagnostics-notes-as-events.cpp.plist
+// RUN: cat %t.plist | %diff_plist %S/Inputs/expected-plists/plist-diagnostics-notes-as-events.cpp.plist -
 
 void log();
 
diff --git a/test/Analysis/copypaste/plist-diagnostics.cpp b/test/Analysis/copypaste/plist-diagnostics.cpp
index 90b53e43f4..c5ea2ae20e 100644
--- a/test/Analysis/copypaste/plist-diagnostics.cpp
+++ b/test/Analysis/copypaste/plist-diagnostics.cpp
@@ -1,5 +1,5 @@
 // RUN: %clang_analyze_cc1 -analyzer-output=plist -o %t.plist -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:MinimumCloneComplexity=10 -verify %s
-// RUN: cat %t.plist | %diff_plist %S/Inputs/expected-plists/plist-diagnostics.cpp.plist
+// RUN: cat %t.plist | %diff_plist %S/Inputs/expected-plists/plist-diagnostics.cpp.plist -
 
 void log();
 
diff --git a/test/Analysis/cxx-for-range.cpp b/test/Analysis/cxx-for-range.cpp
index 8bcad89b6d..4e5fb0ea7f 100644
--- a/test/Analysis/cxx-for-range.cpp
+++ b/test/Analysis/cxx-for-range.cpp
@@ -1,5 +1,5 @@
 // RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core -analyzer-output=plist-multi-file -o %t.plist -verify -analyzer-config eagerly-assume=false %s
-// RUN: cat %t.plist | %diff_plist %S/Inputs/expected-plists/cxx-for-range.cpp.plist
+// RUN: cat %t.plist | %diff_plist %S/Inputs/expected-plists/cxx-for-range.cpp.plist -
 
 extern void work();
 
diff --git a/test/Analysis/diagnostics/Inputs/expected-sarif/sarif-diagnostics-taint-test.c.sarif b/test/Analysis/diagnostics/Inputs/expected-sarif/sarif-diagnostics-taint-test.c.sarif
index cdf4a2daa2..97fe4d7bee 100644
--- a/test/Analysis/diagnostics/Inputs/expected-sarif/sarif-diagnostics-taint-test.c.sarif
+++ b/test/Analysis/diagnostics/Inputs/expected-sarif/sarif-diagnostics-taint-test.c.sarif
@@ -7,7 +7,7 @@
           "fileLocation": {
             "uri": "file:sarif-diagnostics-taint-test.c"
           },
-          "length": 413,
+          "length": 415,
           "mimeType": "text/plain",
           "roles": [
             "resultFile"
diff --git a/test/Analysis/diagnostics/Inputs/expected-sarif/sarif-multi-diagnostic-test.c.sarif b/test/Analysis/diagnostics/Inputs/expected-sarif/sarif-multi-diagnostic-test.c.sarif
index 68e23642d3..8bd8c0adf2 100644
--- a/test/Analysis/diagnostics/Inputs/expected-sarif/sarif-multi-diagnostic-test.c.sarif
+++ b/test/Analysis/diagnostics/Inputs/expected-sarif/sarif-multi-diagnostic-test.c.sarif
@@ -7,7 +7,7 @@
           "fileLocation": {
             "uri": "file:sarif-multi-diagnostic-test.c"
           },
-          "length": 665,
+          "length": 667,
           "mimeType": "text/plain",
           "roles": [
             "resultFile"
diff --git a/test/Analysis/diagnostics/deref-track-symbolic-region.c b/test/Analysis/diagnostics/deref-track-symbolic-region.c
index c8e3583e34..63d0971b85 100644
--- a/test/Analysis/diagnostics/deref-track-symbolic-region.c
+++ b/test/Analysis/diagnostics/deref-track-symbolic-region.c
@@ -1,6 +1,6 @@
 // RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=text -verify %s
 // RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=plist-multi-file  %s -o %t.plist
-// RUN: cat %t.plist | %diff_plist %S/Inputs/expected-plists/deref-track-symbolic-region.c.plist
+// RUN: cat %t.plist | %diff_plist %S/Inputs/expected-plists/deref-track-symbolic-region.c.plist -
 
 struct S {
   int *x;
diff --git a/test/Analysis/diagnostics/report-issues-within-main-file.cpp b/test/Analysis/diagnostics/report-issues-within-main-file.cpp
index 1feef43a9d..f166e311c5 100644
--- a/test/Analysis/diagnostics/report-issues-within-main-file.cpp
+++ b/test/Analysis/diagnostics/report-issues-within-main-file.cpp
@@ -1,5 +1,5 @@
 // RUN: %clang_analyze_cc1 -analyzer-checker=core,unix -analyzer-output=plist-multi-file -analyzer-config report-in-main-source-file=true %s -o %t.plist
-// RUN: cat %t.plist | %diff_plist %S/Inputs/expected-plists/report-issues-within-main-file.cpp.plist
+// RUN: cat %t.plist | %diff_plist %S/Inputs/expected-plists/report-issues-within-main-file.cpp.plist -
 #include "Inputs/include/report-issues-within-main-file.h"
 
 void mainPlusHeader() {
diff --git a/test/Analysis/diagnostics/sarif-diagnostics-taint-test.c b/test/Analysis/diagnostics/sarif-diagnostics-taint-test.c
index 75defbd2fb..37ddc9df6a 100644
--- a/test/Analysis/diagnostics/sarif-diagnostics-taint-test.c
+++ b/test/Analysis/diagnostics/sarif-diagnostics-taint-test.c
@@ -1,4 +1,4 @@
-// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.security.taint,debug.TaintTest %s -verify -analyzer-output=sarif -o - | %diff_sarif %S/Inputs/expected-sarif/sarif-diagnostics-taint-test.c.sarif
+// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.security.taint,debug.TaintTest %s -verify -analyzer-output=sarif -o - | %diff_sarif %S/Inputs/expected-sarif/sarif-diagnostics-taint-test.c.sarif -
 #include "../Inputs/system-header-simulator.h"
 
 int atoi(const char *nptr);
diff --git a/test/Analysis/diagnostics/sarif-multi-diagnostic-test.c b/test/Analysis/diagnostics/sarif-multi-diagnostic-test.c
index 481e3a5814..459128a05f 100644
--- a/test/Analysis/diagnostics/sarif-multi-diagnostic-test.c
+++ b/test/Analysis/diagnostics/sarif-multi-diagnostic-test.c
@@ -1,4 +1,4 @@
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.security.taint,debug.TaintTest %s -verify -analyzer-output=sarif -o - | %diff_sarif %S/Inputs/expected-sarif/sarif-multi-diagnostic-test.c.sarif
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.security.taint,debug.TaintTest %s -verify -analyzer-output=sarif -o - | %diff_sarif %S/Inputs/expected-sarif/sarif-multi-diagnostic-test.c.sarif -
 #include "../Inputs/system-header-simulator.h"
 
 int atoi(const char *nptr);
diff --git a/test/Analysis/diagnostics/undef-value-caller.c b/test/Analysis/diagnostics/undef-value-caller.c
index 0beefd6e53..d537f726f8 100644
--- a/test/Analysis/diagnostics/undef-value-caller.c
+++ b/test/Analysis/diagnostics/undef-value-caller.c
@@ -1,5 +1,5 @@
 // RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=plist -o %t %s
-// RUN: cat %t | %diff_plist %S/Inputs/expected-plists/undef-value-caller.c.plist
+// RUN: cat %t | %diff_plist %S/Inputs/expected-plists/undef-value-caller.c.plist -
 
 #include "undef-value-callee.h"
 
diff --git a/test/Analysis/diagnostics/undef-value-param.c b/test/Analysis/diagnostics/undef-value-param.c
index 8df44141c8..de128dafc4 100644
--- a/test/Analysis/diagnostics/undef-value-param.c
+++ b/test/Analysis/diagnostics/undef-value-param.c
@@ -1,6 +1,6 @@
 // RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=text -verify %s
 // RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=plist-multi-file  %s -o %t.plist
-// RUN: cat %t.plist | %diff_plist %S/Inputs/expected-plists/undef-value-param.c.plist
+// RUN: cat %t.plist | %diff_plist %S/Inputs/expected-plists/undef-value-param.c.plist -
 
 void foo_irrelevant(int c) {
     if (c)
diff --git a/test/Analysis/diagnostics/undef-value-param.m b/test/Analysis/diagnostics/undef-value-param.m
index 11276fa27e..5dfd9f8216 100644
--- a/test/Analysis/diagnostics/undef-value-param.m
+++ b/test/Analysis/diagnostics/undef-value-param.m
@@ -1,6 +1,6 @@
 // RUN: %clang_analyze_cc1 -analyzer-checker=core,osx -analyzer-output=text -verify %s
 // RUN: %clang_analyze_cc1 -analyzer-checker=core,osx -analyzer-output=plist-multi-file %s -o %t.plist
-// RUN: cat %t.plist | %diff_plist %S/Inputs/expected-plists/undef-value-param.m.plist
+// RUN: cat %t.plist | %diff_plist %S/Inputs/expected-plists/undef-value-param.m.plist -
 
 typedef signed char BOOL;
 @protocol NSObject  - (BOOL)isEqual:(id)object; @end
diff --git a/test/Analysis/edges-new.mm b/test/Analysis/edges-new.mm
index 4a5ecd897e..5a58850d06 100644
--- a/test/Analysis/edges-new.mm
+++ b/test/Analysis/edges-new.mm
@@ -1,5 +1,5 @@
 // RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,deadcode.DeadStores,osx.cocoa.RetainCount,unix.Malloc,unix.MismatchedDeallocator -analyzer-output=plist -o %t -w %s
-// RUN: cat %t | %diff_plist %S/Inputs/expected-plists/edges-new.mm.plist
+// RUN: cat %t | %diff_plist %S/Inputs/expected-plists/edges-new.mm.plist -
 
 //===----------------------------------------------------------------------===//
 // Forward declarations (from headers).
diff --git a/test/Analysis/generics.m b/test/Analysis/generics.m
index 00b0d0ae3f..1d6fa84a9c 100644
--- a/test/Analysis/generics.m
+++ b/test/Analysis/generics.m
@@ -1,6 +1,6 @@
 // RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.ObjCGenerics,alpha.core.DynamicTypeChecker -verify -Wno-objc-method-access %s
 // RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.ObjCGenerics,alpha.core.DynamicTypeChecker -verify -Wno-objc-method-access %s -analyzer-output=plist -o %t.plist
-// RUN: cat %t.plist | %diff_plist %S/Inputs/expected-plists/generics.m.plist
+// RUN: cat %t.plist | %diff_plist %S/Inputs/expected-plists/generics.m.plist -
 
 #if !__has_feature(objc_generics)
 #  error Compiler does not support Objective-C generics?
diff --git a/test/Analysis/inline-plist.c b/test/Analysis/inline-plist.c
index bac1a0d31c..b3fb554da7 100644
--- a/test/Analysis/inline-plist.c
+++ b/test/Analysis/inline-plist.c
@@ -1,6 +1,6 @@
 // RUN: %clang_analyze_cc1 %s -analyzer-checker=core.NullDereference,core.DivideZero -fblocks -analyzer-output=text -analyzer-config suppress-null-return-paths=false -verify -analyzer-config eagerly-assume=false %s
 // RUN: %clang_analyze_cc1 -analyzer-config eagerly-assume=false %s -analyzer-checker=core.NullDereference,core.DivideZero -fblocks -analyzer-output=plist -analyzer-config suppress-null-return-paths=false -o %t
-// RUN: cat %t | %diff_plist %S/Inputs/expected-plists/inline-plist.c.plist
+// RUN: cat %t | %diff_plist %S/Inputs/expected-plists/inline-plist.c.plist -
 
 // 
 void mmm(int y) {
diff --git a/test/Analysis/inline-unique-reports.c b/test/Analysis/inline-unique-reports.c
index b01dde268f..94289a1e8d 100644
--- a/test/Analysis/inline-unique-reports.c
+++ b/test/Analysis/inline-unique-reports.c
@@ -1,5 +1,5 @@
 // RUN: %clang_analyze_cc1 %s -analyzer-checker=core.NullDereference -analyzer-output=plist -o %t > /dev/null 2>&1
-// RUN: cat %t | %diff_plist %S/Inputs/expected-plists/inline-unique-reports.c.plist
+// RUN: cat %t | %diff_plist %S/Inputs/expected-plists/inline-unique-reports.c.plist -
 
 static inline bug(int *p) {
   *p = 0xDEADBEEF;
diff --git a/test/Analysis/inlining/eager-reclamation-path-notes.c b/test/Analysis/inlining/eager-reclamation-path-notes.c
index 3aaa8d0682..8dfd14dd34 100644
--- a/test/Analysis/inlining/eager-reclamation-path-notes.c
+++ b/test/Analysis/inlining/eager-reclamation-path-notes.c
@@ -1,6 +1,6 @@
 // RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=text -analyzer-config graph-trim-interval=5 -verify %s
 // RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=plist-multi-file -analyzer-config graph-trim-interval=5 %s -o %t.plist
-// RUN: cat %t.plist | %diff_plist %S/Inputs/expected-plists/eager-reclamation-path-notes.c.plist
+// RUN: cat %t.plist | %diff_plist %S/Inputs/expected-plists/eager-reclamation-path-notes.c.plist -
 
 void use(int *ptr, int val) {
   *ptr = val; // expected-warning {{Dereference of null pointer (loaded from variable 'ptr')}}
diff --git a/test/Analysis/inlining/eager-reclamation-path-notes.cpp b/test/Analysis/inlining/eager-reclamation-path-notes.cpp
index dedc3b5b21..7cbda91b65 100644
--- a/test/Analysis/inlining/eager-reclamation-path-notes.cpp
+++ b/test/Analysis/inlining/eager-reclamation-path-notes.cpp
@@ -1,6 +1,6 @@
 // RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=text -analyzer-config graph-trim-interval=5 -analyzer-config suppress-null-return-paths=false -verify %s
 // RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=plist-multi-file -analyzer-config graph-trim-interval=5 -analyzer-config suppress-null-return-paths=false %s -o %t.plist
-// RUN: cat %t.plist | %diff_plist %S/Inputs/expected-plists/eager-reclamation-path-notes.cpp.plist
+// RUN: cat %t.plist | %diff_plist %S/Inputs/expected-plists/eager-reclamation-path-notes.cpp.plist -
 
 typedef struct {
   int getValue();
diff --git a/test/Analysis/inlining/path-notes.c b/test/Analysis/inlining/path-notes.c
index eeeebdb98c..253ff949dc 100644
--- a/test/Analysis/inlining/path-notes.c
+++ b/test/Analysis/inlining/path-notes.c
@@ -1,6 +1,6 @@
 // RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=text -analyzer-config suppress-null-return-paths=false -verify %s
 // RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=plist-multi-file -analyzer-config suppress-null-return-paths=false %s -o %t.plist
-// RUN: cat %t.plist | %diff_plist %S/Inputs/expected-plists/path-notes.c.plist
+// RUN: cat %t.plist | %diff_plist %S/Inputs/expected-plists/path-notes.c.plist -
 
 void zero(int **p) {
   *p = 0;
diff --git a/test/Analysis/inlining/path-notes.cpp b/test/Analysis/inlining/path-notes.cpp
index 26d779902c..4385923743 100644
--- a/test/Analysis/inlining/path-notes.cpp
+++ b/test/Analysis/inlining/path-notes.cpp
@@ -1,6 +1,6 @@
 // RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=text -analyzer-config c++-inlining=destructors -std=c++11 -verify -Wno-tautological-undefined-compare %s
 // RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=plist-multi-file -analyzer-config c++-inlining=destructors -std=c++11 %s -o %t.plist -Wno-tautological-undefined-compare
-// RUN: cat %t.plist | %diff_plist %S/Inputs/expected-plists/path-notes.cpp.plist
+// RUN: cat %t.plist | %diff_plist %S/Inputs/expected-plists/path-notes.cpp.plist -
 
 class Foo {
 public:
diff --git a/test/Analysis/inlining/path-notes.m b/test/Analysis/inlining/path-notes.m
index 66d27d3fcc..d48a891976 100644
--- a/test/Analysis/inlining/path-notes.m
+++ b/test/Analysis/inlining/path-notes.m
@@ -1,6 +1,6 @@
 // RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.NilArg,osx.cocoa.RetainCount -analyzer-output=text -analyzer-config suppress-null-return-paths=false -fblocks -verify %s
 // RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.NilArg,osx.cocoa.RetainCount -analyzer-output=plist-multi-file -analyzer-config suppress-null-return-paths=false -fblocks %s -o %t.plist
-// RUN: cat %t.plist | %diff_plist %S/Inputs/expected-plists/path-notes.m.plist
+// RUN: cat %t.plist | %diff_plist %S/Inputs/expected-plists/path-notes.m.plist -
 
 typedef struct dispatch_queue_s *dispatch_queue_t;
 typedef void (^dispatch_block_t)(void);
diff --git a/test/Analysis/lit.local.cfg b/test/Analysis/lit.local.cfg
index fdab3cfd12..84f7569152 100644
--- a/test/Analysis/lit.local.cfg
+++ b/test/Analysis/lit.local.cfg
@@ -12,11 +12,11 @@ config.test_format = analyzer_test.AnalyzerTest(
 # Diff command used by Clang Analyzer tests (when comparing .plist files
 # with reference output)
 config.substitutions.append(('%diff_plist',
-    'diff -u -w -I "/" -I ".:" -I "version" -'))
+    'diff -u -w -I "/" -I ".:" -I "version"'))
 
 # Diff command for testing SARIF output to reference output.
 config.substitutions.append(('%diff_sarif',
-    '''diff -U1 -w -I ".*file:.*%basename_t" -I '"version":' -I "2\.0\.0\-csd\.[0-9]*\.beta\." -'''))
+    '''diff -U1 -w -I ".*file:.*%basename_t" -I '"version":' -I "2\.0\.0\-csd\.[0-9]*\.beta\."'''))
 
 if not config.root.clang_staticanalyzer:
     config.unsupported = True
diff --git a/test/Analysis/method-call-path-notes.cpp b/test/Analysis/method-call-path-notes.cpp
index b99455dbf7..0da25117b0 100644
--- a/test/Analysis/method-call-path-notes.cpp
+++ b/test/Analysis/method-call-path-notes.cpp
@@ -1,6 +1,6 @@
 // RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=text -verify %s
 // RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=plist-multi-file  %s -o %t.plist
-// RUN: cat %t.plist | %diff_plist %S/Inputs/expected-plists/method-call-path-notes.cpp.plist
+// RUN: cat %t.plist | %diff_plist %S/Inputs/expected-plists/method-call-path-notes.cpp.plist -
 
 // Test warning about null or uninitialized pointer values used as instance member
 // calls.
diff --git a/test/Analysis/model-file.cpp b/test/Analysis/model-file.cpp
index fd821a92c7..c5615e9271 100644
--- a/test/Analysis/model-file.cpp
+++ b/test/Analysis/model-file.cpp
@@ -1,5 +1,5 @@
 // RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-config faux-bodies=true,model-path=%S/Inputs/Models -analyzer-output=plist-multi-file -verify %s -o %t
-// RUN: cat %t | %diff_plist %S/Inputs/expected-plists/model-file.cpp.plist
+// RUN: cat %t | %diff_plist %S/Inputs/expected-plists/model-file.cpp.plist -
 
 typedef int* intptr;
 
diff --git a/test/Analysis/null-deref-path-notes.m b/test/Analysis/null-deref-path-notes.m
index 4da1a485fd..46ca4b3e78 100644
--- a/test/Analysis/null-deref-path-notes.m
+++ b/test/Analysis/null-deref-path-notes.m
@@ -1,6 +1,6 @@
 // RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-store=region -analyzer-output=text -fblocks -verify -Wno-objc-root-class %s
 // RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-store=region -analyzer-output=plist-multi-file -fblocks -Wno-objc-root-class %s -o %t
-// RUN: cat %t | %diff_plist %S/Inputs/expected-plists/null-deref-path-notes.m.plist
+// RUN: cat %t | %diff_plist %S/Inputs/expected-plists/null-deref-path-notes.m.plist -
 
 @interface Root {
 @public
diff --git a/test/Analysis/nullability-notes.m b/test/Analysis/nullability-notes.m
index e36b39bdda..850d18327e 100644
--- a/test/Analysis/nullability-notes.m
+++ b/test/Analysis/nullability-notes.m
@@ -1,6 +1,6 @@
 // RUN: %clang_analyze_cc1 -fblocks -analyzer-checker=core,nullability.NullPassedToNonnull,nullability.NullReturnedFromNonnull,nullability.NullablePassedToNonnull,nullability.NullableReturnedFromNonnull,nullability.NullableDereferenced -analyzer-output=text -verify %s
 // RUN: %clang_analyze_cc1 -fblocks -analyzer-checker=core,nullability.NullPassedToNonnull,nullability.NullReturnedFromNonnull,nullability.NullablePassedToNonnull,nullability.NullableReturnedFromNonnull,nullability.NullableDereferenced -analyzer-output=plist -o %t.plist %s
-// RUN: cat %t.plist | %diff_plist %S/Inputs/expected-plists/nullability-notes.m.plist
+// RUN: cat %t.plist | %diff_plist %S/Inputs/expected-plists/nullability-notes.m.plist -
 
 #include "Inputs/system-header-simulator-for-nullability.h"
 
diff --git a/test/Analysis/objc-arc.m b/test/Analysis/objc-arc.m
index c8cc3e7360..08fca7659c 100644
--- a/test/Analysis/objc-arc.m
+++ b/test/Analysis/objc-arc.m
@@ -1,5 +1,5 @@
 // RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,osx.cocoa.RetainCount,deadcode -verify -fblocks -analyzer-opt-analyze-nested-blocks -fobjc-arc -analyzer-output=plist-multi-file -o %t.plist %s
-// RUN: cat %t.plist | %diff_plist %S/Inputs/expected-plists/objc-arc.m.plist
+// RUN: cat %t.plist | %diff_plist %S/Inputs/expected-plists/objc-arc.m.plist -
 
 typedef signed char BOOL;
 typedef struct _NSZone NSZone;
diff --git a/test/Analysis/plist-macros-with-expansion.cpp b/test/Analysis/plist-macros-with-expansion.cpp
index 14dccd07c6..c3175a3321 100644
--- a/test/Analysis/plist-macros-with-expansion.cpp
+++ b/test/Analysis/plist-macros-with-expansion.cpp
@@ -6,7 +6,7 @@
 //
 // Check the actual plist output.
 //   RUN: cat %t.plist | %diff_plist \
-//   RUN:   %S/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist
+//   RUN:   %S/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist -
 //
 // Check the macro expansions from the plist output here, to make the test more
 // understandable.
diff --git a/test/Analysis/plist-macros.cpp b/test/Analysis/plist-macros.cpp
index a71b1dc55d..3eb604e2ed 100644
--- a/test/Analysis/plist-macros.cpp
+++ b/test/Analysis/plist-macros.cpp
@@ -1,6 +1,6 @@
 // RUN: %clang_analyze_cc1 -analyzer-checker=core,unix -verify %s
 // RUN: %clang_analyze_cc1 -analyzer-checker=core,unix -analyzer-output=plist-multi-file %s -o %t.plist
-// RUN: cat %t.plist | %diff_plist %S/Inputs/expected-plists/plist-macros.cpp.plist
+// RUN: cat %t.plist | %diff_plist %S/Inputs/expected-plists/plist-macros.cpp.plist -
 
 
 typedef __typeof(sizeof(int)) size_t;
diff --git a/test/Analysis/plist-output-alternate.m b/test/Analysis/plist-output-alternate.m
index 5f7c1a243f..525f738dc7 100644
--- a/test/Analysis/plist-output-alternate.m
+++ b/test/Analysis/plist-output-alternate.m
@@ -1,5 +1,5 @@
 // RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.RetainCount,alpha.core -fblocks -analyzer-output=plist -o %t %s
-// RUN: cat %t | %diff_plist %S/Inputs/expected-plists/plist-output-alternate.m.plist
+// RUN: cat %t | %diff_plist %S/Inputs/expected-plists/plist-output-alternate.m.plist -
 
 void test_null_init(void) {
   int *p = 0;
diff --git a/test/Analysis/plist-output.m b/test/Analysis/plist-output.m
index 1e849712e9..21602fc472 100644
--- a/test/Analysis/plist-output.m
+++ b/test/Analysis/plist-output.m
@@ -1,5 +1,5 @@
 // RUN: %clang_analyze_cc1 -analyzer-config eagerly-assume=false %s -analyzer-checker=osx.cocoa.RetainCount,deadcode.DeadStores,core -analyzer-output=plist -o %t.plist
-// RUN: cat %t.plist | %diff_plist %S/Inputs/expected-plists/plist-output.m.plist
+// RUN: cat %t.plist | %diff_plist %S/Inputs/expected-plists/plist-output.m.plist -
 
 void test_null_init(void) {
   int *p = 0;
diff --git a/test/Analysis/retain-release-path-notes.m b/test/Analysis/retain-release-path-notes.m
index 2ade99d883..bd24b6aa80 100644
--- a/test/Analysis/retain-release-path-notes.m
+++ b/test/Analysis/retain-release-path-notes.m
@@ -1,6 +1,6 @@
 // RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -analyzer-store=region -analyzer-output=text -verify %s
 // RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -analyzer-store=region -analyzer-output=plist-multi-file %s -o %t
-// RUN: cat %t | %diff_plist %S/Inputs/expected-plists/retain-release-path-notes.m.plist
+// RUN: cat %t | %diff_plist %S/Inputs/expected-plists/retain-release-path-notes.m.plist -
 
 /***
 This file is for testing the path-sensitive notes for retain/release errors.
diff --git a/test/Analysis/unix-fns.c b/test/Analysis/unix-fns.c
index 7f50167e3f..96e5d1d445 100644
--- a/test/Analysis/unix-fns.c
+++ b/test/Analysis/unix-fns.c
@@ -1,5 +1,5 @@
 // RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,unix.API,osx.API,optin.portability %s -analyzer-store=region -analyzer-output=plist -analyzer-config faux-bodies=true  -fblocks -verify -o %t.plist
-// RUN: cat %t.plist | %diff_plist %S/Inputs/expected-plists/unix-fns.c.plist
+// RUN: cat %t.plist | %diff_plist %S/Inputs/expected-plists/unix-fns.c.plist -
 // RUN: mkdir -p %t.dir
 // RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.API,osx.API,optin.portability -analyzer-output=html -analyzer-config faux-bodies=true -fblocks -o %t.dir %s
 // RUN: rm -fR %t.dir
-- 
cgit v1.2.3


From c45c23b1ed38314cf8f4eb73036fa0a7dbcb5441 Mon Sep 17 00:00:00 2001
From: George Karpenkov 
Date: Thu, 10 Jan 2019 18:15:57 +0000
Subject: [analyzer] Quote the type of the leaked/problematic object in
 diagnostics for readability

Differential Revision: https://reviews.llvm.org/D56344

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350867 91177308-0d34-0410-b5e6-96231b3b80d8
---
 .../RetainCountChecker/RetainCountDiagnostics.cpp  |   17 +-
 .../Inputs/expected-plists/edges-new.mm.plist      |    4 +-
 .../Inputs/expected-plists/objc-arc.m.plist        |   26 +-
 .../expected-plists/objc-radar17039661.m.plist     | 2342 ++++++++++----------
 .../expected-plists/plist-output-alternate.m.plist |    4 +-
 .../retain-release-path-notes.m.plist              |   38 +-
 test/Analysis/objc-radar17039661.m                 | 1276 +----------
 test/Analysis/osobject-retain-release.cpp          |   32 +-
 test/Analysis/retain-release-arc.m                 |    2 +-
 test/Analysis/retain-release-path-notes.m          |   18 +-
 test/Analysis/retaincountchecker-compoundregion.m  |    4 +-
 11 files changed, 1263 insertions(+), 2500 deletions(-)

diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
index 0f01d9a995..1f370fc301 100644
--- a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
+++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
@@ -157,14 +157,14 @@ static void generateDiagnosticsForCallLike(ProgramStateRef CurrSt,
   }
 
   if (CurrV.getObjKind() == ObjKind::CF) {
-    os << " returns a Core Foundation object of type "
-       << Sym->getType().getAsString() << " with a ";
+    os << " a Core Foundation object of type '"
+       << Sym->getType().getAsString() << "' with a ";
   } else if (CurrV.getObjKind() == ObjKind::OS) {
-    os << " returns an OSObject of type " << getPrettyTypeName(Sym->getType())
-       << " with a ";
+    os << " an OSObject of type '" << getPrettyTypeName(Sym->getType())
+       << "' with a ";
   } else if (CurrV.getObjKind() == ObjKind::Generalized) {
-    os << " returns an object of type " << Sym->getType().getAsString()
-       << " with a ";
+    os << " an object of type '" << Sym->getType().getAsString()
+       << "' with a ";
   } else {
     assert(CurrV.getObjKind() == ObjKind::ObjC);
     QualType T = Sym->getType();
@@ -587,7 +587,8 @@ CFRefLeakReportVisitor::getEndPath(BugReporterContext &BRC,
   if (RegionDescription) {
     os << "object allocated and stored into '" << *RegionDescription << '\'';
   } else {
-    os << "allocated object of type " << getPrettyTypeName(Sym->getType());
+    os << "allocated object of type '" << getPrettyTypeName(Sym->getType())
+       << "'";
   }
 
   // Get the retain count.
@@ -724,7 +725,7 @@ void CFRefLeakReport::createDescription(CheckerContext &Ctx) {
   } else {
 
     // If we can't figure out the name, just supply the type information.
-    os << " of type " << getPrettyTypeName(Sym->getType());
+    os << " of type '" << getPrettyTypeName(Sym->getType()) << "'";
   }
 }
 
diff --git a/test/Analysis/Inputs/expected-plists/edges-new.mm.plist b/test/Analysis/Inputs/expected-plists/edges-new.mm.plist
index b5f5d6e604..449050d595 100644
--- a/test/Analysis/Inputs/expected-plists/edges-new.mm.plist
+++ b/test/Analysis/Inputs/expected-plists/edges-new.mm.plist
@@ -1933,9 +1933,9 @@
      
      depth0
      extended_message
-     Call to function 'CFNumberCreate' returns a Core Foundation object of type CFNumberRef with a +1 retain count
+     Call to function 'CFNumberCreate' returns a Core Foundation object of type 'CFNumberRef' with a +1 retain count
      message
-     Call to function 'CFNumberCreate' returns a Core Foundation object of type CFNumberRef with a +1 retain count
+     Call to function 'CFNumberCreate' returns a Core Foundation object of type 'CFNumberRef' with a +1 retain count
     
     
      kindcontrol
diff --git a/test/Analysis/Inputs/expected-plists/objc-arc.m.plist b/test/Analysis/Inputs/expected-plists/objc-arc.m.plist
index 3f9d63e7a6..966ea9ac09 100644
--- a/test/Analysis/Inputs/expected-plists/objc-arc.m.plist
+++ b/test/Analysis/Inputs/expected-plists/objc-arc.m.plist
@@ -223,9 +223,9 @@
      
      depth0
      extended_message
-     Call to function 'CFDateCreate' returns a Core Foundation object of type CFDateRef with a +1 retain count
+     Call to function 'CFDateCreate' returns a Core Foundation object of type 'CFDateRef' with a +1 retain count
      message
-     Call to function 'CFDateCreate' returns a Core Foundation object of type CFDateRef with a +1 retain count
+     Call to function 'CFDateCreate' returns a Core Foundation object of type 'CFDateRef' with a +1 retain count
     
     
      kindcontrol
@@ -739,9 +739,9 @@
      
      depth0
      extended_message
-     Call to function 'CFCreateSomething' returns a Core Foundation object of type CFTypeRef with a +1 retain count
+     Call to function 'CFCreateSomething' returns a Core Foundation object of type 'CFTypeRef' with a +1 retain count
      message
-     Call to function 'CFCreateSomething' returns a Core Foundation object of type CFTypeRef with a +1 retain count
+     Call to function 'CFCreateSomething' returns a Core Foundation object of type 'CFTypeRef' with a +1 retain count
     
     
      kindcontrol
@@ -934,9 +934,9 @@
      
      depth0
      extended_message
-     Call to function 'CFCreateString' returns a Core Foundation object of type CFStringRef with a +1 retain count
+     Call to function 'CFCreateString' returns a Core Foundation object of type 'CFStringRef' with a +1 retain count
      message
-     Call to function 'CFCreateString' returns a Core Foundation object of type CFStringRef with a +1 retain count
+     Call to function 'CFCreateString' returns a Core Foundation object of type 'CFStringRef' with a +1 retain count
     
     
      kindcontrol
@@ -1353,9 +1353,9 @@
      
      depth0
      extended_message
-     Call to function 'CFDateCreate' returns a Core Foundation object of type CFDateRef with a +1 retain count
+     Call to function 'CFDateCreate' returns a Core Foundation object of type 'CFDateRef' with a +1 retain count
      message
-     Call to function 'CFDateCreate' returns a Core Foundation object of type CFDateRef with a +1 retain count
+     Call to function 'CFDateCreate' returns a Core Foundation object of type 'CFDateRef' with a +1 retain count
     
     
      kindcontrol
@@ -1679,9 +1679,9 @@
      
      depth0
      extended_message
-     Call to function 'CFCreateString' returns a Core Foundation object of type CFStringRef with a +1 retain count
+     Call to function 'CFCreateString' returns a Core Foundation object of type 'CFStringRef' with a +1 retain count
      message
-     Call to function 'CFCreateString' returns a Core Foundation object of type CFStringRef with a +1 retain count
+     Call to function 'CFCreateString' returns a Core Foundation object of type 'CFStringRef' with a +1 retain count
     
     
      kindcontrol
@@ -1727,12 +1727,12 @@
      
      depth0
      extended_message
-     Object leaked: allocated object of type CFStringRef is not referenced later in this execution path and has a retain count of +1
+     Object leaked: allocated object of type 'CFStringRef' is not referenced later in this execution path and has a retain count of +1
      message
-     Object leaked: allocated object of type CFStringRef is not referenced later in this execution path and has a retain count of +1
+     Object leaked: allocated object of type 'CFStringRef' is not referenced later in this execution path and has a retain count of +1
     
    
-   descriptionPotential leak of an object of type CFStringRef
+   descriptionPotential leak of an object of type 'CFStringRef'
    categoryMemory (Core Foundation/Objective-C)
    typeLeak
    check_nameosx.cocoa.RetainCount
diff --git a/test/Analysis/Inputs/expected-plists/objc-radar17039661.m.plist b/test/Analysis/Inputs/expected-plists/objc-radar17039661.m.plist
index 1cfbbbd5ad..b5b26d050e 100644
--- a/test/Analysis/Inputs/expected-plists/objc-radar17039661.m.plist
+++ b/test/Analysis/Inputs/expected-plists/objc-radar17039661.m.plist
@@ -1,1275 +1,1309 @@
-diagnostics
-
- 
-  path
-  
-   
-    kindcontrol
-    edges
-     
-      
-       start
-        
-         
-          line48
-          col3
-          file0
-         
-         
-          line48
-          col15
-          file0
-         
-        
-       end
-        
-         
-          line49
-          col3
-          file0
-         
-         
-          line49
-          col6
-          file0
-         
-        
-      
-     
-   
-   
-    kindcontrol
-    edges
-     
-      
-       start
-        
-         
-          line49
-          col3
-          file0
-         
-         
-          line49
-          col6
-          file0
-         
-        
-       end
-        
-         
-          line49
-          col26
-          file0
-         
-         
-          line49
-          col38
-          file0
-         
-        
-      
-     
-   
-   
-    kindevent
-    location
+
+
+
+
+ clang_version
+clang version 8.0.0 
+ diagnostics
+ 
+  
+   path
+   
     
-     line49
-     col26
-     file0
-    
-    ranges
-    
+     kindcontrol
+     edges
       
        
-        line49
-        col26
-        file0
+        start
+         
+          
+           line49
+           col3
+           file0
+          
+          
+           line49
+           col15
+           file0
+          
+         
+        end
+         
+          
+           line50
+           col3
+           file0
+          
+          
+           line50
+           col6
+           file0
+          
+         
        
+      
+    
+    
+     kindcontrol
+     edges
+      
        
-        line53
-        col4
-        file0
+        start
+         
+          
+           line50
+           col3
+           file0
+          
+          
+           line50
+           col6
+           file0
+          
+         
+        end
+         
+          
+           line50
+           col26
+           file0
+          
+          
+           line50
+           col38
+           file0
+          
+         
        
       
-    
-    depth0
-    extended_message
-    Calling 'performAction'
-    message
-    Calling 'performAction'
-   
-   
-    kindevent
-    location
-    
-     line27
-     col1
-     file0
     
-    depth1
-    extended_message
-    Entered call from 'runTest'
-    message
-    Entered call from 'runTest'
-   
-   
-    kindcontrol
-    edges
-     
-      
-       start
-        
-         
-          line27
-          col1
-          file0
-         
-         
-          line27
-          col6
-          file0
-         
-        
-       end
-        
-         
-          line28
-          col3
-          file0
-         
-         
-          line28
-          col15
-          file0
-         
-        
-      
-     
-   
-   
-    kindcontrol
-    edges
+    
+     kindevent
+     location
+     
+      line50
+      col26
+      file0
+     
+     ranges
      
-      
-       start
-        
-         
-          line28
-          col3
-          file0
-         
-         
-          line28
-          col15
-          file0
-         
-        
-       end
-        
-         
-          line29
-          col3
-          file0
-         
-         
-          line29
-          col21
-          file0
-         
-        
-      
+       
+        
+         line50
+         col26
+         file0
+        
+        
+         line54
+         col4
+         file0
+        
+       
      
-   
-   
-    kindevent
-    location
+     depth0
+     extended_message
+     Calling 'performAction'
+     message
+     Calling 'performAction'
+    
     
-     line29
-     col3
-     file0
+     kindevent
+     location
+     
+      line28
+      col1
+      file0
+     
+     depth1
+     extended_message
+     Entered call from 'runTest'
+     message
+     Entered call from 'runTest'
     
-    ranges
-    
+    
+     kindcontrol
+     edges
       
        
-        line29
-        col3
-        file0
+        start
+         
+          
+           line28
+           col1
+           file0
+          
+          
+           line28
+           col6
+           file0
+          
+         
+        end
+         
+          
+           line29
+           col3
+           file0
+          
+          
+           line29
+           col15
+           file0
+          
+         
        
+      
+    
+    
+     kindcontrol
+     edges
+      
        
-        line43
-        col4
-        file0
+        start
+         
+          
+           line29
+           col3
+           file0
+          
+          
+           line29
+           col15
+           file0
+          
+         
+        end
+         
+          
+           line30
+           col3
+           file0
+          
+          
+           line30
+           col21
+           file0
+          
+         
        
       
-    
-    depth1
-    extended_message
-    Calling 'reallyPerformAction'
-    message
-    Calling 'reallyPerformAction'
-   
-   
-    kindevent
-    location
-    
-     line22
-     col1
-     file0
     
-    depth2
-    extended_message
-    Entered call from 'performAction'
-    message
-    Entered call from 'performAction'
-   
-   
-    kindcontrol
-    edges
+    
+     kindevent
+     location
+     
+      line30
+      col3
+      file0
+     
+     ranges
      
-      
-       start
-        
-         
-          line22
-          col1
-          file0
-         
-         
-          line22
-          col6
-          file0
-         
-        
-       end
-        
-         
-          line23
-          col3
-          file0
-         
-         
-          line23
-          col16
-          file0
-         
-        
-      
+       
+        
+         line30
+         col3
+         file0
+        
+        
+         line44
+         col4
+         file0
+        
+       
      
-   
-   
-    kindevent
-    location
+     depth1
+     extended_message
+     Calling 'reallyPerformAction'
+     message
+     Calling 'reallyPerformAction'
+    
     
-     line23
-     col3
-     file0
+     kindevent
+     location
+     
+      line23
+      col1
+      file0
+     
+     depth2
+     extended_message
+     Entered call from 'performAction'
+     message
+     Entered call from 'performAction'
     
-    ranges
-    
+    
+     kindcontrol
+     edges
       
        
-        line23
-        col3
-        file0
-       
-       
-        line23
-        col58
-        file0
+        start
+         
+          
+           line23
+           col1
+           file0
+          
+          
+           line23
+           col6
+           file0
+          
+         
+        end
+         
+          
+           line24
+           col3
+           file0
+          
+          
+           line24
+           col16
+           file0
+          
+         
        
       
-    
-    depth2
-    extended_message
-    Calling anonymous block
-    message
-    Calling anonymous block
-   
-   
-    kindevent
-    location
-    
-     line29
-     col23
-     file0
     
-    depth3
-    extended_message
-    Entered call from 'reallyPerformAction'
-    message
-    Entered call from 'reallyPerformAction'
-   
-   
-    kindcontrol
-    edges
-     
-      
-       start
-        
-         
-          line29
-          col23
-          file0
-         
-         
-          line29
-          col23
-          file0
-         
-        
-       end
-        
-         
-          line31
-          col5
-          file0
-         
-         
-          line31
-          col6
-          file0
-         
-        
-      
-     
-   
-   
-    kindcontrol
-    edges
+    
+     kindevent
+     location
+     
+      line24
+      col3
+      file0
+     
+     ranges
      
-      
-       start
-        
-         
-          line31
-          col5
-          file0
-         
-         
-          line31
-          col6
-          file0
-         
-        
-       end
-        
-         
-          line31
-          col9
-          file0
-         
-         
-          line31
-          col12
-          file0
-         
-        
-      
+       
+        
+         line24
+         col3
+         file0
+        
+        
+         line24
+         col58
+         file0
+        
+       
      
-   
-   
-    kindevent
-    location
+     depth2
+     extended_message
+     Calling anonymous block
+     message
+     Calling anonymous block
+    
     
-     line31
-     col9
-     file0
+     kindevent
+     location
+     
+      line30
+      col23
+      file0
+     
+     depth3
+     extended_message
+     Entered call from 'reallyPerformAction'
+     message
+     Entered call from 'reallyPerformAction'
     
-    ranges
-    
+    
+     kindcontrol
+     edges
       
        
-        line31
-        col9
-        file0
+        start
+         
+          
+           line30
+           col23
+           file0
+          
+          
+           line30
+           col23
+           file0
+          
+         
+        end
+         
+          
+           line32
+           col5
+           file0
+          
+          
+           line32
+           col6
+           file0
+          
+         
        
+      
+    
+    
+     kindcontrol
+     edges
+      
        
-        line31
-        col12
-        file0
+        start
+         
+          
+           line32
+           col5
+           file0
+          
+          
+           line32
+           col6
+           file0
+          
+         
+        end
+         
+          
+           line32
+           col9
+           file0
+          
+          
+           line32
+           col12
+           file0
+          
+         
        
       
-    
-    depth3
-    extended_message
-    Assuming 'cond' is not equal to 0
-    message
-    Assuming 'cond' is not equal to 0
-   
-   
-    kindcontrol
-    edges
+    
+    
+     kindevent
+     location
+     
+      line32
+      col9
+      file0
+     
+     ranges
      
-      
-       start
-        
-         
-          line31
-          col9
-          file0
-         
-         
-          line31
-          col12
-          file0
-         
-        
-       end
-        
-         
-          line33
-          col7
-          file0
-         
-         
-          line33
-          col14
-          file0
-         
-        
-      
+       
+        
+         line32
+         col9
+         file0
+        
+        
+         line32
+         col12
+         file0
+        
+       
      
-   
-   
-    kindevent
-    location
-    
-     line33
-     col30
-     file0
+     depth3
+     extended_message
+     Assuming 'cond' is not equal to 0
+     message
+     Assuming 'cond' is not equal to 0
     
-    ranges
-    
+    
+     kindcontrol
+     edges
       
        
-        line33
-        col30
-        file0
-       
-       
-        line33
-        col50
-        file0
+        start
+         
+          
+           line32
+           col9
+           file0
+          
+          
+           line32
+           col12
+           file0
+          
+         
+        end
+         
+          
+           line34
+           col7
+           file0
+          
+          
+           line34
+           col14
+           file0
+          
+         
        
       
-    
-    depth3
-    extended_message
-    NSNumber boxed expression produces an object with a +0 retain count
-    message
-    NSNumber boxed expression produces an object with a +0 retain count
-   
-   
-    kindcontrol
-    edges
-     
-      
-       start
-        
-         
-          line33
-          col7
-          file0
-         
-         
-          line33
-          col14
-          file0
-         
-        
-       end
-        
-         
-          line35
-          col7
-          file0
-         
-         
-          line35
-          col14
-          file0
-         
-        
-      
-     
-   
-   
-    kindcontrol
-    edges
+    
+    
+     kindevent
+     location
+     
+      line34
+      col30
+      file0
+     
+     ranges
      
-      
-       start
-        
-         
-          line35
-          col7
-          file0
-         
-         
-          line35
-          col14
-          file0
-         
-        
-       end
-        
-         
-          line35
-          col33
-          file0
-         
-         
-          line35
-          col38
-          file0
-         
-        
-      
+       
+        
+         line34
+         col30
+         file0
+        
+        
+         line34
+         col50
+         file0
+        
+       
      
-   
-   
-    kindevent
-    location
-    
-     line35
-     col33
-     file0
+     depth3
+     extended_message
+     NSNumber boxed expression produces an object with a +0 retain count
+     message
+     NSNumber boxed expression produces an object with a +0 retain count
     
-    ranges
-    
+    
+     kindcontrol
+     edges
       
        
-        line35
-        col33
-        file0
+        start
+         
+          
+           line34
+           col7
+           file0
+          
+          
+           line34
+           col14
+           file0
+          
+         
+        end
+         
+          
+           line36
+           col7
+           file0
+          
+          
+           line36
+           col14
+           file0
+          
+         
        
+      
+    
+    
+     kindcontrol
+     edges
+      
        
-        line35
-        col50
-        file0
+        start
+         
+          
+           line36
+           col7
+           file0
+          
+          
+           line36
+           col14
+           file0
+          
+         
+        end
+         
+          
+           line36
+           col33
+           file0
+          
+          
+           line36
+           col38
+           file0
+          
+         
        
       
-    
-    depth3
-    extended_message
-    Calling anonymous block
-    message
-    Calling anonymous block
-   
-   
-    kindevent
-    location
-    
-     line49
-     col40
-     file0
     
-    depth4
-    extended_message
-    Entered call
-    message
-    Entered call
-   
-   
-    kindcontrol
-    edges
+    
+     kindevent
+     location
+     
+      line36
+      col33
+      file0
+     
+     ranges
      
-      
-       start
-        
-         
-          line49
-          col40
-          file0
-         
-         
-          line49
-          col40
-          file0
-         
-        
-       end
-        
-         
-          line50
-          col5
-          file0
-         
-         
-          line50
-          col17
-          file0
-         
-        
-      
+       
+        
+         line36
+         col33
+         file0
+        
+        
+         line36
+         col50
+         file0
+        
+       
      
-   
-   
-    kindevent
-    location
+     depth3
+     extended_message
+     Calling anonymous block
+     message
+     Calling anonymous block
+    
     
-     line50
-     col21
-     file0
+     kindevent
+     location
+     
+      line50
+      col40
+      file0
+     
+     depth4
+     extended_message
+     Entered call
+     message
+     Entered call
     
-    ranges
-    
+    
+     kindcontrol
+     edges
       
        
-        line50
-        col21
-        file0
-       
-       
-        line50
-        col39
-        file0
+        start
+         
+          
+           line50
+           col40
+           file0
+          
+          
+           line50
+           col40
+           file0
+          
+         
+        end
+         
+          
+           line51
+           col5
+           file0
+          
+          
+           line51
+           col17
+           file0
+          
+         
        
       
+    
+    
+     kindevent
+     location
+     
+      line51
+      col21
+      file0
+     
+     ranges
+     
+       
+        
+         line51
+         col21
+         file0
+        
+        
+         line51
+         col39
+         file0
+        
+       
+       
+        
+         line51
+         col22
+         file0
+        
+        
+         line51
+         col31
+         file0
+        
+       
+     
+     depth4
+     extended_message
+     Reference count incremented. The object now has a +1 retain count
+     message
+     Reference count incremented. The object now has a +1 retain count
+    
+    
+     kindcontrol
+     edges
       
        
-        line50
-        col22
-        file0
-       
-       
-        line50
-        col31
-        file0
+        start
+         
+          
+           line51
+           col5
+           file0
+          
+          
+           line51
+           col17
+           file0
+          
+         
+        end
+         
+          
+           line53
+           col5
+           file0
+          
+          
+           line53
+           col10
+           file0
+          
+         
        
       
-    
-    depth4
-    extended_message
-    Reference count incremented. The object now has a +1 retain count
-    message
-    Reference count incremented. The object now has a +1 retain count
-   
-   
-    kindcontrol
-    edges
+    
+    
+     kindevent
+     location
+     
+      line36
+      col33
+      file0
+     
+     ranges
      
-      
-       start
-        
-         
-          line50
-          col5
-          file0
-         
-         
-          line50
-          col17
-          file0
-         
-        
-       end
-        
-         
-          line52
-          col5
-          file0
-         
-         
-          line52
-          col10
-          file0
-         
-        
-      
+       
+        
+         line36
+         col33
+         file0
+        
+        
+         line36
+         col50
+         file0
+        
+       
      
-   
-   
-    kindevent
-    location
-    
-     line35
-     col33
-     file0
+     depth3
+     extended_message
+     Returning to caller
+     message
+     Returning to caller
     
-    ranges
-    
+    
+     kindcontrol
+     edges
       
        
-        line35
-        col33
-        file0
-       
-       
-        line35
-        col50
-        file0
+        start
+         
+          
+           line36
+           col33
+           file0
+          
+          
+           line36
+           col38
+           file0
+          
+         
+        end
+         
+          
+           line36
+           col7
+           file0
+          
+          
+           line36
+           col14
+           file0
+          
+         
        
       
-    
-    depth3
-    extended_message
-    Returning to caller
-    message
-    Returning to caller
-   
-   
-    kindcontrol
-    edges
-     
-      
-       start
-        
-         
-          line35
-          col33
-          file0
-         
-         
-          line35
-          col38
-          file0
-         
-        
-       end
-        
-         
-          line35
-          col7
-          file0
-         
-         
-          line35
-          col14
-          file0
-         
-        
-      
-     
-   
-   
-    kindcontrol
-    edges
-     
-      
-       start
-        
-         
-          line35
-          col7
-          file0
-         
-         
-          line35
-          col14
-          file0
-         
-        
-       end
-        
-         
-          line37
-          col7
-          file0
-         
-         
-          line37
-          col8
-          file0
-         
-        
-      
-     
-   
-   
-    kindcontrol
-    edges
-     
-      
-       start
-        
-         
-          line37
-          col7
-          file0
-         
-         
-          line37
-          col8
-          file0
-         
-        
-       end
-        
-         
-          line40
-          col7
-          file0
-         
-         
-          line40
-          col18
-          file0
-         
-        
-      
-     
-   
-   
-    kindevent
-    location
-    
-     line23
-     col3
-     file0
     
-    ranges
-    
+    
+     kindcontrol
+     edges
       
        
-        line23
-        col3
-        file0
+        start
+         
+          
+           line36
+           col7
+           file0
+          
+          
+           line36
+           col14
+           file0
+          
+         
+        end
+         
+          
+           line38
+           col7
+           file0
+          
+          
+           line38
+           col8
+           file0
+          
+         
        
+      
+    
+    
+     kindcontrol
+     edges
+      
        
-        line23
-        col58
-        file0
+        start
+         
+          
+           line38
+           col7
+           file0
+          
+          
+           line38
+           col8
+           file0
+          
+         
+        end
+         
+          
+           line41
+           col7
+           file0
+          
+          
+           line41
+           col18
+           file0
+          
+         
        
       
-    
-    depth2
-    extended_message
-    Returning to caller
-    message
-    Returning to caller
-   
-   
-    kindcontrol
-    edges
+    
+    
+     kindevent
+     location
+     
+      line24
+      col3
+      file0
+     
+     ranges
      
-      
-       start
-        
-         
-          line23
-          col3
-          file0
-         
-         
-          line23
-          col16
-          file0
-         
-        
-       end
-        
-         
-          line24
-          col3
-          file0
-         
-         
-          line24
-          col16
-          file0
-         
-        
-      
+       
+        
+         line24
+         col3
+         file0
+        
+        
+         line24
+         col58
+         file0
+        
+       
      
-   
-   
-    kindevent
-    location
-    
-     line24
-     col3
-     file0
+     depth2
+     extended_message
+     Returning to caller
+     message
+     Returning to caller
     
-    ranges
-    
+    
+     kindcontrol
+     edges
       
        
-        line24
-        col3
-        file0
-       
-       
-        line24
-        col58
-        file0
+        start
+         
+          
+           line24
+           col3
+           file0
+          
+          
+           line24
+           col16
+           file0
+          
+         
+        end
+         
+          
+           line25
+           col3
+           file0
+          
+          
+           line25
+           col16
+           file0
+          
+         
        
       
-    
-    depth2
-    extended_message
-    Calling anonymous block
-    message
-    Calling anonymous block
-   
-   
-    kindevent
-    location
-    
-     line29
-     col23
-     file0
     
-    depth3
-    extended_message
-    Entered call from 'reallyPerformAction'
-    message
-    Entered call from 'reallyPerformAction'
-   
-   
-    kindcontrol
-    edges
-     
-      
-       start
-        
-         
-          line29
-          col23
-          file0
-         
-         
-          line29
-          col23
-          file0
-         
-        
-       end
-        
-         
-          line31
-          col5
-          file0
-         
-         
-          line31
-          col6
-          file0
-         
-        
-      
-     
-   
-   
-    kindcontrol
-    edges
+    
+     kindevent
+     location
+     
+      line25
+      col3
+      file0
+     
+     ranges
      
-      
-       start
-        
-         
-          line31
-          col5
-          file0
-         
-         
-          line31
-          col6
-          file0
-         
-        
-       end
-        
-         
-          line31
-          col9
-          file0
-         
-         
-          line31
-          col12
-          file0
-         
-        
-      
+       
+        
+         line25
+         col3
+         file0
+        
+        
+         line25
+         col58
+         file0
+        
+       
      
-   
-   
-    kindevent
-    location
+     depth2
+     extended_message
+     Calling anonymous block
+     message
+     Calling anonymous block
+    
     
-     line31
-     col9
-     file0
+     kindevent
+     location
+     
+      line30
+      col23
+      file0
+     
+     depth3
+     extended_message
+     Entered call from 'reallyPerformAction'
+     message
+     Entered call from 'reallyPerformAction'
     
-    ranges
-    
+    
+     kindcontrol
+     edges
       
        
-        line31
-        col9
-        file0
+        start
+         
+          
+           line30
+           col23
+           file0
+          
+          
+           line30
+           col23
+           file0
+          
+         
+        end
+         
+          
+           line32
+           col5
+           file0
+          
+          
+           line32
+           col6
+           file0
+          
+         
        
+      
+    
+    
+     kindcontrol
+     edges
+      
        
-        line31
-        col12
-        file0
+        start
+         
+          
+           line32
+           col5
+           file0
+          
+          
+           line32
+           col6
+           file0
+          
+         
+        end
+         
+          
+           line32
+           col9
+           file0
+          
+          
+           line32
+           col12
+           file0
+          
+         
        
       
-    
-    depth3
-    extended_message
-    Assuming 'cond' is not equal to 0
-    message
-    Assuming 'cond' is not equal to 0
-   
-   
-    kindcontrol
-    edges
-     
-      
-       start
-        
-         
-          line31
-          col9
-          file0
-         
-         
-          line31
-          col12
-          file0
-         
-        
-       end
-        
-         
-          line33
-          col7
-          file0
-         
-         
-          line33
-          col14
-          file0
-         
-        
-      
-     
-   
-   
-    kindcontrol
-    edges
-     
-      
-       start
-        
-         
-          line33
-          col7
-          file0
-         
-         
-          line33
-          col14
-          file0
-         
-        
-       end
-        
-         
-          line35
-          col7
-          file0
-         
-         
-          line35
-          col14
-          file0
-         
-        
-      
-     
-   
-   
-    kindcontrol
-    edges
+    
+    
+     kindevent
+     location
+     
+      line32
+      col9
+      file0
+     
+     ranges
      
-      
-       start
-        
-         
-          line35
-          col7
-          file0
-         
-         
-          line35
-          col14
-          file0
-         
-        
-       end
-        
-         
-          line35
-          col33
-          file0
-         
-         
-          line35
-          col38
-          file0
-         
-        
-      
+       
+        
+         line32
+         col9
+         file0
+        
+        
+         line32
+         col12
+         file0
+        
+       
      
-   
-   
-    kindevent
-    location
-    
-     line35
-     col33
-     file0
+     depth3
+     extended_message
+     Assuming 'cond' is not equal to 0
+     message
+     Assuming 'cond' is not equal to 0
     
-    ranges
-    
+    
+     kindcontrol
+     edges
       
        
-        line35
-        col33
-        file0
+        start
+         
+          
+           line32
+           col9
+           file0
+          
+          
+           line32
+           col12
+           file0
+          
+         
+        end
+         
+          
+           line34
+           col7
+           file0
+          
+          
+           line34
+           col14
+           file0
+          
+         
        
+      
+    
+    
+     kindcontrol
+     edges
+      
        
-        line35
-        col50
-        file0
+        start
+         
+          
+           line34
+           col7
+           file0
+          
+          
+           line34
+           col14
+           file0
+          
+         
+        end
+         
+          
+           line36
+           col7
+           file0
+          
+          
+           line36
+           col14
+           file0
+          
+         
        
       
-    
-    depth3
-    extended_message
-    Calling anonymous block
-    message
-    Calling anonymous block
-   
-   
-    kindevent
-    location
+    
     
-     line49
-     col40
-     file0
+     kindcontrol
+     edges
+      
+       
+        start
+         
+          
+           line36
+           col7
+           file0
+          
+          
+           line36
+           col14
+           file0
+          
+         
+        end
+         
+          
+           line36
+           col33
+           file0
+          
+          
+           line36
+           col38
+           file0
+          
+         
+       
+      
     
-    depth4
-    extended_message
-    Entered call
-    message
-    Entered call
-   
-   
-    kindcontrol
-    edges
-     
-      
-       start
-        
-         
-          line49
-          col40
-          file0
-         
-         
-          line49
-          col40
-          file0
-         
-        
-       end
-        
-         
-          line50
-          col5
-          file0
-         
-         
-          line50
-          col17
-          file0
-         
-        
-      
-     
-   
-   
-    kindcontrol
-    edges
+    
+     kindevent
+     location
+     
+      line36
+      col33
+      file0
+     
+     ranges
      
-      
-       start
-        
-         
-          line50
-          col5
-          file0
-         
-         
-          line50
-          col17
-          file0
-         
-        
-       end
-        
-         
-          line52
-          col5
-          file0
-         
-         
-          line52
-          col10
-          file0
-         
-        
-      
+       
+        
+         line36
+         col33
+         file0
+        
+        
+         line36
+         col50
+         file0
+        
+       
      
-   
-   
-    kindevent
-    location
+     depth3
+     extended_message
+     Calling anonymous block
+     message
+     Calling anonymous block
+    
     
-     line52
-     col5
-     file0
+     kindevent
+     location
+     
+      line50
+      col40
+      file0
+     
+     depth4
+     extended_message
+     Entered call
+     message
+     Entered call
     
-    ranges
-    
+    
+     kindcontrol
+     edges
       
        
-        line52
-        col5
-        file0
+        start
+         
+          
+           line50
+           col40
+           file0
+          
+          
+           line50
+           col40
+           file0
+          
+         
+        end
+         
+          
+           line51
+           col5
+           file0
+          
+          
+           line51
+           col17
+           file0
+          
+         
        
+      
+    
+    
+     kindcontrol
+     edges
+      
        
-        line52
-        col21
-        file0
+        start
+         
+          
+           line51
+           col5
+           file0
+          
+          
+           line51
+           col17
+           file0
+          
+         
+        end
+         
+          
+           line53
+           col5
+           file0
+          
+          
+           line53
+           col10
+           file0
+          
+         
        
       
-    
-    depth4
-    extended_message
-    Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1
-    message
-    Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1
-   
-  
-  descriptionPotential leak of an object
-  categoryMemory (Core Foundation/Objective-C)
-  typeLeak
- location
- 
-  line52
-  col5
-  file0
- 
- 
-
-
+    
+    
+     kindevent
+     location
+     
+      line53
+      col5
+      file0
+     
+     ranges
+     
+       
+        
+         line53
+         col5
+         file0
+        
+        
+         line53
+         col21
+         file0
+        
+       
+     
+     depth4
+     extended_message
+     Object leaked: allocated object of type 'NSNumber *' is not referenced later in this execution path and has a retain count of +1
+     message
+     Object leaked: allocated object of type 'NSNumber *' is not referenced later in this execution path and has a retain count of +1
+    
+   
+   descriptionPotential leak of an object of type 'NSNumber *'
+   categoryMemory (Core Foundation/Objective-C)
+   typeLeak
+   check_nameosx.cocoa.RetainCount
+   
+   issue_hash_content_of_line_in_context500e2bbda41c8086771ad98b6bcfdc50
+  location
+  
+   line53
+   col5
+   file0
+  
+  ExecutedLines
+  
+   0
+   
+    23
+    24
+    25
+    28
+    29
+    30
+    32
+    34
+    36
+    38
+    41
+    48
+    49
+    50
+    51
+    53
+   
+  
+  
+ 
+ files
+ 
+  /Volumes/Transcend/code/monorepo/llvm-project/clang/test/Analysis/objc-radar17039661.m
+ 
 
-
+
\ No newline at end of file
diff --git a/test/Analysis/Inputs/expected-plists/plist-output-alternate.m.plist b/test/Analysis/Inputs/expected-plists/plist-output-alternate.m.plist
index b3383375dc..966d5a7bce 100644
--- a/test/Analysis/Inputs/expected-plists/plist-output-alternate.m.plist
+++ b/test/Analysis/Inputs/expected-plists/plist-output-alternate.m.plist
@@ -1299,9 +1299,9 @@
      
      depth0
      extended_message
-     Call to function 'CFNumberCreate' returns a Core Foundation object of type CFNumberRef with a +1 retain count
+     Call to function 'CFNumberCreate' returns a Core Foundation object of type 'CFNumberRef' with a +1 retain count
      message
-     Call to function 'CFNumberCreate' returns a Core Foundation object of type CFNumberRef with a +1 retain count
+     Call to function 'CFNumberCreate' returns a Core Foundation object of type 'CFNumberRef' with a +1 retain count
     
     
      kindcontrol
diff --git a/test/Analysis/Inputs/expected-plists/retain-release-path-notes.m.plist b/test/Analysis/Inputs/expected-plists/retain-release-path-notes.m.plist
index f7ff277b54..13b654a19c 100644
--- a/test/Analysis/Inputs/expected-plists/retain-release-path-notes.m.plist
+++ b/test/Analysis/Inputs/expected-plists/retain-release-path-notes.m.plist
@@ -155,9 +155,9 @@
      
      depth0
      extended_message
-     Call to function 'CFCreateSomething' returns a Core Foundation object of type CFTypeRef with a +1 retain count
+     Call to function 'CFCreateSomething' returns a Core Foundation object of type 'CFTypeRef' with a +1 retain count
      message
-     Call to function 'CFCreateSomething' returns a Core Foundation object of type CFTypeRef with a +1 retain count
+     Call to function 'CFCreateSomething' returns a Core Foundation object of type 'CFTypeRef' with a +1 retain count
     
     
      kindcontrol
@@ -822,9 +822,9 @@
      
      depth0
      extended_message
-     Call to function 'CFGetSomething' returns a Core Foundation object of type CFTypeRef with a +0 retain count
+     Call to function 'CFGetSomething' returns a Core Foundation object of type 'CFTypeRef' with a +0 retain count
      message
-     Call to function 'CFGetSomething' returns a Core Foundation object of type CFTypeRef with a +0 retain count
+     Call to function 'CFGetSomething' returns a Core Foundation object of type 'CFTypeRef' with a +0 retain count
     
     
      kindcontrol
@@ -1883,9 +1883,9 @@
      
      depth0
      extended_message
-     Call to function 'CFCreateSomething' returns a Core Foundation object of type CFTypeRef with a +1 retain count
+     Call to function 'CFCreateSomething' returns a Core Foundation object of type 'CFTypeRef' with a +1 retain count
      message
-     Call to function 'CFCreateSomething' returns a Core Foundation object of type CFTypeRef with a +1 retain count
+     Call to function 'CFCreateSomething' returns a Core Foundation object of type 'CFTypeRef' with a +1 retain count
     
     
      kindcontrol
@@ -2006,9 +2006,9 @@
      
      depth0
      extended_message
-     Call to function 'CFGetSomething' returns a Core Foundation object of type CFTypeRef with a +0 retain count
+     Call to function 'CFGetSomething' returns a Core Foundation object of type 'CFTypeRef' with a +0 retain count
      message
-     Call to function 'CFGetSomething' returns a Core Foundation object of type CFTypeRef with a +0 retain count
+     Call to function 'CFGetSomething' returns a Core Foundation object of type 'CFTypeRef' with a +0 retain count
     
     
      kindcontrol
@@ -2127,9 +2127,9 @@
      
      depth0
      extended_message
-     Call to function 'CFCreateSomething' returns a Core Foundation object of type CFTypeRef with a +1 retain count
+     Call to function 'CFCreateSomething' returns a Core Foundation object of type 'CFTypeRef' with a +1 retain count
      message
-     Call to function 'CFCreateSomething' returns a Core Foundation object of type CFTypeRef with a +1 retain count
+     Call to function 'CFCreateSomething' returns a Core Foundation object of type 'CFTypeRef' with a +1 retain count
     
     
      kindcontrol
@@ -3834,12 +3834,12 @@
      
      depth0
      extended_message
-     Object leaked: allocated object of type MyObj * is not referenced later in this execution path and has a retain count of +1
+     Object leaked: allocated object of type 'MyObj *' is not referenced later in this execution path and has a retain count of +1
      message
-     Object leaked: allocated object of type MyObj * is not referenced later in this execution path and has a retain count of +1
+     Object leaked: allocated object of type 'MyObj *' is not referenced later in this execution path and has a retain count of +1
     
    
-   descriptionPotential leak of an object of type MyObj *
+   descriptionPotential leak of an object of type 'MyObj *'
    categoryMemory (Core Foundation/Objective-C)
    typeLeak
    check_nameosx.cocoa.RetainCount
@@ -4298,9 +4298,9 @@
      
      depth0
      extended_message
-     Call to function 'CFCreateSomething' returns a Core Foundation object of type CFTypeRef with a +1 retain count
+     Call to function 'CFCreateSomething' returns a Core Foundation object of type 'CFTypeRef' with a +1 retain count
      message
-     Call to function 'CFCreateSomething' returns a Core Foundation object of type CFTypeRef with a +1 retain count
+     Call to function 'CFCreateSomething' returns a Core Foundation object of type 'CFTypeRef' with a +1 retain count
     
     
      kindcontrol
@@ -4571,9 +4571,9 @@
      
      depth0
      extended_message
-     Call to function 'CFGetSomething' returns a Core Foundation object of type CFTypeRef with a +0 retain count
+     Call to function 'CFGetSomething' returns a Core Foundation object of type 'CFTypeRef' with a +0 retain count
      message
-     Call to function 'CFGetSomething' returns a Core Foundation object of type CFTypeRef with a +0 retain count
+     Call to function 'CFGetSomething' returns a Core Foundation object of type 'CFTypeRef' with a +0 retain count
     
     
      kindcontrol
@@ -4768,9 +4768,9 @@
      
      depth0
      extended_message
-     Call to function 'CFGetSomething' returns a Core Foundation object of type CFTypeRef with a +0 retain count
+     Call to function 'CFGetSomething' returns a Core Foundation object of type 'CFTypeRef' with a +0 retain count
      message
-     Call to function 'CFGetSomething' returns a Core Foundation object of type CFTypeRef with a +0 retain count
+     Call to function 'CFGetSomething' returns a Core Foundation object of type 'CFTypeRef' with a +0 retain count
     
     
      kindcontrol
diff --git a/test/Analysis/objc-radar17039661.m b/test/Analysis/objc-radar17039661.m
index 5f7c531eae..484e43c5dd 100644
--- a/test/Analysis/objc-radar17039661.m
+++ b/test/Analysis/objc-radar17039661.m
@@ -1,6 +1,7 @@
 // RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.RetainCount -fblocks -verify %s
 // RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.RetainCount -fblocks -analyzer-output=plist-multi-file %s -o %t
-// RUN: FileCheck --input-file=%t %s
+// RUN: cat %t | %diff_plist %S/Inputs/expected-plists/objc-radar17039661.m.plist -
+
 @class NSString;
 typedef long NSInteger;
 typedef unsigned char BOOL;
@@ -58,1276 +59,3 @@ void runTest() {
     return;
   }
 }
-
-// CHECK: diagnostics
-// CHECK: 
-// CHECK:  
-// CHECK:   path
-// CHECK:   
-// CHECK:    
-// CHECK:     kindcontrol
-// CHECK:     edges
-// CHECK:      
-// CHECK:       
-// CHECK:        start
-// CHECK:         
-// CHECK:          
-// CHECK:           line48
-// CHECK:           col3
-// CHECK:           file0
-// CHECK:          
-// CHECK:          
-// CHECK:           line48
-// CHECK:           col15
-// CHECK:           file0
-// CHECK:          
-// CHECK:         
-// CHECK:        end
-// CHECK:         
-// CHECK:          
-// CHECK:           line49
-// CHECK:           col3
-// CHECK:           file0
-// CHECK:          
-// CHECK:          
-// CHECK:           line49
-// CHECK:           col6
-// CHECK:           file0
-// CHECK:          
-// CHECK:         
-// CHECK:       
-// CHECK:      
-// CHECK:    
-// CHECK:    
-// CHECK:     kindcontrol
-// CHECK:     edges
-// CHECK:      
-// CHECK:       
-// CHECK:        start
-// CHECK:         
-// CHECK:          
-// CHECK:           line49
-// CHECK:           col3
-// CHECK:           file0
-// CHECK:          
-// CHECK:          
-// CHECK:           line49
-// CHECK:           col6
-// CHECK:           file0
-// CHECK:          
-// CHECK:         
-// CHECK:        end
-// CHECK:         
-// CHECK:          
-// CHECK:           line49
-// CHECK:           col26
-// CHECK:           file0
-// CHECK:          
-// CHECK:          
-// CHECK:           line49
-// CHECK:           col38
-// CHECK:           file0
-// CHECK:          
-// CHECK:         
-// CHECK:       
-// CHECK:      
-// CHECK:    
-// CHECK:    
-// CHECK:     kindevent
-// CHECK:     location
-// CHECK:     
-// CHECK:      line49
-// CHECK:      col26
-// CHECK:      file0
-// CHECK:     
-// CHECK:     ranges
-// CHECK:     
-// CHECK:       
-// CHECK:        
-// CHECK:         line49
-// CHECK:         col26
-// CHECK:         file0
-// CHECK:        
-// CHECK:        
-// CHECK:         line53
-// CHECK:         col4
-// CHECK:         file0
-// CHECK:        
-// CHECK:       
-// CHECK:     
-// CHECK:     depth0
-// CHECK:     extended_message
-// CHECK:     Calling 'performAction'
-// CHECK:     message
-// CHECK:     Calling 'performAction'
-// CHECK:    
-// CHECK:    
-// CHECK:     kindevent
-// CHECK:     location
-// CHECK:     
-// CHECK:      line27
-// CHECK:      col1
-// CHECK:      file0
-// CHECK:     
-// CHECK:     depth1
-// CHECK:     extended_message
-// CHECK:     Entered call from 'runTest'
-// CHECK:     message
-// CHECK:     Entered call from 'runTest'
-// CHECK:    
-// CHECK:    
-// CHECK:     kindcontrol
-// CHECK:     edges
-// CHECK:      
-// CHECK:       
-// CHECK:        start
-// CHECK:         
-// CHECK:          
-// CHECK:           line27
-// CHECK:           col1
-// CHECK:           file0
-// CHECK:          
-// CHECK:          
-// CHECK:           line27
-// CHECK:           col6
-// CHECK:           file0
-// CHECK:          
-// CHECK:         
-// CHECK:        end
-// CHECK:         
-// CHECK:          
-// CHECK:           line28
-// CHECK:           col3
-// CHECK:           file0
-// CHECK:          
-// CHECK:          
-// CHECK:           line28
-// CHECK:           col15
-// CHECK:           file0
-// CHECK:          
-// CHECK:         
-// CHECK:       
-// CHECK:      
-// CHECK:    
-// CHECK:    
-// CHECK:     kindcontrol
-// CHECK:     edges
-// CHECK:      
-// CHECK:       
-// CHECK:        start
-// CHECK:         
-// CHECK:          
-// CHECK:           line28
-// CHECK:           col3
-// CHECK:           file0
-// CHECK:          
-// CHECK:          
-// CHECK:           line28
-// CHECK:           col15
-// CHECK:           file0
-// CHECK:          
-// CHECK:         
-// CHECK:        end
-// CHECK:         
-// CHECK:          
-// CHECK:           line29
-// CHECK:           col3
-// CHECK:           file0
-// CHECK:          
-// CHECK:          
-// CHECK:           line29
-// CHECK:           col21
-// CHECK:           file0
-// CHECK:          
-// CHECK:         
-// CHECK:       
-// CHECK:      
-// CHECK:    
-// CHECK:    
-// CHECK:     kindevent
-// CHECK:     location
-// CHECK:     
-// CHECK:      line29
-// CHECK:      col3
-// CHECK:      file0
-// CHECK:     
-// CHECK:     ranges
-// CHECK:     
-// CHECK:       
-// CHECK:        
-// CHECK:         line29
-// CHECK:         col3
-// CHECK:         file0
-// CHECK:        
-// CHECK:        
-// CHECK:         line43
-// CHECK:         col4
-// CHECK:         file0
-// CHECK:        
-// CHECK:       
-// CHECK:     
-// CHECK:     depth1
-// CHECK:     extended_message
-// CHECK:     Calling 'reallyPerformAction'
-// CHECK:     message
-// CHECK:     Calling 'reallyPerformAction'
-// CHECK:    
-// CHECK:    
-// CHECK:     kindevent
-// CHECK:     location
-// CHECK:     
-// CHECK:      line22
-// CHECK:      col1
-// CHECK:      file0
-// CHECK:     
-// CHECK:     depth2
-// CHECK:     extended_message
-// CHECK:     Entered call from 'performAction'
-// CHECK:     message
-// CHECK:     Entered call from 'performAction'
-// CHECK:    
-// CHECK:    
-// CHECK:     kindcontrol
-// CHECK:     edges
-// CHECK:      
-// CHECK:       
-// CHECK:        start
-// CHECK:         
-// CHECK:          
-// CHECK:           line22
-// CHECK:           col1
-// CHECK:           file0
-// CHECK:          
-// CHECK:          
-// CHECK:           line22
-// CHECK:           col6
-// CHECK:           file0
-// CHECK:          
-// CHECK:         
-// CHECK:        end
-// CHECK:         
-// CHECK:          
-// CHECK:           line23
-// CHECK:           col3
-// CHECK:           file0
-// CHECK:          
-// CHECK:          
-// CHECK:           line23
-// CHECK:           col16
-// CHECK:           file0
-// CHECK:          
-// CHECK:         
-// CHECK:       
-// CHECK:      
-// CHECK:    
-// CHECK:    
-// CHECK:     kindevent
-// CHECK:     location
-// CHECK:     
-// CHECK:      line23
-// CHECK:      col3
-// CHECK:      file0
-// CHECK:     
-// CHECK:     ranges
-// CHECK:     
-// CHECK:       
-// CHECK:        
-// CHECK:         line23
-// CHECK:         col3
-// CHECK:         file0
-// CHECK:        
-// CHECK:        
-// CHECK:         line23
-// CHECK:         col58
-// CHECK:         file0
-// CHECK:        
-// CHECK:       
-// CHECK:     
-// CHECK:     depth2
-// CHECK:     extended_message
-// CHECK:     Calling anonymous block
-// CHECK:     message
-// CHECK:     Calling anonymous block
-// CHECK:    
-// CHECK:    
-// CHECK:     kindevent
-// CHECK:     location
-// CHECK:     
-// CHECK:      line29
-// CHECK:      col23
-// CHECK:      file0
-// CHECK:     
-// CHECK:     depth3
-// CHECK:     extended_message
-// CHECK:     Entered call from 'reallyPerformAction'
-// CHECK:     message
-// CHECK:     Entered call from 'reallyPerformAction'
-// CHECK:    
-// CHECK:    
-// CHECK:     kindcontrol
-// CHECK:     edges
-// CHECK:      
-// CHECK:       
-// CHECK:        start
-// CHECK:         
-// CHECK:          
-// CHECK:           line29
-// CHECK:           col23
-// CHECK:           file0
-// CHECK:          
-// CHECK:          
-// CHECK:           line29
-// CHECK:           col23
-// CHECK:           file0
-// CHECK:          
-// CHECK:         
-// CHECK:        end
-// CHECK:         
-// CHECK:          
-// CHECK:           line31
-// CHECK:           col5
-// CHECK:           file0
-// CHECK:          
-// CHECK:          
-// CHECK:           line31
-// CHECK:           col6
-// CHECK:           file0
-// CHECK:          
-// CHECK:         
-// CHECK:       
-// CHECK:      
-// CHECK:    
-// CHECK:    
-// CHECK:     kindcontrol
-// CHECK:     edges
-// CHECK:      
-// CHECK:       
-// CHECK:        start
-// CHECK:         
-// CHECK:          
-// CHECK:           line31
-// CHECK:           col5
-// CHECK:           file0
-// CHECK:          
-// CHECK:          
-// CHECK:           line31
-// CHECK:           col6
-// CHECK:           file0
-// CHECK:          
-// CHECK:         
-// CHECK:        end
-// CHECK:         
-// CHECK:          
-// CHECK:           line31
-// CHECK:           col9
-// CHECK:           file0
-// CHECK:          
-// CHECK:          
-// CHECK:           line31
-// CHECK:           col12
-// CHECK:           file0
-// CHECK:          
-// CHECK:         
-// CHECK:       
-// CHECK:      
-// CHECK:    
-// CHECK:    
-// CHECK:     kindevent
-// CHECK:     location
-// CHECK:     
-// CHECK:      line31
-// CHECK:      col9
-// CHECK:      file0
-// CHECK:     
-// CHECK:     ranges
-// CHECK:     
-// CHECK:       
-// CHECK:        
-// CHECK:         line31
-// CHECK:         col9
-// CHECK:         file0
-// CHECK:        
-// CHECK:        
-// CHECK:         line31
-// CHECK:         col12
-// CHECK:         file0
-// CHECK:        
-// CHECK:       
-// CHECK:     
-// CHECK:     depth3
-// CHECK:     extended_message
-// CHECK:     Assuming 'cond' is not equal to 0
-// CHECK:     message
-// CHECK:     Assuming 'cond' is not equal to 0
-// CHECK:    
-// CHECK:    
-// CHECK:     kindcontrol
-// CHECK:     edges
-// CHECK:      
-// CHECK:       
-// CHECK:        start
-// CHECK:         
-// CHECK:          
-// CHECK:           line31
-// CHECK:           col9
-// CHECK:           file0
-// CHECK:          
-// CHECK:          
-// CHECK:           line31
-// CHECK:           col12
-// CHECK:           file0
-// CHECK:          
-// CHECK:         
-// CHECK:        end
-// CHECK:         
-// CHECK:          
-// CHECK:           line33
-// CHECK:           col7
-// CHECK:           file0
-// CHECK:          
-// CHECK:          
-// CHECK:           line33
-// CHECK:           col14
-// CHECK:           file0
-// CHECK:          
-// CHECK:         
-// CHECK:       
-// CHECK:      
-// CHECK:    
-// CHECK:    
-// CHECK:     kindevent
-// CHECK:     location
-// CHECK:     
-// CHECK:      line33
-// CHECK:      col30
-// CHECK:      file0
-// CHECK:     
-// CHECK:     ranges
-// CHECK:     
-// CHECK:       
-// CHECK:        
-// CHECK:         line33
-// CHECK:         col30
-// CHECK:         file0
-// CHECK:        
-// CHECK:        
-// CHECK:         line33
-// CHECK:         col50
-// CHECK:         file0
-// CHECK:        
-// CHECK:       
-// CHECK:     
-// CHECK:     depth3
-// CHECK:     extended_message
-// CHECK:     NSNumber boxed expression produces an object with a +0 retain count
-// CHECK:     message
-// CHECK:     NSNumber boxed expression produces an object with a +0 retain count
-// CHECK:    
-// CHECK:    
-// CHECK:     kindcontrol
-// CHECK:     edges
-// CHECK:      
-// CHECK:       
-// CHECK:        start
-// CHECK:         
-// CHECK:          
-// CHECK:           line33
-// CHECK:           col7
-// CHECK:           file0
-// CHECK:          
-// CHECK:          
-// CHECK:           line33
-// CHECK:           col14
-// CHECK:           file0
-// CHECK:          
-// CHECK:         
-// CHECK:        end
-// CHECK:         
-// CHECK:          
-// CHECK:           line35
-// CHECK:           col7
-// CHECK:           file0
-// CHECK:          
-// CHECK:          
-// CHECK:           line35
-// CHECK:           col14
-// CHECK:           file0
-// CHECK:          
-// CHECK:         
-// CHECK:       
-// CHECK:      
-// CHECK:    
-// CHECK:    
-// CHECK:     kindcontrol
-// CHECK:     edges
-// CHECK:      
-// CHECK:       
-// CHECK:        start
-// CHECK:         
-// CHECK:          
-// CHECK:           line35
-// CHECK:           col7
-// CHECK:           file0
-// CHECK:          
-// CHECK:          
-// CHECK:           line35
-// CHECK:           col14
-// CHECK:           file0
-// CHECK:          
-// CHECK:         
-// CHECK:        end
-// CHECK:         
-// CHECK:          
-// CHECK:           line35
-// CHECK:           col33
-// CHECK:           file0
-// CHECK:          
-// CHECK:          
-// CHECK:           line35
-// CHECK:           col38
-// CHECK:           file0
-// CHECK:          
-// CHECK:         
-// CHECK:       
-// CHECK:      
-// CHECK:    
-// CHECK:    
-// CHECK:     kindevent
-// CHECK:     location
-// CHECK:     
-// CHECK:      line35
-// CHECK:      col33
-// CHECK:      file0
-// CHECK:     
-// CHECK:     ranges
-// CHECK:     
-// CHECK:       
-// CHECK:        
-// CHECK:         line35
-// CHECK:         col33
-// CHECK:         file0
-// CHECK:        
-// CHECK:        
-// CHECK:         line35
-// CHECK:         col50
-// CHECK:         file0
-// CHECK:        
-// CHECK:       
-// CHECK:     
-// CHECK:     depth3
-// CHECK:     extended_message
-// CHECK:     Calling anonymous block
-// CHECK:     message
-// CHECK:     Calling anonymous block
-// CHECK:    
-// CHECK:    
-// CHECK:     kindevent
-// CHECK:     location
-// CHECK:     
-// CHECK:      line49
-// CHECK:      col40
-// CHECK:      file0
-// CHECK:     
-// CHECK:     depth4
-// CHECK:     extended_message
-// CHECK:     Entered call
-// CHECK:     message
-// CHECK:     Entered call
-// CHECK:    
-// CHECK:    
-// CHECK:     kindcontrol
-// CHECK:     edges
-// CHECK:      
-// CHECK:       
-// CHECK:        start
-// CHECK:         
-// CHECK:          
-// CHECK:           line49
-// CHECK:           col40
-// CHECK:           file0
-// CHECK:          
-// CHECK:          
-// CHECK:           line49
-// CHECK:           col40
-// CHECK:           file0
-// CHECK:          
-// CHECK:         
-// CHECK:        end
-// CHECK:         
-// CHECK:          
-// CHECK:           line50
-// CHECK:           col5
-// CHECK:           file0
-// CHECK:          
-// CHECK:          
-// CHECK:           line50
-// CHECK:           col17
-// CHECK:           file0
-// CHECK:          
-// CHECK:         
-// CHECK:       
-// CHECK:      
-// CHECK:    
-// CHECK:    
-// CHECK:     kindevent
-// CHECK:     location
-// CHECK:     
-// CHECK:      line50
-// CHECK:      col21
-// CHECK:      file0
-// CHECK:     
-// CHECK:     ranges
-// CHECK:     
-// CHECK:       
-// CHECK:        
-// CHECK:         line50
-// CHECK:         col21
-// CHECK:         file0
-// CHECK:        
-// CHECK:        
-// CHECK:         line50
-// CHECK:         col39
-// CHECK:         file0
-// CHECK:        
-// CHECK:       
-// CHECK:       
-// CHECK:        
-// CHECK:         line50
-// CHECK:         col22
-// CHECK:         file0
-// CHECK:        
-// CHECK:        
-// CHECK:         line50
-// CHECK:         col31
-// CHECK:         file0
-// CHECK:        
-// CHECK:       
-// CHECK:     
-// CHECK:     depth4
-// CHECK:     extended_message
-// CHECK:     Reference count incremented. The object now has a +1 retain count
-// CHECK:     message
-// CHECK:     Reference count incremented. The object now has a +1 retain count
-// CHECK:    
-// CHECK:    
-// CHECK:     kindcontrol
-// CHECK:     edges
-// CHECK:      
-// CHECK:       
-// CHECK:        start
-// CHECK:         
-// CHECK:          
-// CHECK:           line50
-// CHECK:           col5
-// CHECK:           file0
-// CHECK:          
-// CHECK:          
-// CHECK:           line50
-// CHECK:           col17
-// CHECK:           file0
-// CHECK:          
-// CHECK:         
-// CHECK:        end
-// CHECK:         
-// CHECK:          
-// CHECK:           line52
-// CHECK:           col5
-// CHECK:           file0
-// CHECK:          
-// CHECK:          
-// CHECK:           line52
-// CHECK:           col10
-// CHECK:           file0
-// CHECK:          
-// CHECK:         
-// CHECK:       
-// CHECK:      
-// CHECK:    
-// CHECK:    
-// CHECK:     kindevent
-// CHECK:     location
-// CHECK:     
-// CHECK:      line35
-// CHECK:      col33
-// CHECK:      file0
-// CHECK:     
-// CHECK:     ranges
-// CHECK:     
-// CHECK:       
-// CHECK:        
-// CHECK:         line35
-// CHECK:         col33
-// CHECK:         file0
-// CHECK:        
-// CHECK:        
-// CHECK:         line35
-// CHECK:         col50
-// CHECK:         file0
-// CHECK:        
-// CHECK:       
-// CHECK:     
-// CHECK:     depth3
-// CHECK:     extended_message
-// CHECK:     Returning to caller
-// CHECK:     message
-// CHECK:     Returning to caller
-// CHECK:    
-// CHECK:    
-// CHECK:     kindcontrol
-// CHECK:     edges
-// CHECK:      
-// CHECK:       
-// CHECK:        start
-// CHECK:         
-// CHECK:          
-// CHECK:           line35
-// CHECK:           col33
-// CHECK:           file0
-// CHECK:          
-// CHECK:          
-// CHECK:           line35
-// CHECK:           col38
-// CHECK:           file0
-// CHECK:          
-// CHECK:         
-// CHECK:        end
-// CHECK:         
-// CHECK:          
-// CHECK:           line35
-// CHECK:           col7
-// CHECK:           file0
-// CHECK:          
-// CHECK:          
-// CHECK:           line35
-// CHECK:           col14
-// CHECK:           file0
-// CHECK:          
-// CHECK:         
-// CHECK:       
-// CHECK:      
-// CHECK:    
-// CHECK:    
-// CHECK:     kindcontrol
-// CHECK:     edges
-// CHECK:      
-// CHECK:       
-// CHECK:        start
-// CHECK:         
-// CHECK:          
-// CHECK:           line35
-// CHECK:           col7
-// CHECK:           file0
-// CHECK:          
-// CHECK:          
-// CHECK:           line35
-// CHECK:           col14
-// CHECK:           file0
-// CHECK:          
-// CHECK:         
-// CHECK:        end
-// CHECK:         
-// CHECK:          
-// CHECK:           line37
-// CHECK:           col7
-// CHECK:           file0
-// CHECK:          
-// CHECK:          
-// CHECK:           line37
-// CHECK:           col8
-// CHECK:           file0
-// CHECK:          
-// CHECK:         
-// CHECK:       
-// CHECK:      
-// CHECK:    
-// CHECK:    
-// CHECK:     kindcontrol
-// CHECK:     edges
-// CHECK:      
-// CHECK:       
-// CHECK:        start
-// CHECK:         
-// CHECK:          
-// CHECK:           line37
-// CHECK:           col7
-// CHECK:           file0
-// CHECK:          
-// CHECK:          
-// CHECK:           line37
-// CHECK:           col8
-// CHECK:           file0
-// CHECK:          
-// CHECK:         
-// CHECK:        end
-// CHECK:         
-// CHECK:          
-// CHECK:           line40
-// CHECK:           col7
-// CHECK:           file0
-// CHECK:          
-// CHECK:          
-// CHECK:           line40
-// CHECK:           col18
-// CHECK:           file0
-// CHECK:          
-// CHECK:         
-// CHECK:       
-// CHECK:      
-// CHECK:    
-// CHECK:    
-// CHECK:     kindevent
-// CHECK:     location
-// CHECK:     
-// CHECK:      line23
-// CHECK:      col3
-// CHECK:      file0
-// CHECK:     
-// CHECK:     ranges
-// CHECK:     
-// CHECK:       
-// CHECK:        
-// CHECK:         line23
-// CHECK:         col3
-// CHECK:         file0
-// CHECK:        
-// CHECK:        
-// CHECK:         line23
-// CHECK:         col58
-// CHECK:         file0
-// CHECK:        
-// CHECK:       
-// CHECK:     
-// CHECK:     depth2
-// CHECK:     extended_message
-// CHECK:     Returning to caller
-// CHECK:     message
-// CHECK:     Returning to caller
-// CHECK:    
-// CHECK:    
-// CHECK:     kindcontrol
-// CHECK:     edges
-// CHECK:      
-// CHECK:       
-// CHECK:        start
-// CHECK:         
-// CHECK:          
-// CHECK:           line23
-// CHECK:           col3
-// CHECK:           file0
-// CHECK:          
-// CHECK:          
-// CHECK:           line23
-// CHECK:           col16
-// CHECK:           file0
-// CHECK:          
-// CHECK:         
-// CHECK:        end
-// CHECK:         
-// CHECK:          
-// CHECK:           line24
-// CHECK:           col3
-// CHECK:           file0
-// CHECK:          
-// CHECK:          
-// CHECK:           line24
-// CHECK:           col16
-// CHECK:           file0
-// CHECK:          
-// CHECK:         
-// CHECK:       
-// CHECK:      
-// CHECK:    
-// CHECK:    
-// CHECK:     kindevent
-// CHECK:     location
-// CHECK:     
-// CHECK:      line24
-// CHECK:      col3
-// CHECK:      file0
-// CHECK:     
-// CHECK:     ranges
-// CHECK:     
-// CHECK:       
-// CHECK:        
-// CHECK:         line24
-// CHECK:         col3
-// CHECK:         file0
-// CHECK:        
-// CHECK:        
-// CHECK:         line24
-// CHECK:         col58
-// CHECK:         file0
-// CHECK:        
-// CHECK:       
-// CHECK:     
-// CHECK:     depth2
-// CHECK:     extended_message
-// CHECK:     Calling anonymous block
-// CHECK:     message
-// CHECK:     Calling anonymous block
-// CHECK:    
-// CHECK:    
-// CHECK:     kindevent
-// CHECK:     location
-// CHECK:     
-// CHECK:      line29
-// CHECK:      col23
-// CHECK:      file0
-// CHECK:     
-// CHECK:     depth3
-// CHECK:     extended_message
-// CHECK:     Entered call from 'reallyPerformAction'
-// CHECK:     message
-// CHECK:     Entered call from 'reallyPerformAction'
-// CHECK:    
-// CHECK:    
-// CHECK:     kindcontrol
-// CHECK:     edges
-// CHECK:      
-// CHECK:       
-// CHECK:        start
-// CHECK:         
-// CHECK:          
-// CHECK:           line29
-// CHECK:           col23
-// CHECK:           file0
-// CHECK:          
-// CHECK:          
-// CHECK:           line29
-// CHECK:           col23
-// CHECK:           file0
-// CHECK:          
-// CHECK:         
-// CHECK:        end
-// CHECK:         
-// CHECK:          
-// CHECK:           line31
-// CHECK:           col5
-// CHECK:           file0
-// CHECK:          
-// CHECK:          
-// CHECK:           line31
-// CHECK:           col6
-// CHECK:           file0
-// CHECK:          
-// CHECK:         
-// CHECK:       
-// CHECK:      
-// CHECK:    
-// CHECK:    
-// CHECK:     kindcontrol
-// CHECK:     edges
-// CHECK:      
-// CHECK:       
-// CHECK:        start
-// CHECK:         
-// CHECK:          
-// CHECK:           line31
-// CHECK:           col5
-// CHECK:           file0
-// CHECK:          
-// CHECK:          
-// CHECK:           line31
-// CHECK:           col6
-// CHECK:           file0
-// CHECK:          
-// CHECK:         
-// CHECK:        end
-// CHECK:         
-// CHECK:          
-// CHECK:           line31
-// CHECK:           col9
-// CHECK:           file0
-// CHECK:          
-// CHECK:          
-// CHECK:           line31
-// CHECK:           col12
-// CHECK:           file0
-// CHECK:          
-// CHECK:         
-// CHECK:       
-// CHECK:      
-// CHECK:    
-// CHECK:    
-// CHECK:     kindevent
-// CHECK:     location
-// CHECK:     
-// CHECK:      line31
-// CHECK:      col9
-// CHECK:      file0
-// CHECK:     
-// CHECK:     ranges
-// CHECK:     
-// CHECK:       
-// CHECK:        
-// CHECK:         line31
-// CHECK:         col9
-// CHECK:         file0
-// CHECK:        
-// CHECK:        
-// CHECK:         line31
-// CHECK:         col12
-// CHECK:         file0
-// CHECK:        
-// CHECK:       
-// CHECK:     
-// CHECK:     depth3
-// CHECK:     extended_message
-// CHECK:     Assuming 'cond' is not equal to 0
-// CHECK:     message
-// CHECK:     Assuming 'cond' is not equal to 0
-// CHECK:    
-// CHECK:    
-// CHECK:     kindcontrol
-// CHECK:     edges
-// CHECK:      
-// CHECK:       
-// CHECK:        start
-// CHECK:         
-// CHECK:          
-// CHECK:           line31
-// CHECK:           col9
-// CHECK:           file0
-// CHECK:          
-// CHECK:          
-// CHECK:           line31
-// CHECK:           col12
-// CHECK:           file0
-// CHECK:          
-// CHECK:         
-// CHECK:        end
-// CHECK:         
-// CHECK:          
-// CHECK:           line33
-// CHECK:           col7
-// CHECK:           file0
-// CHECK:          
-// CHECK:          
-// CHECK:           line33
-// CHECK:           col14
-// CHECK:           file0
-// CHECK:          
-// CHECK:         
-// CHECK:       
-// CHECK:      
-// CHECK:    
-// CHECK:    
-// CHECK:     kindcontrol
-// CHECK:     edges
-// CHECK:      
-// CHECK:       
-// CHECK:        start
-// CHECK:         
-// CHECK:          
-// CHECK:           line33
-// CHECK:           col7
-// CHECK:           file0
-// CHECK:          
-// CHECK:          
-// CHECK:           line33
-// CHECK:           col14
-// CHECK:           file0
-// CHECK:          
-// CHECK:         
-// CHECK:        end
-// CHECK:         
-// CHECK:          
-// CHECK:           line35
-// CHECK:           col7
-// CHECK:           file0
-// CHECK:          
-// CHECK:          
-// CHECK:           line35
-// CHECK:           col14
-// CHECK:           file0
-// CHECK:          
-// CHECK:         
-// CHECK:       
-// CHECK:      
-// CHECK:    
-// CHECK:    
-// CHECK:     kindcontrol
-// CHECK:     edges
-// CHECK:      
-// CHECK:       
-// CHECK:        start
-// CHECK:         
-// CHECK:          
-// CHECK:           line35
-// CHECK:           col7
-// CHECK:           file0
-// CHECK:          
-// CHECK:          
-// CHECK:           line35
-// CHECK:           col14
-// CHECK:           file0
-// CHECK:          
-// CHECK:         
-// CHECK:        end
-// CHECK:         
-// CHECK:          
-// CHECK:           line35
-// CHECK:           col33
-// CHECK:           file0
-// CHECK:          
-// CHECK:          
-// CHECK:           line35
-// CHECK:           col38
-// CHECK:           file0
-// CHECK:          
-// CHECK:         
-// CHECK:       
-// CHECK:      
-// CHECK:    
-// CHECK:    
-// CHECK:     kindevent
-// CHECK:     location
-// CHECK:     
-// CHECK:      line35
-// CHECK:      col33
-// CHECK:      file0
-// CHECK:     
-// CHECK:     ranges
-// CHECK:     
-// CHECK:       
-// CHECK:        
-// CHECK:         line35
-// CHECK:         col33
-// CHECK:         file0
-// CHECK:        
-// CHECK:        
-// CHECK:         line35
-// CHECK:         col50
-// CHECK:         file0
-// CHECK:        
-// CHECK:       
-// CHECK:     
-// CHECK:     depth3
-// CHECK:     extended_message
-// CHECK:     Calling anonymous block
-// CHECK:     message
-// CHECK:     Calling anonymous block
-// CHECK:    
-// CHECK:    
-// CHECK:     kindevent
-// CHECK:     location
-// CHECK:     
-// CHECK:      line49
-// CHECK:      col40
-// CHECK:      file0
-// CHECK:     
-// CHECK:     depth4
-// CHECK:     extended_message
-// CHECK:     Entered call
-// CHECK:     message
-// CHECK:     Entered call
-// CHECK:    
-// CHECK:    
-// CHECK:     kindcontrol
-// CHECK:     edges
-// CHECK:      
-// CHECK:       
-// CHECK:        start
-// CHECK:         
-// CHECK:          
-// CHECK:           line49
-// CHECK:           col40
-// CHECK:           file0
-// CHECK:          
-// CHECK:          
-// CHECK:           line49
-// CHECK:           col40
-// CHECK:           file0
-// CHECK:          
-// CHECK:         
-// CHECK:        end
-// CHECK:         
-// CHECK:          
-// CHECK:           line50
-// CHECK:           col5
-// CHECK:           file0
-// CHECK:          
-// CHECK:          
-// CHECK:           line50
-// CHECK:           col17
-// CHECK:           file0
-// CHECK:          
-// CHECK:         
-// CHECK:       
-// CHECK:      
-// CHECK:    
-// CHECK:    
-// CHECK:     kindcontrol
-// CHECK:     edges
-// CHECK:      
-// CHECK:       
-// CHECK:        start
-// CHECK:         
-// CHECK:          
-// CHECK:           line50
-// CHECK:           col5
-// CHECK:           file0
-// CHECK:          
-// CHECK:          
-// CHECK:           line50
-// CHECK:           col17
-// CHECK:           file0
-// CHECK:          
-// CHECK:         
-// CHECK:        end
-// CHECK:         
-// CHECK:          
-// CHECK:           line52
-// CHECK:           col5
-// CHECK:           file0
-// CHECK:          
-// CHECK:          
-// CHECK:           line52
-// CHECK:           col10
-// CHECK:           file0
-// CHECK:          
-// CHECK:         
-// CHECK:       
-// CHECK:      
-// CHECK:    
-// CHECK:    
-// CHECK:     kindevent
-// CHECK:     location
-// CHECK:     
-// CHECK:      line52
-// CHECK:      col5
-// CHECK:      file0
-// CHECK:     
-// CHECK:     ranges
-// CHECK:     
-// CHECK:       
-// CHECK:        
-// CHECK:         line52
-// CHECK:         col5
-// CHECK:         file0
-// CHECK:        
-// CHECK:        
-// CHECK:         line52
-// CHECK:         col21
-// CHECK:         file0
-// CHECK:        
-// CHECK:       
-// CHECK:     
-// CHECK:     depth4
-// CHECK:     extended_message
-// CHECK:     Object leaked: allocated object of type NSNumber * is not referenced later in this execution path and has a retain count of +1
-// CHECK:     message
-// CHECK:     Object leaked: allocated object of type NSNumber * is not referenced later in this execution path and has a retain count of +1
-// CHECK:    
-// CHECK:   
-// CHECK:   descriptionPotential leak of an object of type NSNumber *
-// CHECK:   categoryMemory (Core Foundation/Objective-C)
-// CHECK:   typeLeak
-// CHECK:  location
-// CHECK:  
-// CHECK:   line52
-// CHECK:   col5
-// CHECK:   file0
-// CHECK:  
-// CHECK:  
-// CHECK: 
diff --git a/test/Analysis/osobject-retain-release.cpp b/test/Analysis/osobject-retain-release.cpp
index 1fc5e31aa5..ca8a45c37f 100644
--- a/test/Analysis/osobject-retain-release.cpp
+++ b/test/Analysis/osobject-retain-release.cpp
@@ -117,14 +117,14 @@ void os_consume_ok(OS_CONSUME OSObject *obj) {
 }
 
 void use_os_consume_violation() {
-  OSObject *obj = new OSObject; // expected-note{{Operator 'new' returns an OSObject of type OSObject with a +1 retain count}}
+  OSObject *obj = new OSObject; // expected-note{{Operator 'new' returns an OSObject of type 'OSObject' with a +1 retain count}}
   os_consume_violation(obj); // expected-note{{Calling 'os_consume_violation'}}
                              // expected-note@-1{{Returning from 'os_consume_violation'}}
 } // expected-note{{Object leaked: object allocated and stored into 'obj' is not referenced later in this execution path and has a retain count of +1}}
   // expected-warning@-1{{Potential leak of an object stored into 'obj'}}
 
 void use_os_consume_violation_two_args() {
-  OSObject *obj = new OSObject; // expected-note{{Operator 'new' returns an OSObject of type OSObject with a +1 retain count}}
+  OSObject *obj = new OSObject; // expected-note{{Operator 'new' returns an OSObject of type 'OSObject' with a +1 retain count}}
   os_consume_violation_two_args(obj, coin()); // expected-note{{Calling 'os_consume_violation_two_args'}}
                              // expected-note@-1{{Returning from 'os_consume_violation_two_args'}}
 } // expected-note{{Object leaked: object allocated and stored into 'obj' is not referenced later in this execution path and has a retain count of +1}}
@@ -195,7 +195,7 @@ void check_free_no_error() {
 }
 
 void check_free_use_after_free() {
-  OSArray *arr = OSArray::withCapacity(10); // expected-note{{Call to method 'OSArray::withCapacity' returns an OSObject of type OSArray with a +1 retain count}}
+  OSArray *arr = OSArray::withCapacity(10); // expected-note{{Call to method 'OSArray::withCapacity' returns an OSObject of type 'OSArray' with a +1 retain count}}
   arr->retain(); // expected-note{{Reference count incremented. The object now has a +2 retain count}}
   arr->free(); // expected-note{{Object released}}
   arr->retain(); // expected-warning{{Reference-counted object is used after it is released}}
@@ -203,13 +203,13 @@ void check_free_use_after_free() {
 }
 
 unsigned int check_leak_explicit_new() {
-  OSArray *arr = new OSArray; // expected-note{{Operator 'new' returns an OSObject of type OSArray with a +1 retain count}}
+  OSArray *arr = new OSArray; // expected-note{{Operator 'new' returns an OSObject of type 'OSArray' with a +1 retain count}}
   return arr->getCount(); // expected-note{{Object leaked: object allocated and stored into 'arr' is not referenced later in this execution path and has a retain count of +1}}
                           // expected-warning@-1{{Potential leak of an object stored into 'arr'}}
 }
 
 unsigned int check_leak_factory() {
-  OSArray *arr = OSArray::withCapacity(10); // expected-note{{Call to method 'OSArray::withCapacity' returns an OSObject of type OSArray with a +1 retain count}}
+  OSArray *arr = OSArray::withCapacity(10); // expected-note{{Call to method 'OSArray::withCapacity' returns an OSObject of type 'OSArray' with a +1 retain count}}
   return arr->getCount(); // expected-note{{Object leaked: object allocated and stored into 'arr' is not referenced later in this execution path and has a retain count of +1}}
                           // expected-warning@-1{{Potential leak of an object stored into 'arr'}}
 }
@@ -228,18 +228,18 @@ void check_custom_iterator_rule(OSArray *arr) {
 }
 
 void check_iterator_leak(OSArray *arr) {
-  arr->getIterator(); // expected-note{{Call to method 'OSArray::getIterator' returns an OSObject of type OSIterator with a +1 retain count}}
-} // expected-note{{Object leaked: allocated object of type OSIterator is not referenced later}}
-  // expected-warning@-1{{Potential leak of an object of type OSIterator}}
+  arr->getIterator(); // expected-note{{Call to method 'OSArray::getIterator' returns an OSObject of type 'OSIterator' with a +1 retain count}}
+} // expected-note{{Object leaked: allocated object of type 'OSIterator' is not referenced later}}
+  // expected-warning@-1{{Potential leak of an object of type 'OSIterator}}'
 
 void check_no_invalidation() {
-  OSArray *arr = OSArray::withCapacity(10); // expected-note{{Call to method 'OSArray::withCapacity' returns an OSObject of type OSArray with a +1 retain count}}
+  OSArray *arr = OSArray::withCapacity(10); // expected-note{{Call to method 'OSArray::withCapacity' returns an OSObject of type 'OSArray' with a +1 retain count}}
   OtherStruct::doNothingToArray(arr);
 } // expected-warning{{Potential leak of an object stored into 'arr'}}
   // expected-note@-1{{Object leaked}}
 
 void check_no_invalidation_other_struct() {
-  OSArray *arr = OSArray::withCapacity(10); // expected-note{{Call to method 'OSArray::withCapacity' returns an OSObject of type OSArray with a +1 retain count}}
+  OSArray *arr = OSArray::withCapacity(10); // expected-note{{Call to method 'OSArray::withCapacity' returns an OSObject of type 'OSArray' with a +1 retain count}}
   OtherStruct other(arr); // expected-warning{{Potential leak}}
                           // expected-note@-1{{Object leaked}}
 }
@@ -266,8 +266,8 @@ struct ArrayOwner : public OSObject {
 };
 
 OSArray *generateArray() {
-  return OSArray::withCapacity(10); // expected-note{{Call to method 'OSArray::withCapacity' returns an OSObject of type OSArray with a +1 retain count}}
-                                    // expected-note@-1{{Call to method 'OSArray::withCapacity' returns an OSObject of type OSArray with a +1 retain count}}
+  return OSArray::withCapacity(10); // expected-note{{Call to method 'OSArray::withCapacity' returns an OSObject of type 'OSArray' with a +1 retain count}}
+                                    // expected-note@-1{{Call to method 'OSArray::withCapacity' returns an OSObject of type 'OSArray' with a +1 retain count}}
 }
 
 unsigned int check_leak_good_error_message() {
@@ -285,7 +285,7 @@ unsigned int check_leak_msg_temporary() {
   return generateArray()->getCount(); // expected-warning{{Potential leak of an object}}
                                       // expected-note@-1{{Calling 'generateArray'}}
                                       // expected-note@-2{{Returning from 'generateArray'}}
-                                      // expected-note@-3{{Object leaked: allocated object of type OSArray is not referenced later in this execution path and has a retain count of +1}}
+                                      // expected-note@-3{{Object leaked: allocated object of type 'OSArray' is not referenced later in this execution path and has a retain count of +1}}
 }
 
 void check_confusing_getters() {
@@ -354,14 +354,14 @@ void check_dynamic_cast_null_check() {
 }
 
 void use_after_release() {
-  OSArray *arr = OSArray::withCapacity(10); // expected-note{{Call to method 'OSArray::withCapacity' returns an OSObject of type OSArray with a +1 retain count}}
+  OSArray *arr = OSArray::withCapacity(10); // expected-note{{Call to method 'OSArray::withCapacity' returns an OSObject of type 'OSArray' with a +1 retain count}}
   arr->release(); // expected-note{{Object released}}
   arr->getCount(); // expected-warning{{Reference-counted object is used after it is released}}
                    // expected-note@-1{{Reference-counted object is used after it is released}}
 }
 
 void potential_leak() {
-  OSArray *arr = OSArray::withCapacity(10); // expected-note{{Call to method 'OSArray::withCapacity' returns an OSObject of type OSArray with a +1 retain count}}
+  OSArray *arr = OSArray::withCapacity(10); // expected-note{{Call to method 'OSArray::withCapacity' returns an OSObject of type 'OSArray' with a +1 retain count}}
   arr->retain(); // expected-note{{Reference count incremented. The object now has a +2 retain count}}
   arr->release(); // expected-note{{Reference count decremented. The object now has a +1 retain count}}
   arr->getCount();
@@ -412,7 +412,7 @@ unsigned int no_warn_ok_release(ArrayOwner *owner) {
 }
 
 unsigned int warn_on_overrelease_with_unknown_source(ArrayOwner *owner) {
-  OSArray *arr = owner->getArraySourceUnknown(); // expected-note{{Call to method 'ArrayOwner::getArraySourceUnknown' returns an OSObject of type OSArray with a +0 retain count}}
+  OSArray *arr = owner->getArraySourceUnknown(); // expected-note{{Call to method 'ArrayOwner::getArraySourceUnknown' returns an OSObject of type 'OSArray' with a +0 retain count}}
   arr->release(); // expected-warning{{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}}
                   // expected-note@-1{{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}}
   return arr->getCount();
diff --git a/test/Analysis/retain-release-arc.m b/test/Analysis/retain-release-arc.m
index 702f8a4116..31081e964a 100644
--- a/test/Analysis/retain-release-arc.m
+++ b/test/Analysis/retain-release-arc.m
@@ -90,7 +90,7 @@ void _dispatch_object_validate(dispatch_object_t object);
   CFErrorRef error;
   CFDictionaryRef testDict = CFPropertyListCreateWithData(kCFAllocatorDefault, (__bridge CFDataRef)plistData, 0, 0, &error);
 #if HAS_ARC
-      // expected-note@-2 {{Call to function 'CFPropertyListCreateWithData' returns a Core Foundation object of type CFPropertyListRef with a +1 retain count}}
+      // expected-note@-2 {{Call to function 'CFPropertyListCreateWithData' returns a Core Foundation object of type 'CFPropertyListRef' with a +1 retain count}}
 #endif
   return (__bridge NSDictionary *)testDict;
 #if HAS_ARC
diff --git a/test/Analysis/retain-release-path-notes.m b/test/Analysis/retain-release-path-notes.m
index bd24b6aa80..23171eda1c 100644
--- a/test/Analysis/retain-release-path-notes.m
+++ b/test/Analysis/retain-release-path-notes.m
@@ -49,7 +49,7 @@ void creationViaAlloc () {
 }
 
 void creationViaCFCreate () {
-  CFTypeRef leaked = CFCreateSomething(); // expected-note{{Call to function 'CFCreateSomething' returns a Core Foundation object of type CFTypeRef with a +1 retain count}}
+  CFTypeRef leaked = CFCreateSomething(); // expected-note{{Call to function 'CFCreateSomething' returns a Core Foundation object of type 'CFTypeRef' with a +1 retain count}}
   return; // expected-warning{{leak}} expected-note{{Object leaked: object allocated and stored into 'leaked' is not referenced later in this execution path and has a retain count of +1}}
 }
 
@@ -68,7 +68,7 @@ void acquisitionViaProperty (Foo *foo) {
 }
 
 void acquisitionViaCFFunction () {
-  CFTypeRef leaked = CFGetSomething(); // expected-note{{Call to function 'CFGetSomething' returns a Core Foundation object of type CFTypeRef with a +0 retain count}}
+  CFTypeRef leaked = CFGetSomething(); // expected-note{{Call to function 'CFGetSomething' returns a Core Foundation object of type 'CFTypeRef' with a +0 retain count}}
   CFRetain(leaked); // expected-note{{Reference count incremented. The object now has a +1 retain count}}
   return; // expected-warning{{leak}} expected-note{{Object leaked: object allocated and stored into 'leaked' is not referenced later in this execution path and has a retain count of +1}}
 }
@@ -99,19 +99,19 @@ void autoreleaseUnowned (Foo *foo) {
 }
 
 void makeCollectableIgnored() {
-  CFTypeRef leaked = CFCreateSomething(); // expected-note{{Call to function 'CFCreateSomething' returns a Core Foundation object of type CFTypeRef with a +1 retain count}}
+  CFTypeRef leaked = CFCreateSomething(); // expected-note{{Call to function 'CFCreateSomething' returns a Core Foundation object of type 'CFTypeRef' with a +1 retain count}}
   CFMakeCollectable(leaked);
   NSMakeCollectable(leaked);
   return; // expected-warning{{leak}} expected-note{{Object leaked: object allocated and stored into 'leaked' is not referenced later in this execution path and has a retain count of +1}}
 }
 
 CFTypeRef CFCopyRuleViolation () {
-  CFTypeRef object = CFGetSomething(); // expected-note{{Call to function 'CFGetSomething' returns a Core Foundation object of type CFTypeRef with a +0 retain count}}
+  CFTypeRef object = CFGetSomething(); // expected-note{{Call to function 'CFGetSomething' returns a Core Foundation object of type 'CFTypeRef' with a +0 retain count}}
   return object; // expected-warning{{Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected}} expected-note{{Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected}}
 }
 
 CFTypeRef CFGetRuleViolation () {
-  CFTypeRef object = CFCreateSomething(); // expected-note{{Call to function 'CFCreateSomething' returns a Core Foundation object of type CFTypeRef with a +1 retain count}}
+  CFTypeRef object = CFCreateSomething(); // expected-note{{Call to function 'CFCreateSomething' returns a Core Foundation object of type 'CFTypeRef' with a +1 retain count}}
   return object; // expected-warning{{leak}} expected-note{{Object leaked: object allocated and stored into 'object' is returned from a function whose name ('CFGetRuleViolation') does not contain 'Copy' or 'Create'.  This violates the naming convention rules given in the Memory Management Guide for Core Foundation}}
 }
 
@@ -227,7 +227,7 @@ static int Cond;
                                 // expected-note@-1 {{Method returns an instance of MyObj with a +1 retain count}}
                                 // expected-note@-2 {{Calling 'initX'}}
                                 // expected-note@-3 {{Returning from 'initX'}}
-                                // expected-note@-4 {{Object leaked: allocated object of type MyObj * is not referenced later in this execution path and has a retain count of +1}}
+                                // expected-note@-4 {{Object leaked: allocated object of type 'MyObj *' is not referenced later in this execution path and has a retain count of +1}}
   // initI is inlined because the allocation happens within initY
   id y = [[MyObj alloc] initY];
                                 // expected-note@-1 {{Calling 'initY'}}
@@ -244,20 +244,20 @@ static int Cond;
 
 
 void CFOverAutorelease() {
-  CFTypeRef object = CFCreateSomething(); // expected-note{{Call to function 'CFCreateSomething' returns a Core Foundation object of type CFTypeRef with a +1 retain count}}
+  CFTypeRef object = CFCreateSomething(); // expected-note{{Call to function 'CFCreateSomething' returns a Core Foundation object of type 'CFTypeRef' with a +1 retain count}}
   CFAutorelease(object); // expected-note{{Object autoreleased}}
   CFAutorelease(object); // expected-note{{Object autoreleased}}
   return; // expected-warning{{Object autoreleased too many times}} expected-note{{Object was autoreleased 2 times but the object has a +1 retain count}}
 }
 
 void CFAutoreleaseUnowned() {
-  CFTypeRef object = CFGetSomething(); // expected-note{{Call to function 'CFGetSomething' returns a Core Foundation object of type CFTypeRef with a +0 retain count}}
+  CFTypeRef object = CFGetSomething(); // expected-note{{Call to function 'CFGetSomething' returns a Core Foundation object of type 'CFTypeRef' with a +0 retain count}}
   CFAutorelease(object); // expected-note{{Object autoreleased}}
   return; // expected-warning{{Object autoreleased too many times}} expected-note{{Object was autoreleased but has a +0 retain count}}
 }
 
 void CFAutoreleaseUnownedMixed() {
-  CFTypeRef object = CFGetSomething(); // expected-note{{Call to function 'CFGetSomething' returns a Core Foundation object of type CFTypeRef with a +0 retain count}}
+  CFTypeRef object = CFGetSomething(); // expected-note{{Call to function 'CFGetSomething' returns a Core Foundation object of type 'CFTypeRef' with a +0 retain count}}
   CFAutorelease(object); // expected-note{{Object autoreleased}}
   [(id)object autorelease]; // expected-note{{Object autoreleased}}
   return; // expected-warning{{Object autoreleased too many times}} expected-note{{Object was autoreleased 2 times but the object has a +0 retain count}}
diff --git a/test/Analysis/retaincountchecker-compoundregion.m b/test/Analysis/retaincountchecker-compoundregion.m
index ce1f7a9aa1..83857e268d 100644
--- a/test/Analysis/retaincountchecker-compoundregion.m
+++ b/test/Analysis/retaincountchecker-compoundregion.m
@@ -19,7 +19,7 @@ void foo(CFAllocatorRef allocator) {
   int width = 0;
   int height = 0;
   CFTypeRef* values = (CFTypeRef[]){
-    CFNumberCreate(allocator, kCFNumberSInt32Type, &width), //expected-warning{{Potential leak of an object of type CFNumberRef}}
-    CFNumberCreate(allocator, kCFNumberSInt32Type, &height), //expected-warning{{Potential leak of an object of type CFNumberRef}}
+    CFNumberCreate(allocator, kCFNumberSInt32Type, &width), //expected-warning{{Potential leak of an object of type 'CFNumberRef'}}
+    CFNumberCreate(allocator, kCFNumberSInt32Type, &height), //expected-warning{{Potential leak of an object of type 'CFNumberRef'}}
   };
 }
-- 
cgit v1.2.3


From 3cd5b128daf2b432d5adab97ed60d6d54ba129f4 Mon Sep 17 00:00:00 2001
From: George Karpenkov 
Date: Thu, 10 Jan 2019 18:16:10 +0000
Subject: [analyzer] [NFC] [RetainCountChecker] Remove dead unused map

Differential Revision: https://reviews.llvm.org/D56402

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350868 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h
index 0c233f72dd..95b1a3a6c5 100644
--- a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h
+++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h
@@ -256,11 +256,6 @@ class RetainCountChecker
   mutable std::unique_ptr overAutorelease, returnNotOwnedForOwned;
   mutable std::unique_ptr leakWithinFunction, leakAtReturn;
 
-  typedef llvm::DenseMap SymbolTagMap;
-
-  // This map is only used to ensure proper deletion of any allocated tags.
-  mutable SymbolTagMap DeadSymbolTags;
-
   mutable std::unique_ptr Summaries;
 public:
   static constexpr const char *DeallocTagDescription = "DeallocSent";
@@ -273,7 +268,6 @@ public:
 
   RetainCountChecker() {}
 
-  ~RetainCountChecker() override { DeleteContainerSeconds(DeadSymbolTags); }
 
   CFRefBug *getLeakWithinFunctionBug(const LangOptions &LOpts) const;
 
-- 
cgit v1.2.3


From cf5ae62b3d7291ab7cf73ce9bdd9eca4a59191ab Mon Sep 17 00:00:00 2001
From: George Karpenkov 
Date: Thu, 10 Jan 2019 18:16:25 +0000
Subject: [analyzer] Update the category name for RetainCountChecker reports

..now that it includes OSObjects

rdar://46509986

Differential Revision: https://reviews.llvm.org/D56404

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350869 91177308-0d34-0410-b5e6-96231b3b80d8
---
 .../Core/BugReporter/CommonBugCategories.h         |  2 +-
 lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp   |  6 +--
 .../RetainCountChecker/RetainCountChecker.cpp      | 42 ++++++++---------
 .../RetainCountChecker/RetainCountChecker.h        | 13 +++---
 .../RetainCountChecker/RetainCountDiagnostics.cpp  | 44 +++++++++---------
 .../RetainCountChecker/RetainCountDiagnostics.h    | 23 ++++-----
 lib/StaticAnalyzer/Core/CommonBugCategories.cpp    |  4 +-
 .../Inputs/expected-plists/edges-new.mm.plist      |  6 +--
 .../Inputs/expected-plists/objc-arc.m.plist        | 12 ++---
 .../expected-plists/objc-radar17039661.m.plist     |  4 +-
 .../expected-plists/plist-output-alternate.m.plist |  2 +-
 .../Inputs/expected-plists/plist-output.m.plist    |  2 +-
 .../retain-release-path-notes.m.plist              | 54 +++++++++++-----------
 .../Inputs/expected-plists/path-notes.m.plist      |  2 +-
 14 files changed, 107 insertions(+), 109 deletions(-)

diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h b/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h
index 0e80e7bc19..d07525661a 100644
--- a/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h
@@ -16,7 +16,7 @@ namespace clang {
     namespace categories {
       extern const char * const CoreFoundationObjectiveC;
       extern const char * const LogicError;
-      extern const char * const MemoryCoreFoundationObjectiveC;
+      extern const char * const MemoryRefCount;
       extern const char * const MemoryError;
       extern const char * const UnixAPI;
     }
diff --git a/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp b/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp
index eeff47ba82..00a912f27a 100644
--- a/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp
+++ b/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp
@@ -757,15 +757,15 @@ ObjCDeallocChecker::ObjCDeallocChecker()
 
   MissingReleaseBugType.reset(
       new BugType(this, "Missing ivar release (leak)",
-                  categories::MemoryCoreFoundationObjectiveC));
+                  categories::MemoryRefCount));
 
   ExtraReleaseBugType.reset(
       new BugType(this, "Extra ivar release",
-                  categories::MemoryCoreFoundationObjectiveC));
+                  categories::MemoryRefCount));
 
   MistakenDeallocBugType.reset(
       new BugType(this, "Mistaken dealloc",
-                  categories::MemoryCoreFoundationObjectiveC));
+                  categories::MemoryRefCount));
 }
 
 void ObjCDeallocChecker::initIdentifierInfoAndSelectors(
diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
index 28873a465f..371221229b 100644
--- a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
@@ -39,19 +39,19 @@ ProgramStateRef removeRefBinding(ProgramStateRef State, SymbolRef Sym) {
   return State->remove(Sym);
 }
 
-class UseAfterRelease : public CFRefBug {
+class UseAfterRelease : public RefCountBug {
 public:
   UseAfterRelease(const CheckerBase *checker)
-      : CFRefBug(checker, "Use-after-release") {}
+      : RefCountBug(checker, "Use-after-release") {}
 
   const char *getDescription() const override {
     return "Reference-counted object is used after it is released";
   }
 };
 
-class BadRelease : public CFRefBug {
+class BadRelease : public RefCountBug {
 public:
-  BadRelease(const CheckerBase *checker) : CFRefBug(checker, "Bad release") {}
+  BadRelease(const CheckerBase *checker) : RefCountBug(checker, "Bad release") {}
 
   const char *getDescription() const override {
     return "Incorrect decrement of the reference count of an object that is "
@@ -59,30 +59,30 @@ public:
   }
 };
 
-class DeallocNotOwned : public CFRefBug {
+class DeallocNotOwned : public RefCountBug {
 public:
   DeallocNotOwned(const CheckerBase *checker)
-      : CFRefBug(checker, "-dealloc sent to non-exclusively owned object") {}
+      : RefCountBug(checker, "-dealloc sent to non-exclusively owned object") {}
 
   const char *getDescription() const override {
     return "-dealloc sent to object that may be referenced elsewhere";
   }
 };
 
-class OverAutorelease : public CFRefBug {
+class OverAutorelease : public RefCountBug {
 public:
   OverAutorelease(const CheckerBase *checker)
-      : CFRefBug(checker, "Object autoreleased too many times") {}
+      : RefCountBug(checker, "Object autoreleased too many times") {}
 
   const char *getDescription() const override {
     return "Object autoreleased too many times";
   }
 };
 
-class ReturnedNotOwnedForOwned : public CFRefBug {
+class ReturnedNotOwnedForOwned : public RefCountBug {
 public:
   ReturnedNotOwnedForOwned(const CheckerBase *checker)
-      : CFRefBug(checker, "Method should return an owned object") {}
+      : RefCountBug(checker, "Method should return an owned object") {}
 
   const char *getDescription() const override {
     return "Object with a +0 retain count returned to caller where a +1 "
@@ -90,9 +90,9 @@ public:
   }
 };
 
-class Leak : public CFRefBug {
+class Leak : public RefCountBug {
 public:
-  Leak(const CheckerBase *checker, StringRef name) : CFRefBug(checker, name) {
+  Leak(const CheckerBase *checker, StringRef name) : RefCountBug(checker, name) {
     // Leaks should not be reported if they are post-dominated by a sink.
     setSuppressOnSink(true);
   }
@@ -414,14 +414,14 @@ void RetainCountChecker::checkPostCall(const CallEvent &Call,
   checkSummary(*Summ, Call, C);
 }
 
-CFRefBug *
+RefCountBug *
 RetainCountChecker::getLeakWithinFunctionBug(const LangOptions &LOpts) const {
   if (!leakWithinFunction)
     leakWithinFunction.reset(new Leak(this, "Leak"));
   return leakWithinFunction.get();
 }
 
-CFRefBug *
+RefCountBug *
 RetainCountChecker::getLeakAtReturnBug(const LangOptions &LOpts) const {
   if (!leakAtReturn)
     leakAtReturn.reset(new Leak(this, "Leak of returned object"));
@@ -816,7 +816,7 @@ void RetainCountChecker::processNonLeakError(ProgramStateRef St,
   if (!N)
     return;
 
-  CFRefBug *BT;
+  RefCountBug *BT;
   switch (ErrorKind) {
     default:
       llvm_unreachable("Unhandled error.");
@@ -838,7 +838,7 @@ void RetainCountChecker::processNonLeakError(ProgramStateRef St,
   }
 
   assert(BT);
-  auto report = llvm::make_unique(
+  auto report = llvm::make_unique(
       *BT, C.getASTContext().getLangOpts(), N, Sym);
   report->addRange(ErrorRange);
   C.emitReport(std::move(report));
@@ -1042,7 +1042,7 @@ ExplodedNode * RetainCountChecker::checkReturnWithRetEffect(const ReturnStmt *S,
         ExplodedNode *N = C.addTransition(state, Pred, &ReturnOwnLeakTag);
         if (N) {
           const LangOptions &LOpts = C.getASTContext().getLangOpts();
-          auto R = llvm::make_unique(
+          auto R = llvm::make_unique(
               *getLeakAtReturnBug(LOpts), LOpts, N, Sym, C);
           C.emitReport(std::move(R));
         }
@@ -1070,7 +1070,7 @@ ExplodedNode * RetainCountChecker::checkReturnWithRetEffect(const ReturnStmt *S,
           if (!returnNotOwnedForOwned)
             returnNotOwnedForOwned.reset(new ReturnedNotOwnedForOwned(this));
 
-          auto R = llvm::make_unique(
+          auto R = llvm::make_unique(
               *returnNotOwnedForOwned, C.getASTContext().getLangOpts(), N, Sym);
           C.emitReport(std::move(R));
         }
@@ -1274,7 +1274,7 @@ RetainCountChecker::handleAutoreleaseCounts(ProgramStateRef state,
       overAutorelease.reset(new OverAutorelease(this));
 
     const LangOptions &LOpts = Ctx.getASTContext().getLangOpts();
-    auto R = llvm::make_unique(*overAutorelease, LOpts, N, Sym,
+    auto R = llvm::make_unique(*overAutorelease, LOpts, N, Sym,
                                             os.str());
     Ctx.emitReport(std::move(R));
   }
@@ -1323,12 +1323,12 @@ RetainCountChecker::processLeaks(ProgramStateRef state,
          I = Leaked.begin(), E = Leaked.end(); I != E; ++I) {
 
       const LangOptions &LOpts = Ctx.getASTContext().getLangOpts();
-      CFRefBug *BT = Pred ? getLeakWithinFunctionBug(LOpts)
+      RefCountBug *BT = Pred ? getLeakWithinFunctionBug(LOpts)
                           : getLeakAtReturnBug(LOpts);
       assert(BT && "BugType not initialized.");
 
       Ctx.emitReport(
-          llvm::make_unique(*BT, LOpts, N, *I, Ctx));
+          llvm::make_unique(*BT, LOpts, N, *I, Ctx));
     }
   }
 
diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h
index 95b1a3a6c5..87633feecc 100644
--- a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h
+++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h
@@ -251,10 +251,10 @@ class RetainCountChecker
                     check::RegionChanges,
                     eval::Assume,
                     eval::Call > {
-  mutable std::unique_ptr useAfterRelease, releaseNotOwned;
-  mutable std::unique_ptr deallocNotOwned;
-  mutable std::unique_ptr overAutorelease, returnNotOwnedForOwned;
-  mutable std::unique_ptr leakWithinFunction, leakAtReturn;
+  mutable std::unique_ptr useAfterRelease, releaseNotOwned;
+  mutable std::unique_ptr deallocNotOwned;
+  mutable std::unique_ptr overAutorelease, returnNotOwnedForOwned;
+  mutable std::unique_ptr leakWithinFunction, leakAtReturn;
 
   mutable std::unique_ptr Summaries;
 public:
@@ -268,10 +268,9 @@ public:
 
   RetainCountChecker() {}
 
+  RefCountBug *getLeakWithinFunctionBug(const LangOptions &LOpts) const;
 
-  CFRefBug *getLeakWithinFunctionBug(const LangOptions &LOpts) const;
-
-  CFRefBug *getLeakAtReturnBug(const LangOptions &LOpts) const;
+  RefCountBug *getLeakAtReturnBug(const LangOptions &LOpts) const;
 
   RetainSummaryManager &getSummaryManager(ASTContext &Ctx) const {
     // FIXME: We don't support ARC being turned on and off during one analysis.
diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
index 1f370fc301..b4f58b55a3 100644
--- a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
+++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
@@ -189,12 +189,12 @@ namespace clang {
 namespace ento {
 namespace retaincountchecker {
 
-class CFRefReportVisitor : public BugReporterVisitor {
+class RefCountReportVisitor : public BugReporterVisitor {
 protected:
   SymbolRef Sym;
 
 public:
-  CFRefReportVisitor(SymbolRef sym) : Sym(sym) {}
+  RefCountReportVisitor(SymbolRef sym) : Sym(sym) {}
 
   void Profile(llvm::FoldingSetNodeID &ID) const override {
     static int x = 0;
@@ -211,9 +211,9 @@ public:
                                                   BugReport &BR) override;
 };
 
-class CFRefLeakReportVisitor : public CFRefReportVisitor {
+class RefLeakReportVisitor : public RefCountReportVisitor {
 public:
-  CFRefLeakReportVisitor(SymbolRef sym) : CFRefReportVisitor(sym) {}
+  RefLeakReportVisitor(SymbolRef sym) : RefCountReportVisitor(sym) {}
 
   std::shared_ptr getEndPath(BugReporterContext &BRC,
                                                   const ExplodedNode *N,
@@ -303,7 +303,7 @@ annotateConsumedSummaryMismatch(const ExplodedNode *N,
 }
 
 std::shared_ptr
-CFRefReportVisitor::VisitNode(const ExplodedNode *N,
+RefCountReportVisitor::VisitNode(const ExplodedNode *N,
                               BugReporterContext &BRC, BugReport &BR) {
 
   const SourceManager &SM = BRC.getSourceManager();
@@ -548,14 +548,14 @@ static AllocationInfo GetAllocationSite(ProgramStateManager &StateMgr,
 }
 
 std::shared_ptr
-CFRefReportVisitor::getEndPath(BugReporterContext &BRC,
+RefCountReportVisitor::getEndPath(BugReporterContext &BRC,
                                const ExplodedNode *EndN, BugReport &BR) {
   BR.markInteresting(Sym);
   return BugReporterVisitor::getDefaultEndPath(BRC, EndN, BR);
 }
 
 std::shared_ptr
-CFRefLeakReportVisitor::getEndPath(BugReporterContext &BRC,
+RefLeakReportVisitor::getEndPath(BugReporterContext &BRC,
                                    const ExplodedNode *EndN, BugReport &BR) {
 
   // Tell the BugReporterContext to report cases when the tracked symbol is
@@ -637,21 +637,23 @@ CFRefLeakReportVisitor::getEndPath(BugReporterContext &BRC,
   return std::make_shared(L, os.str());
 }
 
-CFRefReport::CFRefReport(CFRefBug &D, const LangOptions &LOpts, ExplodedNode *n,
-                         SymbolRef sym, bool registerVisitor)
+RefCountReport::RefCountReport(RefCountBug &D, const LangOptions &LOpts,
+                               ExplodedNode *n, SymbolRef sym,
+                               bool registerVisitor)
     : BugReport(D, D.getDescription(), n), Sym(sym) {
   if (registerVisitor)
-    addVisitor(llvm::make_unique(sym));
+    addVisitor(llvm::make_unique(sym));
 }
 
-CFRefReport::CFRefReport(CFRefBug &D, const LangOptions &LOpts, ExplodedNode *n,
-                         SymbolRef sym, StringRef endText)
+RefCountReport::RefCountReport(RefCountBug &D, const LangOptions &LOpts,
+                               ExplodedNode *n, SymbolRef sym,
+                               StringRef endText)
     : BugReport(D, D.getDescription(), endText, n) {
 
-  addVisitor(llvm::make_unique(sym));
+  addVisitor(llvm::make_unique(sym));
 }
 
-void CFRefLeakReport::deriveParamLocation(CheckerContext &Ctx, SymbolRef sym) {
+void RefLeakReport::deriveParamLocation(CheckerContext &Ctx, SymbolRef sym) {
   const SourceManager& SMgr = Ctx.getSourceManager();
 
   if (!sym->getOriginRegion())
@@ -670,7 +672,7 @@ void CFRefLeakReport::deriveParamLocation(CheckerContext &Ctx, SymbolRef sym) {
   }
 }
 
-void CFRefLeakReport::deriveAllocLocation(CheckerContext &Ctx,
+void RefLeakReport::deriveAllocLocation(CheckerContext &Ctx,
                                           SymbolRef sym) {
   // Most bug reports are cached at the location where they occurred.
   // With leaks, we want to unique them by the location where they were
@@ -713,7 +715,7 @@ void CFRefLeakReport::deriveAllocLocation(CheckerContext &Ctx,
   UniqueingDecl = AllocNode->getLocationContext()->getDecl();
 }
 
-void CFRefLeakReport::createDescription(CheckerContext &Ctx) {
+void RefLeakReport::createDescription(CheckerContext &Ctx) {
   assert(Location.isValid() && UniqueingDecl && UniqueingLocation.isValid());
   Description.clear();
   llvm::raw_string_ostream os(Description);
@@ -729,10 +731,10 @@ void CFRefLeakReport::createDescription(CheckerContext &Ctx) {
   }
 }
 
-CFRefLeakReport::CFRefLeakReport(CFRefBug &D, const LangOptions &LOpts,
-                                 ExplodedNode *n, SymbolRef sym,
-                                 CheckerContext &Ctx)
-  : CFRefReport(D, LOpts, n, sym, false) {
+RefLeakReport::RefLeakReport(RefCountBug &D, const LangOptions &LOpts,
+                             ExplodedNode *n, SymbolRef sym,
+                             CheckerContext &Ctx)
+    : RefCountReport(D, LOpts, n, sym, false) {
 
   deriveAllocLocation(Ctx, sym);
   if (!AllocBinding)
@@ -740,5 +742,5 @@ CFRefLeakReport::CFRefLeakReport(CFRefBug &D, const LangOptions &LOpts,
 
   createDescription(Ctx);
 
-  addVisitor(llvm::make_unique(sym));
+  addVisitor(llvm::make_unique(sym));
 }
diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h
index f27027ab62..9f796abe8e 100644
--- a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h
+++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h
@@ -24,41 +24,39 @@ namespace clang {
 namespace ento {
 namespace retaincountchecker {
 
-class CFRefBug : public BugType {
+class RefCountBug : public BugType {
 protected:
-  CFRefBug(const CheckerBase *checker, StringRef name)
-      : BugType(checker, name, categories::MemoryCoreFoundationObjectiveC) {}
+  RefCountBug(const CheckerBase *checker, StringRef name)
+      : BugType(checker, name, categories::MemoryRefCount) {}
 
 public:
-
-  // FIXME: Eventually remove.
   virtual const char *getDescription() const = 0;
 
   virtual bool isLeak() const { return false; }
 };
 
-class CFRefReport : public BugReport {
+class RefCountReport : public BugReport {
 protected:
   SymbolRef Sym;
 
 public:
-  CFRefReport(CFRefBug &D, const LangOptions &LOpts,
+  RefCountReport(RefCountBug &D, const LangOptions &LOpts,
               ExplodedNode *n, SymbolRef sym,
               bool registerVisitor = true);
 
-  CFRefReport(CFRefBug &D, const LangOptions &LOpts,
+  RefCountReport(RefCountBug &D, const LangOptions &LOpts,
               ExplodedNode *n, SymbolRef sym,
               StringRef endText);
 
   llvm::iterator_range getRanges() override {
-    const CFRefBug& BugTy = static_cast(getBugType());
+    const RefCountBug& BugTy = static_cast(getBugType());
     if (!BugTy.isLeak())
       return BugReport::getRanges();
     return llvm::make_range(ranges_iterator(), ranges_iterator());
   }
 };
 
-class CFRefLeakReport : public CFRefReport {
+class RefLeakReport : public RefCountReport {
   const MemRegion* AllocBinding;
   const Stmt *AllocStmt;
 
@@ -71,9 +69,8 @@ class CFRefLeakReport : public CFRefReport {
   void createDescription(CheckerContext &Ctx);
 
 public:
-  CFRefLeakReport(CFRefBug &D, const LangOptions &LOpts,
-                  ExplodedNode *n, SymbolRef sym,
-                  CheckerContext &Ctx);
+  RefLeakReport(RefCountBug &D, const LangOptions &LOpts, ExplodedNode *n,
+                SymbolRef sym, CheckerContext &Ctx);
 
   PathDiagnosticLocation getLocation(const SourceManager &SM) const override {
     assert(Location.isValid());
diff --git a/lib/StaticAnalyzer/Core/CommonBugCategories.cpp b/lib/StaticAnalyzer/Core/CommonBugCategories.cpp
index 421dfa48c9..cdae3ef011 100644
--- a/lib/StaticAnalyzer/Core/CommonBugCategories.cpp
+++ b/lib/StaticAnalyzer/Core/CommonBugCategories.cpp
@@ -14,8 +14,8 @@ namespace clang { namespace ento { namespace categories {
 
 const char * const CoreFoundationObjectiveC = "Core Foundation/Objective-C";
 const char * const LogicError = "Logic error";
-const char * const MemoryCoreFoundationObjectiveC =
-  "Memory (Core Foundation/Objective-C)";
+const char * const MemoryRefCount =
+  "Memory (Core Foundation/Objective-C/OSObject)";
 const char * const MemoryError = "Memory error";
 const char * const UnixAPI = "Unix API";
 }}}
diff --git a/test/Analysis/Inputs/expected-plists/edges-new.mm.plist b/test/Analysis/Inputs/expected-plists/edges-new.mm.plist
index 449050d595..bcb659c0b3 100644
--- a/test/Analysis/Inputs/expected-plists/edges-new.mm.plist
+++ b/test/Analysis/Inputs/expected-plists/edges-new.mm.plist
@@ -2118,7 +2118,7 @@
     
    
    descriptionPotential leak of an object stored into 'value'
-   categoryMemory (Core Foundation/Objective-C)
+   categoryMemory (Core Foundation/Objective-C/OSObject)
    typeLeak
    check_nameosx.cocoa.RetainCount
    
@@ -11217,7 +11217,7 @@
     
    
    descriptionPotential leak of an object stored into 'foo'
-   categoryMemory (Core Foundation/Objective-C)
+   categoryMemory (Core Foundation/Objective-C/OSObject)
    typeLeak
    check_nameosx.cocoa.RetainCount
    
@@ -21063,7 +21063,7 @@
     
    
    descriptionPotential leak of an object stored into 'foo'
-   categoryMemory (Core Foundation/Objective-C)
+   categoryMemory (Core Foundation/Objective-C/OSObject)
    typeLeak
    check_nameosx.cocoa.RetainCount
    
diff --git a/test/Analysis/Inputs/expected-plists/objc-arc.m.plist b/test/Analysis/Inputs/expected-plists/objc-arc.m.plist
index 966ea9ac09..650da09090 100644
--- a/test/Analysis/Inputs/expected-plists/objc-arc.m.plist
+++ b/test/Analysis/Inputs/expected-plists/objc-arc.m.plist
@@ -311,7 +311,7 @@
     
    
    descriptionPotential leak of an object stored into 'date'
-   categoryMemory (Core Foundation/Objective-C)
+   categoryMemory (Core Foundation/Objective-C/OSObject)
    typeLeak
    check_nameosx.cocoa.RetainCount
    
@@ -842,7 +842,7 @@
     
    
    descriptionPotential leak of an object stored into 'obj5'
-   categoryMemory (Core Foundation/Objective-C)
+   categoryMemory (Core Foundation/Objective-C/OSObject)
    typeLeak
    check_nameosx.cocoa.RetainCount
    
@@ -988,7 +988,7 @@
     
    
    descriptionPotential leak of an object stored into 'obj6'
-   categoryMemory (Core Foundation/Objective-C)
+   categoryMemory (Core Foundation/Objective-C/OSObject)
    typeLeak
    check_nameosx.cocoa.RetainCount
    
@@ -1422,7 +1422,7 @@
     
    
    descriptionPotential leak of an object stored into 'date'
-   categoryMemory (Core Foundation/Objective-C)
+   categoryMemory (Core Foundation/Objective-C/OSObject)
    typeLeak
    check_nameosx.cocoa.RetainCount
    
@@ -1733,7 +1733,7 @@
     
    
    descriptionPotential leak of an object of type 'CFStringRef'
-   categoryMemory (Core Foundation/Objective-C)
+   categoryMemory (Core Foundation/Objective-C/OSObject)
    typeLeak
    check_nameosx.cocoa.RetainCount
    
@@ -1927,7 +1927,7 @@
     
    
    descriptionPotential leak of an object stored into 'o'
-   categoryMemory (Core Foundation/Objective-C)
+   categoryMemory (Core Foundation/Objective-C/OSObject)
    typeLeak
    check_nameosx.cocoa.RetainCount
    
diff --git a/test/Analysis/Inputs/expected-plists/objc-radar17039661.m.plist b/test/Analysis/Inputs/expected-plists/objc-radar17039661.m.plist
index b5b26d050e..b778e98bff 100644
--- a/test/Analysis/Inputs/expected-plists/objc-radar17039661.m.plist
+++ b/test/Analysis/Inputs/expected-plists/objc-radar17039661.m.plist
@@ -1266,7 +1266,7 @@
     
    
    descriptionPotential leak of an object of type 'NSNumber *'
-   categoryMemory (Core Foundation/Objective-C)
+   categoryMemory (Core Foundation/Objective-C/OSObject)
    typeLeak
    check_nameosx.cocoa.RetainCount
    
@@ -1306,4 +1306,4 @@
   /Volumes/Transcend/code/monorepo/llvm-project/clang/test/Analysis/objc-radar17039661.m
  
 
-
\ No newline at end of file
+
diff --git a/test/Analysis/Inputs/expected-plists/plist-output-alternate.m.plist b/test/Analysis/Inputs/expected-plists/plist-output-alternate.m.plist
index 966d5a7bce..aedf062672 100644
--- a/test/Analysis/Inputs/expected-plists/plist-output-alternate.m.plist
+++ b/test/Analysis/Inputs/expected-plists/plist-output-alternate.m.plist
@@ -1484,7 +1484,7 @@
     
    
    descriptionPotential leak of an object stored into 'value'
-   categoryMemory (Core Foundation/Objective-C)
+   categoryMemory (Core Foundation/Objective-C/OSObject)
    typeLeak
    check_nameosx.cocoa.RetainCount
    
diff --git a/test/Analysis/Inputs/expected-plists/plist-output.m.plist b/test/Analysis/Inputs/expected-plists/plist-output.m.plist
index a2658e0ff0..cafa9f3b94 100644
--- a/test/Analysis/Inputs/expected-plists/plist-output.m.plist
+++ b/test/Analysis/Inputs/expected-plists/plist-output.m.plist
@@ -2371,7 +2371,7 @@
     
    
    descriptionPotential leak of an object stored into 'foo'
-   categoryMemory (Core Foundation/Objective-C)
+   categoryMemory (Core Foundation/Objective-C/OSObject)
    typeLeak
    check_nameosx.cocoa.RetainCount
    
diff --git a/test/Analysis/Inputs/expected-plists/retain-release-path-notes.m.plist b/test/Analysis/Inputs/expected-plists/retain-release-path-notes.m.plist
index 13b654a19c..b2b90adad1 100644
--- a/test/Analysis/Inputs/expected-plists/retain-release-path-notes.m.plist
+++ b/test/Analysis/Inputs/expected-plists/retain-release-path-notes.m.plist
@@ -103,7 +103,7 @@
     
    
    descriptionPotential leak of an object stored into 'leaked'
-   categoryMemory (Core Foundation/Objective-C)
+   categoryMemory (Core Foundation/Objective-C/OSObject)
    typeLeak
    check_nameosx.cocoa.RetainCount
    
@@ -224,7 +224,7 @@
     
    
    descriptionPotential leak of an object stored into 'leaked'
-   categoryMemory (Core Foundation/Objective-C)
+   categoryMemory (Core Foundation/Objective-C/OSObject)
    typeLeak
    check_nameosx.cocoa.RetainCount
    
@@ -570,7 +570,7 @@
     
    
    descriptionPotential leak of an object stored into 'leaked'
-   categoryMemory (Core Foundation/Objective-C)
+   categoryMemory (Core Foundation/Objective-C/OSObject)
    typeLeak
    check_nameosx.cocoa.RetainCount
    
@@ -769,7 +769,7 @@
     
    
    descriptionPotential leak of an object stored into 'leaked'
-   categoryMemory (Core Foundation/Objective-C)
+   categoryMemory (Core Foundation/Objective-C/OSObject)
    typeLeak
    check_nameosx.cocoa.RetainCount
    
@@ -966,7 +966,7 @@
     
    
    descriptionPotential leak of an object stored into 'leaked'
-   categoryMemory (Core Foundation/Objective-C)
+   categoryMemory (Core Foundation/Objective-C/OSObject)
    typeLeak
    check_nameosx.cocoa.RetainCount
    
@@ -1163,7 +1163,7 @@
     
    
    descriptionReference-counted object is used after it is released
-   categoryMemory (Core Foundation/Objective-C)
+   categoryMemory (Core Foundation/Objective-C/OSObject)
    typeUse-after-release
    check_nameosx.cocoa.RetainCount
    
@@ -1360,7 +1360,7 @@
     
    
    descriptionReference-counted object is used after it is released
-   categoryMemory (Core Foundation/Objective-C)
+   categoryMemory (Core Foundation/Objective-C/OSObject)
    typeUse-after-release
    check_nameosx.cocoa.RetainCount
    
@@ -1632,7 +1632,7 @@
     
    
    descriptionObject autoreleased too many times
-   categoryMemory (Core Foundation/Objective-C)
+   categoryMemory (Core Foundation/Objective-C/OSObject)
    typeObject autoreleased too many times
    check_nameosx.cocoa.RetainCount
    
@@ -1830,7 +1830,7 @@
     
    
    descriptionObject autoreleased too many times
-   categoryMemory (Core Foundation/Objective-C)
+   categoryMemory (Core Foundation/Objective-C/OSObject)
    typeObject autoreleased too many times
    check_nameosx.cocoa.RetainCount
    
@@ -1952,7 +1952,7 @@
     
    
    descriptionPotential leak of an object stored into 'leaked'
-   categoryMemory (Core Foundation/Objective-C)
+   categoryMemory (Core Foundation/Objective-C/OSObject)
    typeLeak
    check_nameosx.cocoa.RetainCount
    
@@ -2075,7 +2075,7 @@
     
    
    descriptionObject with a +0 retain count returned to caller where a +1 (owning) retain count is expected
-   categoryMemory (Core Foundation/Objective-C)
+   categoryMemory (Core Foundation/Objective-C/OSObject)
    typeMethod should return an owned object
    check_nameosx.cocoa.RetainCount
    
@@ -2196,7 +2196,7 @@
     
    
    descriptionPotential leak of an object stored into 'object'
-   categoryMemory (Core Foundation/Objective-C)
+   categoryMemory (Core Foundation/Objective-C/OSObject)
    typeLeak of returned object
    check_nameosx.cocoa.RetainCount
    
@@ -2317,7 +2317,7 @@
     
    
    descriptionObject with a +0 retain count returned to caller where a +1 (owning) retain count is expected
-   categoryMemory (Core Foundation/Objective-C)
+   categoryMemory (Core Foundation/Objective-C/OSObject)
    typeMethod should return an owned object
    check_nameosx.cocoa.RetainCount
    
@@ -2438,7 +2438,7 @@
     
    
    descriptionObject with a +0 retain count returned to caller where a +1 (owning) retain count is expected
-   categoryMemory (Core Foundation/Objective-C)
+   categoryMemory (Core Foundation/Objective-C/OSObject)
    typeMethod should return an owned object
    check_nameosx.cocoa.RetainCount
    
@@ -2559,7 +2559,7 @@
     
    
    descriptionObject with a +0 retain count returned to caller where a +1 (owning) retain count is expected
-   categoryMemory (Core Foundation/Objective-C)
+   categoryMemory (Core Foundation/Objective-C/OSObject)
    typeMethod should return an owned object
    check_nameosx.cocoa.RetainCount
    
@@ -2680,7 +2680,7 @@
     
    
    descriptionPotential leak of an object stored into 'result'
-   categoryMemory (Core Foundation/Objective-C)
+   categoryMemory (Core Foundation/Objective-C/OSObject)
    typeLeak of returned object
    check_nameosx.cocoa.RetainCount
    
@@ -2876,7 +2876,7 @@
     
    
    descriptionObject with a +0 retain count returned to caller where a +1 (owning) retain count is expected
-   categoryMemory (Core Foundation/Objective-C)
+   categoryMemory (Core Foundation/Objective-C/OSObject)
    typeMethod should return an owned object
    check_nameosx.cocoa.RetainCount
    
@@ -2998,7 +2998,7 @@
     
    
    descriptionIncorrect decrement of the reference count of an object that is not owned at this point by the caller
-   categoryMemory (Core Foundation/Objective-C)
+   categoryMemory (Core Foundation/Objective-C/OSObject)
    typeBad release
    check_nameosx.cocoa.RetainCount
    
@@ -3119,7 +3119,7 @@
     
    
    descriptionIncorrect decrement of the reference count of an object that is not owned at this point by the caller
-   categoryMemory (Core Foundation/Objective-C)
+   categoryMemory (Core Foundation/Objective-C/OSObject)
    typeBad release
    check_nameosx.cocoa.RetainCount
    
@@ -3240,7 +3240,7 @@
     
    
    descriptionIncorrect decrement of the reference count of an object that is not owned at this point by the caller
-   categoryMemory (Core Foundation/Objective-C)
+   categoryMemory (Core Foundation/Objective-C/OSObject)
    typeBad release
    check_nameosx.cocoa.RetainCount
    
@@ -3361,7 +3361,7 @@
     
    
    descriptionIncorrect decrement of the reference count of an object that is not owned at this point by the caller
-   categoryMemory (Core Foundation/Objective-C)
+   categoryMemory (Core Foundation/Objective-C/OSObject)
    typeBad release
    check_nameosx.cocoa.RetainCount
    
@@ -3482,7 +3482,7 @@
     
    
    descriptionIncorrect decrement of the reference count of an object that is not owned at this point by the caller
-   categoryMemory (Core Foundation/Objective-C)
+   categoryMemory (Core Foundation/Objective-C/OSObject)
    typeBad release
    check_nameosx.cocoa.RetainCount
    
@@ -3840,7 +3840,7 @@
     
    
    descriptionPotential leak of an object of type 'MyObj *'
-   categoryMemory (Core Foundation/Objective-C)
+   categoryMemory (Core Foundation/Objective-C/OSObject)
    typeLeak
    check_nameosx.cocoa.RetainCount
    
@@ -4239,7 +4239,7 @@
     
    
    descriptionPotential leak of an object stored into 'y'
-   categoryMemory (Core Foundation/Objective-C)
+   categoryMemory (Core Foundation/Objective-C/OSObject)
    typeLeak
    check_nameosx.cocoa.RetainCount
    
@@ -4517,7 +4517,7 @@
     
    
    descriptionObject autoreleased too many times
-   categoryMemory (Core Foundation/Objective-C)
+   categoryMemory (Core Foundation/Objective-C/OSObject)
    typeObject autoreleased too many times
    check_nameosx.cocoa.RetainCount
    
@@ -4715,7 +4715,7 @@
     
    
    descriptionObject autoreleased too many times
-   categoryMemory (Core Foundation/Objective-C)
+   categoryMemory (Core Foundation/Objective-C/OSObject)
    typeObject autoreleased too many times
    check_nameosx.cocoa.RetainCount
    
@@ -4987,7 +4987,7 @@
     
    
    descriptionObject autoreleased too many times
-   categoryMemory (Core Foundation/Objective-C)
+   categoryMemory (Core Foundation/Objective-C/OSObject)
    typeObject autoreleased too many times
    check_nameosx.cocoa.RetainCount
    
diff --git a/test/Analysis/inlining/Inputs/expected-plists/path-notes.m.plist b/test/Analysis/inlining/Inputs/expected-plists/path-notes.m.plist
index 28477e4efe..1974e7ab25 100644
--- a/test/Analysis/inlining/Inputs/expected-plists/path-notes.m.plist
+++ b/test/Analysis/inlining/Inputs/expected-plists/path-notes.m.plist
@@ -1964,7 +1964,7 @@
     
    
    descriptionObject autoreleased too many times
-   categoryMemory (Core Foundation/Objective-C)
+   categoryMemory (Core Foundation/Objective-C/OSObject)
    typeObject autoreleased too many times
    check_nameosx.cocoa.RetainCount
    
-- 
cgit v1.2.3


From 7697c704e135cefdc7f19ba5d6d4749944669be2 Mon Sep 17 00:00:00 2001
From: George Karpenkov 
Date: Thu, 10 Jan 2019 18:28:10 +0000
Subject: [analyzer] [hotfix] Fix the tests

The error must have crept during the cherry-pick.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350870 91177308-0d34-0410-b5e6-96231b3b80d8
---
 .../Checkers/RetainCountChecker/RetainCountDiagnostics.cpp   | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
index b4f58b55a3..4309603862 100644
--- a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
+++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
@@ -156,23 +156,25 @@ static void generateDiagnosticsForCallLike(ProgramStateRef CurrSt,
     }
   }
 
+   os << " returns ";
+
   if (CurrV.getObjKind() == ObjKind::CF) {
-    os << " a Core Foundation object of type '"
+    os << "a Core Foundation object of type '"
        << Sym->getType().getAsString() << "' with a ";
   } else if (CurrV.getObjKind() == ObjKind::OS) {
-    os << " an OSObject of type '" << getPrettyTypeName(Sym->getType())
+    os << "an OSObject of type '" << getPrettyTypeName(Sym->getType())
        << "' with a ";
   } else if (CurrV.getObjKind() == ObjKind::Generalized) {
-    os << " an object of type '" << Sym->getType().getAsString()
+    os << "an object of type '" << Sym->getType().getAsString()
        << "' with a ";
   } else {
     assert(CurrV.getObjKind() == ObjKind::ObjC);
     QualType T = Sym->getType();
     if (!isa(T)) {
-      os << " returns an Objective-C object with a ";
+      os << "an Objective-C object with a ";
     } else {
       const ObjCObjectPointerType *PT = cast(T);
-      os << " returns an instance of " << PT->getPointeeType().getAsString()
+      os << "an instance of " << PT->getPointeeType().getAsString()
          << " with a ";
     }
   }
-- 
cgit v1.2.3


From 23a55bd3f5c9f0483b82f4ecd489d3c0284d34b9 Mon Sep 17 00:00:00 2001
From: Nicolas Lesser 
Date: Thu, 10 Jan 2019 19:03:33 +0000
Subject: Fix false positive unsequenced access and modification warning in
 array subscript expression.

Summary: In the [expr.sub] p1, we can read that for a given E1[E2], E1 is sequenced before E2.

Patch by Mateusz Janek.

Reviewers: rsmith, Rakete1111

Reviewed By: rsmith, Rakete1111

Subscribers: riccibruno, lebedev.ri, Rakete1111, hiraditya, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D50766



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350874 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/Sema/SemaChecking.cpp               | 44 +++++++++++++++++++++------------
 test/SemaCXX/warn-unsequenced-cxx17.cpp |  8 ++++++
 test/SemaCXX/warn-unsequenced.cpp       |  1 +
 3 files changed, 37 insertions(+), 16 deletions(-)
 create mode 100644 test/SemaCXX/warn-unsequenced-cxx17.cpp

diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index cd96200b81..a47c01daf0 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -11908,30 +11908,42 @@ public:
       notePostUse(O, E);
   }
 
-  void VisitBinComma(BinaryOperator *BO) {
-    // C++11 [expr.comma]p1:
-    //   Every value computation and side effect associated with the left
-    //   expression is sequenced before every value computation and side
-    //   effect associated with the right expression.
-    SequenceTree::Seq LHS = Tree.allocate(Region);
-    SequenceTree::Seq RHS = Tree.allocate(Region);
+  void VisitSequencedExpressions(Expr *SequencedBefore, Expr *SequencedAfter) {
+    SequenceTree::Seq BeforeRegion = Tree.allocate(Region);
+    SequenceTree::Seq AfterRegion = Tree.allocate(Region);
     SequenceTree::Seq OldRegion = Region;
 
     {
-      SequencedSubexpression SeqLHS(*this);
-      Region = LHS;
-      Visit(BO->getLHS());
+      SequencedSubexpression SeqBefore(*this);
+      Region = BeforeRegion;
+      Visit(SequencedBefore);
     }
 
-    Region = RHS;
-    Visit(BO->getRHS());
+    Region = AfterRegion;
+    Visit(SequencedAfter);
 
     Region = OldRegion;
 
-    // Forget that LHS and RHS are sequenced. They are both unsequenced
-    // with respect to other stuff.
-    Tree.merge(LHS);
-    Tree.merge(RHS);
+    Tree.merge(BeforeRegion);
+    Tree.merge(AfterRegion);
+  }
+
+  void VisitArraySubscriptExpr(ArraySubscriptExpr *ASE) {
+    // C++17 [expr.sub]p1:
+    //   The expression E1[E2] is identical (by definition) to *((E1)+(E2)). The
+    //   expression E1 is sequenced before the expression E2.
+    if (SemaRef.getLangOpts().CPlusPlus17)
+      VisitSequencedExpressions(ASE->getLHS(), ASE->getRHS());
+    else
+      Base::VisitStmt(ASE);
+  }
+
+  void VisitBinComma(BinaryOperator *BO) {
+    // C++11 [expr.comma]p1:
+    //   Every value computation and side effect associated with the left
+    //   expression is sequenced before every value computation and side
+    //   effect associated with the right expression.
+    VisitSequencedExpressions(BO->getLHS(), BO->getRHS());
   }
 
   void VisitBinAssign(BinaryOperator *BO) {
diff --git a/test/SemaCXX/warn-unsequenced-cxx17.cpp b/test/SemaCXX/warn-unsequenced-cxx17.cpp
new file mode 100644
index 0000000000..3c221fb8d6
--- /dev/null
+++ b/test/SemaCXX/warn-unsequenced-cxx17.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++17 -Wno-unused %s
+
+void test() {
+  int xs[10];
+  int *p = xs;
+  // expected-no-diagnostics
+  p[(long long unsigned)(p = 0)]; // ok
+}
diff --git a/test/SemaCXX/warn-unsequenced.cpp b/test/SemaCXX/warn-unsequenced.cpp
index 9e8a5b46c2..6d4468cabf 100644
--- a/test/SemaCXX/warn-unsequenced.cpp
+++ b/test/SemaCXX/warn-unsequenced.cpp
@@ -81,6 +81,7 @@ void test() {
   int *p = xs;
   a = *(a++, p); // ok
   a = a++ && a; // ok
+  p[(long long unsigned)(p = 0)]; // expected-warning {{unsequenced modification and access to 'p'}}
 
   A *q = &agg1;
   (q = &agg2)->y = q->x; // expected-warning {{unsequenced modification and access to 'q'}}
-- 
cgit v1.2.3


From 2c8a83b312df12ea7c66fc1282664c5877aeff1f Mon Sep 17 00:00:00 2001
From: Nick Desaulniers 
Date: Thu, 10 Jan 2019 19:12:39 +0000
Subject: [SemaCXX] add -Woverride-init alias to -Winitializer-overrides

Summary:
https://bugs.llvm.org/show_bug.cgi?id=40251
https://github.com/ClangBuiltLinux/linux/issues/307

Reviewers: rsmith

Reviewed By: rsmith

Subscribers: cfe-commits, nathanchance, srhines

Differential Revision: https://reviews.llvm.org/D56522

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350877 91177308-0d34-0410-b5e6-96231b3b80d8
---
 docs/DiagnosticsReference.rst            | 4 ++++
 include/clang/Basic/DiagnosticGroups.td  | 2 ++
 test/SemaCXX/designated-initializers.cpp | 1 +
 3 files changed, 7 insertions(+)

diff --git a/docs/DiagnosticsReference.rst b/docs/DiagnosticsReference.rst
index 94502f9c49..e8f754ac85 100644
--- a/docs/DiagnosticsReference.rst
+++ b/docs/DiagnosticsReference.rst
@@ -7885,6 +7885,10 @@ This diagnostic is enabled by default.
 |                                                                                               |+---------------------+|
 +-----------------------------------------------------------------------------------------------+-----------------------+
 
+-Woverride-init
+--------------
+Synonym for `-Winitializer-overrides`_.
+
 
 -Woverride-module
 -----------------
diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td
index ddf206da06..19e187cc5d 100644
--- a/include/clang/Basic/DiagnosticGroups.td
+++ b/include/clang/Basic/DiagnosticGroups.td
@@ -365,6 +365,8 @@ def NullArithmetic : DiagGroup<"null-arithmetic">;
 def NullCharacter : DiagGroup<"null-character">;
 def NullDereference : DiagGroup<"null-dereference">;
 def InitializerOverrides : DiagGroup<"initializer-overrides">;
+// For compatibility with GCC; -Woverride-init = -Winitializer-overrides
+def : DiagGroup<"override-init", [InitializerOverrides]>;
 def NonNull : DiagGroup<"nonnull">;
 def NonPODVarargs : DiagGroup<"non-pod-varargs">;
 def ClassVarargs : DiagGroup<"class-varargs", [NonPODVarargs]>;
diff --git a/test/SemaCXX/designated-initializers.cpp b/test/SemaCXX/designated-initializers.cpp
index e5b5f3c9cc..04002c0b6c 100644
--- a/test/SemaCXX/designated-initializers.cpp
+++ b/test/SemaCXX/designated-initializers.cpp
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -Winitializer-overrides %s
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -Woverride-init %s
 
 template  struct Foo {
   struct SubFoo {
-- 
cgit v1.2.3


From e6a18409a80f0f50f655d20c863ed2c64b942c1d Mon Sep 17 00:00:00 2001
From: Nick Desaulniers 
Date: Thu, 10 Jan 2019 19:26:35 +0000
Subject: fixup: sphinx warning

Fixes the sphinx warning:
tools/clang/docs/DiagnosticsReference.rst:7889: WARNING: Title underline
too short.

That I just introduced in r350877.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350878 91177308-0d34-0410-b5e6-96231b3b80d8
---
 docs/DiagnosticsReference.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/docs/DiagnosticsReference.rst b/docs/DiagnosticsReference.rst
index e8f754ac85..7d9b1e8359 100644
--- a/docs/DiagnosticsReference.rst
+++ b/docs/DiagnosticsReference.rst
@@ -7886,7 +7886,7 @@ This diagnostic is enabled by default.
 +-----------------------------------------------------------------------------------------------+-----------------------+
 
 -Woverride-init
---------------
+---------------
 Synonym for `-Winitializer-overrides`_.
 
 
-- 
cgit v1.2.3


From 89552b7feb5ef6dff41441946e4c76bc2f91bb02 Mon Sep 17 00:00:00 2001
From: Yaxun Liu 
Date: Thu, 10 Jan 2019 20:09:52 +0000
Subject: [HIP] Use nul instead of /dev/null when running on windows

When clang is running on windows, /dev/null is not available. Use nul as empty input file instead.

Differential Revision: https://reviews.llvm.org/D56225


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350885 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/Driver/ToolChains/HIP.cpp | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/lib/Driver/ToolChains/HIP.cpp b/lib/Driver/ToolChains/HIP.cpp
index b44aadda79..868765cf88 100644
--- a/lib/Driver/ToolChains/HIP.cpp
+++ b/lib/Driver/ToolChains/HIP.cpp
@@ -24,6 +24,12 @@ using namespace clang::driver::tools;
 using namespace clang;
 using namespace llvm::opt;
 
+#if _WIN32 || _WIN64
+#define NULL_FILE "nul"
+#else
+#define NULL_FILE "/dev/null"
+#endif
+
 namespace {
 
 static void addBCLib(Compilation &C, const ArgList &Args,
@@ -197,7 +203,7 @@ void AMDGCN::constructHIPFatbinCommand(Compilation &C, const JobAction &JA,
   // ToDo: Remove the dummy host binary entry which is required by
   // clang-offload-bundler.
   std::string BundlerTargetArg = "-targets=host-x86_64-unknown-linux";
-  std::string BundlerInputArg = "-inputs=/dev/null";
+  std::string BundlerInputArg = "-inputs=" NULL_FILE;
 
   for (const auto &II : Inputs) {
     const auto* A = II.getAction();
-- 
cgit v1.2.3


From f4c2b45ed7bf906b2d9079c19c3a36f161c89a44 Mon Sep 17 00:00:00 2001
From: Akira Hatanaka 
Date: Thu, 10 Jan 2019 20:12:16 +0000
Subject: [Sema] Call CheckPlaceholderExpr to resolve typeof or decltype
 placeholder expressions while an unevaluated context is still on the
 expression evaluation context stack.

This prevents recordUseOfWeek from being called when a weak variable is
used as an operand of a decltype or a typeof expression and fixes
spurious -Warc-repeated-use-of-weak warnings.

rdar://problem/45742525

Differential Revision: https://reviews.llvm.org/D55662

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350887 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/Sema/SemaExpr.cpp              | 4 ++++
 lib/Sema/SemaExprCXX.cpp           | 5 +++++
 lib/Sema/SemaExprObjC.cpp          | 2 +-
 lib/Sema/SemaTemplateDeduction.cpp | 4 ++++
 lib/Sema/SemaType.cpp              | 8 ++------
 test/SemaObjC/arc-repeated-weak.mm | 3 +++
 6 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index eddf90178b..f65e97ed0b 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -14557,6 +14557,10 @@ void Sema::DiscardCleanupsInEvaluationContext() {
 }
 
 ExprResult Sema::HandleExprEvaluationContextForTypeof(Expr *E) {
+  ExprResult Result = CheckPlaceholderExpr(E);
+  if (Result.isInvalid())
+    return ExprError();
+  E = Result.get();
   if (!E->getType()->isVariablyModifiedType())
     return E;
   return TransformToPotentiallyEvaluated(E);
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index e963058b73..04f77a8e39 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -6543,6 +6543,11 @@ ExprResult Sema::ActOnDecltypeExpression(Expr *E) {
              ExpressionEvaluationContextRecord::EK_Decltype &&
          "not in a decltype expression");
 
+  ExprResult Result = CheckPlaceholderExpr(E);
+  if (Result.isInvalid())
+    return ExprError();
+  E = Result.get();
+
   // C++11 [expr.call]p11:
   //   If a function call is a prvalue of object type,
   // -- if the function call is either
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp
index ce80db7ca6..ed780efd4c 100644
--- a/lib/Sema/SemaExprObjC.cpp
+++ b/lib/Sema/SemaExprObjC.cpp
@@ -3161,7 +3161,7 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver,
           Prop->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_weak;
         if (!IsWeak && Sel.isUnarySelector())
           IsWeak = ReturnType.getObjCLifetime() & Qualifiers::OCL_Weak;
-        if (IsWeak &&
+        if (IsWeak && !isUnevaluatedContext() &&
             !Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, LBracLoc))
           getCurFunction()->recordUseOfWeak(Result, Prop);
       }
diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp
index 155d842c58..f2f989ce12 100644
--- a/lib/Sema/SemaTemplateDeduction.cpp
+++ b/lib/Sema/SemaTemplateDeduction.cpp
@@ -4429,6 +4429,10 @@ Sema::DeduceAutoType(TypeLoc Type, Expr *&Init, QualType &Result,
         return DAR_FailedAlreadyDiagnosed;
       }
 
+      ExprResult ER = CheckPlaceholderExpr(Init);
+      if (ER.isInvalid())
+        return DAR_FailedAlreadyDiagnosed;
+      Init = ER.get();
       QualType Deduced = BuildDecltypeType(Init, Init->getBeginLoc(), false);
       if (Deduced.isNull())
         return DAR_FailedAlreadyDiagnosed;
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index bf2bfda9ce..bf1b9c66a7 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -8055,9 +8055,7 @@ QualType Sema::getElaboratedType(ElaboratedTypeKeyword Keyword,
 }
 
 QualType Sema::BuildTypeofExprType(Expr *E, SourceLocation Loc) {
-  ExprResult ER = CheckPlaceholderExpr(E);
-  if (ER.isInvalid()) return QualType();
-  E = ER.get();
+  assert(!E->hasPlaceholderType() && "unexpected placeholder");
 
   if (!getLangOpts().CPlusPlus && E->refersToBitField())
     Diag(E->getExprLoc(), diag::err_sizeof_alignof_typeof_bitfield) << 2;
@@ -8142,9 +8140,7 @@ static QualType getDecltypeForExpr(Sema &S, Expr *E) {
 
 QualType Sema::BuildDecltypeType(Expr *E, SourceLocation Loc,
                                  bool AsUnevaluated) {
-  ExprResult ER = CheckPlaceholderExpr(E);
-  if (ER.isInvalid()) return QualType();
-  E = ER.get();
+  assert(!E->hasPlaceholderType() && "unexpected placeholder");
 
   if (AsUnevaluated && CodeSynthesisContexts.empty() &&
       E->HasSideEffects(Context, false)) {
diff --git a/test/SemaObjC/arc-repeated-weak.mm b/test/SemaObjC/arc-repeated-weak.mm
index d153eb9a52..4eec4d2fe6 100644
--- a/test/SemaObjC/arc-repeated-weak.mm
+++ b/test/SemaObjC/arc-repeated-weak.mm
@@ -462,6 +462,9 @@ void foo() {
   NSString * t2 = NSBundle.foo2.prop;
   use(NSBundle.foo2.weakProp); // expected-warning{{weak property 'weakProp' may be accessed multiple times}}
   use(NSBundle2.foo2.weakProp); // expected-note{{also accessed here}}
+  decltype([NSBundle2.foo2 weakProp]) t3;
+  decltype(NSBundle2.foo2.weakProp) t4;
+  __typeof__(NSBundle2.foo2.weakProp) t5;
 }
 
 // This used to crash in the constructor of WeakObjectProfileTy when a
-- 
cgit v1.2.3


From f1be9f83db361c97bd52f6b6624485ecc63546d0 Mon Sep 17 00:00:00 2001
From: Stephen Kelly 
Date: Thu, 10 Jan 2019 20:58:21 +0000
Subject: NFC: Change case of identifiers

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350890 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/AST/TextNodeDumper.h | 20 ++++++++++----------
 lib/AST/ASTDumper.cpp              |  4 ++--
 lib/AST/TextNodeDumper.cpp         |  2 +-
 3 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/include/clang/AST/TextNodeDumper.h b/include/clang/AST/TextNodeDumper.h
index db8087c9aa..8b6fde938d 100644
--- a/include/clang/AST/TextNodeDumper.h
+++ b/include/clang/AST/TextNodeDumper.h
@@ -27,7 +27,7 @@ class TextTreeStructure {
   const bool ShowColors;
 
   /// Pending[i] is an action to dump an entity at level i.
-  llvm::SmallVector, 32> Pending;
+  llvm::SmallVector, 32> Pending;
 
   /// Indicates whether we're at the top level.
   bool TopLevel = true;
@@ -39,13 +39,13 @@ class TextTreeStructure {
   std::string Prefix;
 
 public:
-  /// Add a child of the current node.  Calls doAddChild without arguments
-  template  void addChild(Fn doAddChild) {
+  /// Add a child of the current node.  Calls DoAddChild without arguments
+  template  void AddChild(Fn DoAddChild) {
     // If we're at the top level, there's nothing interesting to do; just
     // run the dumper.
     if (TopLevel) {
       TopLevel = false;
-      doAddChild();
+      DoAddChild();
       while (!Pending.empty()) {
         Pending.back()(true);
         Pending.pop_back();
@@ -56,7 +56,7 @@ public:
       return;
     }
 
-    auto dumpWithIndent = [this, doAddChild](bool isLastChild) {
+    auto DumpWithIndent = [this, DoAddChild](bool IsLastChild) {
       // Print out the appropriate tree structure and work out the prefix for
       // children of this node. For instance:
       //
@@ -72,15 +72,15 @@ public:
       {
         OS << '\n';
         ColorScope Color(OS, ShowColors, IndentColor);
-        OS << Prefix << (isLastChild ? '`' : '|') << '-';
-        this->Prefix.push_back(isLastChild ? ' ' : '|');
+        OS << Prefix << (IsLastChild ? '`' : '|') << '-';
+        this->Prefix.push_back(IsLastChild ? ' ' : '|');
         this->Prefix.push_back(' ');
       }
 
       FirstChild = true;
       unsigned Depth = Pending.size();
 
-      doAddChild();
+      DoAddChild();
 
       // If any children are left, they're the last at their nesting level.
       // Dump those ones out now.
@@ -94,10 +94,10 @@ public:
     };
 
     if (FirstChild) {
-      Pending.push_back(std::move(dumpWithIndent));
+      Pending.push_back(std::move(DumpWithIndent));
     } else {
       Pending.back()(false);
-      Pending.back() = std::move(dumpWithIndent);
+      Pending.back() = std::move(DumpWithIndent);
     }
     FirstChild = false;
   }
diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp
index 8d2e003504..698fca0b33 100644
--- a/lib/AST/ASTDumper.cpp
+++ b/lib/AST/ASTDumper.cpp
@@ -58,8 +58,8 @@ namespace  {
     const bool ShowColors;
 
     /// Dump a child of the current node.
-    template void dumpChild(Fn doDumpChild) {
-      NodeDumper.addChild(doDumpChild);
+    template void dumpChild(Fn DoDumpChild) {
+      NodeDumper.AddChild(DoDumpChild);
     }
 
   public:
diff --git a/lib/AST/TextNodeDumper.cpp b/lib/AST/TextNodeDumper.cpp
index b04a3cfdc8..3598e28680 100644
--- a/lib/AST/TextNodeDumper.cpp
+++ b/lib/AST/TextNodeDumper.cpp
@@ -165,7 +165,7 @@ void TextNodeDumper::dumpDeclRef(const Decl *D, const char *Label) {
   if (!D)
     return;
 
-  addChild([=] {
+  AddChild([=] {
     if (Label)
       OS << Label << ' ';
     dumpBareDeclRef(D);
-- 
cgit v1.2.3


From 898c95d5a806bc78fbad0256e54fa3b79d3e5327 Mon Sep 17 00:00:00 2001
From: Aaron Ballman 
Date: Thu, 10 Jan 2019 21:22:13 +0000
Subject: Correct the source range returned from preprocessor callbacks.

This adjusts the source range passed in to the preprocessor callbacks to only include the condition range itself, rather than all of the conditionally skipped tokens.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350891 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/Lex/Preprocessor.h  |   7 ++-
 lib/Lex/PPDirectives.cpp          |  74 ++++++++++++++----------
 lib/Lex/PPExpressions.cpp         |   8 +--
 unittests/Lex/PPCallbacksTest.cpp | 119 +++++++++++++++++++++++++++++++++++++-
 4 files changed, 170 insertions(+), 38 deletions(-)

diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h
index 64ddb5307f..36cb718570 100644
--- a/include/clang/Lex/Preprocessor.h
+++ b/include/clang/Lex/Preprocessor.h
@@ -1816,8 +1816,8 @@ public:
   void CheckEndOfDirective(const char *DirType, bool EnableMacros = false);
 
   /// Read and discard all tokens remaining on the current line until
-  /// the tok::eod token is found.
-  void DiscardUntilEndOfDirective();
+  /// the tok::eod token is found. Returns the range of the skipped tokens.
+  SourceRange DiscardUntilEndOfDirective();
 
   /// Returns true if the preprocessor has seen a use of
   /// __DATE__ or __TIME__ in the file so far.
@@ -1982,6 +1982,9 @@ private:
 
     /// True if the expression contained identifiers that were undefined.
     bool IncludedUndefinedIds;
+
+    /// The source range for the expression.
+    SourceRange ExprRange;
   };
 
   /// Evaluate an integer constant expression that may occur after a
diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp
index 15fc086f8a..c6baa99e90 100644
--- a/lib/Lex/PPDirectives.cpp
+++ b/lib/Lex/PPDirectives.cpp
@@ -79,12 +79,18 @@ Preprocessor::AllocateVisibilityMacroDirective(SourceLocation Loc,
 
 /// Read and discard all tokens remaining on the current line until
 /// the tok::eod token is found.
-void Preprocessor::DiscardUntilEndOfDirective() {
+SourceRange Preprocessor::DiscardUntilEndOfDirective() {
   Token Tmp;
-  do {
-    LexUnexpandedToken(Tmp);
+  SourceRange Res;
+
+  LexUnexpandedToken(Tmp);
+  Res.setBegin(Tmp.getLocation());
+  while (Tmp.isNot(tok::eod)) {
     assert(Tmp.isNot(tok::eof) && "EOF seen while discarding directive tokens");
-  } while (Tmp.isNot(tok::eod));
+    LexUnexpandedToken(Tmp);
+  }
+  Res.setEnd(Tmp.getLocation());
+  return Res;
 }
 
 /// Enumerates possible cases of #define/#undef a reserved identifier.
@@ -538,19 +544,19 @@ void Preprocessor::SkipExcludedConditionalBlock(SourceLocation HashTokenLoc,
         if (CondInfo.WasSkipping || CondInfo.FoundNonSkip) {
           DiscardUntilEndOfDirective();
         } else {
-          const SourceLocation CondBegin = CurPPLexer->getSourceLocation();
           // Restore the value of LexingRawMode so that identifiers are
           // looked up, etc, inside the #elif expression.
           assert(CurPPLexer->LexingRawMode && "We have to be skipping here!");
           CurPPLexer->LexingRawMode = false;
           IdentifierInfo *IfNDefMacro = nullptr;
-          const bool CondValue = EvaluateDirectiveExpression(IfNDefMacro).Conditional;
+          DirectiveEvalResult DER = EvaluateDirectiveExpression(IfNDefMacro);
+          const bool CondValue = DER.Conditional;
           CurPPLexer->LexingRawMode = true;
           if (Callbacks) {
-            const SourceLocation CondEnd = CurPPLexer->getSourceLocation();
-            Callbacks->Elif(Tok.getLocation(),
-                            SourceRange(CondBegin, CondEnd),
-                            (CondValue ? PPCallbacks::CVK_True : PPCallbacks::CVK_False), CondInfo.IfLoc);
+            Callbacks->Elif(
+                Tok.getLocation(), DER.ExprRange,
+                (CondValue ? PPCallbacks::CVK_True : PPCallbacks::CVK_False),
+                CondInfo.IfLoc);
           }
           // If this condition is true, enter it!
           if (CondValue) {
@@ -1116,19 +1122,24 @@ void Preprocessor::HandleLineDirective() {
     ; // ok
   else if (StrTok.isNot(tok::string_literal)) {
     Diag(StrTok, diag::err_pp_line_invalid_filename);
-    return DiscardUntilEndOfDirective();
+    DiscardUntilEndOfDirective();
+    return;
   } else if (StrTok.hasUDSuffix()) {
     Diag(StrTok, diag::err_invalid_string_udl);
-    return DiscardUntilEndOfDirective();
+    DiscardUntilEndOfDirective();
+    return;
   } else {
     // Parse and validate the string, converting it into a unique ID.
     StringLiteralParser Literal(StrTok, *this);
     assert(Literal.isAscii() && "Didn't allow wide strings in");
-    if (Literal.hadError)
-      return DiscardUntilEndOfDirective();
+    if (Literal.hadError) {
+      DiscardUntilEndOfDirective();
+      return;
+    }
     if (Literal.Pascal) {
       Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
-      return DiscardUntilEndOfDirective();
+      DiscardUntilEndOfDirective();
+      return;
     }
     FilenameID = SourceMgr.getLineTableFilenameID(Literal.GetString());
 
@@ -1261,19 +1272,24 @@ void Preprocessor::HandleDigitDirective(Token &DigitTok) {
     FileKind = SourceMgr.getFileCharacteristic(DigitTok.getLocation());
   } else if (StrTok.isNot(tok::string_literal)) {
     Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
-    return DiscardUntilEndOfDirective();
+    DiscardUntilEndOfDirective();
+    return;
   } else if (StrTok.hasUDSuffix()) {
     Diag(StrTok, diag::err_invalid_string_udl);
-    return DiscardUntilEndOfDirective();
+    DiscardUntilEndOfDirective();
+    return;
   } else {
     // Parse and validate the string, converting it into a unique ID.
     StringLiteralParser Literal(StrTok, *this);
     assert(Literal.isAscii() && "Didn't allow wide strings in");
-    if (Literal.hadError)
-      return DiscardUntilEndOfDirective();
+    if (Literal.hadError) {
+      DiscardUntilEndOfDirective();
+      return;
+    }
     if (Literal.Pascal) {
       Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
-      return DiscardUntilEndOfDirective();
+      DiscardUntilEndOfDirective();
+      return;
     }
     FilenameID = SourceMgr.getLineTableFilenameID(Literal.GetString());
 
@@ -1343,7 +1359,8 @@ void Preprocessor::HandleIdentSCCSDirective(Token &Tok) {
 
   if (StrTok.hasUDSuffix()) {
     Diag(StrTok, diag::err_invalid_string_udl);
-    return DiscardUntilEndOfDirective();
+    DiscardUntilEndOfDirective();
+    return;
   }
 
   // Verify that there is nothing after the string, other than EOD.
@@ -2783,10 +2800,8 @@ void Preprocessor::HandleIfDirective(Token &IfToken,
 
   // Parse and evaluate the conditional expression.
   IdentifierInfo *IfNDefMacro = nullptr;
-  const SourceLocation ConditionalBegin = CurPPLexer->getSourceLocation();
   const DirectiveEvalResult DER = EvaluateDirectiveExpression(IfNDefMacro);
   const bool ConditionalTrue = DER.Conditional;
-  const SourceLocation ConditionalEnd = CurPPLexer->getSourceLocation();
 
   // If this condition is equivalent to #ifndef X, and if this is the first
   // directive seen, handle it for the multiple-include optimization.
@@ -2799,9 +2814,9 @@ void Preprocessor::HandleIfDirective(Token &IfToken,
   }
 
   if (Callbacks)
-    Callbacks->If(IfToken.getLocation(),
-                  SourceRange(ConditionalBegin, ConditionalEnd),
-                  (ConditionalTrue ? PPCallbacks::CVK_True : PPCallbacks::CVK_False));
+    Callbacks->If(
+        IfToken.getLocation(), DER.ExprRange,
+        (ConditionalTrue ? PPCallbacks::CVK_True : PPCallbacks::CVK_False));
 
   // Should we include the stuff contained by this directive?
   if (PPOpts->SingleFileParseMode && DER.IncludedUndefinedIds) {
@@ -2894,9 +2909,7 @@ void Preprocessor::HandleElifDirective(Token &ElifToken,
   // #elif directive in a non-skipping conditional... start skipping.
   // We don't care what the condition is, because we will always skip it (since
   // the block immediately before it was included).
-  const SourceLocation ConditionalBegin = CurPPLexer->getSourceLocation();
-  DiscardUntilEndOfDirective();
-  const SourceLocation ConditionalEnd = CurPPLexer->getSourceLocation();
+  SourceRange ConditionRange = DiscardUntilEndOfDirective();
 
   PPConditionalInfo CI;
   if (CurPPLexer->popConditionalLevel(CI)) {
@@ -2912,8 +2925,7 @@ void Preprocessor::HandleElifDirective(Token &ElifToken,
   if (CI.FoundElse) Diag(ElifToken, diag::pp_err_elif_after_else);
 
   if (Callbacks)
-    Callbacks->Elif(ElifToken.getLocation(),
-                    SourceRange(ConditionalBegin, ConditionalEnd),
+    Callbacks->Elif(ElifToken.getLocation(), ConditionRange,
                     PPCallbacks::CVK_NotEvaluated, CI.IfLoc);
 
   if (PPOpts->SingleFileParseMode && !CI.FoundNonSkip) {
diff --git a/lib/Lex/PPExpressions.cpp b/lib/Lex/PPExpressions.cpp
index ac01efad9b..a60b7c97fc 100644
--- a/lib/Lex/PPExpressions.cpp
+++ b/lib/Lex/PPExpressions.cpp
@@ -152,8 +152,8 @@ static bool EvaluateDefined(PPValue &Result, Token &PeekTok, DefinedTracker &DT,
       return true;
     }
     // Consume the ).
-    Result.setEnd(PeekTok.getLocation());
     PP.LexNonComment(PeekTok);
+    Result.setEnd(PeekTok.getLocation());
   } else {
     // Consume identifier.
     Result.setEnd(PeekTok.getLocation());
@@ -863,7 +863,7 @@ Preprocessor::EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro) {
 
     // Restore 'DisableMacroExpansion'.
     DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
-    return {ResVal.Val != 0, DT.IncludedUndefinedIds};
+    return {ResVal.Val != 0, DT.IncludedUndefinedIds, ResVal.getRange()};
   }
 
   // Otherwise, we must have a binary operator (e.g. "#if 1 < 2"), so parse the
@@ -876,7 +876,7 @@ Preprocessor::EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro) {
 
     // Restore 'DisableMacroExpansion'.
     DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
-    return {false, DT.IncludedUndefinedIds};
+    return {false, DT.IncludedUndefinedIds, ResVal.getRange()};
   }
 
   // If we aren't at the tok::eod token, something bad happened, like an extra
@@ -888,5 +888,5 @@ Preprocessor::EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro) {
 
   // Restore 'DisableMacroExpansion'.
   DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
-  return {ResVal.Val != 0, DT.IncludedUndefinedIds};
+  return {ResVal.Val != 0, DT.IncludedUndefinedIds, ResVal.getRange()};
 }
diff --git a/unittests/Lex/PPCallbacksTest.cpp b/unittests/Lex/PPCallbacksTest.cpp
index d0ff45ec7c..29d5268921 100644
--- a/unittests/Lex/PPCallbacksTest.cpp
+++ b/unittests/Lex/PPCallbacksTest.cpp
@@ -65,6 +65,29 @@ public:
   SrcMgr::CharacteristicKind FileType;
 };
 
+class CondDirectiveCallbacks : public PPCallbacks {
+public:
+  struct Result {
+    SourceRange ConditionRange;
+    ConditionValueKind ConditionValue;
+
+    Result(SourceRange R, ConditionValueKind K)
+        : ConditionRange(R), ConditionValue(K) {}
+  };
+
+  std::vector Results;
+
+  void If(SourceLocation Loc, SourceRange ConditionRange,
+          ConditionValueKind ConditionValue) override {
+    Results.emplace_back(ConditionRange, ConditionValue);
+  }
+
+  void Elif(SourceLocation Loc, SourceRange ConditionRange,
+            ConditionValueKind ConditionValue, SourceLocation IfLoc) override {
+    Results.emplace_back(ConditionRange, ConditionValue);
+  }
+};
+
 // Stub to collect data from PragmaOpenCLExtension callbacks.
 class PragmaOpenCLExtensionCallbacks : public PPCallbacks {
 public:
@@ -137,6 +160,15 @@ protected:
     return StringRef(B, E - B);
   }
 
+  StringRef GetSourceStringToEnd(CharSourceRange Range) {
+    const char *B = SourceMgr.getCharacterData(Range.getBegin());
+    const char *E = SourceMgr.getCharacterData(Range.getEnd());
+
+    return StringRef(
+        B,
+        E - B + Lexer::MeasureTokenLength(Range.getEnd(), SourceMgr, LangOpts));
+  }
+
   // Run lexer over SourceText and collect FilenameRange from
   // the InclusionDirective callback.
   CharSourceRange InclusionDirectiveFilenameRange(const char *SourceText,
@@ -199,6 +231,36 @@ protected:
     return Callbacks;
   }
 
+  std::vector
+  DirectiveExprRange(StringRef SourceText) {
+    TrivialModuleLoader ModLoader;
+    MemoryBufferCache PCMCache;
+    std::unique_ptr Buf =
+        llvm::MemoryBuffer::getMemBuffer(SourceText);
+    SourceMgr.setMainFileID(SourceMgr.createFileID(std::move(Buf)));
+    HeaderSearch HeaderInfo(std::make_shared(), SourceMgr,
+                            Diags, LangOpts, Target.get());
+    Preprocessor PP(std::make_shared(), Diags, LangOpts,
+                    SourceMgr, PCMCache, HeaderInfo, ModLoader,
+                    /*IILookup =*/nullptr,
+                    /*OwnsHeaderSearch =*/false);
+    PP.Initialize(*Target);
+    auto *Callbacks = new CondDirectiveCallbacks;
+    PP.addPPCallbacks(std::unique_ptr(Callbacks));
+
+    // Lex source text.
+    PP.EnterMainSourceFile();
+
+    while (true) {
+      Token Tok;
+      PP.Lex(Tok);
+      if (Tok.is(tok::eof))
+        break;
+    }
+
+    return Callbacks->Results;
+  }
+
   PragmaOpenCLExtensionCallbacks::CallbackParameters
   PragmaOpenCLExtensionCall(const char *SourceText) {
     LangOptions OpenCLLangOpts;
@@ -368,4 +430,59 @@ TEST_F(PPCallbacksTest, OpenCLExtensionPragmaDisabled) {
   ASSERT_EQ(ExpectedState, Parameters.State);
 }
 
-} // anonoymous namespace
+TEST_F(PPCallbacksTest, DirectiveExprRanges) {
+  const auto &Results1 = DirectiveExprRange("#if FLUZZY_FLOOF\n#endif\n");
+  EXPECT_EQ(Results1.size(), 1);
+  EXPECT_EQ(
+      GetSourceStringToEnd(CharSourceRange(Results1[0].ConditionRange, false)),
+      "FLUZZY_FLOOF");
+
+  const auto &Results2 = DirectiveExprRange("#if 1 + 4 < 7\n#endif\n");
+  EXPECT_EQ(Results2.size(), 1);
+  EXPECT_EQ(
+      GetSourceStringToEnd(CharSourceRange(Results2[0].ConditionRange, false)),
+      "1 + 4 < 7");
+
+  const auto &Results3 = DirectiveExprRange("#if 1 + \\\n  2\n#endif\n");
+  EXPECT_EQ(Results3.size(), 1);
+  EXPECT_EQ(
+      GetSourceStringToEnd(CharSourceRange(Results3[0].ConditionRange, false)),
+      "1 + \\\n  2");
+
+  const auto &Results4 = DirectiveExprRange("#if 0\n#elif FLOOFY\n#endif\n");
+  EXPECT_EQ(Results4.size(), 2);
+  EXPECT_EQ(
+      GetSourceStringToEnd(CharSourceRange(Results4[0].ConditionRange, false)),
+      "0");
+  EXPECT_EQ(
+      GetSourceStringToEnd(CharSourceRange(Results4[1].ConditionRange, false)),
+      "FLOOFY");
+
+  const auto &Results5 = DirectiveExprRange("#if 1\n#elif FLOOFY\n#endif\n");
+  EXPECT_EQ(Results5.size(), 2);
+  EXPECT_EQ(
+      GetSourceStringToEnd(CharSourceRange(Results5[0].ConditionRange, false)),
+      "1");
+  EXPECT_EQ(
+      GetSourceStringToEnd(CharSourceRange(Results5[1].ConditionRange, false)),
+      "FLOOFY");
+
+  const auto &Results6 =
+      DirectiveExprRange("#if defined(FLUZZY_FLOOF)\n#endif\n");
+  EXPECT_EQ(Results6.size(), 1);
+  EXPECT_EQ(
+      GetSourceStringToEnd(CharSourceRange(Results6[0].ConditionRange, false)),
+      "defined(FLUZZY_FLOOF)");
+
+  const auto &Results7 =
+      DirectiveExprRange("#if 1\n#elif defined(FLOOFY)\n#endif\n");
+  EXPECT_EQ(Results7.size(), 2);
+  EXPECT_EQ(
+      GetSourceStringToEnd(CharSourceRange(Results7[0].ConditionRange, false)),
+      "1");
+  EXPECT_EQ(
+      GetSourceStringToEnd(CharSourceRange(Results7[1].ConditionRange, false)),
+      "defined(FLOOFY)");
+}
+
+} // namespace
-- 
cgit v1.2.3


From 9cedc71c6c932d740160a10164361882fee406cb Mon Sep 17 00:00:00 2001
From: Sterling Augustine 
Date: Thu, 10 Jan 2019 22:25:58 +0000
Subject: Properly support -shared-libgcc. This revision was revied in D55016.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350900 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/Driver/ToolChains/CommonArgs.cpp |  9 +++------
 test/Driver/linux-ld.c               | 19 +++++++------------
 2 files changed, 10 insertions(+), 18 deletions(-)

diff --git a/lib/Driver/ToolChains/CommonArgs.cpp b/lib/Driver/ToolChains/CommonArgs.cpp
index dcafc5d1ab..cada16174f 100644
--- a/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/lib/Driver/ToolChains/CommonArgs.cpp
@@ -1159,11 +1159,8 @@ static void AddLibgcc(const llvm::Triple &Triple, const Driver &D,
   bool StaticLibgcc = Args.hasArg(options::OPT_static_libgcc) ||
                       Args.hasArg(options::OPT_static);
 
-  // The driver ignores -shared-libgcc and therefore treats such cases as
-  // unspecified.  Breaking out the two variables as below makes the current
-  // behavior explicit.
-  bool UnspecifiedLibgcc = !StaticLibgcc;
-  bool SharedLibgcc = !StaticLibgcc;
+  bool SharedLibgcc = Args.hasArg(options::OPT_shared_libgcc);
+  bool UnspecifiedLibgcc = !StaticLibgcc && !SharedLibgcc;
 
   // Gcc adds libgcc arguments in various ways:
   //
@@ -1180,7 +1177,7 @@ static void AddLibgcc(const llvm::Triple &Triple, const Driver &D,
   if (LibGccFirst)
     CmdArgs.push_back("-lgcc");
 
-  bool AsNeeded = D.CCCIsCC() && !StaticLibgcc && !isAndroid && !isCygMing;
+  bool AsNeeded = D.CCCIsCC() && UnspecifiedLibgcc && !isAndroid && !isCygMing;
   if (AsNeeded)
     CmdArgs.push_back("--as-needed");
 
diff --git a/test/Driver/linux-ld.c b/test/Driver/linux-ld.c
index dc2f775abe..3ab81be490 100644
--- a/test/Driver/linux-ld.c
+++ b/test/Driver/linux-ld.c
@@ -211,24 +211,19 @@
 // RUN:     --gcc-toolchain="" \
 // RUN:     --sysroot=%S/Inputs/basic_linux_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-CLANG-SHARED-LIBGCC %s
-// CHECK-CLANG-SHARED-LIBGCC: warning: argument unused during compilation: '-shared-libgcc'
-// This will be the correct check once the driver supports -shared-libgcc
-// SKIP-CHECK-CLANG-SHARED-LIBGCC: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
-// SKIP-CHECK-CLANG-SHARED-LIBGCC: "-lgcc_s" "-lgcc"
-// SKIP-CHECK-CLANG-SHARED-LIBGCC: "-lc"
-// SKIP-CHECK-CLANG-SHARED-LIBGCC: "-lgcc_s" "-lgcc"
+// CHECK-CLANG-SHARED-LIBGCC: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
+// CHECK-CLANG-SHARED-LIBGCC: "-lgcc_s" "-lgcc"
+// CHECK-CLANG-SHARED-LIBGCC: "-lc"
+// CHECK-CLANG-SHARED-LIBGCC: "-lgcc_s" "-lgcc"
 //
 // RUN: %clang -shared-libgcc -dynamic -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     --target=x86_64-unknown-linux -rtlib=platform \
 // RUN:     --gcc-toolchain="" \
 // RUN:     --sysroot=%S/Inputs/basic_linux_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-CLANG-SHARED-LIBGCC-DYNAMIC %s
-// CHECK-CLANG-SHARED-LIBGCC-DYNAMIC: warning: argument unused during compilation: '-shared-libgcc'
-// CHECK-CLANG-SHARED-LIBGCC-DYNAMIC: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
-// This will be the correct check once the driver supports -shared-libgcc
-// SKIP-CHECK-CLANG-SHARED-LIBGCC-DYNAMIC: "-lgcc_s" "-lgcc"
-// SKIP-CHECK-CLANG-SHARED-LIBGCC-DYNAMIC: "-lc"
-// SKIP-CHECK-CLANG-SHARED-LIBGCC-DYNAMIC: "-lgcc_s" "-lgcc"
+// CHECK-CLANG-SHARED-LIBGCC-DYNAMIC: "-lgcc_s" "-lgcc"
+// CHECK-CLANG-SHARED-LIBGCC-DYNAMIC: "-lc"
+// CHECK-CLANG-SHARED-LIBGCC-DYNAMIC: "-lgcc_s" "-lgcc"
 //
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     --target=aarch64-linux-android -rtlib=platform \
-- 
cgit v1.2.3


From 2f9e8fb6b8195fddf0452dadf6a9b6d824bee23c Mon Sep 17 00:00:00 2001
From: Artem Dergachev 
Date: Thu, 10 Jan 2019 23:44:44 +0000
Subject: [analyzer] pr38838, pr39976: Fix crash on diagnosing before implicit
 destructor.

We need to be able to emit the diagnostic at PreImplicitCall,
and the patch implements this functionality.

However, for now the need for emitting such diagnostics is not all that great:
it is only necessary to not crash when emitting a false positive due to an
unrelated issue of having dead symbol collection not working properly.

Coming up with a non-false-positive test seems impossible with the current
set of checkers, though it is likely to be needed for good things as well
in the future.

Differential Revision: https://reviews.llvm.org/D56042

rdar://problem/46911462


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350907 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/StaticAnalyzer/Core/PathDiagnostic.cpp |  2 ++
 test/Analysis/diagnostics/dtors.cpp        | 25 +++++++++++++++++++++++++
 2 files changed, 27 insertions(+)
 create mode 100644 test/Analysis/diagnostics/dtors.cpp

diff --git a/lib/StaticAnalyzer/Core/PathDiagnostic.cpp b/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
index 691176dfc1..3e93bb6a7c 100644
--- a/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
+++ b/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
@@ -723,6 +723,8 @@ PathDiagnosticLocation::create(const ProgramPoint& P,
   } else if (Optional PIP = P.getAs()) {
     return PathDiagnosticLocation(PIP->getInitializer()->getSourceLocation(),
                                   SMng);
+  } else if (Optional PIC = P.getAs()) {
+    return PathDiagnosticLocation(PIC->getLocation(), SMng);
   } else if (Optional PIE = P.getAs()) {
     return PathDiagnosticLocation(PIE->getLocation(), SMng);
   } else if (Optional CE = P.getAs()) {
diff --git a/test/Analysis/diagnostics/dtors.cpp b/test/Analysis/diagnostics/dtors.cpp
new file mode 100644
index 0000000000..094917e432
--- /dev/null
+++ b/test/Analysis/diagnostics/dtors.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_analyze_cc1 -w -analyzer-checker=core,cplusplus -verify %s
+
+// expected-no-diagnostics
+
+namespace no_crash_on_delete_dtor {
+// We were crashing when producing diagnostics for this code.
+struct S {
+  void foo();
+  ~S();
+};
+
+struct smart_ptr {
+  int x;
+  S *s;
+  smart_ptr(S *);
+  S *get() {
+    return (x || 0) ? nullptr : s;
+  }
+};
+
+void bar(smart_ptr p) {
+  delete p.get();
+  p.get()->foo();
+}
+} // namespace no_crash_on_delete_dtor
-- 
cgit v1.2.3


From 5cb757a4741ccb3490ca24f49474492620c966c0 Mon Sep 17 00:00:00 2001
From: Thomas Lively 
Date: Thu, 10 Jan 2019 23:49:00 +0000
Subject: [WebAssembly] Add unimplemented-simd128 feature, gate builtins

Summary: Depends on D56501. Also adds a macro define
`__wasm_unimplemented_simd128__` for feature detection of
unimplemented SIMD builtins.

Reviewers: aheejin, dschuff

Subscribers: sbc100, jgravelle-google, sunfish, kristina, cfe-commits, rrwinterton

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350909 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/Basic/BuiltinsWebAssembly.def | 141 ++++++++++++++--------------
 include/clang/Driver/Options.td             |   2 +
 lib/Basic/Targets/WebAssembly.cpp           |  49 ++++++++++
 lib/Basic/Targets/WebAssembly.h             |  15 +--
 test/CodeGen/builtins-wasm.c                |  10 +-
 test/Preprocessor/wasm-target-features.c    |   9 ++
 6 files changed, 142 insertions(+), 84 deletions(-)

diff --git a/include/clang/Basic/BuiltinsWebAssembly.def b/include/clang/Basic/BuiltinsWebAssembly.def
index e1e97fe26a..7b201dbf0e 100644
--- a/include/clang/Basic/BuiltinsWebAssembly.def
+++ b/include/clang/Basic/BuiltinsWebAssembly.def
@@ -16,6 +16,10 @@
 
 // The format of this database matches clang/Basic/Builtins.def.
 
+#if defined(BUILTIN) && !defined(TARGET_BUILTIN)
+#   define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BUILTIN(ID, TYPE, ATTRS)
+#endif
+
 // Query the current memory size, and increase the current memory size.
 // Note that memory.size is not "c" (readnone) because it must be sequenced
 // with respect to memory.grow calls.
@@ -30,9 +34,15 @@ BUILTIN(__builtin_wasm_mem_grow, "zIiz", "n")
 BUILTIN(__builtin_wasm_current_memory, "z", "n")
 BUILTIN(__builtin_wasm_grow_memory, "zz", "n")
 
+// Floating point min/max
+BUILTIN(__builtin_wasm_min_f32, "fff", "nc")
+BUILTIN(__builtin_wasm_max_f32, "fff", "nc")
+BUILTIN(__builtin_wasm_min_f64, "ddd", "nc")
+BUILTIN(__builtin_wasm_max_f64, "ddd", "nc")
+
 // Exception handling builtins.
-BUILTIN(__builtin_wasm_throw, "vUiv*", "r")
-BUILTIN(__builtin_wasm_rethrow, "v", "r")
+TARGET_BUILTIN(__builtin_wasm_throw, "vUiv*", "r", "exception-handling")
+TARGET_BUILTIN(__builtin_wasm_rethrow, "v", "r", "exception-handling")
 
 // Atomic wait and notify.
 BUILTIN(__builtin_wasm_atomic_wait_i32, "ii*iLLi", "n")
@@ -40,73 +50,68 @@ BUILTIN(__builtin_wasm_atomic_wait_i64, "iLLi*LLiLLi", "n")
 BUILTIN(__builtin_wasm_atomic_notify, "Uii*Ui", "n")
 
 // Saturating fp-to-int conversions
-BUILTIN(__builtin_wasm_trunc_saturate_s_i32_f32, "if", "nc")
-BUILTIN(__builtin_wasm_trunc_saturate_u_i32_f32, "if", "nc")
-BUILTIN(__builtin_wasm_trunc_saturate_s_i32_f64, "id", "nc")
-BUILTIN(__builtin_wasm_trunc_saturate_u_i32_f64, "id", "nc")
-BUILTIN(__builtin_wasm_trunc_saturate_s_i64_f32, "LLif", "nc")
-BUILTIN(__builtin_wasm_trunc_saturate_u_i64_f32, "LLif", "nc")
-BUILTIN(__builtin_wasm_trunc_saturate_s_i64_f64, "LLid", "nc")
-BUILTIN(__builtin_wasm_trunc_saturate_u_i64_f64, "LLid", "nc")
-
-// Floating point min/max
-BUILTIN(__builtin_wasm_min_f32, "fff", "nc")
-BUILTIN(__builtin_wasm_max_f32, "fff", "nc")
-BUILTIN(__builtin_wasm_min_f64, "ddd", "nc")
-BUILTIN(__builtin_wasm_max_f64, "ddd", "nc")
+TARGET_BUILTIN(__builtin_wasm_trunc_saturate_s_i32_f32, "if", "nc", "nontrapping-fptoint")
+TARGET_BUILTIN(__builtin_wasm_trunc_saturate_u_i32_f32, "if", "nc", "nontrapping-fptoint")
+TARGET_BUILTIN(__builtin_wasm_trunc_saturate_s_i32_f64, "id", "nc", "nontrapping-fptoint")
+TARGET_BUILTIN(__builtin_wasm_trunc_saturate_u_i32_f64, "id", "nc", "nontrapping-fptoint")
+TARGET_BUILTIN(__builtin_wasm_trunc_saturate_s_i64_f32, "LLif", "nc", "nontrapping-fptoint")
+TARGET_BUILTIN(__builtin_wasm_trunc_saturate_u_i64_f32, "LLif", "nc", "nontrapping-fptoint")
+TARGET_BUILTIN(__builtin_wasm_trunc_saturate_s_i64_f64, "LLid", "nc", "nontrapping-fptoint")
+TARGET_BUILTIN(__builtin_wasm_trunc_saturate_u_i64_f64, "LLid", "nc", "nontrapping-fptoint")
 
 // SIMD builtins
-BUILTIN(__builtin_wasm_extract_lane_s_i8x16, "iV16cIi", "nc")
-BUILTIN(__builtin_wasm_extract_lane_u_i8x16, "iV16cIi", "nc")
-BUILTIN(__builtin_wasm_extract_lane_s_i16x8, "iV8sIi", "nc")
-BUILTIN(__builtin_wasm_extract_lane_u_i16x8, "iV8sIi", "nc")
-BUILTIN(__builtin_wasm_extract_lane_i32x4, "iV4iIi", "nc")
-BUILTIN(__builtin_wasm_extract_lane_i64x2, "LLiV2LLiIi", "nc")
-BUILTIN(__builtin_wasm_extract_lane_f32x4, "fV4fIi", "nc")
-BUILTIN(__builtin_wasm_extract_lane_f64x2, "dV2dIi", "nc")
-
-BUILTIN(__builtin_wasm_replace_lane_i8x16, "V16cV16cIii", "nc")
-BUILTIN(__builtin_wasm_replace_lane_i16x8, "V8sV8sIii", "nc")
-BUILTIN(__builtin_wasm_replace_lane_i32x4, "V4iV4iIii", "nc")
-BUILTIN(__builtin_wasm_replace_lane_i64x2, "V2LLiV2LLiIiLLi", "nc")
-BUILTIN(__builtin_wasm_replace_lane_f32x4, "V4fV4fIif", "nc")
-BUILTIN(__builtin_wasm_replace_lane_f64x2, "V2dV2dIid", "nc")
-
-BUILTIN(__builtin_wasm_add_saturate_s_i8x16, "V16cV16cV16c", "nc")
-BUILTIN(__builtin_wasm_add_saturate_u_i8x16, "V16cV16cV16c", "nc")
-BUILTIN(__builtin_wasm_add_saturate_s_i16x8, "V8sV8sV8s", "nc")
-BUILTIN(__builtin_wasm_add_saturate_u_i16x8, "V8sV8sV8s", "nc")
-
-BUILTIN(__builtin_wasm_sub_saturate_s_i8x16, "V16cV16cV16c", "nc")
-BUILTIN(__builtin_wasm_sub_saturate_u_i8x16, "V16cV16cV16c", "nc")
-BUILTIN(__builtin_wasm_sub_saturate_s_i16x8, "V8sV8sV8s", "nc")
-BUILTIN(__builtin_wasm_sub_saturate_u_i16x8, "V8sV8sV8s", "nc")
-
-BUILTIN(__builtin_wasm_bitselect, "V4iV4iV4iV4i", "nc")
-
-BUILTIN(__builtin_wasm_any_true_i8x16, "iV16c", "nc")
-BUILTIN(__builtin_wasm_any_true_i16x8, "iV8s", "nc")
-BUILTIN(__builtin_wasm_any_true_i32x4, "iV4i", "nc")
-BUILTIN(__builtin_wasm_any_true_i64x2, "iV2LLi", "nc")
-BUILTIN(__builtin_wasm_all_true_i8x16, "iV16c", "nc")
-BUILTIN(__builtin_wasm_all_true_i16x8, "iV8s", "nc")
-BUILTIN(__builtin_wasm_all_true_i32x4, "iV4i", "nc")
-BUILTIN(__builtin_wasm_all_true_i64x2, "iV2LLi", "nc")
-
-BUILTIN(__builtin_wasm_abs_f32x4, "V4fV4f", "nc")
-BUILTIN(__builtin_wasm_abs_f64x2, "V2dV2d", "nc")
-
-BUILTIN(__builtin_wasm_min_f32x4, "V4fV4fV4f", "nc")
-BUILTIN(__builtin_wasm_max_f32x4, "V4fV4fV4f", "nc")
-BUILTIN(__builtin_wasm_min_f64x2, "V2dV2dV2d", "nc")
-BUILTIN(__builtin_wasm_max_f64x2, "V2dV2dV2d", "nc")
-
-BUILTIN(__builtin_wasm_sqrt_f32x4, "V4fV4f", "nc")
-BUILTIN(__builtin_wasm_sqrt_f64x2, "V2dV2d", "nc")
-
-BUILTIN(__builtin_wasm_trunc_saturate_s_i32x4_f32x4, "V4iV4f", "nc")
-BUILTIN(__builtin_wasm_trunc_saturate_u_i32x4_f32x4, "V4iV4f", "nc")
-BUILTIN(__builtin_wasm_trunc_saturate_s_i64x2_f64x2, "V2LLiV2d", "nc")
-BUILTIN(__builtin_wasm_trunc_saturate_u_i64x2_f64x2, "V2LLiV2d", "nc")
+TARGET_BUILTIN(__builtin_wasm_extract_lane_s_i8x16, "iV16cIi", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_extract_lane_u_i8x16, "iV16cIi", "nc", "unimplemented-simd128")
+TARGET_BUILTIN(__builtin_wasm_extract_lane_s_i16x8, "iV8sIi", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_extract_lane_u_i16x8, "iV8sIi", "nc", "unimplemented-simd128")
+TARGET_BUILTIN(__builtin_wasm_extract_lane_i32x4, "iV4iIi", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_extract_lane_i64x2, "LLiV2LLiIi", "nc", "unimplemented-simd128")
+TARGET_BUILTIN(__builtin_wasm_extract_lane_f32x4, "fV4fIi", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_extract_lane_f64x2, "dV2dIi", "nc", "unimplemented-simd128")
+
+TARGET_BUILTIN(__builtin_wasm_replace_lane_i8x16, "V16cV16cIii", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_replace_lane_i16x8, "V8sV8sIii", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_replace_lane_i32x4, "V4iV4iIii", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_replace_lane_i64x2, "V2LLiV2LLiIiLLi", "nc", "unimplemented-simd128")
+TARGET_BUILTIN(__builtin_wasm_replace_lane_f32x4, "V4fV4fIif", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_replace_lane_f64x2, "V2dV2dIid", "nc", "unimplemented-simd128")
+
+TARGET_BUILTIN(__builtin_wasm_add_saturate_s_i8x16, "V16cV16cV16c", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_add_saturate_u_i8x16, "V16cV16cV16c", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_add_saturate_s_i16x8, "V8sV8sV8s", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_add_saturate_u_i16x8, "V8sV8sV8s", "nc", "simd128")
+
+TARGET_BUILTIN(__builtin_wasm_sub_saturate_s_i8x16, "V16cV16cV16c", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_sub_saturate_u_i8x16, "V16cV16cV16c", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_sub_saturate_s_i16x8, "V8sV8sV8s", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_sub_saturate_u_i16x8, "V8sV8sV8s", "nc", "simd128")
+
+TARGET_BUILTIN(__builtin_wasm_bitselect, "V4iV4iV4iV4i", "nc", "simd128")
+
+TARGET_BUILTIN(__builtin_wasm_any_true_i8x16, "iV16c", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_any_true_i16x8, "iV8s", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_any_true_i32x4, "iV4i", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_any_true_i64x2, "iV2LLi", "nc", "unimplemented-simd128")
+TARGET_BUILTIN(__builtin_wasm_all_true_i8x16, "iV16c", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_all_true_i16x8, "iV8s", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_all_true_i32x4, "iV4i", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_all_true_i64x2, "iV2LLi", "nc", "unimplemented-simd128")
+
+TARGET_BUILTIN(__builtin_wasm_abs_f32x4, "V4fV4f", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_abs_f64x2, "V2dV2d", "nc", "unimplemented-simd128")
+
+TARGET_BUILTIN(__builtin_wasm_min_f32x4, "V4fV4fV4f", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_max_f32x4, "V4fV4fV4f", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_min_f64x2, "V2dV2dV2d", "nc", "unimplemented-simd128")
+TARGET_BUILTIN(__builtin_wasm_max_f64x2, "V2dV2dV2d", "nc", "unimplemented-simd128")
+
+TARGET_BUILTIN(__builtin_wasm_sqrt_f32x4, "V4fV4f", "nc", "unimplemented-simd128")
+TARGET_BUILTIN(__builtin_wasm_sqrt_f64x2, "V2dV2d", "nc", "unimplemented-simd128")
+
+TARGET_BUILTIN(__builtin_wasm_trunc_saturate_s_i32x4_f32x4, "V4iV4f", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_trunc_saturate_u_i32x4_f32x4, "V4iV4f", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_trunc_saturate_s_i64x2_f64x2, "V2LLiV2d", "nc", "unimplemented-simd128")
+TARGET_BUILTIN(__builtin_wasm_trunc_saturate_u_i64x2_f64x2, "V2LLiV2d", "nc", "unimplemented-simd128")
 
 #undef BUILTIN
+#undef TARGET_BUILTIN
diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td
index 9e6b1afde4..bb4436a638 100644
--- a/include/clang/Driver/Options.td
+++ b/include/clang/Driver/Options.td
@@ -2141,6 +2141,8 @@ def mbranch_protection_EQ : Joined<["-"], "mbranch-protection=">,
   HelpText<"Enforce targets of indirect branches and function returns">;
 
 def msimd128 : Flag<["-"], "msimd128">, Group;
+def munimplemented_simd128 : Flag<["-"], "munimplemented-simd128">, Group;
+def mno_unimplemented_simd128 : Flag<["-"], "mno-unimplemented-simd128">, Group;
 def mno_simd128 : Flag<["-"], "mno-simd128">, Group;
 def mnontrapping_fptoint : Flag<["-"], "mnontrapping-fptoint">, Group;
 def mno_nontrapping_fptoint : Flag<["-"], "mno-nontrapping-fptoint">, Group;
diff --git a/lib/Basic/Targets/WebAssembly.cpp b/lib/Basic/Targets/WebAssembly.cpp
index b8a2a092af..2fdc84bb8c 100644
--- a/lib/Basic/Targets/WebAssembly.cpp
+++ b/lib/Basic/Targets/WebAssembly.cpp
@@ -24,6 +24,8 @@ using namespace clang::targets;
 const Builtin::Info WebAssemblyTargetInfo::BuiltinInfo[] = {
 #define BUILTIN(ID, TYPE, ATTRS)                                               \
   {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
+#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE)                               \
+  {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE},
 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER)                                    \
   {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
 #include "clang/Basic/BuiltinsWebAssembly.def"
@@ -35,6 +37,7 @@ static constexpr llvm::StringLiteral ValidCPUNames[] = {
 bool WebAssemblyTargetInfo::hasFeature(StringRef Feature) const {
   return llvm::StringSwitch(Feature)
       .Case("simd128", SIMDLevel >= SIMD128)
+      .Case("unimplemented-simd128", SIMDLevel >= UnimplementedSIMD128)
       .Case("nontrapping-fptoint", HasNontrappingFPToInt)
       .Case("sign-ext", HasSignExt)
       .Case("exception-handling", HasExceptionHandling)
@@ -55,6 +58,44 @@ void WebAssemblyTargetInfo::getTargetDefines(const LangOptions &Opts,
   defineCPUMacros(Builder, "wasm", /*Tuning=*/false);
   if (SIMDLevel >= SIMD128)
     Builder.defineMacro("__wasm_simd128__");
+  if (SIMDLevel >= UnimplementedSIMD128)
+    Builder.defineMacro("__wasm_unimplemented_simd128__");
+}
+
+void WebAssemblyTargetInfo::setSIMDLevel(llvm::StringMap &Features,
+                                         SIMDEnum Level) {
+  switch (Level) {
+  case UnimplementedSIMD128:
+    Features["unimplemented-simd128"] = true;
+    LLVM_FALLTHROUGH;
+  case SIMD128:
+    Features["simd128"] = true;
+    LLVM_FALLTHROUGH;
+  case NoSIMD:
+    break;
+  }
+}
+
+bool WebAssemblyTargetInfo::initFeatureMap(
+    llvm::StringMap &Features, DiagnosticsEngine &Diags, StringRef CPU,
+    const std::vector &FeaturesVec) const {
+  if (CPU == "bleeding-edge") {
+    Features["nontrapping-fptoint"] = true;
+    Features["sign-ext"] = true;
+    setSIMDLevel(Features, SIMD128);
+  }
+  // Other targets do not consider user-configured features here, but while we
+  // are actively developing new features it is useful to let user-configured
+  // features control availability of builtins
+  setSIMDLevel(Features, SIMDLevel);
+  if (HasNontrappingFPToInt)
+    Features["nontrapping-fptoint"] = true;
+  if (HasSignExt)
+    Features["sign-ext"] = true;
+  if (HasExceptionHandling)
+    Features["exception-handling"] = true;
+
+  return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
 }
 
 bool WebAssemblyTargetInfo::handleTargetFeatures(
@@ -68,6 +109,14 @@ bool WebAssemblyTargetInfo::handleTargetFeatures(
       SIMDLevel = std::min(SIMDLevel, SIMDEnum(SIMD128 - 1));
       continue;
     }
+    if (Feature == "+unimplemented-simd128") {
+      SIMDLevel = std::max(SIMDLevel, SIMDEnum(UnimplementedSIMD128));
+      continue;
+    }
+    if (Feature == "-unimplemented-simd128") {
+      SIMDLevel = std::min(SIMDLevel, SIMDEnum(UnimplementedSIMD128 - 1));
+      continue;
+    }
     if (Feature == "+nontrapping-fptoint") {
       HasNontrappingFPToInt = true;
       continue;
diff --git a/lib/Basic/Targets/WebAssembly.h b/lib/Basic/Targets/WebAssembly.h
index c04c5cb6fb..3dea9a373c 100644
--- a/lib/Basic/Targets/WebAssembly.h
+++ b/lib/Basic/Targets/WebAssembly.h
@@ -28,7 +28,8 @@ class LLVM_LIBRARY_VISIBILITY WebAssemblyTargetInfo : public TargetInfo {
   enum SIMDEnum {
     NoSIMD,
     SIMD128,
-  } SIMDLevel;
+    UnimplementedSIMD128,
+  } SIMDLevel = NoSIMD;
 
   bool HasNontrappingFPToInt;
   bool HasSignExt;
@@ -59,18 +60,12 @@ protected:
                         MacroBuilder &Builder) const override;
 
 private:
+  static void setSIMDLevel(llvm::StringMap &Features, SIMDEnum Level);
+
   bool
   initFeatureMap(llvm::StringMap &Features, DiagnosticsEngine &Diags,
                  StringRef CPU,
-                 const std::vector &FeaturesVec) const override {
-    if (CPU == "bleeding-edge") {
-      Features["simd128"] = true;
-      Features["nontrapping-fptoint"] = true;
-      Features["sign-ext"] = true;
-    }
-    return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
-  }
-
+                 const std::vector &FeaturesVec) const override;
   bool hasFeature(StringRef Feature) const final;
 
   bool handleTargetFeatures(std::vector &Features,
diff --git a/test/CodeGen/builtins-wasm.c b/test/CodeGen/builtins-wasm.c
index dce721ef5a..3c2288b252 100644
--- a/test/CodeGen/builtins-wasm.c
+++ b/test/CodeGen/builtins-wasm.c
@@ -1,9 +1,6 @@
-// RUN: %clang_cc1 -triple wasm32-unknown-unknown -fno-lax-vector-conversions \
-// RUN:   -O3 -emit-llvm -o - %s \
-// RUN:   | FileCheck %s -check-prefixes WEBASSEMBLY,WEBASSEMBLY32
-// RUN: %clang_cc1 -triple wasm64-unknown-unknown -fno-lax-vector-conversions \
-// RUN:   -O3 -emit-llvm -o - %s \
-// RUN:   | FileCheck %s -check-prefixes WEBASSEMBLY,WEBASSEMBLY64
+// RUN: %clang_cc1 -triple wasm32-unknown-unknown -target-feature +unimplemented-simd128 -target-feature +nontrapping-fptoint -target-feature +exception-handling -fno-lax-vector-conversions -O3 -emit-llvm -o - %s | FileCheck %s -check-prefixes WEBASSEMBLY,WEBASSEMBLY32
+// RUN: %clang_cc1 -triple wasm64-unknown-unknown -target-feature +unimplemented-simd128 -target-feature +nontrapping-fptoint -target-feature +exception-handling -fno-lax-vector-conversions -O3 -emit-llvm -o - %s | FileCheck %s -check-prefixes WEBASSEMBLY,WEBASSEMBLY64
+// RUN: not %clang_cc1 -triple wasm64-unknown-unknown -target-feature +nontrapping-fptoint -target-feature +exception-handling -fno-lax-vector-conversions -O3 -emit-llvm -o - %s 2>&1 | FileCheck %s -check-prefixes MISSING-SIMD
 
 // SIMD convenience types
 typedef char i8x16 __attribute((vector_size(16)));
@@ -158,6 +155,7 @@ double max_f64(double x, double y) {
 
 int extract_lane_s_i8x16(i8x16 v) {
   return __builtin_wasm_extract_lane_s_i8x16(v, 13);
+  // MISSING-SIMD: error: '__builtin_wasm_extract_lane_s_i8x16' needs target feature simd128
   // WEBASSEMBLY: extractelement <16 x i8> %v, i32 13
   // WEBASSEMBLY-NEXT: sext
   // WEBASSEMBLY-NEXT: ret
diff --git a/test/Preprocessor/wasm-target-features.c b/test/Preprocessor/wasm-target-features.c
index f4d40b1774..92aaefd73c 100644
--- a/test/Preprocessor/wasm-target-features.c
+++ b/test/Preprocessor/wasm-target-features.c
@@ -8,6 +8,15 @@
 // SIMD128:#define __wasm_simd128__ 1{{$}}
 //
 // RUN: %clang -E -dM %s -o - 2>&1 \
+// RUN:     -target wasm32-unknown-unknown -munimplemented-simd128 \
+// RUN:   | FileCheck %s -check-prefix=SIMD128-UNIMPLEMENTED
+// RUN: %clang -E -dM %s -o - 2>&1 \
+// RUN:     -target wasm64-unknown-unknown -munimplemented-simd128 \
+// RUN:   | FileCheck %s -check-prefix=SIMD128-UNIMPLEMENTED
+//
+// SIMD128-UNIMPLEMENTED:#define __wasm_unimplemented_simd128__ 1{{$}}
+//
+// RUN: %clang -E -dM %s -o - 2>&1 \
 // RUN:     -target wasm32-unknown-unknown -mcpu=mvp \
 // RUN:   | FileCheck %s -check-prefix=MVP
 // RUN: %clang -E -dM %s -o - 2>&1 \
-- 
cgit v1.2.3


From 57cccd459fadccac6766bf8f1ecbe0f6a3184059 Mon Sep 17 00:00:00 2001
From: Aaron Ballman 
Date: Fri, 11 Jan 2019 00:13:57 +0000
Subject: Add an explicit initializer to silence a -Wmissing-field-initializers
 diagnostic; NFC.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350912 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/Lex/PPExpressions.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/Lex/PPExpressions.cpp b/lib/Lex/PPExpressions.cpp
index a60b7c97fc..d40cd5cba7 100644
--- a/lib/Lex/PPExpressions.cpp
+++ b/lib/Lex/PPExpressions.cpp
@@ -849,7 +849,7 @@ Preprocessor::EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro) {
 
     // Restore 'DisableMacroExpansion'.
     DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
-    return {false, DT.IncludedUndefinedIds};
+    return {false, DT.IncludedUndefinedIds, {}};
   }
 
   // If we are at the end of the expression after just parsing a value, there
-- 
cgit v1.2.3


From f9802cffcd89aa6245a0bb3f6d21929b23d5b96f Mon Sep 17 00:00:00 2001
From: Richard Trieu 
Date: Fri, 11 Jan 2019 01:32:35 +0000
Subject: Fix header issues.

Several headers would fail to compile if other headers were not previously
included.  The usual issue is that a class is forward declared, but the
full definition is needed.  The requirement for the definition is use of
isa/dyn_cast or calling functions of pointer-packed data types such as
DenseMap or PointerIntPair.  Add missing includes to these headers.

SVals.h required an out-of-line method definition in the .cpp file to avoid
circular inclusion of headers with BasicValueFactory.h


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350913 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/AST/ASTStructuralEquivalence.h                | 1 +
 include/clang/AST/BaseSubobject.h                           | 1 +
 include/clang/AST/Mangle.h                                  | 1 +
 include/clang/AST/TemplateName.h                            | 1 +
 include/clang/Analysis/ConstructionContext.h                | 1 +
 include/clang/Lex/PreprocessingRecord.h                     | 1 +
 include/clang/Sema/Scope.h                                  | 1 +
 include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h | 1 +
 include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h     | 4 +---
 lib/CodeGen/CGOpenCLRuntime.h                               | 1 +
 lib/CodeGen/CGOpenMPRuntime.h                               | 1 +
 lib/CodeGen/VarBypassDetector.h                             | 1 +
 lib/StaticAnalyzer/Core/SVals.cpp                           | 4 ++++
 13 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/include/clang/AST/ASTStructuralEquivalence.h b/include/clang/AST/ASTStructuralEquivalence.h
index 2037796cd5..f8847505bc 100644
--- a/include/clang/AST/ASTStructuralEquivalence.h
+++ b/include/clang/AST/ASTStructuralEquivalence.h
@@ -15,6 +15,7 @@
 #ifndef LLVM_CLANG_AST_ASTSTRUCTURALEQUIVALENCE_H
 #define LLVM_CLANG_AST_ASTSTRUCTURALEQUIVALENCE_H
 
+#include "clang/AST/DeclBase.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/DenseSet.h"
 #include "llvm/ADT/Optional.h"
diff --git a/include/clang/AST/BaseSubobject.h b/include/clang/AST/BaseSubobject.h
index 2b702c76b2..8fd4ac69eb 100644
--- a/include/clang/AST/BaseSubobject.h
+++ b/include/clang/AST/BaseSubobject.h
@@ -15,6 +15,7 @@
 #define LLVM_CLANG_AST_BASESUBOBJECT_H
 
 #include "clang/AST/CharUnits.h"
+#include "clang/AST/DeclCXX.h"
 #include "llvm/ADT/DenseMapInfo.h"
 #include "llvm/Support/type_traits.h"
 #include 
diff --git a/include/clang/AST/Mangle.h b/include/clang/AST/Mangle.h
index c42fe91b32..309ed5a1a5 100644
--- a/include/clang/AST/Mangle.h
+++ b/include/clang/AST/Mangle.h
@@ -14,6 +14,7 @@
 #ifndef LLVM_CLANG_AST_MANGLE_H
 #define LLVM_CLANG_AST_MANGLE_H
 
+#include "clang/AST/Decl.h"
 #include "clang/AST/Type.h"
 #include "clang/Basic/ABI.h"
 #include "llvm/ADT/DenseMap.h"
diff --git a/include/clang/AST/TemplateName.h b/include/clang/AST/TemplateName.h
index d88d58d0a2..48272597d4 100644
--- a/include/clang/AST/TemplateName.h
+++ b/include/clang/AST/TemplateName.h
@@ -14,6 +14,7 @@
 #ifndef LLVM_CLANG_AST_TEMPLATENAME_H
 #define LLVM_CLANG_AST_TEMPLATENAME_H
 
+#include "clang/AST/NestedNameSpecifier.h"
 #include "clang/Basic/LLVM.h"
 #include "llvm/ADT/FoldingSet.h"
 #include "llvm/ADT/PointerIntPair.h"
diff --git a/include/clang/Analysis/ConstructionContext.h b/include/clang/Analysis/ConstructionContext.h
index 9c62bac209..27c1d5b9f1 100644
--- a/include/clang/Analysis/ConstructionContext.h
+++ b/include/clang/Analysis/ConstructionContext.h
@@ -19,6 +19,7 @@
 
 #include "clang/Analysis/Support/BumpVector.h"
 #include "clang/AST/ExprCXX.h"
+#include "clang/AST/ExprObjC.h"
 
 namespace clang {
 
diff --git a/include/clang/Lex/PreprocessingRecord.h b/include/clang/Lex/PreprocessingRecord.h
index 44d79d9b62..027dd3ac5d 100644
--- a/include/clang/Lex/PreprocessingRecord.h
+++ b/include/clang/Lex/PreprocessingRecord.h
@@ -15,6 +15,7 @@
 #ifndef LLVM_CLANG_LEX_PREPROCESSINGRECORD_H
 #define LLVM_CLANG_LEX_PREPROCESSINGRECORD_H
 
+#include "clang/Basic/IdentifierTable.h"
 #include "clang/Basic/LLVM.h"
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Lex/PPCallbacks.h"
diff --git a/include/clang/Sema/Scope.h b/include/clang/Sema/Scope.h
index 11fa036212..9d9ab0514f 100644
--- a/include/clang/Sema/Scope.h
+++ b/include/clang/Sema/Scope.h
@@ -14,6 +14,7 @@
 #ifndef LLVM_CLANG_SEMA_SCOPE_H
 #define LLVM_CLANG_SEMA_SCOPE_H
 
+#include "clang/AST/Decl.h"
 #include "clang/Basic/Diagnostic.h"
 #include "llvm/ADT/PointerIntPair.h"
 #include "llvm/ADT/SmallPtrSet.h"
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
index bf01289a40..3d0ff4efa1 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
@@ -24,6 +24,7 @@
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprObjC.h"
 #include "clang/AST/Type.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
 #include "clang/Basic/LLVM.h"
 #include "clang/Basic/SourceLocation.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
index 1b79bfc3f8..0efe96f67f 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
@@ -530,9 +530,7 @@ public:
     return PTMDataType::getFromOpaqueValue(const_cast(Data));
   }
 
-  bool isNullMemberPointer() const {
-    return getPTMData().isNull();
-  }
+  bool isNullMemberPointer() const;
 
   const DeclaratorDecl *getDecl() const;
 
diff --git a/lib/CodeGen/CGOpenCLRuntime.h b/lib/CodeGen/CGOpenCLRuntime.h
index 3da55af065..750721f1b8 100644
--- a/lib/CodeGen/CGOpenCLRuntime.h
+++ b/lib/CodeGen/CGOpenCLRuntime.h
@@ -16,6 +16,7 @@
 #ifndef LLVM_CLANG_LIB_CODEGEN_CGOPENCLRUNTIME_H
 #define LLVM_CLANG_LIB_CODEGEN_CGOPENCLRUNTIME_H
 
+#include "clang/AST/Expr.h"
 #include "clang/AST/Type.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/IR/Type.h"
diff --git a/lib/CodeGen/CGOpenMPRuntime.h b/lib/CodeGen/CGOpenMPRuntime.h
index 933c8af116..1822a6fd19 100644
--- a/lib/CodeGen/CGOpenMPRuntime.h
+++ b/lib/CodeGen/CGOpenMPRuntime.h
@@ -15,6 +15,7 @@
 #define LLVM_CLANG_LIB_CODEGEN_CGOPENMPRUNTIME_H
 
 #include "CGValue.h"
+#include "clang/AST/DeclOpenMP.h"
 #include "clang/AST/Type.h"
 #include "clang/Basic/OpenMPKinds.h"
 #include "clang/Basic/SourceLocation.h"
diff --git a/lib/CodeGen/VarBypassDetector.h b/lib/CodeGen/VarBypassDetector.h
index f50baf4bab..47fe13cfac 100644
--- a/lib/CodeGen/VarBypassDetector.h
+++ b/lib/CodeGen/VarBypassDetector.h
@@ -15,6 +15,7 @@
 #ifndef LLVM_CLANG_LIB_CODEGEN_VARBYPASSDETECTOR_H
 #define LLVM_CLANG_LIB_CODEGEN_VARBYPASSDETECTOR_H
 
+#include "clang/AST/Decl.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/DenseSet.h"
 #include "llvm/ADT/SmallVector.h"
diff --git a/lib/StaticAnalyzer/Core/SVals.cpp b/lib/StaticAnalyzer/Core/SVals.cpp
index b32be9e82d..933c5c3300 100644
--- a/lib/StaticAnalyzer/Core/SVals.cpp
+++ b/lib/StaticAnalyzer/Core/SVals.cpp
@@ -171,6 +171,10 @@ const TypedValueRegion *nonloc::LazyCompoundVal::getRegion() const {
   return static_cast(Data)->getRegion();
 }
 
+bool nonloc::PointerToMember::isNullMemberPointer() const {
+  return getPTMData().isNull();
+}
+
 const DeclaratorDecl *nonloc::PointerToMember::getDecl() const {
   const auto PTMD = this->getPTMData();
   if (PTMD.isNull())
-- 
cgit v1.2.3


From 205745cdf756f8d32a29fb8541f227139672ee8f Mon Sep 17 00:00:00 2001
From: Brian Gesiak 
Date: Fri, 11 Jan 2019 01:54:53 +0000
Subject: [AST] Remove ASTContext from getThisType (NFC)

Summary:
https://reviews.llvm.org/D54862 removed the usages of `ASTContext&` from
within the `CXXMethodDecl::getThisType` method. Remove the parameter
altogether, as well as all usages of it. This does not result in any
functional change because the parameter was unused since
https://reviews.llvm.org/D54862.

Test Plan: check-clang

Reviewers: akyrtzi, mikael

Reviewed By: mikael

Subscribers: mehdi_amini, dexonsmith, cfe-commits

Differential Revision: https://reviews.llvm.org/D56509

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350914 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/AST/DeclCXX.h              |  2 +-
 lib/AST/DeclCXX.cpp                      |  2 +-
 lib/AST/ExprConstant.cpp                 |  2 +-
 lib/Analysis/Consumed.cpp                | 16 ++++++----------
 lib/CodeGen/CGBlocks.cpp                 |  2 +-
 lib/CodeGen/CGCXXABI.cpp                 |  2 +-
 lib/CodeGen/CGClass.cpp                  |  8 ++++----
 lib/CodeGen/CGDebugInfo.cpp              |  5 ++---
 lib/CodeGen/CGVTables.cpp                |  4 ++--
 lib/CodeGen/CodeGenFunction.cpp          |  4 ++--
 lib/CodeGen/MicrosoftCXXABI.cpp          |  2 +-
 lib/Sema/SemaCoroutine.cpp               |  5 ++---
 lib/Sema/SemaDeclAttr.cpp                |  5 ++---
 lib/Sema/SemaExpr.cpp                    |  2 +-
 lib/Sema/SemaExprCXX.cpp                 |  4 ++--
 lib/Sema/SemaOverload.cpp                |  8 ++++----
 lib/Sema/SemaTemplate.cpp                |  2 +-
 lib/StaticAnalyzer/Core/LoopWidening.cpp |  5 ++---
 lib/StaticAnalyzer/Core/MemRegion.cpp    |  5 ++---
 lib/StaticAnalyzer/Core/SValBuilder.cpp  |  4 ++--
 20 files changed, 40 insertions(+), 49 deletions(-)

diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index 8452806701..d3357c245d 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -2180,7 +2180,7 @@ public:
   /// that for the call operator of a lambda closure type, this returns the
   /// desugared 'this' type (a pointer to the closure type), not the captured
   /// 'this' type.
-  QualType getThisType(ASTContext &C) const;
+  QualType getThisType() const;
 
   static QualType getThisType(const FunctionProtoType *FPT,
                               const CXXRecordDecl *Decl);
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index 2893fca859..31ffeb0dcd 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -2181,7 +2181,7 @@ QualType CXXMethodDecl::getThisType(const FunctionProtoType *FPT,
   return C.getPointerType(ClassTy);
 }
 
-QualType CXXMethodDecl::getThisType(ASTContext &C) const {
+QualType CXXMethodDecl::getThisType() const {
   // C++ 9.3.2p1: The type of this in a member function of a class X is X*.
   // If the member function is declared const, the type of this is const X*,
   // if the member function is declared volatile, the type of this is
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index 2022b07bff..da093ff22c 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -4462,7 +4462,7 @@ static bool HandleFunctionCall(SourceLocation CallLoc,
     if (!handleLValueToRValueConversion(Info, Args[0], Args[0]->getType(),
                                         RHS, RHSValue))
       return false;
-    if (!handleAssignment(Info, Args[0], *This, MD->getThisType(Info.Ctx),
+    if (!handleAssignment(Info, Args[0], *This, MD->getThisType(),
                           RHSValue))
       return false;
     This->moveInto(Result);
diff --git a/lib/Analysis/Consumed.cpp b/lib/Analysis/Consumed.cpp
index 12c8a2c1b3..16eeaba2f6 100644
--- a/lib/Analysis/Consumed.cpp
+++ b/lib/Analysis/Consumed.cpp
@@ -463,7 +463,6 @@ class ConsumedStmtVisitor : public ConstStmtVisitor {
   using InfoEntry = MapType::iterator;
   using ConstInfoEntry = MapType::const_iterator;
 
-  AnalysisDeclContext &AC;
   ConsumedAnalyzer &Analyzer;
   ConsumedStateMap *StateMap;
   MapType PropagationMap;
@@ -515,9 +514,8 @@ public:
   void VisitUnaryOperator(const UnaryOperator *UOp);
   void VisitVarDecl(const VarDecl *Var);
 
-  ConsumedStmtVisitor(AnalysisDeclContext &AC, ConsumedAnalyzer &Analyzer,
-                      ConsumedStateMap *StateMap)
-      : AC(AC), Analyzer(Analyzer), StateMap(StateMap) {}
+  ConsumedStmtVisitor(ConsumedAnalyzer &Analyzer, ConsumedStateMap *StateMap)
+      : Analyzer(Analyzer), StateMap(StateMap) {}
 
   PropagationInfo getInfo(const Expr *StmtNode) const {
     ConstInfoEntry Entry = findInfo(StmtNode);
@@ -774,8 +772,7 @@ void ConsumedStmtVisitor::VisitCXXBindTemporaryExpr(
 void ConsumedStmtVisitor::VisitCXXConstructExpr(const CXXConstructExpr *Call) {
   CXXConstructorDecl *Constructor = Call->getConstructor();
 
-  ASTContext &CurrContext = AC.getASTContext();
-  QualType ThisType = Constructor->getThisType(CurrContext)->getPointeeType();
+  QualType ThisType = Constructor->getThisType()->getPointeeType();
 
   if (!isConsumableType(ThisType))
     return;
@@ -793,7 +790,7 @@ void ConsumedStmtVisitor::VisitCXXConstructExpr(const CXXConstructExpr *Call) {
   } else if (Constructor->isCopyConstructor()) {
     // Copy state from arg.  If setStateOnRead then set arg to CS_Unknown.
     ConsumedState NS =
-      isSetOnReadPtrType(Constructor->getThisType(CurrContext)) ?
+      isSetOnReadPtrType(Constructor->getThisType()) ?
       CS_Unknown : CS_None;
     copyInfo(Call->getArg(0), Call, NS);
   } else {
@@ -1203,8 +1200,7 @@ void ConsumedAnalyzer::determineExpectedReturnState(AnalysisDeclContext &AC,
                                                     const FunctionDecl *D) {
   QualType ReturnType;
   if (const auto *Constructor = dyn_cast(D)) {
-    ASTContext &CurrContext = AC.getASTContext();
-    ReturnType = Constructor->getThisType(CurrContext)->getPointeeType();
+    ReturnType = Constructor->getThisType()->getPointeeType();
   } else
     ReturnType = D->getCallResultType();
 
@@ -1323,7 +1319,7 @@ void ConsumedAnalyzer::run(AnalysisDeclContext &AC) {
   BlockInfo = ConsumedBlockInfo(CFGraph->getNumBlockIDs(), SortedGraph);
 
   CurrStates = llvm::make_unique();
-  ConsumedStmtVisitor Visitor(AC, *this, CurrStates.get());
+  ConsumedStmtVisitor Visitor(*this, CurrStates.get());
 
   // Add all trackable parameters to the state map.
   for (const auto *PI : D->parameters())
diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp
index 239a805913..fa3c3ee861 100644
--- a/lib/CodeGen/CGBlocks.cpp
+++ b/lib/CodeGen/CGBlocks.cpp
@@ -551,7 +551,7 @@ static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF,
   if (block->capturesCXXThis()) {
     assert(CGF && CGF->CurFuncDecl && isa(CGF->CurFuncDecl) &&
            "Can't capture 'this' outside a method");
-    QualType thisType = cast(CGF->CurFuncDecl)->getThisType(C);
+    QualType thisType = cast(CGF->CurFuncDecl)->getThisType();
 
     // Theoretically, this could be in a different address space, so
     // don't assume standard pointer size/align.
diff --git a/lib/CodeGen/CGCXXABI.cpp b/lib/CodeGen/CGCXXABI.cpp
index 3b1b47cdfe..ed168b1ce7 100644
--- a/lib/CodeGen/CGCXXABI.cpp
+++ b/lib/CodeGen/CGCXXABI.cpp
@@ -132,7 +132,7 @@ void CGCXXABI::buildThisParam(CodeGenFunction &CGF, FunctionArgList ¶ms) {
   // generation. Maybe we can come up with a better way?
   auto *ThisDecl = ImplicitParamDecl::Create(
       CGM.getContext(), nullptr, MD->getLocation(),
-      &CGM.getContext().Idents.get("this"), MD->getThisType(CGM.getContext()),
+      &CGM.getContext().Idents.get("this"), MD->getThisType(),
       ImplicitParamDecl::CXXThis);
   params.push_back(ThisDecl);
   CGF.CXXABIThisDecl = ThisDecl;
diff --git a/lib/CodeGen/CGClass.cpp b/lib/CodeGen/CGClass.cpp
index f91f6ede49..ee150a792b 100644
--- a/lib/CodeGen/CGClass.cpp
+++ b/lib/CodeGen/CGClass.cpp
@@ -2014,7 +2014,7 @@ void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D,
   CallArgList Args;
 
   LangAS SlotAS = E->getType().getAddressSpace();
-  QualType ThisType = D->getThisType(getContext());
+  QualType ThisType = D->getThisType();
   LangAS ThisAS = ThisType.getTypePtr()->getPointeeType().getAddressSpace();
   llvm::Value *ThisPtr = This.getPointer();
   if (SlotAS != ThisAS) {
@@ -2025,7 +2025,7 @@ void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D,
                                                     ThisAS, SlotAS, NewType);
   }
   // Push the this ptr.
-  Args.add(RValue::get(ThisPtr), D->getThisType(getContext()));
+  Args.add(RValue::get(ThisPtr), D->getThisType());
 
   // If this is a trivial constructor, emit a memcpy now before we lose
   // the alignment information on the argument.
@@ -2159,7 +2159,7 @@ void CodeGenFunction::EmitInheritedCXXConstructorCall(
     const CXXConstructorDecl *D, bool ForVirtualBase, Address This,
     bool InheritedFromVBase, const CXXInheritedCtorInitExpr *E) {
   CallArgList Args;
-  CallArg ThisArg(RValue::get(This.getPointer()), D->getThisType(getContext()));
+  CallArg ThisArg(RValue::get(This.getPointer()), D->getThisType());
 
   // Forward the parameters.
   if (InheritedFromVBase &&
@@ -2284,7 +2284,7 @@ CodeGenFunction::EmitSynthesizedCXXCopyCtorCall(const CXXConstructorDecl *D,
   CallArgList Args;
 
   // Push the this ptr.
-  Args.add(RValue::get(This.getPointer()), D->getThisType(getContext()));
+  Args.add(RValue::get(This.getPointer()), D->getThisType());
 
   // Push the src ptr.
   QualType QT = *(FPT->param_type_begin());
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp
index 7ebbfbe2ff..41f8721468 100644
--- a/lib/CodeGen/CGDebugInfo.cpp
+++ b/lib/CodeGen/CGDebugInfo.cpp
@@ -1428,8 +1428,7 @@ CGDebugInfo::getOrCreateMethodType(const CXXMethodDecl *Method,
   if (Method->isStatic())
     return cast_or_null(
         getOrCreateType(QualType(Func, 0), Unit));
-  return getOrCreateInstanceMethodType(Method->getThisType(CGM.getContext()),
-                                       Func, Unit);
+  return getOrCreateInstanceMethodType(Method->getThisType(), Func, Unit);
 }
 
 llvm::DISubroutineType *CGDebugInfo::getOrCreateInstanceMethodType(
@@ -4064,7 +4063,7 @@ void CGDebugInfo::EmitDeclareOfBlockLiteralArgVariable(const CGBlockInfo &block,
       QualType type;
       if (auto *Method =
               cast_or_null(blockDecl->getNonClosureContext()))
-        type = Method->getThisType(C);
+        type = Method->getThisType();
       else if (auto *RDecl = dyn_cast(blockDecl->getParent()))
         type = QualType(RDecl->getTypeForDecl(), 0);
       else
diff --git a/lib/CodeGen/CGVTables.cpp b/lib/CodeGen/CGVTables.cpp
index 09535900b5..bfb089ff90 100644
--- a/lib/CodeGen/CGVTables.cpp
+++ b/lib/CodeGen/CGVTables.cpp
@@ -231,7 +231,7 @@ void CodeGenFunction::StartThunk(llvm::Function *Fn, GlobalDecl GD,
 
   // Build FunctionArgs.
   const CXXMethodDecl *MD = cast(GD.getDecl());
-  QualType ThisType = MD->getThisType(getContext());
+  QualType ThisType = MD->getThisType();
   const FunctionProtoType *FPT = MD->getType()->getAs();
   QualType ResultType;
   if (IsUnprototyped)
@@ -310,7 +310,7 @@ void CodeGenFunction::EmitCallAndReturnForThunk(llvm::Constant *CalleePtr,
 
   // Start building CallArgs.
   CallArgList CallArgs;
-  QualType ThisType = MD->getThisType(getContext());
+  QualType ThisType = MD->getThisType();
   CallArgs.add(RValue::get(AdjustedThisPtr), ThisType);
 
   if (isa(MD))
diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp
index 123ece2cac..2b25fb469d 100644
--- a/lib/CodeGen/CodeGenFunction.cpp
+++ b/lib/CodeGen/CodeGenFunction.cpp
@@ -1156,7 +1156,7 @@ void CodeGenFunction::StartFunction(GlobalDecl GD,
     if (CXXABIThisValue) {
       SanitizerSet SkippedChecks;
       SkippedChecks.set(SanitizerKind::ObjectSize, true);
-      QualType ThisTy = MD->getThisType(getContext());
+      QualType ThisTy = MD->getThisType();
 
       // If this is the call operator of a lambda with no capture-default, it
       // may have a static invoker function, which may call this operator with
@@ -1256,7 +1256,7 @@ QualType CodeGenFunction::BuildFunctionArgList(GlobalDecl GD,
   const CXXMethodDecl *MD = dyn_cast(FD);
   if (MD && MD->isInstance()) {
     if (CGM.getCXXABI().HasThisReturn(GD))
-      ResTy = MD->getThisType(getContext());
+      ResTy = MD->getThisType();
     else if (CGM.getCXXABI().hasMostDerivedReturn(GD))
       ResTy = CGM.getContext().VoidPtrTy;
     CGM.getCXXABI().buildThisParam(*this, Args);
diff --git a/lib/CodeGen/MicrosoftCXXABI.cpp b/lib/CodeGen/MicrosoftCXXABI.cpp
index 0ad19ad5ab..5545bc6647 100644
--- a/lib/CodeGen/MicrosoftCXXABI.cpp
+++ b/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -3929,7 +3929,7 @@ MicrosoftCXXABI::getAddrOfCXXCtorClosure(const CXXConstructorDecl *CD,
   CallArgList Args;
 
   // Push the this ptr.
-  Args.add(RValue::get(This), CD->getThisType(getContext()));
+  Args.add(RValue::get(This), CD->getThisType());
 
   // Push the src ptr.
   if (SrcVal)
diff --git a/lib/Sema/SemaCoroutine.cpp b/lib/Sema/SemaCoroutine.cpp
index a84116c1bc..181efa6d3d 100644
--- a/lib/Sema/SemaCoroutine.cpp
+++ b/lib/Sema/SemaCoroutine.cpp
@@ -84,8 +84,7 @@ static QualType lookupPromiseType(Sema &S, const FunctionDecl *FD,
       //      ref-qualifier or with the & ref-qualifier
       //  -- "rvalue reference to cv X" for functions declared with the &&
       //      ref-qualifier
-      QualType T =
-          MD->getThisType(S.Context)->getAs()->getPointeeType();
+      QualType T = MD->getThisType()->getAs()->getPointeeType();
       T = FnType->getRefQualifier() == RQ_RValue
               ? S.Context.getRValueReferenceType(T)
               : S.Context.getLValueReferenceType(T, /*SpelledAsLValue*/ true);
@@ -506,7 +505,7 @@ VarDecl *Sema::buildCoroutinePromise(SourceLocation Loc) {
   auto *FD = cast(CurContext);
   bool IsThisDependentType = [&] {
     if (auto *MD = dyn_cast_or_null(FD))
-      return MD->isInstance() && MD->getThisType(Context)->isDependentType();
+      return MD->isInstance() && MD->getThisType()->isDependentType();
     else
       return false;
   }();
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index b5859d1fb7..241eea4927 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -1151,8 +1151,7 @@ static void handleConsumableAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
 
 static bool checkForConsumableClass(Sema &S, const CXXMethodDecl *MD,
                                     const ParsedAttr &AL) {
-  ASTContext &CurrContext = S.getASTContext();
-  QualType ThisType = MD->getThisType(CurrContext)->getPointeeType();
+  QualType ThisType = MD->getThisType()->getPointeeType();
 
   if (const CXXRecordDecl *RD = ThisType->getAsCXXRecordDecl()) {
     if (!RD->hasAttr()) {
@@ -1265,7 +1264,7 @@ static void handleReturnTypestateAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
   //
   //} else if (const CXXConstructorDecl *Constructor =
   //             dyn_cast(D)) {
-  //  ReturnType = Constructor->getThisType(S.getASTContext())->getPointeeType();
+  //  ReturnType = Constructor->getThisType()->getPointeeType();
   //
   //} else {
   //
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index f65e97ed0b..31d7407b0a 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -2585,7 +2585,7 @@ Sema::PerformObjectMemberConversion(Expr *From,
     if (Method->isStatic())
       return From;
 
-    DestType = Method->getThisType(Context);
+    DestType = Method->getThisType();
     DestRecordType = DestType->getPointeeType();
 
     if (FromType->getAs()) {
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index 04f77a8e39..56af640aa4 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -1064,7 +1064,7 @@ QualType Sema::getCurrentThisType() {
 
   if (CXXMethodDecl *method = dyn_cast(DC)) {
     if (method && method->isInstance())
-      ThisTy = method->getThisType(Context);
+      ThisTy = method->getThisType();
   }
 
   if (ThisTy.isNull() && isLambdaCallOperator(CurContext) &&
@@ -3588,7 +3588,7 @@ void Sema::CheckVirtualDtorCall(CXXDestructorDecl *dtor, SourceLocation Loc,
   if (getSourceManager().isInSystemHeader(PointeeRD->getLocation()))
     return;
 
-  QualType ClassType = dtor->getThisType(Context)->getPointeeType();
+  QualType ClassType = dtor->getThisType()->getPointeeType();
   if (PointeeRD->isAbstract()) {
     // If the class is abstract, we warn by default, because we're
     // sure the code has undefined behavior.
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 172116e30c..d54e905061 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -3277,7 +3277,7 @@ IsInitializerListConstructorConversion(Sema &S, Expr *From, QualType ToType,
   case OR_Success: {
     // Record the standard conversion we used and the conversion function.
     CXXConstructorDecl *Constructor = cast(Best->Function);
-    QualType ThisType = Constructor->getThisType(S.Context);
+    QualType ThisType = Constructor->getThisType();
     // Initializer lists don't have conversions as such.
     User.Before.setAsIdentityConversion();
     User.HadMultipleCandidates = HadMultipleCandidates;
@@ -3458,7 +3458,7 @@ IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType,
       //   sequence converts the source type to the type required by
       //   the argument of the constructor.
       //
-      QualType ThisType = Constructor->getThisType(S.Context);
+      QualType ThisType = Constructor->getThisType();
       if (isa(From)) {
         // Initializer lists don't have conversions as such.
         User.Before.setAsIdentityConversion();
@@ -5212,12 +5212,12 @@ Sema::PerformObjectArgumentInitialization(Expr *From,
                                           CXXMethodDecl *Method) {
   QualType FromRecordType, DestType;
   QualType ImplicitParamRecordType  =
-    Method->getThisType(Context)->getAs()->getPointeeType();
+    Method->getThisType()->getAs()->getPointeeType();
 
   Expr::Classification FromClassification;
   if (const PointerType *PT = From->getType()->getAs()) {
     FromRecordType = PT->getPointeeType();
-    DestType = Method->getThisType(Context);
+    DestType = Method->getThisType();
     FromClassification = Expr::Classification::makeSimpleLValue();
   } else {
     FromRecordType = From->getType();
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index 35935f994c..3f9dc98910 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -627,7 +627,7 @@ Sema::ActOnDependentIdExpression(const CXXScopeSpec &SS,
 
   if (!MightBeCxx11UnevalField && !isAddressOfOperand && !IsEnum &&
       isa(DC) && cast(DC)->isInstance()) {
-    QualType ThisType = cast(DC)->getThisType(Context);
+    QualType ThisType = cast(DC)->getThisType();
 
     // Since the 'this' expression is synthesized, we don't need to
     // perform the double-lookup check.
diff --git a/lib/StaticAnalyzer/Core/LoopWidening.cpp b/lib/StaticAnalyzer/Core/LoopWidening.cpp
index d7fed2558c..8f6cb9a6b0 100644
--- a/lib/StaticAnalyzer/Core/LoopWidening.cpp
+++ b/lib/StaticAnalyzer/Core/LoopWidening.cpp
@@ -85,9 +85,8 @@ ProgramStateRef getWidenedLoopState(ProgramStateRef PrevState,
   // have 'this' pointers.
   const CXXMethodDecl *CXXMD = dyn_cast(STC->getDecl());
   if (CXXMD && !CXXMD->isStatic()) {
-    const CXXThisRegion *ThisR = MRMgr.getCXXThisRegion(
-        CXXMD->getThisType(STC->getAnalysisDeclContext()->getASTContext()),
-        STC);
+    const CXXThisRegion *ThisR =
+        MRMgr.getCXXThisRegion(CXXMD->getThisType(), STC);
     ITraits.setTrait(ThisR,
                      RegionAndSymbolInvalidationTraits::TK_PreserveContents);
   }
diff --git a/lib/StaticAnalyzer/Core/MemRegion.cpp b/lib/StaticAnalyzer/Core/MemRegion.cpp
index da368de322..9a1d4d73c2 100644
--- a/lib/StaticAnalyzer/Core/MemRegion.cpp
+++ b/lib/StaticAnalyzer/Core/MemRegion.cpp
@@ -1105,9 +1105,8 @@ MemRegionManager::getCXXThisRegion(QualType thisPointerTy,
   // FIXME: when operator() of lambda is analyzed as a top level function and
   // 'this' refers to a this to the enclosing scope, there is no right region to
   // return.
-  while (!LC->inTopFrame() &&
-         (!D || D->isStatic() ||
-          PT != D->getThisType(getContext())->getAs())) {
+  while (!LC->inTopFrame() && (!D || D->isStatic() ||
+                               PT != D->getThisType()->getAs())) {
     LC = LC->getParent();
     D = dyn_cast(LC->getDecl());
   }
diff --git a/lib/StaticAnalyzer/Core/SValBuilder.cpp b/lib/StaticAnalyzer/Core/SValBuilder.cpp
index aeb27fefed..6c0d487c8a 100644
--- a/lib/StaticAnalyzer/Core/SValBuilder.cpp
+++ b/lib/StaticAnalyzer/Core/SValBuilder.cpp
@@ -271,8 +271,8 @@ DefinedSVal SValBuilder::getBlockPointer(const BlockDecl *block,
 /// Return a memory region for the 'this' object reference.
 loc::MemRegionVal SValBuilder::getCXXThis(const CXXMethodDecl *D,
                                           const StackFrameContext *SFC) {
-  return loc::MemRegionVal(getRegionManager().
-                           getCXXThisRegion(D->getThisType(getContext()), SFC));
+  return loc::MemRegionVal(
+      getRegionManager().getCXXThisRegion(D->getThisType(), SFC));
 }
 
 /// Return a memory region for the 'this' object reference.
-- 
cgit v1.2.3


From ad7a7a80dbde79b35df9ba54809d33d427481dee Mon Sep 17 00:00:00 2001
From: Richard Smith 
Date: Fri, 11 Jan 2019 01:59:33 +0000
Subject: Remember to instantiate explicit template argument lists in a friend
 function declaration.

We'd previously often just drop these on the floor, and friend
redeclaration matching would usually (but not always) figure out the
right redeclaration anyway.

Also, don't try to match a dependent friend function template
specialization to a template until instantiation, and don't forget to
reject qualified friend declarations in dependent contexts that don't
name an already-declared entity.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350915 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/AST/TemplateBase.h         |  6 ++-
 lib/Sema/SemaDecl.cpp                    | 10 ++--
 lib/Sema/SemaOverload.cpp                |  1 +
 lib/Sema/SemaTemplateInstantiateDecl.cpp | 84 +++++++++++++++++++++++++++-----
 test/SemaTemplate/friend.cpp             | 75 ++++++++++++++++++++++++++++
 5 files changed, 161 insertions(+), 15 deletions(-)

diff --git a/include/clang/AST/TemplateBase.h b/include/clang/AST/TemplateBase.h
index 01bdc0df1a..e3a773b4e4 100644
--- a/include/clang/AST/TemplateBase.h
+++ b/include/clang/AST/TemplateBase.h
@@ -620,13 +620,17 @@ public:
   /// The number of template arguments in TemplateArgs.
   unsigned NumTemplateArgs;
 
+  SourceLocation getLAngleLoc() const { return LAngleLoc; }
+  SourceLocation getRAngleLoc() const { return RAngleLoc; }
+
   /// Retrieve the template arguments
   const TemplateArgumentLoc *getTemplateArgs() const {
     return getTrailingObjects();
   }
+  unsigned getNumTemplateArgs() const { return NumTemplateArgs; }
 
   llvm::ArrayRef arguments() const {
-    return llvm::makeArrayRef(getTemplateArgs(), NumTemplateArgs);
+    return llvm::makeArrayRef(getTemplateArgs(), getNumTemplateArgs());
   }
 
   const TemplateArgumentLoc &operator[](unsigned I) const {
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 2b88955285..f77aeb64b3 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -9030,10 +9030,14 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
         // selecting a friend based on a dependent factor.  But there
         // are situations where these conditions don't apply and we
         // can actually do this check immediately.
+        //
+        // Unless the scope is dependent, it's always an error if qualified
+        // redeclaration lookup found nothing at all. Diagnose that now;
+        // nothing will diagnose that error later.
         if (isFriend &&
-            (TemplateParamLists.size() ||
-             D.getCXXScopeSpec().getScopeRep()->isDependent() ||
-             CurContext->isDependentContext())) {
+            (D.getCXXScopeSpec().getScopeRep()->isDependent() ||
+             (!Previous.empty() && (TemplateParamLists.size() ||
+                                    CurContext->isDependentContext())))) {
           // ignore these
         } else {
           // The user tried to provide an out-of-line definition for a
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index d54e905061..52be0598fb 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -1057,6 +1057,7 @@ Sema::CheckOverload(Scope *S, FunctionDecl *New, const LookupResult &Old,
   // third bullet. If the type of the friend is dependent, skip this lookup
   // until instantiation.
   if (New->getFriendObjectKind() && New->getQualifier() &&
+      !New->getDependentSpecializationInfo() &&
       !New->getType()->isDependentType()) {
     LookupResult TemplateSpecResult(LookupResult::Temporary, Old);
     TemplateSpecResult.addAllDecls(Old);
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 31353e45ba..fad3c065e8 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -1747,10 +1747,13 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
     Function->setInstantiationOfMemberFunction(D, TSK_ImplicitInstantiation);
   }
 
+  if (isFriend)
+    Function->setObjectOfFriendDecl();
+
   if (InitFunctionInstantiation(Function, D))
     Function->setInvalidDecl();
 
-  bool isExplicitSpecialization = false;
+  bool IsExplicitSpecialization = false;
 
   LookupResult Previous(
       SemaRef, Function->getDeclName(), SourceLocation(),
@@ -1763,9 +1766,6 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
         = D->getDependentSpecializationInfo()) {
     assert(isFriend && "non-friend has dependent specialization info?");
 
-    // This needs to be set now for future sanity.
-    Function->setObjectOfFriendDecl();
-
     // Instantiate the explicit template arguments.
     TemplateArgumentListInfo ExplicitArgs(Info->getLAngleLoc(),
                                           Info->getRAngleLoc());
@@ -1788,8 +1788,25 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
                                                     Previous))
       Function->setInvalidDecl();
 
-    isExplicitSpecialization = true;
+    IsExplicitSpecialization = true;
+  } else if (const ASTTemplateArgumentListInfo *Info =
+                 D->getTemplateSpecializationArgsAsWritten()) {
+    // The name of this function was written as a template-id.
+    SemaRef.LookupQualifiedName(Previous, DC);
 
+    // Instantiate the explicit template arguments.
+    TemplateArgumentListInfo ExplicitArgs(Info->getLAngleLoc(),
+                                          Info->getRAngleLoc());
+    if (SemaRef.Subst(Info->getTemplateArgs(), Info->getNumTemplateArgs(),
+                      ExplicitArgs, TemplateArgs))
+      return nullptr;
+
+    if (SemaRef.CheckFunctionTemplateSpecialization(Function,
+                                                    &ExplicitArgs,
+                                                    Previous))
+      Function->setInvalidDecl();
+
+    IsExplicitSpecialization = true;
   } else if (TemplateParams || !FunctionTemplate) {
     // Look only into the namespace where the friend would be declared to
     // find a previous declaration. This is the innermost enclosing namespace,
@@ -1804,11 +1821,8 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
       Previous.clear();
   }
 
-  if (isFriend)
-    Function->setObjectOfFriendDecl();
-
   SemaRef.CheckFunctionDeclaration(/*Scope*/ nullptr, Function, Previous,
-                                   isExplicitSpecialization);
+                                   IsExplicitSpecialization);
 
   NamedDecl *PrincipalDecl = (TemplateParams
                               ? cast(FunctionTemplate)
@@ -2055,7 +2069,54 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
   LookupResult Previous(SemaRef, NameInfo, Sema::LookupOrdinaryName,
                         Sema::ForExternalRedeclaration);
 
-  if (!FunctionTemplate || TemplateParams || isFriend) {
+  bool IsExplicitSpecialization = false;
+
+  // If the name of this function was written as a template-id, instantiate
+  // the explicit template arguments.
+  if (DependentFunctionTemplateSpecializationInfo *Info
+        = D->getDependentSpecializationInfo()) {
+    assert(isFriend && "non-friend has dependent specialization info?");
+
+    // Instantiate the explicit template arguments.
+    TemplateArgumentListInfo ExplicitArgs(Info->getLAngleLoc(),
+                                          Info->getRAngleLoc());
+    if (SemaRef.Subst(Info->getTemplateArgs(), Info->getNumTemplateArgs(),
+                      ExplicitArgs, TemplateArgs))
+      return nullptr;
+
+    // Map the candidate templates to their instantiations.
+    for (unsigned I = 0, E = Info->getNumTemplates(); I != E; ++I) {
+      Decl *Temp = SemaRef.FindInstantiatedDecl(D->getLocation(),
+                                                Info->getTemplate(I),
+                                                TemplateArgs);
+      if (!Temp) return nullptr;
+
+      Previous.addDecl(cast(Temp));
+    }
+
+    if (SemaRef.CheckFunctionTemplateSpecialization(Method,
+                                                    &ExplicitArgs,
+                                                    Previous))
+      Method->setInvalidDecl();
+
+    IsExplicitSpecialization = true;
+  } else if (const ASTTemplateArgumentListInfo *Info =
+                 D->getTemplateSpecializationArgsAsWritten()) {
+    SemaRef.LookupQualifiedName(Previous, DC);
+
+    TemplateArgumentListInfo ExplicitArgs(Info->getLAngleLoc(),
+                                          Info->getRAngleLoc());
+    if (SemaRef.Subst(Info->getTemplateArgs(), Info->getNumTemplateArgs(),
+                      ExplicitArgs, TemplateArgs))
+      return nullptr;
+
+    if (SemaRef.CheckFunctionTemplateSpecialization(Method,
+                                                    &ExplicitArgs,
+                                                    Previous))
+      Method->setInvalidDecl();
+
+    IsExplicitSpecialization = true;
+  } else if (!FunctionTemplate || TemplateParams || isFriend) {
     SemaRef.LookupQualifiedName(Previous, Record);
 
     // In C++, the previous declaration we find might be a tag type
@@ -2067,7 +2128,8 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
   }
 
   if (!IsClassScopeSpecialization)
-    SemaRef.CheckFunctionDeclaration(nullptr, Method, Previous, false);
+    SemaRef.CheckFunctionDeclaration(nullptr, Method, Previous,
+                                     IsExplicitSpecialization);
 
   if (D->isPure())
     SemaRef.CheckPureMethod(Method, SourceRange());
diff --git a/test/SemaTemplate/friend.cpp b/test/SemaTemplate/friend.cpp
index ef1aed50e6..777682be3f 100644
--- a/test/SemaTemplate/friend.cpp
+++ b/test/SemaTemplate/friend.cpp
@@ -47,3 +47,78 @@ inline void foo() {}
 inline void bar() {}
 C c;
 }
+
+namespace qualified_friend {
+  void f(int); // expected-note 2{{type mismatch at 1st parameter}}
+  template void f(T*); // expected-note 2{{could not match 'type-parameter-0-0 *' against 'double'}}
+  template void nondep();
+
+  template struct X1 {
+    friend void qualified_friend::f(double); // expected-error {{friend declaration of 'f' does not match any declaration in namespace 'qualified_friend'}}
+    friend void qualified_friend::g(); // expected-error {{friend declaration of 'g' does not match any declaration in namespace 'qualified_friend'}}
+  };
+  template struct X2 {
+    friend void qualified_friend::f(T); // expected-error {{friend declaration of 'f' does not match any declaration in namespace 'qualified_friend'}}
+  };
+  X1 xi;
+  X2 xd; // expected-note {{in instantiation of}}
+  X2 x2i;
+
+  struct Y {
+    void f(int); // expected-note 2{{type mismatch at 1st parameter}}
+    template void f(T*); // expected-note 2{{could not match 'type-parameter-0-0 *' against 'double'}}
+    template void nondep();
+  };
+
+  template struct Z1 {
+    friend void Y::f(double); // expected-error {{friend declaration of 'f' does not match any declaration in 'qualified_friend::Y'}}
+    friend void Y::g(); // expected-error {{friend declaration of 'g' does not match any declaration in 'qualified_friend::Y'}}
+  };
+  template struct Z2 {
+    friend void Y::f(T); // expected-error {{friend declaration of 'f' does not match any declaration in 'qualified_friend::Y'}}
+  };
+  Z1 zi;
+  Z2 zd; // expected-note {{in instantiation of}}
+  Z2 z2i;
+
+  template
+  struct OK {
+    friend void qualified_friend::f(int);
+    friend void qualified_friend::f(int*);
+    friend void qualified_friend::f(T*);
+    friend void qualified_friend::f(T*);
+    friend void qualified_friend::nondep();
+    friend void qualified_friend::nondep();
+
+    friend void Y::f(int);
+    friend void Y::f(int*);
+    friend void Y::f(T*);
+    friend void Y::f(T*);
+    friend void Y::nondep();
+    friend void Y::nondep();
+  };
+  OK ok;
+}
+
+namespace qualified_friend_finds_nothing {
+  // FIXME: The status of this example is unclear. For now, we diagnose if the
+  // qualified declaration has nothing it can redeclare, but allow qualified
+  // lookup to find later-declared function templates during instantiation.
+  //
+  // This matches the behavior of GCC, EDG, ICC, and MSVC (except that GCC and
+  // ICC bizarrely accept the instantiation of B).
+  namespace N {}
+
+  template struct A {
+    friend void N::f(T); // expected-error {{friend declaration of 'f' does not match}}
+  };
+  namespace N { void f(); } // expected-note {{different number of parameters}}
+
+  template struct B {
+    friend void N::f(T); // expected-error {{friend declaration of 'f' does not match}}
+  };
+  B bf; // expected-note {{in instantiation of}}
+
+  namespace N { void f(int); }
+  B bi; // ok?!
+}
-- 
cgit v1.2.3


From e3bf574a5ea6bb82ca687acd03bbe9efd08cdf9e Mon Sep 17 00:00:00 2001
From: Akira Hatanaka 
Date: Fri, 11 Jan 2019 04:57:34 +0000
Subject: [Sema] If CheckPlaceholderExpr rewrites the initializer of an auto
 variable during auto type deduction, use the rewritten initializer when
 performing initialization of the variable.

This silences spurious -Warc-repeated-use-of-weak warnings that are
issued when the initializer uses a weak ObjC pointer.

Differential Revision: https://reviews.llvm.org/D55662

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350917 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/Sema/Sema.h          |  4 ++--
 lib/Sema/SemaDecl.cpp              | 10 ++++++----
 lib/Sema/SemaExprCXX.cpp           |  7 +++----
 lib/Sema/SemaLambda.cpp            | 10 ++++------
 test/SemaObjC/arc-repeated-weak.mm | 16 ++++++++++++++--
 5 files changed, 29 insertions(+), 18 deletions(-)

diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index c79ca74d32..c9498c19c2 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -1960,7 +1960,7 @@ public:
   bool CheckVariableDeclaration(VarDecl *NewVD, LookupResult &Previous);
   void CheckVariableDeclarationType(VarDecl *NewVD);
   bool DeduceVariableDeclarationType(VarDecl *VDecl, bool DirectInit,
-                                     Expr *Init);
+                                     Expr *&Init);
   void CheckCompleteVariableDeclaration(VarDecl *VD);
   void CheckCompleteDecompositionDeclaration(DecompositionDecl *DD);
   void MaybeSuggestAddingStaticToDecl(const FunctionDecl *D);
@@ -7095,7 +7095,7 @@ public:
   QualType deduceVarTypeFromInitializer(VarDecl *VDecl, DeclarationName Name,
                                         QualType Type, TypeSourceInfo *TSI,
                                         SourceRange Range, bool DirectInit,
-                                        Expr *Init);
+                                        Expr *&Init);
 
   TypeLoc getReturnTypeLoc(FunctionDecl *FD) const;
 
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index f77aeb64b3..0fb4ba60bf 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -10812,7 +10812,7 @@ QualType Sema::deduceVarTypeFromInitializer(VarDecl *VDecl,
                                             DeclarationName Name, QualType Type,
                                             TypeSourceInfo *TSI,
                                             SourceRange Range, bool DirectInit,
-                                            Expr *Init) {
+                                            Expr *&Init) {
   bool IsInitCapture = !VDecl;
   assert((!VDecl || !VDecl->isInitCapture()) &&
          "init captures are expected to be deduced prior to initialization");
@@ -10928,7 +10928,8 @@ QualType Sema::deduceVarTypeFromInitializer(VarDecl *VDecl,
           << (DeduceInit->getType().isNull() ? TSI->getType()
                                              : DeduceInit->getType())
           << DeduceInit->getSourceRange();
-  }
+  } else
+    Init = DeduceInit;
 
   // Warn if we deduced 'id'. 'auto' usually implies type-safety, but using
   // 'id' instead of a specific object type prevents most of our usual
@@ -10945,7 +10946,7 @@ QualType Sema::deduceVarTypeFromInitializer(VarDecl *VDecl,
 }
 
 bool Sema::DeduceVariableDeclarationType(VarDecl *VDecl, bool DirectInit,
-                                         Expr *Init) {
+                                         Expr *&Init) {
   QualType DeducedType = deduceVarTypeFromInitializer(
       VDecl, VDecl->getDeclName(), VDecl->getType(), VDecl->getTypeSourceInfo(),
       VDecl->getSourceRange(), DirectInit, Init);
@@ -11451,8 +11452,9 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl) {
       return;
     }
 
+    Expr *TmpInit = nullptr;
     if (Type->isUndeducedType() &&
-        DeduceVariableDeclarationType(Var, false, nullptr))
+        DeduceVariableDeclarationType(Var, false, TmpInit))
       return;
 
     // C++11 [class.static.data]p3: A static data member can be declared with
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index 56af640aa4..22172ba3fb 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -1865,12 +1865,11 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,
     if (Braced && !getLangOpts().CPlusPlus17)
       Diag(Initializer->getBeginLoc(), diag::ext_auto_new_list_init)
           << AllocType << TypeRange;
-    Expr *Deduce = Inits[0];
     QualType DeducedType;
-    if (DeduceAutoType(AllocTypeInfo, Deduce, DeducedType) == DAR_Failed)
+    if (DeduceAutoType(AllocTypeInfo, Inits[0], DeducedType) == DAR_Failed)
       return ExprError(Diag(StartLoc, diag::err_auto_new_deduction_failure)
-                       << AllocType << Deduce->getType()
-                       << TypeRange << Deduce->getSourceRange());
+                       << AllocType << Inits[0]->getType()
+                       << TypeRange << Inits[0]->getSourceRange());
     if (DeducedType.isNull())
       return ExprError();
     AllocType = DeducedType;
diff --git a/lib/Sema/SemaLambda.cpp b/lib/Sema/SemaLambda.cpp
index 10f5e7b7bc..af233b96d6 100644
--- a/lib/Sema/SemaLambda.cpp
+++ b/lib/Sema/SemaLambda.cpp
@@ -759,14 +759,15 @@ QualType Sema::buildLambdaInitCaptureInitialization(SourceLocation Loc,
   TypeSourceInfo *TSI = TLB.getTypeSourceInfo(Context, DeductType);
 
   // Deduce the type of the init capture.
+  Expr *DeduceInit = Init;
   QualType DeducedType = deduceVarTypeFromInitializer(
       /*VarDecl*/nullptr, DeclarationName(Id), DeductType, TSI,
-      SourceRange(Loc, Loc), IsDirectInit, Init);
+      SourceRange(Loc, Loc), IsDirectInit, DeduceInit);
   if (DeducedType.isNull())
     return QualType();
 
   // Are we a non-list direct initialization?
-  ParenListExpr *CXXDirectInit = dyn_cast(Init);
+  bool CXXDirectInit = isa(Init);
 
   // Perform initialization analysis and ensure any implicit conversions
   // (such as lvalue-to-rvalue) are enforced.
@@ -779,10 +780,7 @@ QualType Sema::buildLambdaInitCaptureInitialization(SourceLocation Loc,
                            : InitializationKind::CreateDirectList(Loc))
           : InitializationKind::CreateCopy(Loc, Init->getBeginLoc());
 
-  MultiExprArg Args = Init;
-  if (CXXDirectInit)
-    Args =
-        MultiExprArg(CXXDirectInit->getExprs(), CXXDirectInit->getNumExprs());
+  MultiExprArg Args = DeduceInit;
   QualType DclT;
   InitializationSequence InitSeq(*this, Entity, Kind, Args);
   ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Args, &DclT);
diff --git a/test/SemaObjC/arc-repeated-weak.mm b/test/SemaObjC/arc-repeated-weak.mm
index 4eec4d2fe6..6c7a6292f9 100644
--- a/test/SemaObjC/arc-repeated-weak.mm
+++ b/test/SemaObjC/arc-repeated-weak.mm
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -fsyntax-only -fobjc-runtime-has-weak -fobjc-arc -fblocks -Wno-objc-root-class -std=c++11 -Warc-repeated-use-of-weak -verify %s
-// RUN: %clang_cc1 -fsyntax-only -fobjc-runtime-has-weak -fobjc-weak -fblocks -Wno-objc-root-class -std=c++11 -Warc-repeated-use-of-weak -verify %s
+// RUN: %clang_cc1 -fsyntax-only -fobjc-runtime-has-weak -fobjc-arc -fblocks -Wno-objc-root-class -std=c++14 -Warc-repeated-use-of-weak -verify %s
+// RUN: %clang_cc1 -fsyntax-only -fobjc-runtime-has-weak -fobjc-weak -fblocks -Wno-objc-root-class -std=c++14 -Warc-repeated-use-of-weak -verify %s
 
 @interface Test {
 @public
@@ -467,6 +467,18 @@ void foo() {
   __typeof__(NSBundle2.foo2.weakProp) t5;
 }
 
+void testAuto() {
+  auto __weak wp = NSBundle2.foo2.weakProp;
+}
+
+void testLambdaCaptureInit() {
+  [capture(NSBundle2.foo2.weakProp)] {} ();
+}
+
+void testAutoNew() {
+  auto p = new auto(NSBundle2.foo2.weakProp);
+}
+
 // This used to crash in the constructor of WeakObjectProfileTy when a
 // DeclRefExpr was passed that didn't reference a VarDecl.
 
-- 
cgit v1.2.3


From b3867657b9dadc3deaf9e66cdf5f92b4b2b65a90 Mon Sep 17 00:00:00 2001
From: Akira Hatanaka 
Date: Fri, 11 Jan 2019 07:06:38 +0000
Subject: [Sema] Make canPassInRegisters return true if the CXXRecordDecl
 passed to it is a trivial_abi class.

A class that has all of its copy and move constructors deleted can still
be passed or returned in registers if the class is annotated with
trivial_abi.

This fixes PR39683.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350920 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/Sema/SemaDeclCXX.cpp        |  3 +++
 test/CodeGenCXX/trivial_abi.cpp | 19 +++++++++++++++++--
 2 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index e19b68718e..c2fa87a079 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -5886,6 +5886,9 @@ static bool canPassInRegisters(Sema &S, CXXRecordDecl *D,
   if (D->isDependentType() || D->isInvalidDecl())
     return false;
 
+  if (D->hasAttr())
+    return true;
+
   // Clang <= 4 used the pre-C++11 rule, which ignores move operations.
   // The PS4 platform ABI follows the behavior of Clang 3.2.
   if (CCK == TargetInfo::CCK_ClangABI4OrPS4)
diff --git a/test/CodeGenCXX/trivial_abi.cpp b/test/CodeGenCXX/trivial_abi.cpp
index 2cf07b2258..e37c8ff615 100644
--- a/test/CodeGenCXX/trivial_abi.cpp
+++ b/test/CodeGenCXX/trivial_abi.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple arm64-apple-ios11 -std=c++11 -fcxx-exceptions -fexceptions -emit-llvm -o - %s | FileCheck %s
-// RUN: %clang_cc1 -triple arm64-apple-ios11 -std=c++11 -fcxx-exceptions -fexceptions -fclang-abi-compat=4.0 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple arm64-apple-ios11 -std=c++17 -fcxx-exceptions -fexceptions -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple arm64-apple-ios11 -std=c++17 -fcxx-exceptions -fexceptions -fclang-abi-compat=4.0 -emit-llvm -o - %s | FileCheck %s
 
 // CHECK: %[[STRUCT_SMALL:.*]] = type { i32* }
 // CHECK: %[[STRUCT_LARGE:.*]] = type { i32*, [128 x i32] }
@@ -43,6 +43,13 @@ struct HasNonTrivial {
   NonTrivial m;
 };
 
+struct __attribute__((trivial_abi)) CopyMoveDeleted {
+  CopyMoveDeleted(int);
+  CopyMoveDeleted(const CopyMoveDeleted &) = delete;
+  CopyMoveDeleted(CopyMoveDeleted &&) = delete;
+  int a;
+};
+
 // CHECK: define void @_Z14testParamSmall5Small(i64 %[[A_COERCE:.*]])
 // CHECK: %[[A:.*]] = alloca %[[STRUCT_SMALL]], align 8
 // CHECK: %[[COERCE_DIVE:.*]] = getelementptr inbounds %[[STRUCT_SMALL]], %[[STRUCT_SMALL]]* %[[A]], i32 0, i32 0
@@ -237,3 +244,11 @@ void calleeExceptionLarge(Large, Large);
 void testExceptionLarge() {
   calleeExceptionLarge(Large(), Large());
 }
+
+// A class with deleted copy and move constructors can still be passed or
+// returned in registers if the class is annotated with trivial_abi.
+
+// CHECK: define i64 @_Z19testCopyMoveDeletedi(i32 %
+CopyMoveDeleted testCopyMoveDeleted(int a) {
+  return a;
+}
-- 
cgit v1.2.3


From 074a530bf75088af4fa8482a9a8795949051b94b Mon Sep 17 00:00:00 2001
From: Bjorn Pettersson 
Date: Fri, 11 Jan 2019 16:53:45 +0000
Subject: Silence -Wsign-compare in unittests

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350933 91177308-0d34-0410-b5e6-96231b3b80d8
---
 unittests/Lex/PPCallbacksTest.cpp | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/unittests/Lex/PPCallbacksTest.cpp b/unittests/Lex/PPCallbacksTest.cpp
index 29d5268921..940328842d 100644
--- a/unittests/Lex/PPCallbacksTest.cpp
+++ b/unittests/Lex/PPCallbacksTest.cpp
@@ -432,25 +432,25 @@ TEST_F(PPCallbacksTest, OpenCLExtensionPragmaDisabled) {
 
 TEST_F(PPCallbacksTest, DirectiveExprRanges) {
   const auto &Results1 = DirectiveExprRange("#if FLUZZY_FLOOF\n#endif\n");
-  EXPECT_EQ(Results1.size(), 1);
+  EXPECT_EQ(Results1.size(), 1U);
   EXPECT_EQ(
       GetSourceStringToEnd(CharSourceRange(Results1[0].ConditionRange, false)),
       "FLUZZY_FLOOF");
 
   const auto &Results2 = DirectiveExprRange("#if 1 + 4 < 7\n#endif\n");
-  EXPECT_EQ(Results2.size(), 1);
+  EXPECT_EQ(Results2.size(), 1U);
   EXPECT_EQ(
       GetSourceStringToEnd(CharSourceRange(Results2[0].ConditionRange, false)),
       "1 + 4 < 7");
 
   const auto &Results3 = DirectiveExprRange("#if 1 + \\\n  2\n#endif\n");
-  EXPECT_EQ(Results3.size(), 1);
+  EXPECT_EQ(Results3.size(), 1U);
   EXPECT_EQ(
       GetSourceStringToEnd(CharSourceRange(Results3[0].ConditionRange, false)),
       "1 + \\\n  2");
 
   const auto &Results4 = DirectiveExprRange("#if 0\n#elif FLOOFY\n#endif\n");
-  EXPECT_EQ(Results4.size(), 2);
+  EXPECT_EQ(Results4.size(), 2U);
   EXPECT_EQ(
       GetSourceStringToEnd(CharSourceRange(Results4[0].ConditionRange, false)),
       "0");
@@ -459,7 +459,7 @@ TEST_F(PPCallbacksTest, DirectiveExprRanges) {
       "FLOOFY");
 
   const auto &Results5 = DirectiveExprRange("#if 1\n#elif FLOOFY\n#endif\n");
-  EXPECT_EQ(Results5.size(), 2);
+  EXPECT_EQ(Results5.size(), 2U);
   EXPECT_EQ(
       GetSourceStringToEnd(CharSourceRange(Results5[0].ConditionRange, false)),
       "1");
@@ -469,14 +469,14 @@ TEST_F(PPCallbacksTest, DirectiveExprRanges) {
 
   const auto &Results6 =
       DirectiveExprRange("#if defined(FLUZZY_FLOOF)\n#endif\n");
-  EXPECT_EQ(Results6.size(), 1);
+  EXPECT_EQ(Results6.size(), 1U);
   EXPECT_EQ(
       GetSourceStringToEnd(CharSourceRange(Results6[0].ConditionRange, false)),
       "defined(FLUZZY_FLOOF)");
 
   const auto &Results7 =
       DirectiveExprRange("#if 1\n#elif defined(FLOOFY)\n#endif\n");
-  EXPECT_EQ(Results7.size(), 2);
+  EXPECT_EQ(Results7.size(), 2U);
   EXPECT_EQ(
       GetSourceStringToEnd(CharSourceRange(Results7[0].ConditionRange, false)),
       "1");
-- 
cgit v1.2.3


From 14f508aa0b57ceaa38543ccf609ba18867c5fa33 Mon Sep 17 00:00:00 2001
From: Chris Kennelly 
Date: Fri, 11 Jan 2019 17:09:22 +0000
Subject: Implementation Feature Test Macros for P0722R3

Summary:
P1353R0, adopted in San Diego, specified an implementation feature test macro for destroying delete (P0722R3).

The implementation of the feature (https://reviews.llvm.org/rL315662) is not guarded behind a flag, so the macro is not conditional on language version.

Reviewers: rsmith

Reviewed By: rsmith

Subscribers: cfe-commits

Differential Revision: https://reviews.llvm.org/D55741

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350934 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/Frontend/InitPreprocessor.cpp |  1 +
 test/Lexer/cxx-features.cpp       |  4 ++++
 www/cxx_status.html               | 11 ++++++++---
 3 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/lib/Frontend/InitPreprocessor.cpp b/lib/Frontend/InitPreprocessor.cpp
index 77b2f479a7..66807b097d 100644
--- a/lib/Frontend/InitPreprocessor.cpp
+++ b/lib/Frontend/InitPreprocessor.cpp
@@ -543,6 +543,7 @@ static void InitializeCPlusPlusFeatureTestMacros(const LangOptions &LangOpts,
   // C++20 features.
   if (LangOpts.Char8)
     Builder.defineMacro("__cpp_char8_t", "201811L");
+  Builder.defineMacro("__cpp_impl_destroying_delete", "201806L");
 
   // TS features.
   if (LangOpts.ConceptsTS)
diff --git a/test/Lexer/cxx-features.cpp b/test/Lexer/cxx-features.cpp
index e4fea0b5bb..09b82b7c47 100644
--- a/test/Lexer/cxx-features.cpp
+++ b/test/Lexer/cxx-features.cpp
@@ -34,6 +34,10 @@
 #error "wrong value for __cpp_char8_t"
 #endif
 
+#if check(impl_destroying_delete, 201806, 201806, 201806, 201806, 201806)
+#error "wrong value for __cpp_impl_destroying_delete"
+#endif
+
 // --- C++17 features ---
 
 #if check(hex_float, 0, 0, 0, 201603, 201603)
diff --git a/www/cxx_status.html b/www/cxx_status.html
index 5fee962ce8..95aa291827 100755
--- a/www/cxx_status.html
+++ b/www/cxx_status.html
@@ -1054,9 +1054,9 @@ and library features that are not part of standard C++.

Available in Clang? - SD-6: SG10 feature test recommendations - SD-6 - N/A + SD-6: SG10 feature test recommendations + SD-6 + N/A Clang 3.4 (N3745)
@@ -1081,6 +1081,11 @@ and library features that are not part of standard C++.

Clang 7 (P0096R5) + + + WIP (P1353R0) + + + issue_hash_content_of_line_in_context5928b2a4699cbae0686391c20e639007 + issue_context_kindfunction + issue_contextf1 + issue_hash_function_offset7 + location + + line354 + col7 + file0 + + ExecutedLines + + 0 + + 347 + 348 + 349 + 350 + 351 + 352 + 353 + 354 + + + + + path + + + kindcontrol + edges + + + start + + + line359 + col3 + file0 + + + line359 + col16 + file0 + + + end + + + line360 + col3 + file0 + + + line360 + col11 + file0 + + + + + + + kindevent + location + + line360 + col20 + file0 + + ranges + + + + line360 + col20 + file0 + + + line360 + col37 + file0 + + + + depth0 + extended_message + Call to function 'CFDateCreate' returns a Core Foundation object of type 'CFDateRef' with a +1 retain count + message + Call to function 'CFDateCreate' returns a Core Foundation object of type 'CFDateRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line360 + col3 + file0 + + + line360 + col11 + file0 + + + end + + + line361 + col3 + file0 + + + line361 + col3 + file0 + + + + + + + kindevent + location + + line361 + col3 + file0 + + ranges + + + + line361 + col3 + file0 + + + line361 + col27 + file0 + + + + + line361 + col4 + file0 + + + line361 + col19 + file0 + + + + depth0 + extended_message + Reference count incremented. The object now has a +2 retain count + message + Reference count incremented. The object now has a +2 retain count + + + kindcontrol + edges + + + start + + + line361 + col3 + file0 + + + line361 + col3 + file0 + + + end + + + line362 + col3 + file0 + + + line362 + col11 + file0 + + + + + + + kindevent + location + + line362 + col3 + file0 + + ranges + + + + line362 + col3 + file0 + + + line362 + col17 + file0 + + + + + line362 + col13 + file0 + + + line362 + col16 + file0 + + + + depth0 + extended_message + Reference count decremented. The object now has a +1 retain count + message + Reference count decremented. The object now has a +1 retain count + + + kindcontrol + edges + + + start + + + line362 + col3 + file0 + + + line362 + col11 + file0 + + + end + + + line364 + col3 + file0 + + + line364 + col3 + file0 + + + + + + + kindevent + location + + line364 + col3 + file0 + + ranges + + + + line364 + col3 + file0 + + + line364 + col28 + file0 + + + + + line364 + col4 + file0 + + + line364 + col19 + file0 + + + + depth0 + extended_message + Object released + message + Object released + + + kindcontrol + edges + + + start + + + line364 + col3 + file0 + + + line364 + col3 + file0 + + + end + + + line365 + col3 + file0 + + + line365 + col3 + file0 + + + + + + + kindcontrol + edges + + + start + + + line365 + col3 + file0 + + + line365 + col3 + file0 + + + end + + + line365 + col7 + file0 + + + line365 + col27 + file0 + + + + + + + kindevent + location + + line365 + col7 + file0 + + ranges + + + + line365 + col29 + file0 + + + line365 + col32 + file0 + + + + depth0 + extended_message + Reference-counted object is used after it is released + message + Reference-counted object is used after it is released + + + descriptionReference-counted object is used after it is released + categoryMemory (Core Foundation/Objective-C/OSObject) + typeUse-after-release + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context6b2e175938153ac041f52ebbf50b1f43 + issue_context_kindfunction + issue_contextf2 + issue_hash_function_offset7 + location + + line365 + col7 + file0 + + ExecutedLines + + 0 + + 358 + 359 + 360 + 361 + 362 + 363 + 364 + 365 + + + + + path + + + kindcontrol + edges + + + start + + + line395 + col3 + file0 + + + line395 + col16 + file0 + + + end + + + line396 + col3 + file0 + + + line396 + col11 + file0 + + + + + + + kindevent + location + + line396 + col20 + file0 + + ranges + + + + line396 + col20 + file0 + + + line396 + col37 + file0 + + + + depth0 + extended_message + Call to function 'CFDateCreate' returns a Core Foundation object of type 'CFDateRef' with a +1 retain count + message + Call to function 'CFDateCreate' returns a Core Foundation object of type 'CFDateRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line396 + col3 + file0 + + + line396 + col11 + file0 + + + end + + + line398 + col3 + file0 + + + line398 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line398 + col3 + file0 + + + line398 + col4 + file0 + + + end + + + line398 + col7 + file0 + + + line398 + col7 + file0 + + + + + + + kindevent + location + + line398 + col7 + file0 + + ranges + + + + line398 + col7 + file0 + + + line398 + col7 + file0 + + + + depth0 + extended_message + Assuming 'x' is 0 + message + Assuming 'x' is 0 + + + kindcontrol + edges + + + start + + + line398 + col7 + file0 + + + line398 + col7 + file0 + + + end + + + line401 + col3 + file0 + + + line401 + col8 + file0 + + + + + + + kindcontrol + edges + + + start + + + line401 + col3 + file0 + + + line401 + col8 + file0 + + + end + + + line401 + col10 + file0 + + + line401 + col10 + file0 + + + + + + + kindevent + location + + line401 + col10 + file0 + + ranges + + + + line401 + col10 + file0 + + + line401 + col10 + file0 + + + + depth0 + extended_message + Object leaked: object allocated and stored into 'date' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'date' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'date' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context3fdbd844ddb925306ba2bb1b3626f310 + issue_context_kindfunction + issue_contextf5 + issue_hash_function_offset2 + location + + line401 + col10 + file0 + + ExecutedLines + + 0 + + 394 + 395 + 396 + 398 + 401 + + + + + path + + + kindevent + location + + line407 + col20 + file0 + + ranges + + + + line407 + col20 + file0 + + + line407 + col62 + file0 + + + + depth0 + extended_message + Call to function 'CFDateCreate' returns a Core Foundation object of type 'CFDateRef' with a +1 retain count + message + Call to function 'CFDateCreate' returns a Core Foundation object of type 'CFDateRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line407 + col3 + file0 + + + line407 + col11 + file0 + + + end + + + line408 + col3 + file0 + + + line408 + col10 + file0 + + + + + + + kindevent + location + + line408 + col3 + file0 + + ranges + + + + line408 + col3 + file0 + + + line408 + col16 + file0 + + + + + line408 + col12 + file0 + + + line408 + col15 + file0 + + + + depth0 + extended_message + Reference count incremented. The object now has a +2 retain count + message + Reference count incremented. The object now has a +2 retain count + + + kindcontrol + edges + + + start + + + line408 + col3 + file0 + + + line408 + col10 + file0 + + + end + + + line409 + col3 + file0 + + + line409 + col8 + file0 + + + + + + + kindevent + location + + line409 + col3 + file0 + + ranges + + + + line409 + col3 + file0 + + + line409 + col13 + file0 + + + + depth0 + extended_message + Object leaked: object allocated and stored into 'date' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'date' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'date' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context8529da75e357c59fb0a7fefb0b6e0952 + issue_context_kindfunction + issue_contextf6 + issue_hash_function_offset1 + location + + line409 + col3 + file0 + + ExecutedLines + + 0 + + 406 + 407 + 408 + 409 + + + + + path + + + kindevent + location + + line415 + col20 + file0 + + ranges + + + + line415 + col20 + file0 + + + line415 + col62 + file0 + + + + depth0 + extended_message + Call to function 'CFDateCreate' returns a Core Foundation object of type 'CFDateRef' with a +1 retain count + message + Call to function 'CFDateCreate' returns a Core Foundation object of type 'CFDateRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line415 + col3 + file0 + + + line415 + col11 + file0 + + + end + + + line416 + col3 + file0 + + + line416 + col10 + file0 + + + + + + + kindevent + location + + line416 + col3 + file0 + + ranges + + + + line416 + col3 + file0 + + + line416 + col16 + file0 + + + + + line416 + col12 + file0 + + + line416 + col15 + file0 + + + + depth0 + extended_message + Reference count incremented. The object now has a +2 retain count + message + Reference count incremented. The object now has a +2 retain count + + + kindcontrol + edges + + + start + + + line416 + col3 + file0 + + + line416 + col10 + file0 + + + end + + + line418 + col3 + file0 + + + line418 + col8 + file0 + + + + + + + kindevent + location + + line418 + col3 + file0 + + ranges + + + + line418 + col3 + file0 + + + line418 + col13 + file0 + + + + depth0 + extended_message + Object leaked: object allocated and stored into 'date' is not referenced later in this execution path and has a retain count of +2 + message + Object leaked: object allocated and stored into 'date' is not referenced later in this execution path and has a retain count of +2 + + + descriptionPotential leak of an object stored into 'date' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_contexteb0faa12081b1e28b218e4c6e53d57ec + issue_context_kindfunction + issue_contextf7 + issue_hash_function_offset1 + location + + line418 + col3 + file0 + + ExecutedLines + + 0 + + 414 + 415 + 416 + 417 + 418 + + + + + path + + + kindcontrol + edges + + + start + + + line415 + col3 + file0 + + + line415 + col11 + file0 + + + end + + + line417 + col3 + file0 + + + line417 + col6 + file0 + + + + + + + kindevent + location + + line417 + col10 + file0 + + ranges + + + + line417 + col10 + file0 + + + line417 + col52 + file0 + + + + depth0 + extended_message + Call to function 'CFDateCreate' returns a Core Foundation object of type 'CFDateRef' with a +1 retain count + message + Call to function 'CFDateCreate' returns a Core Foundation object of type 'CFDateRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line417 + col3 + file0 + + + line417 + col6 + file0 + + + end + + + line418 + col3 + file0 + + + line418 + col8 + file0 + + + + + + + kindevent + location + + line418 + col3 + file0 + + ranges + + + + line418 + col3 + file0 + + + line418 + col13 + file0 + + + + depth0 + extended_message + Object leaked: object allocated and stored into 'date' is returned from a function whose name ('f7') does not contain 'Copy' or 'Create'. This violates the naming convention rules given in the Memory Management Guide for Core Foundation + message + Object leaked: object allocated and stored into 'date' is returned from a function whose name ('f7') does not contain 'Copy' or 'Create'. This violates the naming convention rules given in the Memory Management Guide for Core Foundation + + + descriptionPotential leak of an object stored into 'date' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak of returned object + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context404d4de8faa444bc52fd510380bd0a63 + issue_context_kindfunction + issue_contextf7 + issue_hash_function_offset3 + location + + line418 + col3 + file0 + + ExecutedLines + + 0 + + 414 + 415 + 416 + 417 + 418 + + + + + path + + + kindevent + location + + line426 + col20 + file0 + + ranges + + + + line426 + col20 + file0 + + + line426 + col33 + file0 + + + + depth0 + extended_message + Call to function 'MyDateCreate' returns a Core Foundation object of type 'CFDateRef' with a +1 retain count + message + Call to function 'MyDateCreate' returns a Core Foundation object of type 'CFDateRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line426 + col3 + file0 + + + line426 + col11 + file0 + + + end + + + line427 + col3 + file0 + + + line427 + col10 + file0 + + + + + + + kindevent + location + + line427 + col3 + file0 + + ranges + + + + line427 + col3 + file0 + + + line427 + col16 + file0 + + + + + line427 + col12 + file0 + + + line427 + col15 + file0 + + + + depth0 + extended_message + Reference count incremented. The object now has a +2 retain count + message + Reference count incremented. The object now has a +2 retain count + + + kindcontrol + edges + + + start + + + line427 + col3 + file0 + + + line427 + col10 + file0 + + + end + + + line428 + col3 + file0 + + + line428 + col8 + file0 + + + + + + + kindevent + location + + line428 + col3 + file0 + + ranges + + + + line428 + col3 + file0 + + + line428 + col13 + file0 + + + + depth0 + extended_message + Object leaked: object allocated and stored into 'date' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'date' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'date' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context251dff6727b3d99ec95caa28672669ea + issue_context_kindfunction + issue_contextf8 + issue_hash_function_offset1 + location + + line428 + col3 + file0 + + ExecutedLines + + 0 + + 425 + 426 + 427 + 428 + + + + + path + + + kindcontrol + edges + + + start + + + line432 + col3 + file0 + + + line432 + col11 + file0 + + + end + + + line433 + col3 + file0 + + + line433 + col5 + file0 + + + + + + + kindevent + location + + line433 + col3 + file0 + + ranges + + + + line433 + col3 + file0 + + + line433 + col8 + file0 + + + + depth0 + extended_message + 'p' initialized to a null pointer value + message + 'p' initialized to a null pointer value + + + kindcontrol + edges + + + start + + + line433 + col3 + file0 + + + line433 + col5 + file0 + + + end + + + line435 + col3 + file0 + + + line435 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line435 + col3 + file0 + + + line435 + col4 + file0 + + + end + + + line435 + col7 + file0 + + + line435 + col7 + file0 + + + + + + + kindevent + location + + line435 + col7 + file0 + + ranges + + + + line435 + col7 + file0 + + + line435 + col11 + file0 + + + + depth0 + extended_message + Assuming 'date' is null + message + Assuming 'date' is null + + + kindcontrol + edges + + + start + + + line435 + col7 + file0 + + + line435 + col7 + file0 + + + end + + + line435 + col14 + file0 + + + line435 + col14 + file0 + + + + + + + kindcontrol + edges + + + start + + + line435 + col14 + file0 + + + line435 + col14 + file0 + + + end + + + line435 + col17 + file0 + + + line435 + col17 + file0 + + + + + + + kindevent + location + + line435 + col17 + file0 + + ranges + + + + line435 + col15 + file0 + + + line435 + col15 + file0 + + + + depth0 + extended_message + Dereference of null pointer (loaded from variable 'p') + message + Dereference of null pointer (loaded from variable 'p') + + + descriptionDereference of null pointer (loaded from variable 'p') + categoryLogic error + typeDereference of null pointer + check_namecore.NullDereference + + issue_hash_content_of_line_in_context4af5d8d1438976cc7fa006af5f843b13 + issue_context_kindfunction + issue_contextf9 + issue_hash_function_offset4 + location + + line435 + col17 + file0 + + ExecutedLines + + 0 + + 431 + 432 + 433 + 435 + + + + + path + + + kindevent + location + + line444 + col20 + file0 + + ranges + + + + line444 + col20 + file0 + + + line444 + col75 + file0 + + + + depth0 + extended_message + Call to function 'DADiskCreateFromBSDName' returns a Core Foundation object of type 'DADiskRef' with a +1 retain count + message + Call to function 'DADiskCreateFromBSDName' returns a Core Foundation object of type 'DADiskRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line444 + col3 + file0 + + + line444 + col11 + file0 + + + end + + + line445 + col3 + file0 + + + line445 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line445 + col3 + file0 + + + line445 + col4 + file0 + + + end + + + line445 + col7 + file0 + + + line445 + col10 + file0 + + + + + + + kindevent + location + + line445 + col7 + file0 + + ranges + + + + line445 + col7 + file0 + + + line445 + col10 + file0 + + + + depth0 + extended_message + Assuming 'disk' is non-null + message + Assuming 'disk' is non-null + + + kindcontrol + edges + + + start + + + line445 + col7 + file0 + + + line445 + col10 + file0 + + + end + + + line445 + col13 + file0 + + + line445 + col17 + file0 + + + + + + + kindcontrol + edges + + + start + + + line445 + col13 + file0 + + + line445 + col17 + file0 + + + end + + + line447 + col3 + file0 + + + line447 + col6 + file0 + + + + + + + kindcontrol + edges + + + start + + + line447 + col3 + file0 + + + line447 + col6 + file0 + + + end + + + line448 + col3 + file0 + + + line448 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line448 + col3 + file0 + + + line448 + col4 + file0 + + + end + + + line448 + col7 + file0 + + + line448 + col10 + file0 + + + + + + + kindevent + location + + line448 + col7 + file0 + + ranges + + + + line448 + col7 + file0 + + + line448 + col10 + file0 + + + + depth0 + extended_message + Assuming 'disk' is null + message + Assuming 'disk' is null + + + kindcontrol + edges + + + start + + + line448 + col7 + file0 + + + line448 + col10 + file0 + + + end + + + line450 + col3 + file0 + + + line450 + col17 + file0 + + + + + + + kindcontrol + edges + + + start + + + line450 + col3 + file0 + + + line450 + col17 + file0 + + + end + + + line450 + col26 + file0 + + + line450 + col46 + file0 + + + + + + + kindevent + location + + line450 + col26 + file0 + + ranges + + + + line450 + col26 + file0 + + + line450 + col46 + file0 + + + + depth0 + extended_message + Object leaked: object allocated and stored into 'disk' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'disk' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'disk' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context69ae08a90fe52a921ed423df38ed7480 + issue_context_kindfunction + issue_contextf10 + issue_hash_function_offset1 + location + + line450 + col26 + file0 + + ExecutedLines + + 0 + + 443 + 444 + 445 + 447 + 448 + 450 + + + + + path + + + kindcontrol + edges + + + start + + + line444 + col3 + file0 + + + line444 + col11 + file0 + + + end + + + line445 + col3 + file0 + + + line445 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line445 + col3 + file0 + + + line445 + col4 + file0 + + + end + + + line445 + col7 + file0 + + + line445 + col10 + file0 + + + + + + + kindevent + location + + line445 + col7 + file0 + + ranges + + + + line445 + col7 + file0 + + + line445 + col10 + file0 + + + + depth0 + extended_message + Assuming 'disk' is null + message + Assuming 'disk' is null + + + kindcontrol + edges + + + start + + + line445 + col7 + file0 + + + line445 + col10 + file0 + + + end + + + line447 + col3 + file0 + + + line447 + col6 + file0 + + + + + + + kindcontrol + edges + + + start + + + line447 + col3 + file0 + + + line447 + col6 + file0 + + + end + + + line448 + col3 + file0 + + + line448 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line448 + col3 + file0 + + + line448 + col4 + file0 + + + end + + + line448 + col7 + file0 + + + line448 + col10 + file0 + + + + + + + kindevent + location + + line448 + col7 + file0 + + ranges + + + + line448 + col7 + file0 + + + line448 + col10 + file0 + + + + depth0 + extended_message + Assuming 'disk' is null + message + Assuming 'disk' is null + + + kindcontrol + edges + + + start + + + line448 + col7 + file0 + + + line448 + col10 + file0 + + + end + + + line450 + col3 + file0 + + + line450 + col17 + file0 + + + + + + + kindevent + location + + line450 + col26 + file0 + + ranges + + + + line450 + col26 + file0 + + + line450 + col49 + file0 + + + + depth0 + extended_message + Call to function 'DADiskCopyDescription' returns a Core Foundation object of type 'CFDictionaryRef' with a +1 retain count + message + Call to function 'DADiskCopyDescription' returns a Core Foundation object of type 'CFDictionaryRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line450 + col3 + file0 + + + line450 + col17 + file0 + + + end + + + line451 + col3 + file0 + + + line451 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line451 + col3 + file0 + + + line451 + col4 + file0 + + + end + + + line451 + col7 + file0 + + + line451 + col10 + file0 + + + + + + + kindevent + location + + line451 + col7 + file0 + + ranges + + + + line451 + col7 + file0 + + + line451 + col10 + file0 + + + + depth0 + extended_message + Assuming 'dict' is non-null + message + Assuming 'dict' is non-null + + + kindcontrol + edges + + + start + + + line451 + col7 + file0 + + + line451 + col10 + file0 + + + end + + + line451 + col13 + file0 + + + line451 + col17 + file0 + + + + + + + kindevent + location + + line451 + col13 + file0 + + ranges + + + + line451 + col13 + file0 + + + line451 + col17 + file0 + + + + depth0 + extended_message + Object leaked: object allocated and stored into 'dict' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'dict' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'dict' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_contexta7f8c63b1cdc39df79b7457e27ff4930 + issue_context_kindfunction + issue_contextf10 + issue_hash_function_offset7 + location + + line451 + col13 + file0 + + ExecutedLines + + 0 + + 443 + 444 + 445 + 447 + 448 + 450 + 451 + + + + + path + + + kindcontrol + edges + + + start + + + line444 + col3 + file0 + + + line444 + col11 + file0 + + + end + + + line445 + col3 + file0 + + + line445 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line445 + col3 + file0 + + + line445 + col4 + file0 + + + end + + + line445 + col7 + file0 + + + line445 + col10 + file0 + + + + + + + kindevent + location + + line445 + col7 + file0 + + ranges + + + + line445 + col7 + file0 + + + line445 + col10 + file0 + + + + depth0 + extended_message + Assuming 'disk' is null + message + Assuming 'disk' is null + + + kindcontrol + edges + + + start + + + line445 + col7 + file0 + + + line445 + col10 + file0 + + + end + + + line447 + col3 + file0 + + + line447 + col6 + file0 + + + + + + + kindcontrol + edges + + + start + + + line447 + col3 + file0 + + + line447 + col6 + file0 + + + end + + + line448 + col3 + file0 + + + line448 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line448 + col3 + file0 + + + line448 + col4 + file0 + + + end + + + line448 + col7 + file0 + + + line448 + col10 + file0 + + + + + + + kindevent + location + + line448 + col7 + file0 + + ranges + + + + line448 + col7 + file0 + + + line448 + col10 + file0 + + + + depth0 + extended_message + Assuming 'disk' is null + message + Assuming 'disk' is null + + + kindcontrol + edges + + + start + + + line448 + col7 + file0 + + + line448 + col10 + file0 + + + end + + + line450 + col3 + file0 + + + line450 + col17 + file0 + + + + + + + kindcontrol + edges + + + start + + + line450 + col3 + file0 + + + line450 + col17 + file0 + + + end + + + line451 + col3 + file0 + + + line451 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line451 + col3 + file0 + + + line451 + col4 + file0 + + + end + + + line451 + col7 + file0 + + + line451 + col10 + file0 + + + + + + + kindevent + location + + line451 + col7 + file0 + + ranges + + + + line451 + col7 + file0 + + + line451 + col10 + file0 + + + + depth0 + extended_message + Assuming 'dict' is null + message + Assuming 'dict' is null + + + kindcontrol + edges + + + start + + + line451 + col7 + file0 + + + line451 + col10 + file0 + + + end + + + line453 + col3 + file0 + + + line453 + col6 + file0 + + + + + + + kindevent + location + + line453 + col10 + file0 + + ranges + + + + line453 + col10 + file0 + + + line453 + col31 + file0 + + + + depth0 + extended_message + Call to function 'DADiskCopyWholeDisk' returns a Core Foundation object of type 'DADiskRef' with a +1 retain count + message + Call to function 'DADiskCopyWholeDisk' returns a Core Foundation object of type 'DADiskRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line453 + col3 + file0 + + + line453 + col6 + file0 + + + end + + + line454 + col3 + file0 + + + line454 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line454 + col3 + file0 + + + line454 + col4 + file0 + + + end + + + line454 + col7 + file0 + + + line454 + col10 + file0 + + + + + + + kindevent + location + + line454 + col7 + file0 + + ranges + + + + line454 + col7 + file0 + + + line454 + col10 + file0 + + + + depth0 + extended_message + Assuming 'disk' is non-null + message + Assuming 'disk' is non-null + + + kindcontrol + edges + + + start + + + line454 + col7 + file0 + + + line454 + col10 + file0 + + + end + + + line454 + col13 + file0 + + + line454 + col17 + file0 + + + + + + + kindevent + location + + line454 + col13 + file0 + + ranges + + + + line454 + col13 + file0 + + + line454 + col17 + file0 + + + + depth0 + extended_message + Object leaked: object allocated and stored into 'disk' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'disk' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'disk' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_contextcace8e35bed93ecdfa0455ac166aaa97 + issue_context_kindfunction + issue_contextf10 + issue_hash_function_offset10 + location + + line454 + col13 + file0 + + ExecutedLines + + 0 + + 443 + 444 + 445 + 447 + 448 + 450 + 451 + 453 + 454 + + + + + path + + + kindcontrol + edges + + + start + + + line444 + col3 + file0 + + + line444 + col11 + file0 + + + end + + + line445 + col3 + file0 + + + line445 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line445 + col3 + file0 + + + line445 + col4 + file0 + + + end + + + line445 + col7 + file0 + + + line445 + col10 + file0 + + + + + + + kindevent + location + + line445 + col7 + file0 + + ranges + + + + line445 + col7 + file0 + + + line445 + col10 + file0 + + + + depth0 + extended_message + Assuming 'disk' is null + message + Assuming 'disk' is null + + + kindcontrol + edges + + + start + + + line445 + col7 + file0 + + + line445 + col10 + file0 + + + end + + + line447 + col3 + file0 + + + line447 + col6 + file0 + + + + + + + kindevent + location + + line447 + col10 + file0 + + ranges + + + + line447 + col10 + file0 + + + line447 + col63 + file0 + + + + depth0 + extended_message + Call to function 'DADiskCreateFromIOMedia' returns a Core Foundation object of type 'DADiskRef' with a +1 retain count + message + Call to function 'DADiskCreateFromIOMedia' returns a Core Foundation object of type 'DADiskRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line447 + col3 + file0 + + + line447 + col6 + file0 + + + end + + + line448 + col3 + file0 + + + line448 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line448 + col3 + file0 + + + line448 + col4 + file0 + + + end + + + line448 + col7 + file0 + + + line448 + col10 + file0 + + + + + + + kindevent + location + + line448 + col7 + file0 + + ranges + + + + line448 + col7 + file0 + + + line448 + col10 + file0 + + + + depth0 + extended_message + Assuming 'disk' is non-null + message + Assuming 'disk' is non-null + + + kindcontrol + edges + + + start + + + line448 + col7 + file0 + + + line448 + col10 + file0 + + + end + + + line448 + col13 + file0 + + + line448 + col17 + file0 + + + + + + + kindcontrol + edges + + + start + + + line448 + col13 + file0 + + + line448 + col17 + file0 + + + end + + + line450 + col3 + file0 + + + line450 + col17 + file0 + + + + + + + kindcontrol + edges + + + start + + + line450 + col3 + file0 + + + line450 + col17 + file0 + + + end + + + line451 + col3 + file0 + + + line451 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line451 + col3 + file0 + + + line451 + col4 + file0 + + + end + + + line451 + col7 + file0 + + + line451 + col10 + file0 + + + + + + + kindevent + location + + line451 + col7 + file0 + + ranges + + + + line451 + col7 + file0 + + + line451 + col10 + file0 + + + + depth0 + extended_message + Assuming 'dict' is null + message + Assuming 'dict' is null + + + kindcontrol + edges + + + start + + + line451 + col7 + file0 + + + line451 + col10 + file0 + + + end + + + line453 + col3 + file0 + + + line453 + col6 + file0 + + + + + + + kindcontrol + edges + + + start + + + line453 + col3 + file0 + + + line453 + col6 + file0 + + + end + + + line454 + col3 + file0 + + + line454 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line454 + col3 + file0 + + + line454 + col4 + file0 + + + end + + + line454 + col7 + file0 + + + line454 + col10 + file0 + + + + + + + kindevent + location + + line454 + col7 + file0 + + ranges + + + + line454 + col7 + file0 + + + line454 + col10 + file0 + + + + depth0 + extended_message + Assuming 'disk' is null + message + Assuming 'disk' is null + + + kindcontrol + edges + + + start + + + line454 + col7 + file0 + + + line454 + col10 + file0 + + + end + + + line456 + col3 + file0 + + + line456 + col16 + file0 + + + + + + + kindcontrol + edges + + + start + + + line456 + col3 + file0 + + + line456 + col16 + file0 + + + end + + + line456 + col30 + file0 + + + line456 + col46 + file0 + + + + + + + kindevent + location + + line456 + col30 + file0 + + ranges + + + + line456 + col30 + file0 + + + line456 + col46 + file0 + + + + depth0 + extended_message + Object leaked: object allocated and stored into 'disk' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'disk' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'disk' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context778f70549a15e78703b4dcb3a287df33 + issue_context_kindfunction + issue_contextf10 + issue_hash_function_offset4 + location + + line456 + col30 + file0 + + ExecutedLines + + 0 + + 443 + 444 + 445 + 447 + 448 + 450 + 451 + 453 + 454 + 456 + + + + + path + + + kindcontrol + edges + + + start + + + line444 + col3 + file0 + + + line444 + col11 + file0 + + + end + + + line445 + col3 + file0 + + + line445 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line445 + col3 + file0 + + + line445 + col4 + file0 + + + end + + + line445 + col7 + file0 + + + line445 + col10 + file0 + + + + + + + kindevent + location + + line445 + col7 + file0 + + ranges + + + + line445 + col7 + file0 + + + line445 + col10 + file0 + + + + depth0 + extended_message + Assuming 'disk' is null + message + Assuming 'disk' is null + + + kindcontrol + edges + + + start + + + line445 + col7 + file0 + + + line445 + col10 + file0 + + + end + + + line447 + col3 + file0 + + + line447 + col6 + file0 + + + + + + + kindcontrol + edges + + + start + + + line447 + col3 + file0 + + + line447 + col6 + file0 + + + end + + + line448 + col3 + file0 + + + line448 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line448 + col3 + file0 + + + line448 + col4 + file0 + + + end + + + line448 + col7 + file0 + + + line448 + col10 + file0 + + + + + + + kindevent + location + + line448 + col7 + file0 + + ranges + + + + line448 + col7 + file0 + + + line448 + col10 + file0 + + + + depth0 + extended_message + Assuming 'disk' is null + message + Assuming 'disk' is null + + + kindcontrol + edges + + + start + + + line448 + col7 + file0 + + + line448 + col10 + file0 + + + end + + + line450 + col3 + file0 + + + line450 + col17 + file0 + + + + + + + kindcontrol + edges + + + start + + + line450 + col3 + file0 + + + line450 + col17 + file0 + + + end + + + line451 + col3 + file0 + + + line451 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line451 + col3 + file0 + + + line451 + col4 + file0 + + + end + + + line451 + col7 + file0 + + + line451 + col10 + file0 + + + + + + + kindevent + location + + line451 + col7 + file0 + + ranges + + + + line451 + col7 + file0 + + + line451 + col10 + file0 + + + + depth0 + extended_message + Assuming 'dict' is null + message + Assuming 'dict' is null + + + kindcontrol + edges + + + start + + + line451 + col7 + file0 + + + line451 + col10 + file0 + + + end + + + line453 + col3 + file0 + + + line453 + col6 + file0 + + + + + + + kindcontrol + edges + + + start + + + line453 + col3 + file0 + + + line453 + col6 + file0 + + + end + + + line454 + col3 + file0 + + + line454 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line454 + col3 + file0 + + + line454 + col4 + file0 + + + end + + + line454 + col7 + file0 + + + line454 + col10 + file0 + + + + + + + kindevent + location + + line454 + col7 + file0 + + ranges + + + + line454 + col7 + file0 + + + line454 + col10 + file0 + + + + depth0 + extended_message + Assuming 'disk' is null + message + Assuming 'disk' is null + + + kindcontrol + edges + + + start + + + line454 + col7 + file0 + + + line454 + col10 + file0 + + + end + + + line456 + col3 + file0 + + + line456 + col16 + file0 + + + + + + + kindcontrol + edges + + + start + + + line456 + col3 + file0 + + + line456 + col16 + file0 + + + end + + + line456 + col30 + file0 + + + line456 + col46 + file0 + + + + + + + kindevent + location + + line456 + col30 + file0 + + ranges + + + + line456 + col30 + file0 + + + line457 + col68 + file0 + + + + depth0 + extended_message + Call to function 'DADissenterCreate' returns a Core Foundation object of type 'DADissenterRef' with a +1 retain count + message + Call to function 'DADissenterCreate' returns a Core Foundation object of type 'DADissenterRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line456 + col30 + file0 + + + line456 + col46 + file0 + + + end + + + line456 + col3 + file0 + + + line456 + col16 + file0 + + + + + + + kindcontrol + edges + + + start + + + line456 + col3 + file0 + + + line456 + col16 + file0 + + + end + + + line458 + col3 + file0 + + + line458 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line458 + col3 + file0 + + + line458 + col4 + file0 + + + end + + + line458 + col7 + file0 + + + line458 + col15 + file0 + + + + + + + kindevent + location + + line458 + col7 + file0 + + ranges + + + + line458 + col7 + file0 + + + line458 + col15 + file0 + + + + depth0 + extended_message + Assuming 'dissenter' is non-null + message + Assuming 'dissenter' is non-null + + + kindcontrol + edges + + + start + + + line458 + col7 + file0 + + + line458 + col15 + file0 + + + end + + + line458 + col18 + file0 + + + line458 + col22 + file0 + + + + + + + kindevent + location + + line458 + col18 + file0 + + ranges + + + + line458 + col18 + file0 + + + line458 + col22 + file0 + + + + depth0 + extended_message + Object leaked: object allocated and stored into 'dissenter' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'dissenter' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'dissenter' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context6c188b4716e84cdc55b93d40e6c2daf3 + issue_context_kindfunction + issue_contextf10 + issue_hash_function_offset13 + location + + line458 + col18 + file0 + + ExecutedLines + + 0 + + 443 + 444 + 445 + 447 + 448 + 450 + 451 + 453 + 454 + 456 + 457 + 458 + + + + + path + + + kindcontrol + edges + + + start + + + line444 + col3 + file0 + + + line444 + col11 + file0 + + + end + + + line445 + col3 + file0 + + + line445 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line445 + col3 + file0 + + + line445 + col4 + file0 + + + end + + + line445 + col7 + file0 + + + line445 + col10 + file0 + + + + + + + kindevent + location + + line445 + col7 + file0 + + ranges + + + + line445 + col7 + file0 + + + line445 + col10 + file0 + + + + depth0 + extended_message + Assuming 'disk' is null + message + Assuming 'disk' is null + + + kindcontrol + edges + + + start + + + line445 + col7 + file0 + + + line445 + col10 + file0 + + + end + + + line447 + col3 + file0 + + + line447 + col6 + file0 + + + + + + + kindcontrol + edges + + + start + + + line447 + col3 + file0 + + + line447 + col6 + file0 + + + end + + + line448 + col3 + file0 + + + line448 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line448 + col3 + file0 + + + line448 + col4 + file0 + + + end + + + line448 + col7 + file0 + + + line448 + col10 + file0 + + + + + + + kindevent + location + + line448 + col7 + file0 + + ranges + + + + line448 + col7 + file0 + + + line448 + col10 + file0 + + + + depth0 + extended_message + Assuming 'disk' is null + message + Assuming 'disk' is null + + + kindcontrol + edges + + + start + + + line448 + col7 + file0 + + + line448 + col10 + file0 + + + end + + + line450 + col3 + file0 + + + line450 + col17 + file0 + + + + + + + kindcontrol + edges + + + start + + + line450 + col3 + file0 + + + line450 + col17 + file0 + + + end + + + line451 + col3 + file0 + + + line451 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line451 + col3 + file0 + + + line451 + col4 + file0 + + + end + + + line451 + col7 + file0 + + + line451 + col10 + file0 + + + + + + + kindevent + location + + line451 + col7 + file0 + + ranges + + + + line451 + col7 + file0 + + + line451 + col10 + file0 + + + + depth0 + extended_message + Assuming 'dict' is null + message + Assuming 'dict' is null + + + kindcontrol + edges + + + start + + + line451 + col7 + file0 + + + line451 + col10 + file0 + + + end + + + line453 + col3 + file0 + + + line453 + col6 + file0 + + + + + + + kindcontrol + edges + + + start + + + line453 + col3 + file0 + + + line453 + col6 + file0 + + + end + + + line454 + col3 + file0 + + + line454 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line454 + col3 + file0 + + + line454 + col4 + file0 + + + end + + + line454 + col7 + file0 + + + line454 + col10 + file0 + + + + + + + kindevent + location + + line454 + col7 + file0 + + ranges + + + + line454 + col7 + file0 + + + line454 + col10 + file0 + + + + depth0 + extended_message + Assuming 'disk' is null + message + Assuming 'disk' is null + + + kindcontrol + edges + + + start + + + line454 + col7 + file0 + + + line454 + col10 + file0 + + + end + + + line456 + col3 + file0 + + + line456 + col16 + file0 + + + + + + + kindcontrol + edges + + + start + + + line456 + col3 + file0 + + + line456 + col16 + file0 + + + end + + + line458 + col3 + file0 + + + line458 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line458 + col3 + file0 + + + line458 + col4 + file0 + + + end + + + line458 + col7 + file0 + + + line458 + col15 + file0 + + + + + + + kindevent + location + + line458 + col7 + file0 + + ranges + + + + line458 + col7 + file0 + + + line458 + col15 + file0 + + + + depth0 + extended_message + Assuming 'dissenter' is null + message + Assuming 'dissenter' is null + + + kindcontrol + edges + + + start + + + line458 + col7 + file0 + + + line458 + col15 + file0 + + + end + + + line460 + col3 + file0 + + + line460 + col14 + file0 + + + + + + + kindevent + location + + line460 + col26 + file0 + + ranges + + + + line460 + col26 + file0 + + + line460 + col61 + file0 + + + + depth0 + extended_message + Call to function 'DASessionCreate' returns a Core Foundation object of type 'DASessionRef' with a +1 retain count + message + Call to function 'DASessionCreate' returns a Core Foundation object of type 'DASessionRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line460 + col3 + file0 + + + line460 + col14 + file0 + + + end + + + line461 + col3 + file0 + + + line461 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line461 + col3 + file0 + + + line461 + col4 + file0 + + + end + + + line461 + col7 + file0 + + + line461 + col13 + file0 + + + + + + + kindevent + location + + line461 + col7 + file0 + + ranges + + + + line461 + col7 + file0 + + + line461 + col13 + file0 + + + + depth0 + extended_message + Assuming 'session' is non-null + message + Assuming 'session' is non-null + + + kindcontrol + edges + + + start + + + line461 + col7 + file0 + + + line461 + col13 + file0 + + + end + + + line461 + col16 + file0 + + + line461 + col20 + file0 + + + + + + + kindevent + location + + line461 + col16 + file0 + + ranges + + + + line461 + col16 + file0 + + + line461 + col20 + file0 + + + + depth0 + extended_message + Object leaked: object allocated and stored into 'session' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'session' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'session' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context35b9ac7ff198890c88d5839a898b7fea + issue_context_kindfunction + issue_contextf10 + issue_hash_function_offset17 + location + + line461 + col16 + file0 + + ExecutedLines + + 0 + + 443 + 444 + 445 + 447 + 448 + 450 + 451 + 453 + 454 + 456 + 457 + 458 + 460 + 461 + + + + + path + + + kindevent + location + + line478 + col16 + file0 + + ranges + + + + line478 + col16 + file0 + + + line478 + col31 + file0 + + + + depth0 + extended_message + Call to function 'CMCreateFooRef' returns a Core Foundation object of type 'CMFooRef' with a +1 retain count + message + Call to function 'CMCreateFooRef' returns a Core Foundation object of type 'CMFooRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line478 + col3 + file0 + + + line478 + col10 + file0 + + + end + + + line479 + col1 + file0 + + + line479 + col1 + file0 + + + + + + + kindevent + location + + line479 + col1 + file0 + + depth0 + extended_message + Object leaked: object allocated and stored into 'f' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'f' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'f' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context17d84d673b35235b52d8f8f00c1d1eea + issue_context_kindfunction + issue_contexttestLeakCoreMediaReferenceType + issue_hash_function_offset1 + location + + line479 + col1 + file0 + + ExecutedLines + + 0 + + 477 + 478 + 479 + + + + + path + + + kindevent + location + + line482 + col16 + file0 + + ranges + + + + line482 + col16 + file0 + + + line482 + col28 + file0 + + + + depth0 + extended_message + Call to function 'CMGetFooRef' returns a Core Foundation object of type 'CMFooRef' with a +0 retain count + message + Call to function 'CMGetFooRef' returns a Core Foundation object of type 'CMFooRef' with a +0 retain count + + + kindcontrol + edges + + + start + + + line482 + col3 + file0 + + + line482 + col10 + file0 + + + end + + + line483 + col3 + file0 + + + line483 + col11 + file0 + + + + + + + kindevent + location + + line483 + col3 + file0 + + ranges + + + + line483 + col13 + file0 + + + line483 + col13 + file0 + + + + depth0 + extended_message + Incorrect decrement of the reference count of an object that is not owned at this point by the caller + message + Incorrect decrement of the reference count of an object that is not owned at this point by the caller + + + descriptionIncorrect decrement of the reference count of an object that is not owned at this point by the caller + categoryMemory (Core Foundation/Objective-C/OSObject) + typeBad release + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context1702285448a953b02ab74a8eb9a610d9 + issue_context_kindfunction + issue_contexttestOverReleaseMediaReferenceType + issue_hash_function_offset2 + location + + line483 + col3 + file0 + + ExecutedLines + + 0 + + 481 + 482 + 483 + + + + + path + + + kindcontrol + edges + + + start + + + line516 + col3 + file0 + + + line516 + col13 + file0 + + + end + + + line520 + col3 + file0 + + + line520 + col21 + file0 + + + + + + + kindevent + location + + line520 + col23 + file0 + + ranges + + + + line520 + col23 + file0 + + + line520 + col57 + file0 + + + + depth0 + extended_message + Assuming 'buffer' is not equal to 'queue' + message + Assuming 'buffer' is not equal to 'queue' + + + kindevent + location + + line520 + col3 + file0 + + ranges + + + + line520 + col3 + file0 + + + line520 + col58 + file0 + + + + depth0 + extended_message + FALSE + message + FALSE + + + descriptionFALSE + categorydebug + typeChecking analyzer assumptions + check_namedebug.ExprInspection + + issue_hash_content_of_line_in_context78b71dc497a2059b950406cb2a1cfd01 + issue_context_kindfunction + issue_contexttestCMBufferQueueDequeueAndRetain + issue_hash_function_offset5 + location + + line520 + col3 + file0 + + ExecutedLines + + 0 + + 515 + 516 + 520 + + + + + path + + + kindcontrol + edges + + + start + + + line516 + col3 + file0 + + + line516 + col13 + file0 + + + end + + + line520 + col3 + file0 + + + line520 + col21 + file0 + + + + + + + kindevent + location + + line520 + col23 + file0 + + ranges + + + + line520 + col23 + file0 + + + line520 + col57 + file0 + + + + depth0 + extended_message + Assuming 'buffer' is equal to 'queue' + message + Assuming 'buffer' is equal to 'queue' + + + kindevent + location + + line520 + col3 + file0 + + ranges + + + + line520 + col3 + file0 + + + line520 + col58 + file0 + + + + depth0 + extended_message + TRUE + message + TRUE + + + descriptionTRUE + categorydebug + typeChecking analyzer assumptions + check_namedebug.ExprInspection + + issue_hash_content_of_line_in_context78b71dc497a2059b950406cb2a1cfd01 + issue_context_kindfunction + issue_contexttestCMBufferQueueDequeueAndRetain + issue_hash_function_offset5 + location + + line520 + col3 + file0 + + ExecutedLines + + 0 + + 515 + 516 + 520 + + + + + path + + + kindevent + location + + line516 + col24 + file0 + + ranges + + + + line516 + col24 + file0 + + + line516 + col59 + file0 + + + + depth0 + extended_message + Call to function 'CMBufferQueueDequeueAndRetain' returns a Core Foundation object of type 'CMBufferRef' with a +1 retain count + message + Call to function 'CMBufferQueueDequeueAndRetain' returns a Core Foundation object of type 'CMBufferRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line516 + col3 + file0 + + + line516 + col13 + file0 + + + end + + + line520 + col3 + file0 + + + line520 + col21 + file0 + + + + + + + kindevent + location + + line520 + col23 + file0 + + ranges + + + + line520 + col23 + file0 + + + line520 + col57 + file0 + + + + depth0 + extended_message + Assuming 'buffer' is not equal to 'queue' + message + Assuming 'buffer' is not equal to 'queue' + + + kindevent + location + + line520 + col3 + file0 + + ranges + + + + line520 + col3 + file0 + + + line520 + col58 + file0 + + + + depth0 + extended_message + Object leaked: object allocated and stored into 'buffer' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'buffer' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'buffer' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context402566b4ddf1683dac1aefc1ab3e76e9 + issue_context_kindfunction + issue_contexttestCMBufferQueueDequeueAndRetain + issue_hash_function_offset1 + location + + line520 + col3 + file0 + + ExecutedLines + + 0 + + 515 + 516 + 520 + + + + + path + + + kindcontrol + edges + + + start + + + line527 + col3 + file0 + + + line527 + col19 + file0 + + + end + + + line540 + col3 + file0 + + + line540 + col4 + file0 + + + + + + + kindevent + location + + line540 + col22 + file0 + + ranges + + + + line540 + col22 + file0 + + + line540 + col49 + file0 + + + + depth0 + extended_message + Call to function 'CFArrayGetValueAtIndex' returns a Core Foundation object of type 'const void *' with a +0 retain count + message + Call to function 'CFArrayGetValueAtIndex' returns a Core Foundation object of type 'const void *' with a +0 retain count + + + kindcontrol + edges + + + start + + + line540 + col3 + file0 + + + line540 + col4 + file0 + + + end + + + line546 + col3 + file0 + + + line546 + col11 + file0 + + + + + + + kindevent + location + + line546 + col3 + file0 + + ranges + + + + line546 + col13 + file0 + + + line546 + col14 + file0 + + + + depth0 + extended_message + Incorrect decrement of the reference count of an object that is not owned at this point by the caller + message + Incorrect decrement of the reference count of an object that is not owned at this point by the caller + + + descriptionIncorrect decrement of the reference count of an object that is not owned at this point by the caller + categoryMemory (Core Foundation/Objective-C/OSObject) + typeBad release + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context143ef5974bfece95e9894da5250aaff0 + issue_context_kindfunction + issue_contextf11 + issue_hash_function_offset21 + location + + line546 + col3 + file0 + + ExecutedLines + + 0 + + 525 + 527 + 530 + 531 + 534 + 537 + 540 + 543 + 546 + + + + + path + + + kindevent + location + + line554 + col17 + file0 + + ranges + + + + line554 + col17 + file0 + + + line554 + col29 + file0 + + + + depth0 + extended_message + Call to function 'MyCreateFun' returns a Core Foundation object of type 'CFTypeRef' with a +1 retain count + message + Call to function 'MyCreateFun' returns a Core Foundation object of type 'CFTypeRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line554 + col3 + file0 + + + line554 + col11 + file0 + + + end + + + line555 + col1 + file0 + + + line555 + col1 + file0 + + + + + + + kindevent + location + + line555 + col1 + file0 + + depth0 + extended_message + Object leaked: object allocated and stored into 'o' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'o' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'o' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_contextaf4ad99c5fb565d82e1b4848aaca4e24 + issue_context_kindfunction + issue_contextf12 + issue_hash_function_offset1 + location + + line555 + col1 + file0 + + ExecutedLines + + 0 + + 553 + 554 + 555 + + + + + path + + + kindevent + location + + line563 + col25 + file0 + + ranges + + + + line563 + col25 + file0 + + + line563 + col75 + file0 + + + + depth0 + extended_message + Call to function 'CFArrayCreateMutable' returns a Core Foundation object of type 'CFMutableArrayRef' with a +1 retain count + message + Call to function 'CFArrayCreateMutable' returns a Core Foundation object of type 'CFMutableArrayRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line563 + col3 + file0 + + + line563 + col19 + file0 + + + end + + + line564 + col3 + file0 + + + line564 + col3 + file0 + + + + + + + kindevent + location + + line564 + col3 + file0 + + ranges + + + + line564 + col3 + file0 + + + line564 + col22 + file0 + + + + + line564 + col4 + file0 + + + line564 + col9 + file0 + + + + depth0 + extended_message + Object autoreleased + message + Object autoreleased + + + kindcontrol + edges + + + start + + + line564 + col3 + file0 + + + line564 + col3 + file0 + + + end + + + line565 + col3 + file0 + + + line565 + col3 + file0 + + + + + + + kindevent + location + + line565 + col3 + file0 + + ranges + + + + line565 + col3 + file0 + + + line565 + col22 + file0 + + + + + line565 + col4 + file0 + + + line565 + col9 + file0 + + + + depth0 + extended_message + Object autoreleased + message + Object autoreleased + + + kindcontrol + edges + + + start + + + line565 + col3 + file0 + + + line565 + col3 + file0 + + + end + + + line566 + col1 + file0 + + + line566 + col1 + file0 + + + + + + + kindevent + location + + line566 + col1 + file0 + + depth0 + extended_message + Object was autoreleased 2 times but the object has a +1 retain count + message + Object was autoreleased 2 times but the object has a +1 retain count + + + descriptionObject autoreleased too many times + categoryMemory (Core Foundation/Objective-C/OSObject) + typeObject autoreleased too many times + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context58a0b3f8332f42561f89b11f6eb5e91f + issue_context_kindfunction + issue_contextf13_autorelease_b + issue_hash_function_offset4 + location + + line566 + col1 + file0 + + ExecutedLines + + 0 + + 562 + 563 + 564 + 565 + 566 + + + + + path + + + kindevent + location + + line569 + col25 + file0 + + ranges + + + + line569 + col25 + file0 + + + line569 + col75 + file0 + + + + depth0 + extended_message + Call to function 'CFArrayCreateMutable' returns a Core Foundation object of type 'CFMutableArrayRef' with a +1 retain count + message + Call to function 'CFArrayCreateMutable' returns a Core Foundation object of type 'CFMutableArrayRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line569 + col3 + file0 + + + line569 + col19 + file0 + + + end + + + line570 + col3 + file0 + + + line570 + col3 + file0 + + + + + + + kindevent + location + + line570 + col3 + file0 + + ranges + + + + line570 + col3 + file0 + + + line570 + col22 + file0 + + + + + line570 + col4 + file0 + + + line570 + col9 + file0 + + + + depth0 + extended_message + Object autoreleased + message + Object autoreleased + + + kindcontrol + edges + + + start + + + line570 + col3 + file0 + + + line570 + col3 + file0 + + + end + + + line571 + col3 + file0 + + + line571 + col3 + file0 + + + + + + + kindevent + location + + line571 + col3 + file0 + + ranges + + + + line571 + col3 + file0 + + + line571 + col22 + file0 + + + + + line571 + col4 + file0 + + + line571 + col9 + file0 + + + + depth0 + extended_message + Object autoreleased + message + Object autoreleased + + + kindcontrol + edges + + + start + + + line571 + col3 + file0 + + + line571 + col3 + file0 + + + end + + + line572 + col3 + file0 + + + line572 + col8 + file0 + + + + + + + kindevent + location + + line572 + col3 + file0 + + ranges + + + + line572 + col3 + file0 + + + line572 + col10 + file0 + + + + depth0 + extended_message + Object was autoreleased 2 times but the object has a +0 retain count + message + Object was autoreleased 2 times but the object has a +0 retain count + + + descriptionObject autoreleased too many times + categoryMemory (Core Foundation/Objective-C/OSObject) + typeObject autoreleased too many times + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context612dc6574d54c8010703a9776d8a4a0a + issue_context_kindfunction + issue_contextf13_autorelease_c + issue_hash_function_offset4 + location + + line572 + col3 + file0 + + ExecutedLines + + 0 + + 568 + 569 + 570 + 571 + 572 + + + + + path + + + kindevent + location + + line576 + col25 + file0 + + ranges + + + + line576 + col25 + file0 + + + line576 + col75 + file0 + + + + depth0 + extended_message + Call to function 'CFArrayCreateMutable' returns a Core Foundation object of type 'CFMutableArrayRef' with a +1 retain count + message + Call to function 'CFArrayCreateMutable' returns a Core Foundation object of type 'CFMutableArrayRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line576 + col3 + file0 + + + line576 + col19 + file0 + + + end + + + line577 + col3 + file0 + + + line577 + col3 + file0 + + + + + + + kindevent + location + + line577 + col3 + file0 + + ranges + + + + line577 + col3 + file0 + + + line577 + col22 + file0 + + + + + line577 + col4 + file0 + + + line577 + col9 + file0 + + + + depth0 + extended_message + Object autoreleased + message + Object autoreleased + + + kindcontrol + edges + + + start + + + line577 + col3 + file0 + + + line577 + col3 + file0 + + + end + + + line578 + col3 + file0 + + + line578 + col3 + file0 + + + + + + + kindevent + location + + line578 + col3 + file0 + + ranges + + + + line578 + col3 + file0 + + + line578 + col22 + file0 + + + + + line578 + col4 + file0 + + + line578 + col9 + file0 + + + + depth0 + extended_message + Object autoreleased + message + Object autoreleased + + + kindcontrol + edges + + + start + + + line578 + col3 + file0 + + + line578 + col3 + file0 + + + end + + + line579 + col3 + file0 + + + line579 + col19 + file0 + + + + + + + kindcontrol + edges + + + start + + + line579 + col3 + file0 + + + line579 + col19 + file0 + + + end + + + line579 + col25 + file0 + + + line579 + col44 + file0 + + + + + + + kindevent + location + + line579 + col25 + file0 + + ranges + + + + line579 + col25 + file0 + + + line579 + col75 + file0 + + + + depth0 + extended_message + Object was autoreleased 2 times but the object has a +1 retain count + message + Object was autoreleased 2 times but the object has a +1 retain count + + + descriptionObject autoreleased too many times + categoryMemory (Core Foundation/Objective-C/OSObject) + typeObject autoreleased too many times + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_contextc57037289bc3acc586de325df25951ed + issue_context_kindfunction + issue_contextf13_autorelease_d + issue_hash_function_offset4 + location + + line579 + col25 + file0 + + ExecutedLines + + 0 + + 575 + 576 + 577 + 578 + 579 + + + + + path + + + kindevent + location + + line587 + col3 + file0 + + ranges + + + + line587 + col3 + file0 + + + line587 + col53 + file0 + + + + depth0 + extended_message + Call to function 'CFArrayCreateMutable' returns a Core Foundation object of type 'CFMutableArrayRef' with a +1 retain count + message + Call to function 'CFArrayCreateMutable' returns a Core Foundation object of type 'CFMutableArrayRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line587 + col3 + file0 + + + line587 + col22 + file0 + + + end + + + line588 + col1 + file0 + + + line588 + col1 + file0 + + + + + + + kindevent + location + + line588 + col1 + file0 + + depth0 + extended_message + Object leaked: allocated object of type 'CFMutableArrayRef' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: allocated object of type 'CFMutableArrayRef' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object of type 'CFMutableArrayRef' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context6abb479bc4c7782a125d680fddf825ef + issue_context_kindfunction + issue_contextf14_leakimmediately + issue_hash_function_offset1 + location + + line588 + col1 + file0 + + ExecutedLines + + 0 + + 586 + 587 + 588 + + + + + path + + + kindcontrol + edges + + + start + + + line602 + col3 + file0 + + + line602 + col4 + file0 + + + end + + + line602 + col7 + file0 + + + line602 + col7 + file0 + + + + + + + kindevent + location + + line602 + col7 + file0 + + ranges + + + + line602 + col7 + file0 + + + line602 + col7 + file0 + + + + depth0 + extended_message + Assuming 'p' is null + message + Assuming 'p' is null + + + kindcontrol + edges + + + start + + + line602 + col7 + file0 + + + line602 + col7 + file0 + + + end + + + line605 + col3 + file0 + + + line605 + col8 + file0 + + + + + + + kindcontrol + edges + + + start + + + line605 + col3 + file0 + + + line605 + col8 + file0 + + + end + + + line605 + col11 + file0 + + + line605 + col11 + file0 + + + + + + + kindcontrol + edges + + + start + + + line605 + col11 + file0 + + + line605 + col11 + file0 + + + end + + + line607 + col5 + file0 + + + line607 + col13 + file0 + + + + + + + kindevent + location + + line607 + col5 + file0 + + ranges + + + + line607 + col15 + file0 + + + line607 + col15 + file0 + + + + depth0 + extended_message + Null pointer argument in call to CFRelease + message + Null pointer argument in call to CFRelease + + + descriptionNull pointer argument in call to CFRelease + categoryAPI Misuse (Apple) + typenull passed to CF memory management function + check_nameosx.coreFoundation.CFRetainRelease + + issue_hash_content_of_line_in_contexte7e2ba205af363f2c4cec7d01dcb6d6c + issue_context_kindfunction + issue_contextf16 + issue_hash_function_offset6 + location + + line607 + col5 + file0 + + ExecutedLines + + 0 + + 601 + 602 + 605 + 606 + 607 + + + + + path + + + kindcontrol + edges + + + start + + + line602 + col3 + file0 + + + line602 + col4 + file0 + + + end + + + line602 + col7 + file0 + + + line602 + col7 + file0 + + + + + + + kindevent + location + + line602 + col7 + file0 + + ranges + + + + line602 + col7 + file0 + + + line602 + col7 + file0 + + + + depth0 + extended_message + Assuming 'p' is null + message + Assuming 'p' is null + + + kindcontrol + edges + + + start + + + line602 + col7 + file0 + + + line602 + col7 + file0 + + + end + + + line605 + col3 + file0 + + + line605 + col8 + file0 + + + + + + + kindcontrol + edges + + + start + + + line605 + col3 + file0 + + + line605 + col8 + file0 + + + end + + + line605 + col11 + file0 + + + line605 + col11 + file0 + + + + + + + kindcontrol + edges + + + start + + + line605 + col11 + file0 + + + line605 + col11 + file0 + + + end + + + line610 + col5 + file0 + + + line610 + col12 + file0 + + + + + + + kindevent + location + + line610 + col5 + file0 + + ranges + + + + line610 + col14 + file0 + + + line610 + col14 + file0 + + + + depth0 + extended_message + Null pointer argument in call to CFRetain + message + Null pointer argument in call to CFRetain + + + descriptionNull pointer argument in call to CFRetain + categoryAPI Misuse (Apple) + typenull passed to CF memory management function + check_nameosx.coreFoundation.CFRetainRelease + + issue_hash_content_of_line_in_context64f4a3367d5d8e832ca8a23ca4d72717 + issue_context_kindfunction + issue_contextf16 + issue_hash_function_offset9 + location + + line610 + col5 + file0 + + ExecutedLines + + 0 + + 601 + 602 + 605 + 609 + 610 + + + + + path + + + kindcontrol + edges + + + start + + + line602 + col3 + file0 + + + line602 + col4 + file0 + + + end + + + line602 + col7 + file0 + + + line602 + col7 + file0 + + + + + + + kindevent + location + + line602 + col7 + file0 + + ranges + + + + line602 + col7 + file0 + + + line602 + col7 + file0 + + + + depth0 + extended_message + Assuming 'p' is null + message + Assuming 'p' is null + + + kindcontrol + edges + + + start + + + line602 + col7 + file0 + + + line602 + col7 + file0 + + + end + + + line605 + col3 + file0 + + + line605 + col8 + file0 + + + + + + + kindcontrol + edges + + + start + + + line605 + col3 + file0 + + + line605 + col8 + file0 + + + end + + + line605 + col11 + file0 + + + line605 + col11 + file0 + + + + + + + kindcontrol + edges + + + start + + + line605 + col11 + file0 + + + line605 + col11 + file0 + + + end + + + line613 + col5 + file0 + + + line613 + col21 + file0 + + + + + + + kindevent + location + + line613 + col5 + file0 + + ranges + + + + line613 + col23 + file0 + + + line613 + col23 + file0 + + + + depth0 + extended_message + Null pointer argument in call to CFMakeCollectable + message + Null pointer argument in call to CFMakeCollectable + + + descriptionNull pointer argument in call to CFMakeCollectable + categoryAPI Misuse (Apple) + typenull passed to CF memory management function + check_nameosx.coreFoundation.CFRetainRelease + + issue_hash_content_of_line_in_context61123dbb677396de5abbdd778c399140 + issue_context_kindfunction + issue_contextf16 + issue_hash_function_offset12 + location + + line613 + col5 + file0 + + ExecutedLines + + 0 + + 601 + 602 + 605 + 612 + 613 + + + + + path + + + kindcontrol + edges + + + start + + + line602 + col3 + file0 + + + line602 + col4 + file0 + + + end + + + line602 + col7 + file0 + + + line602 + col7 + file0 + + + + + + + kindevent + location + + line602 + col7 + file0 + + ranges + + + + line602 + col7 + file0 + + + line602 + col7 + file0 + + + + depth0 + extended_message + Assuming 'p' is null + message + Assuming 'p' is null + + + kindcontrol + edges + + + start + + + line602 + col7 + file0 + + + line602 + col7 + file0 + + + end + + + line605 + col3 + file0 + + + line605 + col8 + file0 + + + + + + + kindcontrol + edges + + + start + + + line605 + col3 + file0 + + + line605 + col8 + file0 + + + end + + + line605 + col11 + file0 + + + line605 + col11 + file0 + + + + + + + kindcontrol + edges + + + start + + + line605 + col11 + file0 + + + line605 + col11 + file0 + + + end + + + line616 + col5 + file0 + + + line616 + col17 + file0 + + + + + + + kindevent + location + + line616 + col5 + file0 + + ranges + + + + line616 + col19 + file0 + + + line616 + col19 + file0 + + + + depth0 + extended_message + Null pointer argument in call to CFAutorelease + message + Null pointer argument in call to CFAutorelease + + + descriptionNull pointer argument in call to CFAutorelease + categoryAPI Misuse (Apple) + typenull passed to CF memory management function + check_nameosx.coreFoundation.CFRetainRelease + + issue_hash_content_of_line_in_context965bca78fe04bfa55b6ea428da3c20e3 + issue_context_kindfunction + issue_contextf16 + issue_hash_function_offset15 + location + + line616 + col5 + file0 + + ExecutedLines + + 0 + + 601 + 602 + 605 + 615 + 616 + + + + + path + + + kindevent + location + + line656 + col10 + file0 + + ranges + + + + line656 + col10 + file0 + + + line656 + col32 + file0 + + + + depth0 + extended_message + Call to function 'isl_basic_map_cow' returns an object of type 'isl_basic_map *' with a +1 retain count + message + Call to function 'isl_basic_map_cow' returns an object of type 'isl_basic_map *' with a +1 retain count + + + kindcontrol + edges + + + start + + + line656 + col3 + file0 + + + line656 + col6 + file0 + + + end + + + line657 + col1 + file0 + + + line657 + col1 + file0 + + + + + + + kindevent + location + + line657 + col1 + file0 + + depth0 + extended_message + Object leaked: object allocated and stored into 'bmap' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'bmap' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'bmap' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context2cfebefee7b63ce3954419e571be4f63 + issue_context_kindfunction + issue_contextf18 + issue_hash_function_offset2 + location + + line657 + col1 + file0 + + ExecutedLines + + 0 + + 654 + 656 + 657 + + + + + path + + + kindevent + location + + line682 + col17 + file0 + + ranges + + + + line682 + col17 + file0 + + + line682 + col55 + file0 + + + + depth0 + extended_message + Method returns an Objective-C object with a +0 retain count + message + Method returns an Objective-C object with a +0 retain count + + + kindcontrol + edges + + + start + + + line682 + col3 + file0 + + + line682 + col10 + file0 + + + end + + + line683 + col3 + file0 + + + line683 + col8 + file0 + + + + + + + kindevent + location + + line683 + col3 + file0 + + ranges + + + + line683 + col3 + file0 + + + line683 + col10 + file0 + + + + depth0 + extended_message + Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected + message + Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected + + + descriptionObject with a +0 retain count returned to caller where a +1 (owning) retain count is expected + categoryMemory (Core Foundation/Objective-C/OSObject) + typeMethod should return an owned object + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_contextdcd3becc58a149abe6ade5598138d3dd + issue_context_kindObjective-C method + issue_contextnewString + issue_hash_function_offset2 + location + + line683 + col3 + file0 + + ExecutedLines + + 0 + + 681 + 682 + 683 + + + + + path + + + kindevent + location + + line696 + col20 + file0 + + ranges + + + + line696 + col20 + file0 + + + line696 + col63 + file0 + + + + depth0 + extended_message + Method returns an instance of NSString with a +1 retain count + message + Method returns an instance of NSString with a +1 retain count + + + kindcontrol + edges + + + start + + + line696 + col3 + file0 + + + line696 + col10 + file0 + + + end + + + line703 + col3 + file0 + + + line703 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line703 + col3 + file0 + + + line703 + col4 + file0 + + + end + + + line703 + col6 + file0 + + + line703 + col6 + file0 + + + + + + + kindevent + location + + line703 + col6 + file0 + + ranges + + + + line703 + col6 + file0 + + + line703 + col10 + file0 + + + + depth0 + extended_message + Assuming 'name' is nil + message + Assuming 'name' is nil + + + kindcontrol + edges + + + start + + + line703 + col6 + file0 + + + line703 + col6 + file0 + + + end + + + line704 + col5 + file0 + + + line704 + col10 + file0 + + + + + + + kindevent + location + + line704 + col5 + file0 + + ranges + + + + line704 + col5 + file0 + + + line704 + col10 + file0 + + + + depth0 + extended_message + Object leaked: object allocated and stored into 'kind' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'kind' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'kind' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context6688c9cb12f0c76ec80eb03b1d2eddf8 + issue_context_kindfunction + issue_contextrdar_6659160 + issue_hash_function_offset5 + location + + line704 + col5 + file0 + + ExecutedLines + + 0 + + 690 + 691 + 696 + 702 + 703 + 704 + + + + + path + + + kindcontrol + edges + + + start + + + line696 + col3 + file0 + + + line696 + col10 + file0 + + + end + + + line703 + col3 + file0 + + + line703 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line703 + col3 + file0 + + + line703 + col4 + file0 + + + end + + + line703 + col6 + file0 + + + line703 + col6 + file0 + + + + + + + kindevent + location + + line703 + col6 + file0 + + ranges + + + + line703 + col6 + file0 + + + line703 + col10 + file0 + + + + depth0 + extended_message + Assuming 'name' is non-nil + message + Assuming 'name' is non-nil + + + kindcontrol + edges + + + start + + + line703 + col6 + file0 + + + line703 + col6 + file0 + + + end + + + line706 + col3 + file0 + + + line706 + col7 + file0 + + + + + + + kindevent + location + + line706 + col3 + file0 + + ranges + + + + line706 + col3 + file0 + + + line706 + col19 + file0 + + + + depth0 + extended_message + 'kindC' initialized to a null pointer value + message + 'kindC' initialized to a null pointer value + + + kindcontrol + edges + + + start + + + line706 + col3 + file0 + + + line706 + col7 + file0 + + + end + + + line714 + col3 + file0 + + + line714 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line714 + col3 + file0 + + + line714 + col4 + file0 + + + end + + + line714 + col6 + file0 + + + line714 + col9 + file0 + + + + + + + kindevent + location + + line714 + col6 + file0 + + ranges + + + + line714 + col6 + file0 + + + line714 + col9 + file0 + + + + depth0 + extended_message + Assuming 'kind' is nil + message + Assuming 'kind' is nil + + + kindcontrol + edges + + + start + + + line714 + col6 + file0 + + + line714 + col9 + file0 + + + end + + + line716 + col3 + file0 + + + line716 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line716 + col3 + file0 + + + line716 + col4 + file0 + + + end + + + line717 + col5 + file0 + + + line717 + col9 + file0 + + + + + + + kindcontrol + edges + + + start + + + line717 + col5 + file0 + + + line717 + col9 + file0 + + + end + + + line718 + col3 + file0 + + + line718 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line718 + col3 + file0 + + + line718 + col4 + file0 + + + end + + + line718 + col13 + file0 + + + line718 + col17 + file0 + + + + + + + kindevent + location + + line718 + col13 + file0 + + ranges + + + + line718 + col13 + file0 + + + line718 + col17 + file0 + + + + depth0 + extended_message + Array access (from variable 'kindC') results in a null pointer dereference + message + Array access (from variable 'kindC') results in a null pointer dereference + + + descriptionArray access (from variable 'kindC') results in a null pointer dereference + categoryLogic error + typeDereference of null pointer + check_namecore.NullDereference + + issue_hash_content_of_line_in_context2824c4e1d4ab13c3ae5a0ebb2aa4ed89 + issue_context_kindfunction + issue_contextrdar_6659160 + issue_hash_function_offset27 + location + + line718 + col13 + file0 + + ExecutedLines + + 0 + + 690 + 691 + 696 + 702 + 703 + 706 + 707 + 714 + 716 + 717 + 718 + + + + + path + + + kindcontrol + edges + + + start + + + line696 + col3 + file0 + + + line696 + col10 + file0 + + + end + + + line702 + col3 + file0 + + + line702 + col10 + file0 + + + + + + + kindevent + location + + line702 + col20 + file0 + + ranges + + + + line702 + col20 + file0 + + + line702 + col57 + file0 + + + + depth0 + extended_message + Method returns an Objective-C object with a +0 retain count + message + Method returns an Objective-C object with a +0 retain count + + + kindcontrol + edges + + + start + + + line702 + col3 + file0 + + + line702 + col10 + file0 + + + end + + + line703 + col3 + file0 + + + line703 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line703 + col3 + file0 + + + line703 + col4 + file0 + + + end + + + line703 + col6 + file0 + + + line703 + col6 + file0 + + + + + + + kindevent + location + + line703 + col6 + file0 + + ranges + + + + line703 + col6 + file0 + + + line703 + col10 + file0 + + + + depth0 + extended_message + Assuming 'name' is non-nil + message + Assuming 'name' is non-nil + + + kindcontrol + edges + + + start + + + line703 + col6 + file0 + + + line703 + col6 + file0 + + + end + + + line706 + col3 + file0 + + + line706 + col7 + file0 + + + + + + + kindcontrol + edges + + + start + + + line706 + col3 + file0 + + + line706 + col7 + file0 + + + end + + + line714 + col3 + file0 + + + line714 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line714 + col3 + file0 + + + line714 + col4 + file0 + + + end + + + line714 + col6 + file0 + + + line714 + col9 + file0 + + + + + + + kindevent + location + + line714 + col6 + file0 + + ranges + + + + line714 + col6 + file0 + + + line714 + col9 + file0 + + + + depth0 + extended_message + Assuming 'kind' is non-nil + message + Assuming 'kind' is non-nil + + + kindcontrol + edges + + + start + + + line714 + col6 + file0 + + + line714 + col9 + file0 + + + end + + + line715 + col5 + file0 + + + line715 + col9 + file0 + + + + + + + kindcontrol + edges + + + start + + + line715 + col5 + file0 + + + line715 + col9 + file0 + + + end + + + line716 + col3 + file0 + + + line716 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line716 + col3 + file0 + + + line716 + col4 + file0 + + + end + + + line717 + col5 + file0 + + + line717 + col9 + file0 + + + + + + + kindcontrol + edges + + + start + + + line717 + col5 + file0 + + + line717 + col9 + file0 + + + end + + + line718 + col3 + file0 + + + line718 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line718 + col3 + file0 + + + line718 + col4 + file0 + + + end + + + line718 + col6 + file0 + + + line718 + col6 + file0 + + + + + + + kindevent + location + + line718 + col6 + file0 + + ranges + + + + line718 + col6 + file0 + + + line718 + col21 + file0 + + + + depth0 + extended_message + Assuming the condition is false + message + Assuming the condition is false + + + kindcontrol + edges + + + start + + + line718 + col6 + file0 + + + line718 + col6 + file0 + + + end + + + line720 + col3 + file0 + + + line720 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line720 + col3 + file0 + + + line720 + col4 + file0 + + + end + + + line720 + col6 + file0 + + + line720 + col6 + file0 + + + + + + + kindevent + location + + line720 + col6 + file0 + + ranges + + + + line720 + col6 + file0 + + + line720 + col21 + file0 + + + + depth0 + extended_message + Assuming the condition is false + message + Assuming the condition is false + + + kindcontrol + edges + + + start + + + line720 + col6 + file0 + + + line720 + col6 + file0 + + + end + + + line723 + col3 + file0 + + + line723 + col3 + file0 + + + + + + + kindcontrol + edges + + + start + + + line723 + col3 + file0 + + + line723 + col3 + file0 + + + end + + + line724 + col3 + file0 + + + line724 + col3 + file0 + + + + + + + kindevent + location + + line724 + col3 + file0 + + ranges + + + + line724 + col4 + file0 + + + line724 + col7 + file0 + + + + depth0 + extended_message + Incorrect decrement of the reference count of an object that is not owned at this point by the caller + message + Incorrect decrement of the reference count of an object that is not owned at this point by the caller + + + descriptionIncorrect decrement of the reference count of an object that is not owned at this point by the caller + categoryMemory (Core Foundation/Objective-C/OSObject) + typeBad release + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_contextd04966e9b8e981d8f69bf03823253033 + issue_context_kindfunction + issue_contextrdar_6659160 + issue_hash_function_offset33 + location + + line724 + col3 + file0 + + ExecutedLines + + 0 + + 690 + 691 + 696 + 702 + 703 + 706 + 707 + 714 + 715 + 716 + 717 + 718 + 720 + 723 + 724 + + + + + path + + + kindevent + location + + line746 + col12 + file0 + + ranges + + + + line746 + col12 + file0 + + + line746 + col34 + file0 + + + + depth0 + extended_message + Method returns an instance of NSString with a +1 retain count + message + Method returns an instance of NSString with a +1 retain count + + + kindcontrol + edges + + + start + + + line746 + col3 + file0 + + + line746 + col4 + file0 + + + end + + + line747 + col3 + file0 + + + line747 + col3 + file0 + + + + + + + kindevent + location + + line747 + col3 + file0 + + ranges + + + + line747 + col3 + file0 + + + line747 + col15 + file0 + + + + + line747 + col4 + file0 + + + line747 + col6 + file0 + + + + depth0 + extended_message + Object released by directly sending the '-dealloc' message + message + Object released by directly sending the '-dealloc' message + + + kindcontrol + edges + + + start + + + line747 + col3 + file0 + + + line747 + col3 + file0 + + + end + + + line748 + col3 + file0 + + + line748 + col3 + file0 + + + + + + + kindevent + location + + line748 + col3 + file0 + + ranges + + + + line748 + col4 + file0 + + + line748 + col6 + file0 + + + + depth0 + extended_message + Reference-counted object is used after it is released + message + Reference-counted object is used after it is released + + + descriptionReference-counted object is used after it is released + categoryMemory (Core Foundation/Objective-C/OSObject) + typeUse-after-release + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context1b35183a6aca4df5a8732c8da94e3205 + issue_context_kindfunction + issue_contextpr3820_ReleaseAfterDealloc + issue_hash_function_offset3 + location + + line748 + col3 + file0 + + ExecutedLines + + 0 + + 744 + 745 + 746 + 747 + 748 + + + + + path + + + kindcontrol + edges + + + start + + + line754 + col3 + file0 + + + line754 + col7 + file0 + + + end + + + line755 + col3 + file0 + + + line755 + col4 + file0 + + + + + + + kindevent + location + + line755 + col12 + file0 + + ranges + + + + line755 + col12 + file0 + + + line755 + col34 + file0 + + + + depth0 + extended_message + Method returns an instance of NSString with a +1 retain count + message + Method returns an instance of NSString with a +1 retain count + + + kindcontrol + edges + + + start + + + line755 + col3 + file0 + + + line755 + col4 + file0 + + + end + + + line756 + col3 + file0 + + + line756 + col3 + file0 + + + + + + + kindevent + location + + line756 + col3 + file0 + + ranges + + + + line756 + col3 + file0 + + + line756 + col15 + file0 + + + + + line756 + col4 + file0 + + + line756 + col6 + file0 + + + + depth0 + extended_message + Object released + message + Object released + + + kindcontrol + edges + + + start + + + line756 + col3 + file0 + + + line756 + col3 + file0 + + + end + + + line757 + col3 + file0 + + + line757 + col3 + file0 + + + + + + + kindevent + location + + line757 + col3 + file0 + + ranges + + + + line757 + col4 + file0 + + + line757 + col6 + file0 + + + + depth0 + extended_message + Reference-counted object is used after it is released + message + Reference-counted object is used after it is released + + + descriptionReference-counted object is used after it is released + categoryMemory (Core Foundation/Objective-C/OSObject) + typeUse-after-release + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context54f2bd1534fa675b58c4f8eef3120373 + issue_context_kindfunction + issue_contextpr3820_DeallocAfterRelease + issue_hash_function_offset4 + location + + line757 + col3 + file0 + + ExecutedLines + + 0 + + 752 + 753 + 754 + 755 + 756 + 757 + + + + + path + + + kindcontrol + edges + + + start + + + line809 + col2 + file0 + + + line809 + col20 + file0 + + + end + + + line809 + col31 + file0 + + + line809 + col31 + file0 + + + + + + + kindevent + location + + line809 + col31 + file0 + + ranges + + + + line809 + col31 + file0 + + + line809 + col76 + file0 + + + + depth0 + extended_message + Method returns an Objective-C object with a +0 retain count + message + Method returns an Objective-C object with a +0 retain count + + + kindevent + location + + line809 + col30 + file0 + + ranges + + + + line809 + col30 + file0 + + + line809 + col84 + file0 + + + + + line809 + col31 + file0 + + + line809 + col76 + file0 + + + + depth0 + extended_message + Reference count incremented. The object now has a +1 retain count + message + Reference count incremented. The object now has a +1 retain count + + + kindcontrol + edges + + + start + + + line809 + col30 + file0 + + + line809 + col30 + file0 + + + end + + + line809 + col2 + file0 + + + line809 + col20 + file0 + + + + + + + kindcontrol + edges + + + start + + + line809 + col2 + file0 + + + line809 + col20 + file0 + + + end + + + line813 + col2 + file0 + + + line813 + col6 + file0 + + + + + + + kindcontrol + edges + + + start + + + line813 + col2 + file0 + + + line813 + col6 + file0 + + + end + + + line814 + col1 + file0 + + + line814 + col1 + file0 + + + + + + + kindevent + location + + line814 + col1 + file0 + + depth0 + extended_message + Object leaked: object allocated and stored into 'dict' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'dict' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'dict' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context055e6f3413539276fedeac241fccd9b8 + issue_context_kindObjective-C method + issue_contextapplicationDidFinishLaunching: + issue_hash_function_offset1 + location + + line814 + col1 + file0 + + ExecutedLines + + 0 + + 808 + 809 + 811 + 813 + 814 + + + + + path + + + kindcontrol + edges + + + start + + + line821 + col2 + file0 + + + line821 + col20 + file0 + + + end + + + line821 + col31 + file0 + + + line821 + col31 + file0 + + + + + + + kindevent + location + + line821 + col31 + file0 + + ranges + + + + line821 + col31 + file0 + + + line821 + col76 + file0 + + + + depth0 + extended_message + Method returns an Objective-C object with a +0 retain count + message + Method returns an Objective-C object with a +0 retain count + + + kindevent + location + + line821 + col30 + file0 + + ranges + + + + line821 + col30 + file0 + + + line821 + col84 + file0 + + + + + line821 + col31 + file0 + + + line821 + col76 + file0 + + + + depth0 + extended_message + Reference count incremented. The object now has a +1 retain count + message + Reference count incremented. The object now has a +1 retain count + + + kindcontrol + edges + + + start + + + line821 + col30 + file0 + + + line821 + col30 + file0 + + + end + + + line821 + col2 + file0 + + + line821 + col20 + file0 + + + + + + + kindcontrol + edges + + + start + + + line821 + col2 + file0 + + + line821 + col20 + file0 + + + end + + + line822 + col2 + file0 + + + line822 + col3 + file0 + + + + + + + kindcontrol + edges + + + start + + + line822 + col2 + file0 + + + line822 + col3 + file0 + + + end + + + line822 + col6 + file0 + + + line822 + col11 + file0 + + + + + + + kindevent + location + + line822 + col6 + file0 + + ranges + + + + line822 + col6 + file0 + + + line822 + col11 + file0 + + + + depth0 + extended_message + Assuming the condition is false + message + Assuming the condition is false + + + kindcontrol + edges + + + start + + + line822 + col6 + file0 + + + line822 + col11 + file0 + + + end + + + line824 + col1 + file0 + + + line824 + col1 + file0 + + + + + + + kindevent + location + + line824 + col1 + file0 + + depth0 + extended_message + Object leaked: object allocated and stored into 'dict' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'dict' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'dict' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context444f6019b048a95dd71c6be49ecb73ff + issue_context_kindObjective-C method + issue_contextradar10102244 + issue_hash_function_offset1 + location + + line824 + col1 + file0 + + ExecutedLines + + 0 + + 820 + 821 + 822 + 824 + + + + + path + + + kindcontrol + edges + + + start + + + line832 + col3 + file0 + + + line832 + col19 + file0 + + + end + + + line833 + col3 + file0 + + + line833 + col9 + file0 + + + + + + + kindevent + location + + line833 + col20 + file0 + + ranges + + + + line833 + col20 + file0 + + + line833 + col34 + file0 + + + + depth0 + extended_message + Method returns an Objective-C object with a +0 retain count + message + Method returns an Objective-C object with a +0 retain count + + + kindcontrol + edges + + + start + + + line833 + col3 + file0 + + + line833 + col9 + file0 + + + end + + + line834 + col3 + file0 + + + line834 + col3 + file0 + + + + + + + kindevent + location + + line834 + col3 + file0 + + ranges + + + + line834 + col4 + file0 + + + line834 + col8 + file0 + + + + depth0 + extended_message + Incorrect decrement of the reference count of an object that is not owned at this point by the caller + message + Incorrect decrement of the reference count of an object that is not owned at this point by the caller + + + descriptionIncorrect decrement of the reference count of an object that is not owned at this point by the caller + categoryMemory (Core Foundation/Objective-C/OSObject) + typeBad release + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context641de26edd3d85ca241de577afbcda86 + issue_context_kindfunction + issue_contextrdar_6257780_Case1 + issue_hash_function_offset3 + location + + line834 + col3 + file0 + + ExecutedLines + + 0 + + 831 + 832 + 833 + 834 + + + + + path + + + kindcontrol + edges + + + start + + + line909 + col3 + file0 + + + line909 + col3 + file0 + + + end + + + line910 + col3 + file0 + + + line910 + col3 + file0 + + + + + + + kindevent + location + + line910 + col3 + file0 + + ranges + + + + line910 + col3 + file0 + + + line910 + col36 + file0 + + + + depth0 + extended_message + Method returns an instance of RDar6320065Subclass with a +1 retain count + message + Method returns an instance of RDar6320065Subclass with a +1 retain count + + + kindcontrol + edges + + + start + + + line910 + col3 + file0 + + + line910 + col3 + file0 + + + end + + + line911 + col3 + file0 + + + line911 + col8 + file0 + + + + + + + kindevent + location + + line911 + col3 + file0 + + ranges + + + + line911 + col3 + file0 + + + line911 + col13 + file0 + + + + depth0 + extended_message + Object leaked: allocated object of type 'RDar6320065Subclass *' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: allocated object of type 'RDar6320065Subclass *' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object of type 'RDar6320065Subclass *' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context8e8ae80fd006f27a952f77494bd1c05f + issue_context_kindObjective-C method + issue_context_initReturningNewClassBad + issue_hash_function_offset2 + location + + line911 + col3 + file0 + + ExecutedLines + + 0 + + 908 + 909 + 910 + 911 + + + + + path + + + kindcontrol + edges + + + start + + + line914 + col3 + file0 + + + line914 + col3 + file0 + + + end + + + line915 + col3 + file0 + + + line915 + col6 + file0 + + + + + + + kindevent + location + + line915 + col10 + file0 + + ranges + + + + line915 + col10 + file0 + + + line915 + col43 + file0 + + + + depth0 + extended_message + Method returns an instance of RDar6320065Subclass with a +1 retain count + message + Method returns an instance of RDar6320065Subclass with a +1 retain count + + + kindcontrol + edges + + + start + + + line915 + col3 + file0 + + + line915 + col6 + file0 + + + end + + + line916 + col3 + file0 + + + line916 + col8 + file0 + + + + + + + kindevent + location + + line916 + col10 + file0 + + ranges + + + + line916 + col10 + file0 + + + line916 + col27 + file0 + + + + + line916 + col11 + file0 + + + line916 + col14 + file0 + + + + depth0 + extended_message + Object autoreleased + message + Object autoreleased + + + kindevent + location + + line916 + col3 + file0 + + ranges + + + + line916 + col3 + file0 + + + line916 + col27 + file0 + + + + depth0 + extended_message + Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected + message + Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected + + + descriptionObject with a +0 retain count returned to caller where a +1 (owning) retain count is expected + categoryMemory (Core Foundation/Objective-C/OSObject) + typeMethod should return an owned object + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context625e26ef3ae9de238f30175e4e9f4937 + issue_context_kindObjective-C method + issue_contextinitReturningNewClassBad2 + issue_hash_function_offset3 + location + + line916 + col3 + file0 + + ExecutedLines + + 0 + + 913 + 914 + 915 + 916 + + + + + path + + + kindevent + location + + line954 + col37 + file0 + + ranges + + + + line954 + col37 + file0 + + + line954 + col59 + file0 + + + + depth0 + extended_message + Method returns an instance of NSString with a +1 retain count + message + Method returns an instance of NSString with a +1 retain count + + + kindevent + location + + line954 + col30 + file0 + + ranges + + + + line954 + col30 + file0 + + + line954 + col59 + file0 + + + + depth0 + extended_message + Object leaked: allocated object of type 'NSString *' is returned from a method whose name ('NoCopyString') does not start with 'copy', 'mutableCopy', 'alloc' or 'new'. This violates the naming convention rules given in the Memory Management Guide for Cocoa + message + Object leaked: allocated object of type 'NSString *' is returned from a method whose name ('NoCopyString') does not start with 'copy', 'mutableCopy', 'alloc' or 'new'. This violates the naming convention rules given in the Memory Management Guide for Cocoa + + + descriptionPotential leak of an object of type 'NSString *' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak of returned object + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context666dce676597e2cfa3199521864f7b96 + issue_context_kindObjective-C method + issue_contextNoCopyString + issue_hash_function_offset0 + location + + line954 + col30 + file0 + + ExecutedLines + + 0 + + 954 + + + + + path + + + kindevent + location + + line955 + col37 + file0 + + ranges + + + + line955 + col37 + file0 + + + line955 + col59 + file0 + + + + depth0 + extended_message + Method returns an instance of NSString with a +1 retain count + message + Method returns an instance of NSString with a +1 retain count + + + kindevent + location + + line955 + col30 + file0 + + ranges + + + + line955 + col30 + file0 + + + line955 + col59 + file0 + + + + depth0 + extended_message + Object leaked: allocated object of type 'NSString *' is returned from a method whose name ('noCopyString') does not start with 'copy', 'mutableCopy', 'alloc' or 'new'. This violates the naming convention rules given in the Memory Management Guide for Cocoa + message + Object leaked: allocated object of type 'NSString *' is returned from a method whose name ('noCopyString') does not start with 'copy', 'mutableCopy', 'alloc' or 'new'. This violates the naming convention rules given in the Memory Management Guide for Cocoa + + + descriptionPotential leak of an object of type 'NSString *' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak of returned object + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context31104cdb408dbc3faf693a5c31973486 + issue_context_kindObjective-C method + issue_contextnoCopyString + issue_hash_function_offset0 + location + + line955 + col30 + file0 + + ExecutedLines + + 0 + + 955 + + + + + path + + + kindevent + location + + line959 + col3 + file0 + + ranges + + + + line959 + col3 + file0 + + + line959 + col18 + file0 + + + + depth0 + extended_message + Calling 'NoCopyString' + message + Calling 'NoCopyString' + + + kindevent + location + + line954 + col1 + file0 + + depth1 + extended_message + Entered call from 'test_RDar6859457' + message + Entered call from 'test_RDar6859457' + + + kindcontrol + edges + + + start + + + line954 + col1 + file0 + + + line954 + col1 + file0 + + + end + + + line954 + col30 + file0 + + + line954 + col35 + file0 + + + + + + + kindevent + location + + line954 + col37 + file0 + + ranges + + + + line954 + col37 + file0 + + + line954 + col59 + file0 + + + + depth1 + extended_message + Method returns an instance of NSString with a +1 retain count + message + Method returns an instance of NSString with a +1 retain count + + + kindevent + location + + line959 + col3 + file0 + + ranges + + + + line959 + col3 + file0 + + + line959 + col18 + file0 + + + + depth0 + extended_message + Returning from 'NoCopyString' + message + Returning from 'NoCopyString' + + + kindcontrol + edges + + + start + + + line959 + col3 + file0 + + + line959 + col3 + file0 + + + end + + + line960 + col3 + file0 + + + line960 + col3 + file0 + + + + + + + kindevent + location + + line960 + col3 + file0 + + ranges + + + + line960 + col3 + file0 + + + line960 + col18 + file0 + + + + depth0 + extended_message + Object leaked: allocated object of type 'NSString *' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: allocated object of type 'NSString *' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object of type 'NSString *' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context909638940b4d7020f51062089653b231 + issue_context_kindfunction + issue_contexttest_RDar6859457 + issue_hash_function_offset1 + location + + line960 + col3 + file0 + + ExecutedLines + + 0 + + 954 + 958 + 959 + 960 + + + + + path + + + kindcontrol + edges + + + start + + + line959 + col3 + file0 + + + line959 + col3 + file0 + + + end + + + line960 + col3 + file0 + + + line960 + col3 + file0 + + + + + + + kindevent + location + + line960 + col3 + file0 + + ranges + + + + line960 + col3 + file0 + + + line960 + col18 + file0 + + + + depth0 + extended_message + Calling 'noCopyString' + message + Calling 'noCopyString' + + + kindevent + location + + line955 + col1 + file0 + + depth1 + extended_message + Entered call from 'test_RDar6859457' + message + Entered call from 'test_RDar6859457' + + + kindcontrol + edges + + + start + + + line955 + col1 + file0 + + + line955 + col1 + file0 + + + end + + + line955 + col30 + file0 + + + line955 + col35 + file0 + + + + + + + kindevent + location + + line955 + col37 + file0 + + ranges + + + + line955 + col37 + file0 + + + line955 + col59 + file0 + + + + depth1 + extended_message + Method returns an instance of NSString with a +1 retain count + message + Method returns an instance of NSString with a +1 retain count + + + kindevent + location + + line960 + col3 + file0 + + ranges + + + + line960 + col3 + file0 + + + line960 + col18 + file0 + + + + depth0 + extended_message + Returning from 'noCopyString' + message + Returning from 'noCopyString' + + + kindcontrol + edges + + + start + + + line960 + col3 + file0 + + + line960 + col3 + file0 + + + end + + + line961 + col3 + file0 + + + line961 + col3 + file0 + + + + + + + kindevent + location + + line961 + col3 + file0 + + ranges + + + + line961 + col3 + file0 + + + line961 + col54 + file0 + + + + depth0 + extended_message + Object leaked: allocated object of type 'NSString *' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: allocated object of type 'NSString *' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object of type 'NSString *' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context2a37743e32cfa0a86958fed215c30e87 + issue_context_kindfunction + issue_contexttest_RDar6859457 + issue_hash_function_offset2 + location + + line961 + col3 + file0 + + ExecutedLines + + 0 + + 954 + 955 + 958 + 959 + 960 + 961 + + + + + path + + + kindevent + location + + line994 + col10 + file0 + + ranges + + + + line994 + col10 + file0 + + + line994 + col32 + file0 + + + + depth0 + extended_message + Method returns an instance of NSString with a +1 retain count + message + Method returns an instance of NSString with a +1 retain count + + + kindevent + location + + line994 + col3 + file0 + + ranges + + + + line994 + col3 + file0 + + + line994 + col32 + file0 + + + + depth0 + extended_message + Object leaked: allocated object of type 'NSString *' is returned from a method whose name (':') does not start with 'copy', 'mutableCopy', 'alloc' or 'new'. This violates the naming convention rules given in the Memory Management Guide for Cocoa + message + Object leaked: allocated object of type 'NSString *' is returned from a method whose name (':') does not start with 'copy', 'mutableCopy', 'alloc' or 'new'. This violates the naming convention rules given in the Memory Management Guide for Cocoa + + + descriptionPotential leak of an object of type 'NSString *' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak of returned object + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context20b25f0ba6268e055d8491c67c6a26bd + issue_context_kindObjective-C method + issue_context: + issue_hash_function_offset1 + location + + line994 + col3 + file0 + + ExecutedLines + + 0 + + 993 + 994 + + + + + path + + + kindevent + location + + line1024 + col3 + file0 + + ranges + + + + line1024 + col3 + file0 + + + line1024 + col38 + file0 + + + + depth0 + extended_message + Method returns an Objective-C object with a +1 retain count + message + Method returns an Objective-C object with a +1 retain count + + + kindcontrol + edges + + + start + + + line1024 + col3 + file0 + + + line1024 + col3 + file0 + + + end + + + line1025 + col3 + file0 + + + line1025 + col3 + file0 + + + + + + + kindevent + location + + line1025 + col3 + file0 + + ranges + + + + line1025 + col3 + file0 + + + line1025 + col42 + file0 + + + + depth0 + extended_message + Object leaked: allocated object of type 'id' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: allocated object of type 'id' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object of type 'id' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context706b9d732ece93a88487dbbf0b82fd23 + issue_context_kindfunction + issue_contextrdar6902710 + issue_hash_function_offset1 + location + + line1025 + col3 + file0 + + ExecutedLines + + 0 + + 1021 + 1022 + 1023 + 1024 + 1025 + + + + + path + + + kindcontrol + edges + + + start + + + line1024 + col3 + file0 + + + line1024 + col3 + file0 + + + end + + + line1025 + col3 + file0 + + + line1025 + col3 + file0 + + + + + + + kindevent + location + + line1025 + col3 + file0 + + ranges + + + + line1025 + col3 + file0 + + + line1025 + col42 + file0 + + + + depth0 + extended_message + Method returns an Objective-C object with a +1 retain count + message + Method returns an Objective-C object with a +1 retain count + + + kindcontrol + edges + + + start + + + line1025 + col3 + file0 + + + line1025 + col3 + file0 + + + end + + + line1026 + col3 + file0 + + + line1026 + col3 + file0 + + + + + + + kindevent + location + + line1026 + col3 + file0 + + ranges + + + + line1026 + col3 + file0 + + + line1026 + col43 + file0 + + + + depth0 + extended_message + Object leaked: allocated object of type 'id' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: allocated object of type 'id' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object of type 'id' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context631eebb0c921191c24734f98fe93f6bf + issue_context_kindfunction + issue_contextrdar6902710 + issue_hash_function_offset2 + location + + line1026 + col3 + file0 + + ExecutedLines + + 0 + + 1021 + 1022 + 1023 + 1024 + 1025 + 1026 + + + + + path + + + kindcontrol + edges + + + start + + + line1024 + col3 + file0 + + + line1024 + col3 + file0 + + + end + + + line1026 + col3 + file0 + + + line1026 + col3 + file0 + + + + + + + kindevent + location + + line1026 + col3 + file0 + + ranges + + + + line1026 + col3 + file0 + + + line1026 + col43 + file0 + + + + depth0 + extended_message + Method returns a Core Foundation object of type 'CGImageRef' with a +1 retain count + message + Method returns a Core Foundation object of type 'CGImageRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line1026 + col3 + file0 + + + line1026 + col3 + file0 + + + end + + + line1027 + col3 + file0 + + + line1027 + col3 + file0 + + + + + + + kindevent + location + + line1027 + col3 + file0 + + ranges + + + + line1027 + col3 + file0 + + + line1027 + col69 + file0 + + + + depth0 + extended_message + Object leaked: allocated object of type 'CGImageRef' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: allocated object of type 'CGImageRef' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object of type 'CGImageRef' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_contextee36a48521a32c183a086066d3c5ae1f + issue_context_kindfunction + issue_contextrdar6902710 + issue_hash_function_offset3 + location + + line1027 + col3 + file0 + + ExecutedLines + + 0 + + 1021 + 1022 + 1023 + 1024 + 1025 + 1026 + 1027 + + + + + path + + + kindcontrol + edges + + + start + + + line1024 + col3 + file0 + + + line1024 + col3 + file0 + + + end + + + line1027 + col3 + file0 + + + line1027 + col3 + file0 + + + + + + + kindevent + location + + line1027 + col3 + file0 + + ranges + + + + line1027 + col3 + file0 + + + line1027 + col69 + file0 + + + + depth0 + extended_message + Method returns a Core Foundation object of type 'CGImageRef' with a +1 retain count + message + Method returns a Core Foundation object of type 'CGImageRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line1027 + col3 + file0 + + + line1027 + col3 + file0 + + + end + + + line1028 + col1 + file0 + + + line1028 + col1 + file0 + + + + + + + kindevent + location + + line1028 + col1 + file0 + + depth0 + extended_message + Object leaked: allocated object of type 'CGImageRef' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: allocated object of type 'CGImageRef' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object of type 'CGImageRef' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context70a2dd4ee6b6f7caad87a46dc6dd3580 + issue_context_kindfunction + issue_contextrdar6902710 + issue_hash_function_offset4 + location + + line1028 + col1 + file0 + + ExecutedLines + + 0 + + 1021 + 1022 + 1023 + 1024 + 1025 + 1026 + 1027 + 1028 + + + + + path + + + kindevent + location + + line1036 + col3 + file0 + + ranges + + + + line1036 + col3 + file0 + + + line1036 + col45 + file0 + + + + depth0 + extended_message + Method returns a Core Foundation object of type 'CGLayerRef' with a +1 retain count + message + Method returns a Core Foundation object of type 'CGLayerRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line1036 + col3 + file0 + + + line1036 + col3 + file0 + + + end + + + line1037 + col1 + file0 + + + line1037 + col1 + file0 + + + + + + + kindevent + location + + line1037 + col1 + file0 + + depth0 + extended_message + Object leaked: allocated object of type 'CGLayerRef' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: allocated object of type 'CGLayerRef' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object of type 'CGLayerRef' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_contexta82448687d1cbf5cb517914dbe6de4fe + issue_context_kindfunction + issue_contextrdar6945561 + issue_hash_function_offset1 + location + + line1037 + col1 + file0 + + ExecutedLines + + 0 + + 1035 + 1036 + 1037 + + + + + path + + + kindevent + location + + line1045 + col3 + file0 + + ranges + + + + line1045 + col3 + file0 + + + line1045 + col49 + file0 + + + + depth0 + extended_message + Call to function 'IOBSDNameMatching' returns a Core Foundation object of type 'CFMutableDictionaryRef' with a +1 retain count + message + Call to function 'IOBSDNameMatching' returns a Core Foundation object of type 'CFMutableDictionaryRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line1045 + col3 + file0 + + + line1045 + col19 + file0 + + + end + + + line1046 + col1 + file0 + + + line1046 + col1 + file0 + + + + + + + kindevent + location + + line1046 + col1 + file0 + + depth0 + extended_message + Object leaked: allocated object of type 'CFMutableDictionaryRef' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: allocated object of type 'CFMutableDictionaryRef' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object of type 'CFMutableDictionaryRef' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context540e0145994c1e14ea750fe91a497855 + issue_context_kindfunction + issue_contextIOBSDNameMatching_wrapper + issue_hash_function_offset1 + location + + line1046 + col1 + file0 + + ExecutedLines + + 0 + + 1044 + 1045 + 1046 + + + + + path + + + kindevent + location + + line1049 + col3 + file0 + + ranges + + + + line1049 + col3 + file0 + + + line1049 + col25 + file0 + + + + depth0 + extended_message + Call to function 'IOServiceMatching' returns a Core Foundation object of type 'CFMutableDictionaryRef' with a +1 retain count + message + Call to function 'IOServiceMatching' returns a Core Foundation object of type 'CFMutableDictionaryRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line1049 + col3 + file0 + + + line1049 + col19 + file0 + + + end + + + line1050 + col1 + file0 + + + line1050 + col1 + file0 + + + + + + + kindevent + location + + line1050 + col1 + file0 + + depth0 + extended_message + Object leaked: allocated object of type 'CFMutableDictionaryRef' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: allocated object of type 'CFMutableDictionaryRef' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object of type 'CFMutableDictionaryRef' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context99d7012d797e181ef8e9a289ee9099eb + issue_context_kindfunction + issue_contextIOServiceMatching_wrapper + issue_hash_function_offset1 + location + + line1050 + col1 + file0 + + ExecutedLines + + 0 + + 1048 + 1049 + 1050 + + + + + path + + + kindevent + location + + line1053 + col3 + file0 + + ranges + + + + line1053 + col3 + file0 + + + line1053 + col29 + file0 + + + + depth0 + extended_message + Call to function 'IOServiceNameMatching' returns a Core Foundation object of type 'CFMutableDictionaryRef' with a +1 retain count + message + Call to function 'IOServiceNameMatching' returns a Core Foundation object of type 'CFMutableDictionaryRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line1053 + col3 + file0 + + + line1053 + col23 + file0 + + + end + + + line1054 + col1 + file0 + + + line1054 + col1 + file0 + + + + + + + kindevent + location + + line1054 + col1 + file0 + + depth0 + extended_message + Object leaked: allocated object of type 'CFMutableDictionaryRef' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: allocated object of type 'CFMutableDictionaryRef' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object of type 'CFMutableDictionaryRef' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context5d956e58f05bcc1b67ff65e02cbba302 + issue_context_kindfunction + issue_contextIOServiceNameMatching_wrapper + issue_hash_function_offset1 + location + + line1054 + col1 + file0 + + ExecutedLines + + 0 + + 1052 + 1053 + 1054 + + + + + path + + + kindevent + location + + line1061 + col30 + file0 + + ranges + + + + line1061 + col30 + file0 + + + line1061 + col41 + file0 + + + + depth0 + extended_message + Call to function 'CreateDict' returns a Core Foundation object of type 'CFDictionaryRef' with a +1 retain count + message + Call to function 'CreateDict' returns a Core Foundation object of type 'CFDictionaryRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line1061 + col3 + file0 + + + line1061 + col17 + file0 + + + end + + + line1062 + col3 + file0 + + + line1062 + col11 + file0 + + + + + + + kindevent + location + + line1062 + col3 + file0 + + ranges + + + + line1062 + col3 + file0 + + + line1062 + col21 + file0 + + + + + line1062 + col13 + file0 + + + line1062 + col20 + file0 + + + + depth0 + extended_message + Object released + message + Object released + + + kindcontrol + edges + + + start + + + line1062 + col3 + file0 + + + line1062 + col11 + file0 + + + end + + + line1063 + col3 + file0 + + + line1063 + col26 + file0 + + + + + + + kindevent + location + + line1063 + col3 + file0 + + ranges + + + + line1063 + col58 + file0 + + + line1063 + col65 + file0 + + + + depth0 + extended_message + Reference-counted object is used after it is released + message + Reference-counted object is used after it is released + + + descriptionReference-counted object is used after it is released + categoryMemory (Core Foundation/Objective-C/OSObject) + typeUse-after-release + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context84a53bfb58a3a929535b47e28b997382 + issue_context_kindfunction + issue_contextIOServiceAddNotification_wrapper + issue_hash_function_offset4 + location + + line1063 + col3 + file0 + + ExecutedLines + + 0 + + 1058 + 1059 + 1061 + 1062 + 1063 + 1064 + + + + + path + + + kindevent + location + + line1068 + col3 + file0 + + ranges + + + + line1068 + col3 + file0 + + + line1068 + col36 + file0 + + + + depth0 + extended_message + Call to function 'IORegistryEntryIDMatching' returns a Core Foundation object of type 'CFMutableDictionaryRef' with a +1 retain count + message + Call to function 'IORegistryEntryIDMatching' returns a Core Foundation object of type 'CFMutableDictionaryRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line1068 + col3 + file0 + + + line1068 + col27 + file0 + + + end + + + line1069 + col1 + file0 + + + line1069 + col1 + file0 + + + + + + + kindevent + location + + line1069 + col1 + file0 + + depth0 + extended_message + Object leaked: allocated object of type 'CFMutableDictionaryRef' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: allocated object of type 'CFMutableDictionaryRef' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object of type 'CFMutableDictionaryRef' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context36337ff486f6a8b702e68d13393bc975 + issue_context_kindfunction + issue_contextIORegistryEntryIDMatching_wrapper + issue_hash_function_offset1 + location + + line1069 + col1 + file0 + + ExecutedLines + + 0 + + 1067 + 1068 + 1069 + + + + + path + + + kindevent + location + + line1073 + col3 + file0 + + ranges + + + + line1073 + col3 + file0 + + + line1073 + col55 + file0 + + + + depth0 + extended_message + Call to function 'IOOpenFirmwarePathMatching' returns a Core Foundation object of type 'CFMutableDictionaryRef' with a +1 retain count + message + Call to function 'IOOpenFirmwarePathMatching' returns a Core Foundation object of type 'CFMutableDictionaryRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line1073 + col3 + file0 + + + line1073 + col28 + file0 + + + end + + + line1074 + col1 + file0 + + + line1074 + col1 + file0 + + + + + + + kindevent + location + + line1074 + col1 + file0 + + depth0 + extended_message + Object leaked: allocated object of type 'CFMutableDictionaryRef' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: allocated object of type 'CFMutableDictionaryRef' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object of type 'CFMutableDictionaryRef' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_contextee83ca968ddc2ecad7ae4318ce7d1d95 + issue_context_kindfunction + issue_contextIOOpenFirmwarePathMatching_wrapper + issue_hash_function_offset1 + location + + line1074 + col1 + file0 + + ExecutedLines + + 0 + + 1071 + 1072 + 1073 + 1074 + + + + + path + + + kindevent + location + + line1077 + col30 + file0 + + ranges + + + + line1077 + col30 + file0 + + + line1077 + col41 + file0 + + + + depth0 + extended_message + Call to function 'CreateDict' returns a Core Foundation object of type 'CFDictionaryRef' with a +1 retain count + message + Call to function 'CreateDict' returns a Core Foundation object of type 'CFDictionaryRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line1077 + col3 + file0 + + + line1077 + col17 + file0 + + + end + + + line1078 + col3 + file0 + + + line1078 + col29 + file0 + + + + + + + kindevent + location + + line1078 + col3 + file0 + + ranges + + + + line1078 + col3 + file0 + + + line1078 + col51 + file0 + + + + + line1078 + col43 + file0 + + + line1078 + col50 + file0 + + + + depth0 + extended_message + Object released + message + Object released + + + kindcontrol + edges + + + start + + + line1078 + col3 + file0 + + + line1078 + col29 + file0 + + + end + + + line1079 + col3 + file0 + + + line1079 + col11 + file0 + + + + + + + kindevent + location + + line1079 + col3 + file0 + + ranges + + + + line1079 + col13 + file0 + + + line1079 + col20 + file0 + + + + depth0 + extended_message + Reference-counted object is used after it is released + message + Reference-counted object is used after it is released + + + descriptionReference-counted object is used after it is released + categoryMemory (Core Foundation/Objective-C/OSObject) + typeUse-after-release + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_contexte8c08b2b3d53f5890907888e16927805 + issue_context_kindfunction + issue_contextIOServiceGetMatchingService_wrapper + issue_hash_function_offset3 + location + + line1079 + col3 + file0 + + ExecutedLines + + 0 + + 1076 + 1077 + 1078 + 1079 + + + + + path + + + kindevent + location + + line1083 + col30 + file0 + + ranges + + + + line1083 + col30 + file0 + + + line1083 + col41 + file0 + + + + depth0 + extended_message + Call to function 'CreateDict' returns a Core Foundation object of type 'CFDictionaryRef' with a +1 retain count + message + Call to function 'CreateDict' returns a Core Foundation object of type 'CFDictionaryRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line1083 + col3 + file0 + + + line1083 + col17 + file0 + + + end + + + line1084 + col3 + file0 + + + line1084 + col30 + file0 + + + + + + + kindevent + location + + line1084 + col3 + file0 + + ranges + + + + line1084 + col3 + file0 + + + line1084 + col62 + file0 + + + + + line1084 + col44 + file0 + + + line1084 + col51 + file0 + + + + depth0 + extended_message + Object released + message + Object released + + + kindcontrol + edges + + + start + + + line1084 + col3 + file0 + + + line1084 + col30 + file0 + + + end + + + line1085 + col3 + file0 + + + line1085 + col11 + file0 + + + + + + + kindevent + location + + line1085 + col3 + file0 + + ranges + + + + line1085 + col13 + file0 + + + line1085 + col20 + file0 + + + + depth0 + extended_message + Reference-counted object is used after it is released + message + Reference-counted object is used after it is released + + + descriptionReference-counted object is used after it is released + categoryMemory (Core Foundation/Objective-C/OSObject) + typeUse-after-release + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context31664b5acc7980da73f5545fb16b0910 + issue_context_kindfunction + issue_contextIOServiceGetMatchingServices_wrapper + issue_hash_function_offset3 + location + + line1085 + col3 + file0 + + ExecutedLines + + 0 + + 1082 + 1083 + 1084 + 1085 + + + + + path + + + kindevent + location + + line1091 + col30 + file0 + + ranges + + + + line1091 + col30 + file0 + + + line1091 + col41 + file0 + + + + depth0 + extended_message + Call to function 'CreateDict' returns a Core Foundation object of type 'CFDictionaryRef' with a +1 retain count + message + Call to function 'CreateDict' returns a Core Foundation object of type 'CFDictionaryRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line1091 + col3 + file0 + + + line1091 + col17 + file0 + + + end + + + line1092 + col3 + file0 + + + line1092 + col34 + file0 + + + + + + + kindevent + location + + line1092 + col3 + file0 + + ranges + + + + line1092 + col3 + file0 + + + line1092 + col106 + file0 + + + + + line1092 + col66 + file0 + + + line1092 + col73 + file0 + + + + depth0 + extended_message + Object released + message + Object released + + + kindcontrol + edges + + + start + + + line1092 + col3 + file0 + + + line1092 + col34 + file0 + + + end + + + line1093 + col3 + file0 + + + line1093 + col11 + file0 + + + + + + + kindevent + location + + line1093 + col3 + file0 + + ranges + + + + line1093 + col13 + file0 + + + line1093 + col20 + file0 + + + + depth0 + extended_message + Reference-counted object is used after it is released + message + Reference-counted object is used after it is released + + + descriptionReference-counted object is used after it is released + categoryMemory (Core Foundation/Objective-C/OSObject) + typeUse-after-release + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context6edae46016a9671e2d5400b100d5efb5 + issue_context_kindfunction + issue_contextIOServiceAddMatchingNotification_wrapper + issue_hash_function_offset4 + location + + line1093 + col3 + file0 + + ExecutedLines + + 0 + + 1088 + 1089 + 1091 + 1092 + 1093 + + + + + path + + + kindcontrol + edges + + + start + + + line1131 + col3 + file0 + + + line1131 + col23 + file0 + + + end + + + line1134 + col3 + file0 + + + line1134 + col10 + file0 + + + + + + + kindevent + location + + line1134 + col22 + file0 + + ranges + + + + line1134 + col22 + file0 + + + line1134 + col53 + file0 + + + + depth0 + extended_message + Method returns an instance of NSNumber with a +1 retain count + message + Method returns an instance of NSNumber with a +1 retain count + + + kindcontrol + edges + + + start + + + line1134 + col3 + file0 + + + line1134 + col10 + file0 + + + end + + + line1136 + col3 + file0 + + + line1136 + col3 + file0 + + + + + + + kindevent + location + + line1136 + col3 + file0 + + ranges + + + + line1136 + col3 + file0 + + + line1136 + col18 + file0 + + + + + line1136 + col4 + file0 + + + line1136 + col9 + file0 + + + + depth0 + extended_message + Reference count decremented + message + Reference count decremented + + + kindcontrol + edges + + + start + + + line1136 + col3 + file0 + + + line1136 + col3 + file0 + + + end + + + line1137 + col3 + file0 + + + line1137 + col3 + file0 + + + + + + + kindevent + location + + line1137 + col3 + file0 + + ranges + + + + line1137 + col3 + file0 + + + line1137 + col17 + file0 + + + + + line1137 + col4 + file0 + + + line1137 + col9 + file0 + + + + depth0 + extended_message + Reference count incremented. The object now has a +1 retain count + message + Reference count incremented. The object now has a +1 retain count + + + kindcontrol + edges + + + start + + + line1137 + col3 + file0 + + + line1137 + col3 + file0 + + + end + + + line1138 + col3 + file0 + + + line1138 + col11 + file0 + + + + + + + kindevent + location + + line1138 + col3 + file0 + + ranges + + + + line1138 + col3 + file0 + + + line1138 + col23 + file0 + + + + depth0 + extended_message + Object leaked: object allocated and stored into 'number' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'number' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'number' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_contextdcec4e2bd254a3c24e84e598b5a827bf + issue_context_kindfunction + issue_contextrdar_7152619 + issue_hash_function_offset4 + location + + line1138 + col3 + file0 + + ExecutedLines + + 0 + + 67 + 68 + 69 + 70 + 71 + 1130 + 1131 + 1132 + 1133 + 1134 + 1135 + 1136 + 1137 + 1138 + + + + + path + + + kindcontrol + edges + + + start + + + line1147 + col3 + file0 + + + line1147 + col8 + file0 + + + end + + + line1158 + col3 + file0 + + + line1158 + col15 + file0 + + + + + + + kindcontrol + edges + + + start + + + line1158 + col3 + file0 + + + line1158 + col15 + file0 + + + end + + + line1159 + col41 + file0 + + + line1159 + col67 + file0 + + + + + + + kindevent + location + + line1159 + col41 + file0 + + ranges + + + + line1159 + col41 + file0 + + + line1159 + col69 + file0 + + + + depth0 + extended_message + Call to function 'CGColorSpaceCreateDeviceRGB' returns a Core Foundation object of type 'CGColorSpaceRef' with a +1 retain count + message + Call to function 'CGColorSpaceCreateDeviceRGB' returns a Core Foundation object of type 'CGColorSpaceRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line1159 + col41 + file0 + + + line1159 + col67 + file0 + + + end + + + line1158 + col3 + file0 + + + line1158 + col15 + file0 + + + + + + + kindevent + location + + line1158 + col3 + file0 + + ranges + + + + line1158 + col3 + file0 + + + line1158 + col26 + file0 + + + + depth0 + extended_message + Object leaked: allocated object of type 'CGColorSpaceRef' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: allocated object of type 'CGColorSpaceRef' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object of type 'CGColorSpaceRef' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context9317a6bf07dd10dc988f2415cc2c4ef7 + issue_context_kindfunction + issue_contextrdar_7184450 + issue_hash_function_offset13 + location + + line1158 + col3 + file0 + + ExecutedLines + + 0 + + 1145 + 1146 + 1147 + 1148 + 1149 + 1150 + 1151 + 1152 + 1153 + 1154 + 1155 + 1158 + 1159 + 1160 + + + + + path + + + kindcontrol + edges + + + start + + + line1169 + col3 + file0 + + + line1169 + col8 + file0 + + + end + + + line1180 + col3 + file0 + + + line1180 + col15 + file0 + + + + + + + kindcontrol + edges + + + start + + + line1180 + col3 + file0 + + + line1180 + col15 + file0 + + + end + + + line1181 + col40 + file0 + + + line1181 + col66 + file0 + + + + + + + kindevent + location + + line1181 + col40 + file0 + + ranges + + + + line1181 + col40 + file0 + + + line1181 + col68 + file0 + + + + depth0 + extended_message + Call to function 'CGColorSpaceCreateDeviceRGB' returns a Core Foundation object of type 'CGColorSpaceRef' with a +1 retain count + message + Call to function 'CGColorSpaceCreateDeviceRGB' returns a Core Foundation object of type 'CGColorSpaceRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line1181 + col40 + file0 + + + line1181 + col66 + file0 + + + end + + + line1180 + col3 + file0 + + + line1180 + col15 + file0 + + + + + + + kindevent + location + + line1180 + col3 + file0 + + ranges + + + + line1180 + col3 + file0 + + + line1180 + col26 + file0 + + + + depth0 + extended_message + Object leaked: allocated object of type 'CGColorSpaceRef' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: allocated object of type 'CGColorSpaceRef' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object of type 'CGColorSpaceRef' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_contextec3e6216b279aa48d8403c6aab30d996 + issue_context_kindfunction + issue_contextrdar_7184450_pos + issue_hash_function_offset13 + location + + line1180 + col3 + file0 + + ExecutedLines + + 0 + + 1167 + 1168 + 1169 + 1170 + 1171 + 1172 + 1173 + 1174 + 1175 + 1176 + 1177 + 1180 + 1181 + + + + + path + + + kindcontrol + edges + + + start + + + line1169 + col3 + file0 + + + line1169 + col8 + file0 + + + end + + + line1180 + col3 + file0 + + + line1180 + col15 + file0 + + + + + + + kindcontrol + edges + + + start + + + line1180 + col3 + file0 + + + line1180 + col15 + file0 + + + end + + + line1181 + col4 + file0 + + + line1181 + col38 + file0 + + + + + + + kindevent + location + + line1181 + col4 + file0 + + ranges + + + + line1181 + col4 + file0 + + + line1181 + col107 + file0 + + + + depth0 + extended_message + Call to function 'CGGradientCreateWithColorComponents' returns a Core Foundation object of type 'CGGradientRef' with a +1 retain count + message + Call to function 'CGGradientCreateWithColorComponents' returns a Core Foundation object of type 'CGGradientRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line1181 + col4 + file0 + + + line1181 + col38 + file0 + + + end + + + line1183 + col3 + file0 + + + line1183 + col29 + file0 + + + + + + + kindcontrol + edges + + + start + + + line1183 + col3 + file0 + + + line1183 + col29 + file0 + + + end + + + line1185 + col1 + file0 + + + line1185 + col1 + file0 + + + + + + + kindevent + location + + line1185 + col1 + file0 + + depth0 + extended_message + Object leaked: object allocated and stored into 'myGradient' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'myGradient' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'myGradient' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context4b3d6bb6b8dc5c51b7dfa8554b24eb66 + issue_context_kindfunction + issue_contextrdar_7184450_pos + issue_hash_function_offset13 + location + + line1185 + col1 + file0 + + ExecutedLines + + 0 + + 1167 + 1168 + 1169 + 1170 + 1171 + 1172 + 1173 + 1174 + 1175 + 1176 + 1177 + 1180 + 1181 + 1183 + 1184 + 1185 + + + + + path + + + kindevent + location + + line1219 + col22 + file0 + + ranges + + + + line1219 + col22 + file0 + + + line1219 + col53 + file0 + + + + depth0 + extended_message + Method returns an instance of NSNumber with a +1 retain count + message + Method returns an instance of NSNumber with a +1 retain count + + + kindcontrol + edges + + + start + + + line1219 + col3 + file0 + + + line1219 + col10 + file0 + + + end + + + line1220 + col1 + file0 + + + line1220 + col1 + file0 + + + + + + + kindevent + location + + line1220 + col1 + file0 + + depth0 + extended_message + Object leaked: object allocated and stored into 'number' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'number' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'number' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context42a83016e862ec323e24920873073a5a + issue_context_kindfunction + issue_contextrdar_7299394_positive + issue_hash_function_offset1 + location + + line1220 + col1 + file0 + + ExecutedLines + + 0 + + 1218 + 1219 + 1220 + + + + + path + + + kindcontrol + edges + + + start + + + line1454 + col5 + file0 + + + line1454 + col12 + file0 + + + end + + + line1456 + col3 + file0 + + + line1456 + col31 + file0 + + + + + + + kindevent + location + + line1456 + col3 + file0 + + ranges + + + + line1456 + col3 + file0 + + + line1457 + col60 + file0 + + + + depth0 + extended_message + Call to function 'CGBitmapContextCreateWithData' returns a Core Foundation object of type 'CGContextRef' with a +1 retain count + message + Call to function 'CGBitmapContextCreateWithData' returns a Core Foundation object of type 'CGContextRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line1456 + col3 + file0 + + + line1456 + col31 + file0 + + + end + + + line1458 + col1 + file0 + + + line1458 + col1 + file0 + + + + + + + kindevent + location + + line1458 + col1 + file0 + + depth0 + extended_message + Object leaked: allocated object of type 'CGContextRef' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: allocated object of type 'CGContextRef' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object of type 'CGContextRef' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_contexta416473fed3a9dbc6bfee885bee38216 + issue_context_kindfunction + issue_contextrdar_7358899 + issue_hash_function_offset7 + location + + line1458 + col1 + file0 + + ExecutedLines + + 0 + + 1446 + 1447 + 1448 + 1449 + 1454 + 1456 + 1457 + 1458 + + + + + path + + + kindevent + location + + line1474 + col10 + file0 + + ranges + + + + line1474 + col10 + file0 + + + line1474 + col22 + file0 + + + + depth0 + extended_message + Method returns an Objective-C object with a +1 retain count + message + Method returns an Objective-C object with a +1 retain count + + + kindcontrol + edges + + + start + + + line1474 + col3 + file0 + + + line1474 + col4 + file0 + + + end + + + line1475 + col1 + file0 + + + line1475 + col1 + file0 + + + + + + + kindevent + location + + line1475 + col1 + file0 + + depth0 + extended_message + Object leaked: object allocated and stored into 'y' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'y' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'y' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context980dd45e9cf6581dbc2be9ebfc500b7f + issue_context_kindfunction + issue_contextrdar7265711_a + issue_hash_function_offset1 + location + + line1475 + col1 + file0 + + ExecutedLines + + 0 + + 1473 + 1474 + 1475 + + + + + path + + + kindcontrol + edges + + + start + + + line1494 + col3 + file0 + + + line1494 + col10 + file0 + + + end + + + line1495 + col3 + file0 + + + line1495 + col10 + file0 + + + + + + + kindevent + location + + line1495 + col22 + file0 + + ranges + + + + line1495 + col22 + file0 + + + line1495 + col53 + file0 + + + + depth0 + extended_message + Method returns an instance of NSNumber with a +1 retain count + message + Method returns an instance of NSNumber with a +1 retain count + + + kindcontrol + edges + + + start + + + line1495 + col3 + file0 + + + line1495 + col10 + file0 + + + end + + + line1496 + col1 + file0 + + + line1496 + col1 + file0 + + + + + + + kindevent + location + + line1496 + col1 + file0 + + depth0 + extended_message + Object leaked: object allocated and stored into 'number' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'number' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'number' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_contextebf51fb2b16499cf3a5c57d251a91061 + issue_context_kindfunction + issue_contextrdar7306898 + issue_hash_function_offset4 + location + + line1496 + col1 + file0 + + ExecutedLines + + 0 + + 1491 + 1494 + 1495 + 1496 + + + + + path + + + kindevent + location + + line1505 + col3 + file0 + + ranges + + + + line1505 + col3 + file0 + + + line1505 + col23 + file0 + + + + depth0 + extended_message + The 'release' message should be sent to instances of class 'RDar7252064' and not the class directly + message + The 'release' message should be sent to instances of class 'RDar7252064' and not the class directly + + + descriptionThe 'release' message should be sent to instances of class 'RDar7252064' and not the class directly + categoryAPI Misuse (Apple) + typemessage incorrectly sent to class instead of class instance + check_nameosx.cocoa.ClassRelease + + issue_hash_content_of_line_in_contextbdc4aaf3d712232f4ae72dce230189f9 + issue_context_kindfunction + issue_contextrdar7252064 + issue_hash_function_offset1 + location + + line1505 + col3 + file0 + + ExecutedLines + + 0 + + 1504 + 1505 + + + + + path + + + kindcontrol + edges + + + start + + + line1505 + col3 + file0 + + + line1505 + col3 + file0 + + + end + + + line1506 + col3 + file0 + + + line1506 + col3 + file0 + + + + + + + kindevent + location + + line1506 + col3 + file0 + + ranges + + + + line1506 + col3 + file0 + + + line1506 + col22 + file0 + + + + depth0 + extended_message + The 'retain' message should be sent to instances of class 'RDar7252064' and not the class directly + message + The 'retain' message should be sent to instances of class 'RDar7252064' and not the class directly + + + descriptionThe 'retain' message should be sent to instances of class 'RDar7252064' and not the class directly + categoryAPI Misuse (Apple) + typemessage incorrectly sent to class instead of class instance + check_nameosx.cocoa.ClassRelease + + issue_hash_content_of_line_in_contextb767178ef573c7bd520dc62faabc32fc + issue_context_kindfunction + issue_contextrdar7252064 + issue_hash_function_offset2 + location + + line1506 + col3 + file0 + + ExecutedLines + + 0 + + 1504 + 1505 + 1506 + + + + + path + + + kindcontrol + edges + + + start + + + line1505 + col3 + file0 + + + line1505 + col3 + file0 + + + end + + + line1507 + col3 + file0 + + + line1507 + col3 + file0 + + + + + + + kindevent + location + + line1507 + col3 + file0 + + ranges + + + + line1507 + col3 + file0 + + + line1507 + col27 + file0 + + + + depth0 + extended_message + The 'autorelease' message should be sent to instances of class 'RDar7252064' and not the class directly + message + The 'autorelease' message should be sent to instances of class 'RDar7252064' and not the class directly + + + descriptionThe 'autorelease' message should be sent to instances of class 'RDar7252064' and not the class directly + categoryAPI Misuse (Apple) + typemessage incorrectly sent to class instead of class instance + check_nameosx.cocoa.ClassRelease + + issue_hash_content_of_line_in_context3dbe304966f8bffa6bdefc5f3ada7df6 + issue_context_kindfunction + issue_contextrdar7252064 + issue_hash_function_offset3 + location + + line1507 + col3 + file0 + + ExecutedLines + + 0 + + 1504 + 1505 + 1506 + 1507 + + + + + path + + + kindcontrol + edges + + + start + + + line1505 + col3 + file0 + + + line1505 + col3 + file0 + + + end + + + line1508 + col3 + file0 + + + line1508 + col3 + file0 + + + + + + + kindevent + location + + line1508 + col3 + file0 + + ranges + + + + line1508 + col3 + file0 + + + line1508 + col27 + file0 + + + + depth0 + extended_message + The 'drain' message should be sent to instances of class 'NSAutoreleasePool' and not the class directly + message + The 'drain' message should be sent to instances of class 'NSAutoreleasePool' and not the class directly + + + descriptionThe 'drain' message should be sent to instances of class 'NSAutoreleasePool' and not the class directly + categoryAPI Misuse (Apple) + typemessage incorrectly sent to class instead of class instance + check_nameosx.cocoa.ClassRelease + + issue_hash_content_of_line_in_contextc519bce30f1da4bb6e3ecc46453d6958 + issue_context_kindfunction + issue_contextrdar7252064 + issue_hash_function_offset4 + location + + line1508 + col3 + file0 + + ExecutedLines + + 0 + + 1504 + 1505 + 1506 + 1507 + 1508 + + + + + path + + + kindevent + location + + line1535 + col19 + file0 + + ranges + + + + line1535 + col19 + file0 + + + line1535 + col42 + file0 + + + + depth0 + extended_message + Method returns an instance of NSString with a +1 retain count + message + Method returns an instance of NSString with a +1 retain count + + + kindcontrol + edges + + + start + + + line1535 + col3 + file0 + + + line1535 + col10 + file0 + + + end + + + line1536 + col1 + file0 + + + line1536 + col1 + file0 + + + + + + + kindevent + location + + line1536 + col1 + file0 + + depth0 + extended_message + Object leaked: object allocated and stored into 'str' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'str' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'str' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context1174ccc2a30887ebf80fe25fc6722b1a + issue_context_kindfunction + issue_contexttest_attr_1 + issue_hash_function_offset1 + location + + line1536 + col1 + file0 + + ExecutedLines + + 0 + + 1534 + 1535 + 1536 + + + + + path + + + kindevent + location + + line1539 + col19 + file0 + + ranges + + + + line1539 + col19 + file0 + + + line1539 + col44 + file0 + + + + depth0 + extended_message + Method returns a Core Foundation object of type 'NSString *' with a +1 retain count + message + Method returns a Core Foundation object of type 'NSString *' with a +1 retain count + + + kindcontrol + edges + + + start + + + line1539 + col3 + file0 + + + line1539 + col10 + file0 + + + end + + + line1540 + col1 + file0 + + + line1540 + col1 + file0 + + + + + + + kindevent + location + + line1540 + col1 + file0 + + depth0 + extended_message + Object leaked: object allocated and stored into 'str' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'str' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'str' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_contextce9963dd1c85ac22cea4e4fef615354e + issue_context_kindfunction + issue_contexttest_attr_1b + issue_hash_function_offset1 + location + + line1540 + col1 + file0 + + ExecutedLines + + 0 + + 1538 + 1539 + 1540 + + + + + path + + + kindcontrol + edges + + + start + + + line1543 + col3 + file0 + + + line1543 + col10 + file0 + + + end + + + line1544 + col3 + file0 + + + line1544 + col10 + file0 + + + + + + + kindevent + location + + line1544 + col20 + file0 + + ranges + + + + line1544 + col20 + file0 + + + line1544 + col38 + file0 + + + + depth0 + extended_message + Method returns an instance of NSString with a +1 retain count + message + Method returns an instance of NSString with a +1 retain count + + + kindcontrol + edges + + + start + + + line1544 + col3 + file0 + + + line1544 + col10 + file0 + + + end + + + line1545 + col3 + file0 + + + line1545 + col10 + file0 + + + + + + + kindcontrol + edges + + + start + + + line1545 + col3 + file0 + + + line1545 + col10 + file0 + + + end + + + line1545 + col20 + file0 + + + line1545 + col20 + file0 + + + + + + + kindevent + location + + line1545 + col20 + file0 + + ranges + + + + line1545 + col20 + file0 + + + line1545 + col37 + file0 + + + + depth0 + extended_message + Object leaked: object allocated and stored into 'str2' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'str2' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'str2' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context0183088266857082f35eb17f1377fd69 + issue_context_kindfunction + issue_contexttest_attr1c + issue_hash_function_offset2 + location + + line1545 + col20 + file0 + + ExecutedLines + + 0 + + 1542 + 1543 + 1544 + 1545 + + + + + path + + + kindcontrol + edges + + + start + + + line1543 + col3 + file0 + + + line1543 + col10 + file0 + + + end + + + line1546 + col3 + file0 + + + line1546 + col10 + file0 + + + + + + + kindcontrol + edges + + + start + + + line1546 + col3 + file0 + + + line1546 + col10 + file0 + + + end + + + line1546 + col21 + file0 + + + line1546 + col21 + file0 + + + + + + + kindevent + location + + line1546 + col21 + file0 + + ranges + + + + line1546 + col21 + file0 + + + line1546 + col38 + file0 + + + + depth0 + extended_message + Method returns an instance of NSString with a +0 retain count + message + Method returns an instance of NSString with a +0 retain count + + + kindevent + location + + line1546 + col20 + file0 + + ranges + + + + line1546 + col20 + file0 + + + line1546 + col46 + file0 + + + + + line1546 + col21 + file0 + + + line1546 + col38 + file0 + + + + depth0 + extended_message + Reference count incremented. The object now has a +1 retain count + message + Reference count incremented. The object now has a +1 retain count + + + kindcontrol + edges + + + start + + + line1546 + col20 + file0 + + + line1546 + col20 + file0 + + + end + + + line1546 + col3 + file0 + + + line1546 + col10 + file0 + + + + + + + kindcontrol + edges + + + start + + + line1546 + col3 + file0 + + + line1546 + col10 + file0 + + + end + + + line1547 + col1 + file0 + + + line1547 + col1 + file0 + + + + + + + kindevent + location + + line1547 + col1 + file0 + + depth0 + extended_message + Object leaked: object allocated and stored into 'str4' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'str4' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'str4' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context352a17ef8eddd3aa5f7f6e74a74a4df3 + issue_context_kindfunction + issue_contexttest_attr1c + issue_hash_function_offset4 + location + + line1547 + col1 + file0 + + ExecutedLines + + 0 + + 1542 + 1543 + 1544 + 1545 + 1546 + 1547 + + + + + path + + + kindevent + location + + line1550 + col26 + file0 + + ranges + + + + line1550 + col26 + file0 + + + line1550 + col50 + file0 + + + + depth0 + extended_message + Method returns an instance of TestOwnershipAttr with a +1 retain count + message + Method returns an instance of TestOwnershipAttr with a +1 retain count + + + kindcontrol + edges + + + start + + + line1550 + col3 + file0 + + + line1550 + col19 + file0 + + + end + + + line1551 + col1 + file0 + + + line1551 + col1 + file0 + + + + + + + kindevent + location + + line1551 + col1 + file0 + + depth0 + extended_message + Object leaked: object allocated and stored into 'x' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'x' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'x' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_contextd0e564404585060990202acb33f0bb1e + issue_context_kindfunction + issue_contexttestattr2_a + issue_hash_function_offset1 + location + + line1551 + col1 + file0 + + ExecutedLines + + 0 + + 1549 + 1550 + 1551 + + + + + path + + + kindevent + location + + line1554 + col26 + file0 + + ranges + + + + line1554 + col26 + file0 + + + line1554 + col63 + file0 + + + + depth0 + extended_message + Method returns an Objective-C object with a +1 retain count + message + Method returns an Objective-C object with a +1 retain count + + + kindcontrol + edges + + + start + + + line1554 + col3 + file0 + + + line1554 + col19 + file0 + + + end + + + line1555 + col1 + file0 + + + line1555 + col1 + file0 + + + + + + + kindevent + location + + line1555 + col1 + file0 + + depth0 + extended_message + Object leaked: object allocated and stored into 'x' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'x' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'x' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context567dfcbc22471ca4ba9f2fccd9ff14fb + issue_context_kindfunction + issue_contexttestattr2_b + issue_hash_function_offset1 + location + + line1555 + col1 + file0 + + ExecutedLines + + 0 + + 1553 + 1554 + 1555 + + + + + path + + + kindevent + location + + line1558 + col26 + file0 + + ranges + + + + line1558 + col26 + file0 + + + line1558 + col63 + file0 + + + + depth0 + extended_message + Method returns an Objective-C object with a +1 retain count + message + Method returns an Objective-C object with a +1 retain count + + + kindcontrol + edges + + + start + + + line1558 + col3 + file0 + + + line1558 + col19 + file0 + + + end + + + line1559 + col3 + file0 + + + line1559 + col3 + file0 + + + + + + + kindcontrol + edges + + + start + + + line1559 + col3 + file0 + + + line1559 + col3 + file0 + + + end + + + line1560 + col1 + file0 + + + line1560 + col1 + file0 + + + + + + + kindevent + location + + line1560 + col1 + file0 + + depth0 + extended_message + Object leaked: object allocated and stored into 'x' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'x' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'x' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context83cd2670977d513443836653fee8147b + issue_context_kindfunction + issue_contexttestattr2_b_11358224_self_assign_looses_the_leak + issue_hash_function_offset1 + location + + line1560 + col1 + file0 + + ExecutedLines + + 0 + + 1557 + 1558 + 1559 + 1560 + + + + + path + + + kindevent + location + + line1590 + col10 + file0 + + ranges + + + + line1590 + col10 + file0 + + + line1590 + col25 + file0 + + + + depth0 + extended_message + Method returns an instance of NSString with a +1 retain count + message + Method returns an instance of NSString with a +1 retain count + + + kindevent + location + + line1590 + col3 + file0 + + ranges + + + + line1590 + col3 + file0 + + + line1590 + col25 + file0 + + + + depth0 + extended_message + Object leaked: allocated object of type 'NSString *' is returned from a method that is annotated as NS_RETURNS_NOT_RETAINED + message + Object leaked: allocated object of type 'NSString *' is returned from a method that is annotated as NS_RETURNS_NOT_RETAINED + + + descriptionPotential leak of an object of type 'NSString *' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak of returned object + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_contextf83246e7e738918426df1adc915f4eca + issue_context_kindObjective-C method + issue_contextnewString + issue_hash_function_offset1 + location + + line1590 + col3 + file0 + + ExecutedLines + + 0 + + 1589 + 1590 + + + + + path + + + kindcontrol + edges + + + start + + + line1623 + col3 + file0 + + + line1623 + col8 + file0 + + + end + + + line1623 + col26 + file0 + + + line1623 + col26 + file0 + + + + + + + kindevent + location + + line1623 + col26 + file0 + + ranges + + + + line1623 + col26 + file0 + + + line1623 + col53 + file0 + + + + depth0 + extended_message + Calling 'returnsCFRetainedAsCF' + message + Calling 'returnsCFRetainedAsCF' + + + kindevent + location + + line1614 + col1 + file0 + + depth1 + extended_message + Entered call from 'newCFRetainedAsCFNoAttr' + message + Entered call from 'newCFRetainedAsCFNoAttr' + + + kindcontrol + edges + + + start + + + line1614 + col1 + file0 + + + line1614 + col1 + file0 + + + end + + + line1615 + col3 + file0 + + + line1615 + col8 + file0 + + + + + + + kindcontrol + edges + + + start + + + line1615 + col3 + file0 + + + line1615 + col8 + file0 + + + end + + + line1615 + col10 + file0 + + + line1615 + col30 + file0 + + + + + + + kindevent + location + + line1615 + col10 + file0 + + ranges + + + + line1615 + col10 + file0 + + + line1615 + col32 + file0 + + + + depth1 + extended_message + Calling 'returnsRetainedCFDate' + message + Calling 'returnsRetainedCFDate' + + + kindevent + location + + line1604 + col1 + file0 + + depth2 + extended_message + Entered call from 'returnsCFRetainedAsCF' + message + Entered call from 'returnsCFRetainedAsCF' + + + kindcontrol + edges + + + start + + + line1604 + col1 + file0 + + + line1604 + col19 + file0 + + + end + + + line1606 + col3 + file0 + + + line1606 + col8 + file0 + + + + + + + kindevent + location + + line1606 + col10 + file0 + + ranges + + + + line1606 + col10 + file0 + + + line1606 + col52 + file0 + + + + depth2 + extended_message + Call to function 'CFDateCreate' returns a Core Foundation object of type 'CFDateRef' with a +1 retain count + message + Call to function 'CFDateCreate' returns a Core Foundation object of type 'CFDateRef' with a +1 retain count + + + kindevent + location + + line1615 + col10 + file0 + + ranges + + + + line1615 + col10 + file0 + + + line1615 + col32 + file0 + + + + depth1 + extended_message + Returning from 'returnsRetainedCFDate' + message + Returning from 'returnsRetainedCFDate' + + + kindcontrol + edges + + + start + + + line1615 + col10 + file0 + + + line1615 + col30 + file0 + + + end + + + line1615 + col3 + file0 + + + line1615 + col8 + file0 + + + + + + + kindevent + location + + line1623 + col26 + file0 + + ranges + + + + line1623 + col26 + file0 + + + line1623 + col53 + file0 + + + + depth0 + extended_message + Returning from 'returnsCFRetainedAsCF' + message + Returning from 'returnsCFRetainedAsCF' + + + kindcontrol + edges + + + start + + + line1623 + col26 + file0 + + + line1623 + col26 + file0 + + + end + + + line1623 + col21 + file0 + + + line1623 + col21 + file0 + + + + + + + kindevent + location + + line1623 + col21 + file0 + + ranges + + + + line1623 + col21 + file0 + + + line1623 + col66 + file0 + + + + + line1623 + col22 + file0 + + + line1623 + col53 + file0 + + + + depth0 + extended_message + Object autoreleased + message + Object autoreleased + + + kindcontrol + edges + + + start + + + line1623 + col21 + file0 + + + line1623 + col21 + file0 + + + end + + + line1623 + col3 + file0 + + + line1623 + col8 + file0 + + + + + + + kindevent + location + + line1623 + col3 + file0 + + ranges + + + + line1623 + col3 + file0 + + + line1623 + col66 + file0 + + + + depth0 + extended_message + Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected + message + Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected + + + descriptionObject with a +0 retain count returned to caller where a +1 (owning) retain count is expected + categoryMemory (Core Foundation/Objective-C/OSObject) + typeMethod should return an owned object + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context5f233261d96f1d461af36fc3e0efc8eb + issue_context_kindObjective-C method + issue_contextnewCFRetainedAsCFNoAttr + issue_hash_function_offset1 + location + + line1623 + col3 + file0 + + ExecutedLines + + 0 + + 1604 + 1605 + 1606 + 1614 + 1615 + 1622 + 1623 + + + + + path + + + kindcontrol + edges + + + start + + + line1627 + col3 + file0 + + + line1627 + col8 + file0 + + + end + + + line1627 + col20 + file0 + + + line1627 + col40 + file0 + + + + + + + kindevent + location + + line1627 + col20 + file0 + + ranges + + + + line1627 + col20 + file0 + + + line1627 + col42 + file0 + + + + depth0 + extended_message + Calling 'returnsRetainedCFDate' + message + Calling 'returnsRetainedCFDate' + + + kindevent + location + + line1604 + col1 + file0 + + depth1 + extended_message + Entered call from 'alsoReturnsRetained' + message + Entered call from 'alsoReturnsRetained' + + + kindcontrol + edges + + + start + + + line1604 + col1 + file0 + + + line1604 + col19 + file0 + + + end + + + line1606 + col3 + file0 + + + line1606 + col8 + file0 + + + + + + + kindevent + location + + line1606 + col10 + file0 + + ranges + + + + line1606 + col10 + file0 + + + line1606 + col52 + file0 + + + + depth1 + extended_message + Call to function 'CFDateCreate' returns a Core Foundation object of type 'CFDateRef' with a +1 retain count + message + Call to function 'CFDateCreate' returns a Core Foundation object of type 'CFDateRef' with a +1 retain count + + + kindevent + location + + line1627 + col20 + file0 + + ranges + + + + line1627 + col20 + file0 + + + line1627 + col42 + file0 + + + + depth0 + extended_message + Returning from 'returnsRetainedCFDate' + message + Returning from 'returnsRetainedCFDate' + + + kindcontrol + edges + + + start + + + line1627 + col20 + file0 + + + line1627 + col40 + file0 + + + end + + + line1627 + col3 + file0 + + + line1627 + col8 + file0 + + + + + + + kindevent + location + + line1627 + col3 + file0 + + ranges + + + + line1627 + col3 + file0 + + + line1627 + col42 + file0 + + + + depth0 + extended_message + Object leaked: allocated object of type 'CFDateRef' is returned from a method whose name ('alsoReturnsRetained') does not start with 'copy', 'mutableCopy', 'alloc' or 'new'. This violates the naming convention rules given in the Memory Management Guide for Cocoa + message + Object leaked: allocated object of type 'CFDateRef' is returned from a method whose name ('alsoReturnsRetained') does not start with 'copy', 'mutableCopy', 'alloc' or 'new'. This violates the naming convention rules given in the Memory Management Guide for Cocoa + + + descriptionPotential leak of an object of type 'CFDateRef' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak of returned object + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context7ee55b74b5ee01c6ffa2a3d83c8cf88b + issue_context_kindObjective-C method + issue_contextalsoReturnsRetained + issue_hash_function_offset1 + location + + line1627 + col3 + file0 + + ExecutedLines + + 0 + + 1604 + 1605 + 1606 + 1626 + 1627 + + + + + path + + + kindcontrol + edges + + + start + + + line1631 + col3 + file0 + + + line1631 + col8 + file0 + + + end + + + line1631 + col10 + file0 + + + line1631 + col30 + file0 + + + + + + + kindevent + location + + line1631 + col10 + file0 + + ranges + + + + line1631 + col10 + file0 + + + line1631 + col32 + file0 + + + + depth0 + extended_message + Calling 'returnsRetainedCFDate' + message + Calling 'returnsRetainedCFDate' + + + kindevent + location + + line1604 + col1 + file0 + + depth1 + extended_message + Entered call from 'alsoReturnsRetainedAsCF' + message + Entered call from 'alsoReturnsRetainedAsCF' + + + kindcontrol + edges + + + start + + + line1604 + col1 + file0 + + + line1604 + col19 + file0 + + + end + + + line1606 + col3 + file0 + + + line1606 + col8 + file0 + + + + + + + kindevent + location + + line1606 + col10 + file0 + + ranges + + + + line1606 + col10 + file0 + + + line1606 + col52 + file0 + + + + depth1 + extended_message + Call to function 'CFDateCreate' returns a Core Foundation object of type 'CFDateRef' with a +1 retain count + message + Call to function 'CFDateCreate' returns a Core Foundation object of type 'CFDateRef' with a +1 retain count + + + kindevent + location + + line1631 + col10 + file0 + + ranges + + + + line1631 + col10 + file0 + + + line1631 + col32 + file0 + + + + depth0 + extended_message + Returning from 'returnsRetainedCFDate' + message + Returning from 'returnsRetainedCFDate' + + + kindcontrol + edges + + + start + + + line1631 + col10 + file0 + + + line1631 + col30 + file0 + + + end + + + line1631 + col3 + file0 + + + line1631 + col8 + file0 + + + + + + + kindevent + location + + line1631 + col3 + file0 + + ranges + + + + line1631 + col3 + file0 + + + line1631 + col32 + file0 + + + + depth0 + extended_message + Object leaked: allocated object of type 'CFDateRef' is returned from a method whose name ('alsoReturnsRetainedAsCF') does not start with 'copy', 'mutableCopy', 'alloc' or 'new'. This violates the naming convention rules given in the Memory Management Guide for Cocoa + message + Object leaked: allocated object of type 'CFDateRef' is returned from a method whose name ('alsoReturnsRetainedAsCF') does not start with 'copy', 'mutableCopy', 'alloc' or 'new'. This violates the naming convention rules given in the Memory Management Guide for Cocoa + + + descriptionPotential leak of an object of type 'CFDateRef' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak of returned object + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context177b2cf7eb3d8334393ee0861f5a38ac + issue_context_kindObjective-C method + issue_contextalsoReturnsRetainedAsCF + issue_hash_function_offset1 + location + + line1631 + col3 + file0 + + ExecutedLines + + 0 + + 1604 + 1605 + 1606 + 1630 + 1631 + + + + + path + + + kindcontrol + edges + + + start + + + line1651 + col3 + file0 + + + line1651 + col8 + file0 + + + end + + + line1652 + col3 + file0 + + + line1652 + col13 + file0 + + + + + + + kindevent + location + + line1652 + col23 + file0 + + ranges + + + + line1652 + col23 + file0 + + + line1652 + col82 + file0 + + + + depth0 + extended_message + Call to function 'CFNumberCreate' returns a Core Foundation object of type 'CFNumberRef' with a +1 retain count + message + Call to function 'CFNumberCreate' returns a Core Foundation object of type 'CFNumberRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line1652 + col3 + file0 + + + line1652 + col13 + file0 + + + end + + + line1653 + col1 + file0 + + + line1653 + col1 + file0 + + + + + + + kindevent + location + + line1653 + col1 + file0 + + depth0 + extended_message + Object leaked: object allocated and stored into 'value' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'value' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'value' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context85e9d8130a1f1ec37f0ba26746abd749 + issue_context_kindfunction + issue_contexttest_panic_negative + issue_hash_function_offset2 + location + + line1653 + col1 + file0 + + ExecutedLines + + 0 + + 1650 + 1651 + 1652 + 1653 + + + + + path + + + kindcontrol + edges + + + start + + + line1662 + col3 + file0 + + + line1662 + col8 + file0 + + + end + + + line1663 + col3 + file0 + + + line1663 + col13 + file0 + + + + + + + kindevent + location + + line1663 + col23 + file0 + + ranges + + + + line1663 + col23 + file0 + + + line1663 + col82 + file0 + + + + depth0 + extended_message + Call to function 'CFNumberCreate' returns a Core Foundation object of type 'CFNumberRef' with a +1 retain count + message + Call to function 'CFNumberCreate' returns a Core Foundation object of type 'CFNumberRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line1663 + col3 + file0 + + + line1663 + col13 + file0 + + + end + + + line1664 + col3 + file0 + + + line1664 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line1664 + col3 + file0 + + + line1664 + col4 + file0 + + + end + + + line1664 + col7 + file0 + + + line1664 + col7 + file0 + + + + + + + kindevent + location + + line1664 + col7 + file0 + + ranges + + + + line1664 + col7 + file0 + + + line1664 + col7 + file0 + + + + depth0 + extended_message + Assuming 'x' is 0 + message + Assuming 'x' is 0 + + + kindcontrol + edges + + + start + + + line1664 + col7 + file0 + + + line1664 + col7 + file0 + + + end + + + line1666 + col1 + file0 + + + line1666 + col1 + file0 + + + + + + + kindevent + location + + line1666 + col1 + file0 + + depth0 + extended_message + Object leaked: object allocated and stored into 'value' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'value' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'value' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context4a0b16976e0517b38b2ccc16e2928c2e + issue_context_kindfunction + issue_contexttest_panic_neg_2 + issue_hash_function_offset2 + location + + line1666 + col1 + file0 + + ExecutedLines + + 0 + + 1661 + 1662 + 1663 + 1664 + 1666 + + + + + path + + + kindevent + location + + line1686 + col22 + file0 + + ranges + + + + line1686 + col22 + file0 + + + line1686 + col53 + file0 + + + + depth0 + extended_message + Method returns an instance of NSNumber with a +1 retain count + message + Method returns an instance of NSNumber with a +1 retain count + + + kindcontrol + edges + + + start + + + line1686 + col3 + file0 + + + line1686 + col10 + file0 + + + end + + + line1687 + col3 + file0 + + + line1687 + col3 + file0 + + + + + + + kindevent + location + + line1687 + col3 + file0 + + ranges + + + + line1687 + col3 + file0 + + + line1687 + col7 + file0 + + + + depth0 + extended_message + Object leaked: object allocated and stored into 'number' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'number' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'number' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_contextaf73d9c62952a300a7c393ebd5073f75 + issue_context_kindfunction + issue_contexttest_blocks_1_pos + issue_hash_function_offset1 + location + + line1687 + col3 + file0 + + ExecutedLines + + 0 + + 1685 + 1686 + 1687 + + + + + path + + + kindevent + location + + line1707 + col22 + file0 + + ranges + + + + line1707 + col22 + file0 + + + line1707 + col53 + file0 + + + + depth0 + extended_message + Method returns an instance of NSNumber with a +1 retain count + message + Method returns an instance of NSNumber with a +1 retain count + + + kindcontrol + edges + + + start + + + line1707 + col3 + file0 + + + line1707 + col10 + file0 + + + end + + + line1708 + col3 + file0 + + + line1708 + col3 + file0 + + + + + + + kindevent + location + + line1708 + col3 + file0 + + ranges + + + + line1708 + col3 + file0 + + + line1708 + col39 + file0 + + + + depth0 + extended_message + Calling anonymous block + message + Calling anonymous block + + + kindevent + location + + line1708 + col3 + file0 + + depth1 + extended_message + Entered call from 'test_blocks_1_indirect_retain_via_call' + message + Entered call from 'test_blocks_1_indirect_retain_via_call' + + + kindcontrol + edges + + + start + + + line1708 + col3 + file0 + + + line1708 + col3 + file0 + + + end + + + line1708 + col19 + file0 + + + line1708 + col19 + file0 + + + + + + + kindevent + location + + line1708 + col19 + file0 + + ranges + + + + line1708 + col19 + file0 + + + line1708 + col28 + file0 + + + + + line1708 + col20 + file0 + + + line1708 + col20 + file0 + + + + depth1 + extended_message + Reference count incremented. The object now has a +2 retain count + message + Reference count incremented. The object now has a +2 retain count + + + kindevent + location + + line1708 + col3 + file0 + + ranges + + + + line1708 + col3 + file0 + + + line1708 + col39 + file0 + + + + depth0 + extended_message + Returning to caller + message + Returning to caller + + + kindcontrol + edges + + + start + + + line1708 + col3 + file0 + + + line1708 + col3 + file0 + + + end + + + line1709 + col1 + file0 + + + line1709 + col1 + file0 + + + + + + + kindevent + location + + line1709 + col1 + file0 + + depth0 + extended_message + Object leaked: object allocated and stored into 'number' is not referenced later in this execution path and has a retain count of +2 + message + Object leaked: object allocated and stored into 'number' is not referenced later in this execution path and has a retain count of +2 + + + descriptionPotential leak of an object stored into 'number' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context771b2a332053388ffbdd9ba74ea84c5e + issue_context_kindfunction + issue_contexttest_blocks_1_indirect_retain_via_call + issue_hash_function_offset1 + location + + line1709 + col1 + file0 + + ExecutedLines + + 0 + + 1706 + 1707 + 1708 + 1709 + + + + + path + + + kindcontrol + edges + + + start + + + line1759 + col5 + file0 + + + line1759 + col14 + file0 + + + end + + + line1762 + col5 + file0 + + + line1762 + col9 + file0 + + + + + + + kindcontrol + edges + + + start + + + line1762 + col5 + file0 + + + line1762 + col9 + file0 + + + end + + + line1762 + col12 + file0 + + + line1762 + col24 + file0 + + + + + + + kindevent + location + + line1762 + col12 + file0 + + ranges + + + + line1762 + col12 + file0 + + + line1762 + col38 + file0 + + + + depth0 + extended_message + Assuming 'error_to_dump' is not equal to null + message + Assuming 'error_to_dump' is not equal to null + + + kindevent + location + + line1762 + col12 + file0 + + ranges + + + + line1762 + col12 + file0 + + + line1762 + col38 + file0 + + + + depth0 + extended_message + Entering loop body + message + Entering loop body + + + kindcontrol + edges + + + start + + + line1762 + col12 + file0 + + + line1762 + col24 + file0 + + + end + + + line1763 + col9 + file0 + + + line1763 + col23 + file0 + + + + + + + kindcontrol + edges + + + start + + + line1763 + col9 + file0 + + + line1763 + col23 + file0 + + + end + + + line1765 + col9 + file0 + + + line1765 + col12 + file0 + + + + + + + kindevent + location + + line1765 + col16 + file0 + + ranges + + + + line1765 + col16 + file0 + + + line1765 + col49 + file0 + + + + depth0 + extended_message + Call to function 'CFErrorCopyUserInfo' returns a Core Foundation object of type 'CFDictionaryRef' with a +1 retain count + message + Call to function 'CFErrorCopyUserInfo' returns a Core Foundation object of type 'CFDictionaryRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line1765 + col9 + file0 + + + line1765 + col12 + file0 + + + end + + + line1767 + col9 + file0 + + + line1767 + col10 + file0 + + + + + + + kindcontrol + edges + + + start + + + line1767 + col9 + file0 + + + line1767 + col10 + file0 + + + end + + + line1767 + col13 + file0 + + + line1767 + col16 + file0 + + + + + + + kindevent + location + + line1767 + col13 + file0 + + ranges + + + + line1767 + col13 + file0 + + + line1767 + col30 + file0 + + + + depth0 + extended_message + Assuming 'info' is not equal to null + message + Assuming 'info' is not equal to null + + + kindcontrol + edges + + + start + + + line1767 + col13 + file0 + + + line1767 + col16 + file0 + + + end + + + line1770 + col23 + file0 + + + line1770 + col23 + file0 + + + + + + + kindevent + location + + line1770 + col23 + file0 + + depth0 + extended_message + Object leaked: object allocated and stored into 'info' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'info' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'info' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context39f8c30f7436f678d5259c0fdd3a0dad + issue_context_kindfunction + issue_contextrdar_8724287 + issue_hash_function_offset7 + location + + line1770 + col23 + file0 + + ExecutedLines + + 0 + + 1757 + 1758 + 1759 + 1761 + 1762 + 1763 + 1765 + 1767 + 1770 + + + + + path + + + kindevent + location + + line1815 + col10 + file0 + + ranges + + + + line1815 + col10 + file0 + + + line1815 + col60 + file0 + + + + depth0 + extended_message + Call to function 'CFArrayCreateMutable' returns a Core Foundation object of type 'CFMutableArrayRef' with a +1 retain count + message + Call to function 'CFArrayCreateMutable' returns a Core Foundation object of type 'CFMutableArrayRef' with a +1 retain count + + + kindevent + location + + line1815 + col3 + file0 + + ranges + + + + line1815 + col3 + file0 + + + line1815 + col60 + file0 + + + + depth0 + extended_message + Object leaked: allocated object of type 'CFMutableArrayRef' is returned from a function whose name ('camelcase_createno') does not contain 'Copy' or 'Create'. This violates the naming convention rules given in the Memory Management Guide for Core Foundation + message + Object leaked: allocated object of type 'CFMutableArrayRef' is returned from a function whose name ('camelcase_createno') does not contain 'Copy' or 'Create'. This violates the naming convention rules given in the Memory Management Guide for Core Foundation + + + descriptionPotential leak of an object of type 'CFMutableArrayRef' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak of returned object + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context107e3efdeb8cdff4bef4c64183c4f6fa + issue_context_kindfunction + issue_contextcamelcase_createno + issue_hash_function_offset1 + location + + line1815 + col3 + file0 + + ExecutedLines + + 0 + + 1814 + 1815 + + + + + path + + + kindevent + location + + line1823 + col10 + file0 + + ranges + + + + line1823 + col10 + file0 + + + line1823 + col60 + file0 + + + + depth0 + extended_message + Call to function 'CFArrayCreateMutable' returns a Core Foundation object of type 'CFMutableArrayRef' with a +1 retain count + message + Call to function 'CFArrayCreateMutable' returns a Core Foundation object of type 'CFMutableArrayRef' with a +1 retain count + + + kindevent + location + + line1823 + col3 + file0 + + ranges + + + + line1823 + col3 + file0 + + + line1823 + col60 + file0 + + + + depth0 + extended_message + Object leaked: allocated object of type 'CFMutableArrayRef' is returned from a function whose name ('camelcase_copying') does not contain 'Copy' or 'Create'. This violates the naming convention rules given in the Memory Management Guide for Core Foundation + message + Object leaked: allocated object of type 'CFMutableArrayRef' is returned from a function whose name ('camelcase_copying') does not contain 'Copy' or 'Create'. This violates the naming convention rules given in the Memory Management Guide for Core Foundation + + + descriptionPotential leak of an object of type 'CFMutableArrayRef' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak of returned object + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context20c973a013858abb0a926276c956f858 + issue_context_kindfunction + issue_contextcamelcase_copying + issue_hash_function_offset1 + location + + line1823 + col3 + file0 + + ExecutedLines + + 0 + + 1822 + 1823 + + + + + path + + + kindevent + location + + line1844 + col10 + file0 + + ranges + + + + line1844 + col10 + file0 + + + line1844 + col60 + file0 + + + + depth0 + extended_message + Call to function 'CFArrayCreateMutable' returns a Core Foundation object of type 'CFMutableArrayRef' with a +1 retain count + message + Call to function 'CFArrayCreateMutable' returns a Core Foundation object of type 'CFMutableArrayRef' with a +1 retain count + + + kindevent + location + + line1844 + col3 + file0 + + ranges + + + + line1844 + col3 + file0 + + + line1844 + col60 + file0 + + + + depth0 + extended_message + Object leaked: allocated object of type 'CFMutableArrayRef' is returned from a function whose name ('camel_creat') does not contain 'Copy' or 'Create'. This violates the naming convention rules given in the Memory Management Guide for Core Foundation + message + Object leaked: allocated object of type 'CFMutableArrayRef' is returned from a function whose name ('camel_creat') does not contain 'Copy' or 'Create'. This violates the naming convention rules given in the Memory Management Guide for Core Foundation + + + descriptionPotential leak of an object of type 'CFMutableArrayRef' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak of returned object + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context80ee99e51561a37297429740e3a4da0c + issue_context_kindfunction + issue_contextcamel_creat + issue_hash_function_offset1 + location + + line1844 + col3 + file0 + + ExecutedLines + + 0 + + 1843 + 1844 + + + + + path + + + kindevent + location + + line1856 + col10 + file0 + + ranges + + + + line1856 + col10 + file0 + + + line1856 + col60 + file0 + + + + depth0 + extended_message + Call to function 'CFArrayCreateMutable' returns a Core Foundation object of type 'CFMutableArrayRef' with a +1 retain count + message + Call to function 'CFArrayCreateMutable' returns a Core Foundation object of type 'CFMutableArrayRef' with a +1 retain count + + + kindevent + location + + line1856 + col3 + file0 + + ranges + + + + line1856 + col3 + file0 + + + line1856 + col60 + file0 + + + + depth0 + extended_message + Object leaked: allocated object of type 'CFMutableArrayRef' is returned from a function whose name ('camel_copymachine') does not contain 'Copy' or 'Create'. This violates the naming convention rules given in the Memory Management Guide for Core Foundation + message + Object leaked: allocated object of type 'CFMutableArrayRef' is returned from a function whose name ('camel_copymachine') does not contain 'Copy' or 'Create'. This violates the naming convention rules given in the Memory Management Guide for Core Foundation + + + descriptionPotential leak of an object of type 'CFMutableArrayRef' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak of returned object + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_contexta4e28a04f6a8d87c8aaf4d71c37cac0f + issue_context_kindfunction + issue_contextcamel_copymachine + issue_hash_function_offset1 + location + + line1856 + col3 + file0 + + ExecutedLines + + 0 + + 1855 + 1856 + + + + + path + + + kindcontrol + edges + + + start + + + line1876 + col3 + file0 + + + line1876 + col16 + file0 + + + end + + + line1877 + col3 + file0 + + + line1877 + col11 + file0 + + + + + + + kindevent + location + + line1877 + col24 + file0 + + ranges + + + + line1877 + col24 + file0 + + + line1877 + col41 + file0 + + + + depth0 + extended_message + Call to function 'CFDateCreate' returns a Core Foundation object of type 'CFDateRef' with a +1 retain count + message + Call to function 'CFDateCreate' returns a Core Foundation object of type 'CFDateRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line1877 + col3 + file0 + + + line1877 + col11 + file0 + + + end + + + line1878 + col1 + file0 + + + line1878 + col1 + file0 + + + + + + + kindevent + location + + line1878 + col1 + file0 + + depth0 + extended_message + Object leaked: object allocated and stored into 'vals' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'vals' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'vals' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context6b727a438d8411c058fd32867b9402bc + issue_context_kindfunction + issue_contextrdar6582778 + issue_hash_function_offset2 + location + + line1878 + col1 + file0 + + ExecutedLines + + 0 + + 1875 + 1876 + 1877 + 1878 + + + + + path + + + kindcontrol + edges + + + start + + + line1902 + col3 + file0 + + + line1902 + col16 + file0 + + + end + + + line1904 + col3 + file0 + + + line1904 + col10 + file0 + + + + + + + kindevent + location + + line1904 + col22 + file0 + + ranges + + + + line1904 + col22 + file0 + + + line1904 + col64 + file0 + + + + depth0 + extended_message + Method returns an instance of NSString with a +1 retain count + message + Method returns an instance of NSString with a +1 retain count + + + kindcontrol + edges + + + start + + + line1904 + col3 + file0 + + + line1904 + col10 + file0 + + + end + + + line1905 + col3 + file0 + + + line1905 + col3 + file0 + + + + + + + kindevent + location + + line1905 + col3 + file0 + + ranges + + + + line1905 + col3 + file0 + + + line1905 + col18 + file0 + + + + + line1905 + col4 + file0 + + + line1905 + col9 + file0 + + + + depth0 + extended_message + Object released + message + Object released + + + kindcontrol + edges + + + start + + + line1905 + col3 + file0 + + + line1905 + col3 + file0 + + + end + + + line1907 + col3 + file0 + + + line1907 + col10 + file0 + + + + + + + kindcontrol + edges + + + start + + + line1907 + col3 + file0 + + + line1907 + col10 + file0 + + + end + + + line1907 + col27 + file0 + + + line1907 + col27 + file0 + + + + + + + kindevent + location + + line1907 + col27 + file0 + + ranges + + + + line1907 + col28 + file0 + + + line1907 + col33 + file0 + + + + depth0 + extended_message + Reference-counted object is used after it is released + message + Reference-counted object is used after it is released + + + descriptionReference-counted object is used after it is released + categoryMemory (Core Foundation/Objective-C/OSObject) + typeUse-after-release + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_contextb39dcf9df7cec8dd73cbbe25b2a7d6c5 + issue_context_kindfunction + issue_contextrdar10232019_positive + issue_hash_function_offset6 + location + + line1907 + col27 + file0 + + ExecutedLines + + 0 + + 1901 + 1902 + 1904 + 1905 + 1907 + + + + + path + + + kindcontrol + edges + + + start + + + line2034 + col9 + file0 + + + line2034 + col16 + file0 + + + end + + + line2035 + col9 + file0 + + + line2035 + col15 + file0 + + + + + + + kindevent + location + + line2035 + col22 + file0 + + ranges + + + + line2035 + col22 + file0 + + + line2035 + col66 + file0 + + + + depth0 + extended_message + Method returns an instance of NSArray with a +1 retain count + message + Method returns an instance of NSArray with a +1 retain count + + + kindcontrol + edges + + + start + + + line2035 + col9 + file0 + + + line2035 + col15 + file0 + + + end + + + line2038 + col9 + file0 + + + line2038 + col9 + file0 + + + + + + + kindevent + location + + line2038 + col9 + file0 + + ranges + + + + line2038 + col9 + file0 + + + line2038 + col23 + file0 + + + + depth0 + extended_message + Object leaked: object allocated and stored into 'a' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'a' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'a' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_contexta501f743b22f1feb5dc317fcad4f7556 + issue_context_kindfunction + issue_contexttest_objc_arrays + issue_hash_function_offset3 + location + + line2038 + col9 + file0 + + ExecutedLines + + 0 + + 2032 + 2034 + 2035 + 2036 + 2037 + 2038 + + + + + path + + + kindcontrol + edges + + + start + + + line2034 + col9 + file0 + + + line2034 + col16 + file0 + + + end + + + line2038 + col9 + file0 + + + line2038 + col9 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2038 + col9 + file0 + + + line2038 + col9 + file0 + + + end + + + line2042 + col9 + file0 + + + line2042 + col16 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2042 + col9 + file0 + + + line2042 + col16 + file0 + + + end + + + line2044 + col9 + file0 + + + line2044 + col15 + file0 + + + + + + + kindevent + location + + line2044 + col23 + file0 + + ranges + + + + line2044 + col23 + file0 + + + line2044 + col56 + file0 + + + + depth0 + extended_message + Method returns an instance of NSArray with a +1 retain count + message + Method returns an instance of NSArray with a +1 retain count + + + kindcontrol + edges + + + start + + + line2044 + col9 + file0 + + + line2044 + col15 + file0 + + + end + + + line2047 + col9 + file0 + + + line2047 + col9 + file0 + + + + + + + kindevent + location + + line2047 + col9 + file0 + + ranges + + + + line2047 + col9 + file0 + + + line2047 + col23 + file0 + + + + depth0 + extended_message + Object leaked: object allocated and stored into 'a2' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'a2' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'a2' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_contexta141a6ad33e8ff2ae3b13da0ad36ebc5 + issue_context_kindfunction + issue_contexttest_objc_arrays + issue_hash_function_offset12 + location + + line2047 + col9 + file0 + + ExecutedLines + + 0 + + 2032 + 2034 + 2035 + 2036 + 2037 + 2038 + 2042 + 2043 + 2044 + 2045 + 2046 + 2047 + + + + + path + + + kindcontrol + edges + + + start + + + line2034 + col9 + file0 + + + line2034 + col16 + file0 + + + end + + + line2038 + col9 + file0 + + + line2038 + col9 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2038 + col9 + file0 + + + line2038 + col9 + file0 + + + end + + + line2042 + col9 + file0 + + + line2042 + col16 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2042 + col9 + file0 + + + line2042 + col16 + file0 + + + end + + + line2047 + col9 + file0 + + + line2047 + col9 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2047 + col9 + file0 + + + line2047 + col9 + file0 + + + end + + + line2051 + col9 + file0 + + + line2051 + col16 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2051 + col9 + file0 + + + line2051 + col16 + file0 + + + end + + + line2052 + col9 + file0 + + + line2052 + col15 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2052 + col9 + file0 + + + line2052 + col15 + file0 + + + end + + + line2052 + col24 + file0 + + + line2052 + col24 + file0 + + + + + + + kindevent + location + + line2052 + col24 + file0 + + ranges + + + + line2052 + col24 + file0 + + + line2052 + col27 + file0 + + + + depth0 + extended_message + NSArray literal is an object with a +0 retain count + message + NSArray literal is an object with a +0 retain count + + + kindevent + location + + line2052 + col23 + file0 + + ranges + + + + line2052 + col23 + file0 + + + line2052 + col35 + file0 + + + + + line2052 + col24 + file0 + + + line2052 + col27 + file0 + + + + depth0 + extended_message + Reference count incremented. The object now has a +1 retain count + message + Reference count incremented. The object now has a +1 retain count + + + kindcontrol + edges + + + start + + + line2052 + col23 + file0 + + + line2052 + col23 + file0 + + + end + + + line2052 + col9 + file0 + + + line2052 + col15 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2052 + col9 + file0 + + + line2052 + col15 + file0 + + + end + + + line2055 + col9 + file0 + + + line2055 + col9 + file0 + + + + + + + kindevent + location + + line2055 + col9 + file0 + + ranges + + + + line2055 + col9 + file0 + + + line2055 + col23 + file0 + + + + depth0 + extended_message + Object leaked: object allocated and stored into 'a3' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'a3' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'a3' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context2b072d75e8da8e3fe8f7968a85efb37c + issue_context_kindfunction + issue_contexttest_objc_arrays + issue_hash_function_offset20 + location + + line2055 + col9 + file0 + + ExecutedLines + + 0 + + 2032 + 2034 + 2035 + 2036 + 2037 + 2038 + 2042 + 2043 + 2044 + 2045 + 2046 + 2047 + 2051 + 2052 + 2053 + 2054 + 2055 + + + + + path + + + kindcontrol + edges + + + start + + + line2034 + col9 + file0 + + + line2034 + col16 + file0 + + + end + + + line2038 + col9 + file0 + + + line2038 + col9 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2038 + col9 + file0 + + + line2038 + col9 + file0 + + + end + + + line2042 + col9 + file0 + + + line2042 + col16 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2042 + col9 + file0 + + + line2042 + col16 + file0 + + + end + + + line2047 + col9 + file0 + + + line2047 + col9 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2047 + col9 + file0 + + + line2047 + col9 + file0 + + + end + + + line2051 + col9 + file0 + + + line2051 + col16 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2051 + col9 + file0 + + + line2051 + col16 + file0 + + + end + + + line2055 + col9 + file0 + + + line2055 + col9 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2055 + col9 + file0 + + + line2055 + col9 + file0 + + + end + + + line2059 + col9 + file0 + + + line2059 + col16 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2059 + col9 + file0 + + + line2059 + col16 + file0 + + + end + + + line2060 + col9 + file0 + + + line2060 + col15 + file0 + + + + + + + kindevent + location + + line2060 + col22 + file0 + + ranges + + + + line2060 + col22 + file0 + + + line2060 + col57 + file0 + + + + depth0 + extended_message + Method returns an instance of NSArray with a +1 retain count + message + Method returns an instance of NSArray with a +1 retain count + + + kindcontrol + edges + + + start + + + line2060 + col9 + file0 + + + line2060 + col15 + file0 + + + end + + + line2064 + col9 + file0 + + + line2064 + col9 + file0 + + + + + + + kindevent + location + + line2064 + col9 + file0 + + ranges + + + + line2064 + col9 + file0 + + + line2064 + col23 + file0 + + + + depth0 + extended_message + Object leaked: object allocated and stored into 'a' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'a' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'a' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context0bfdfb7e392626e0fccc6ab9f58f1ca8 + issue_context_kindfunction + issue_contexttest_objc_arrays + issue_hash_function_offset28 + location + + line2064 + col9 + file0 + + ExecutedLines + + 0 + + 2032 + 2034 + 2035 + 2036 + 2037 + 2038 + 2042 + 2043 + 2044 + 2045 + 2046 + 2047 + 2051 + 2052 + 2053 + 2054 + 2055 + 2059 + 2060 + 2061 + 2063 + 2064 + + + + + path + + + kindcontrol + edges + + + start + + + line2034 + col9 + file0 + + + line2034 + col16 + file0 + + + end + + + line2038 + col9 + file0 + + + line2038 + col9 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2038 + col9 + file0 + + + line2038 + col9 + file0 + + + end + + + line2042 + col9 + file0 + + + line2042 + col16 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2042 + col9 + file0 + + + line2042 + col16 + file0 + + + end + + + line2047 + col9 + file0 + + + line2047 + col9 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2047 + col9 + file0 + + + line2047 + col9 + file0 + + + end + + + line2051 + col9 + file0 + + + line2051 + col16 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2051 + col9 + file0 + + + line2051 + col16 + file0 + + + end + + + line2055 + col9 + file0 + + + line2055 + col9 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2055 + col9 + file0 + + + line2055 + col9 + file0 + + + end + + + line2059 + col9 + file0 + + + line2059 + col16 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2059 + col9 + file0 + + + line2059 + col16 + file0 + + + end + + + line2064 + col9 + file0 + + + line2064 + col9 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2064 + col9 + file0 + + + line2064 + col9 + file0 + + + end + + + line2068 + col9 + file0 + + + line2068 + col15 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2068 + col9 + file0 + + + line2068 + col15 + file0 + + + end + + + line2069 + col9 + file0 + + + line2069 + col20 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2069 + col9 + file0 + + + line2069 + col20 + file0 + + + end + + + line2069 + col28 + file0 + + + line2069 + col28 + file0 + + + + + + + kindevent + location + + line2069 + col28 + file0 + + ranges + + + + line2069 + col28 + file0 + + + line2069 + col35 + file0 + + + + depth0 + extended_message + NSDictionary literal is an object with a +0 retain count + message + NSDictionary literal is an object with a +0 retain count + + + kindevent + location + + line2069 + col27 + file0 + + ranges + + + + line2069 + col27 + file0 + + + line2069 + col43 + file0 + + + + + line2069 + col28 + file0 + + + line2069 + col35 + file0 + + + + depth0 + extended_message + Reference count incremented. The object now has a +1 retain count + message + Reference count incremented. The object now has a +1 retain count + + + kindcontrol + edges + + + start + + + line2069 + col27 + file0 + + + line2069 + col27 + file0 + + + end + + + line2069 + col9 + file0 + + + line2069 + col20 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2069 + col9 + file0 + + + line2069 + col20 + file0 + + + end + + + line2073 + col9 + file0 + + + line2073 + col9 + file0 + + + + + + + kindevent + location + + line2073 + col9 + file0 + + ranges + + + + line2073 + col9 + file0 + + + line2073 + col23 + file0 + + + + depth0 + extended_message + Object leaked: object allocated and stored into 'a' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'a' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'a' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_contextff7c34e661a42d06a7fb3e9669e70339 + issue_context_kindfunction + issue_contexttest_objc_arrays + issue_hash_function_offset37 + location + + line2073 + col9 + file0 + + ExecutedLines + + 0 + + 2032 + 2034 + 2035 + 2036 + 2037 + 2038 + 2042 + 2043 + 2044 + 2045 + 2046 + 2047 + 2051 + 2052 + 2053 + 2054 + 2055 + 2059 + 2060 + 2061 + 2063 + 2064 + 2068 + 2069 + 2070 + 2072 + 2073 + + + + + path + + + kindcontrol + edges + + + start + + + line2078 + col3 + file0 + + + line2078 + col4 + file0 + + + end + + + line2078 + col15 + file0 + + + line2078 + col15 + file0 + + + + + + + kindevent + location + + line2078 + col15 + file0 + + ranges + + + + line2078 + col15 + file0 + + + line2078 + col16 + file0 + + + + depth0 + extended_message + NSNumber literal is an object with a +0 retain count + message + NSNumber literal is an object with a +0 retain count + + + kindevent + location + + line2078 + col14 + file0 + + ranges + + + + line2078 + col14 + file0 + + + line2078 + col24 + file0 + + + + + line2078 + col15 + file0 + + + line2078 + col16 + file0 + + + + depth0 + extended_message + Reference count incremented. The object now has a +1 retain count + message + Reference count incremented. The object now has a +1 retain count + + + kindcontrol + edges + + + start + + + line2078 + col14 + file0 + + + line2078 + col14 + file0 + + + end + + + line2078 + col3 + file0 + + + line2078 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2078 + col3 + file0 + + + line2078 + col4 + file0 + + + end + + + line2079 + col3 + file0 + + + line2079 + col3 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2079 + col3 + file0 + + + line2079 + col3 + file0 + + + end + + + line2080 + col1 + file0 + + + line2080 + col1 + file0 + + + + + + + kindevent + location + + line2080 + col1 + file0 + + depth0 + extended_message + Object leaked: object allocated and stored into 'value' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'value' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'value' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context73e84c042932d2e17e00f00dc3d36d5a + issue_context_kindfunction + issue_contexttest_objc_integer_literals + issue_hash_function_offset1 + location + + line2080 + col1 + file0 + + ExecutedLines + + 0 + + 2077 + 2078 + 2079 + 2080 + + + + + path + + + kindcontrol + edges + + + start + + + line2083 + col3 + file0 + + + line2083 + col4 + file0 + + + end + + + line2083 + col15 + file0 + + + line2083 + col15 + file0 + + + + + + + kindevent + location + + line2083 + col15 + file0 + + ranges + + + + line2083 + col15 + file0 + + + line2083 + col18 + file0 + + + + depth0 + extended_message + NSNumber boxed expression produces an object with a +0 retain count + message + NSNumber boxed expression produces an object with a +0 retain count + + + kindevent + location + + line2083 + col14 + file0 + + ranges + + + + line2083 + col14 + file0 + + + line2083 + col26 + file0 + + + + + line2083 + col15 + file0 + + + line2083 + col18 + file0 + + + + depth0 + extended_message + Reference count incremented. The object now has a +1 retain count + message + Reference count incremented. The object now has a +1 retain count + + + kindcontrol + edges + + + start + + + line2083 + col14 + file0 + + + line2083 + col14 + file0 + + + end + + + line2083 + col3 + file0 + + + line2083 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2083 + col3 + file0 + + + line2083 + col4 + file0 + + + end + + + line2087 + col3 + file0 + + + line2087 + col3 + file0 + + + + + + + kindevent + location + + line2087 + col3 + file0 + + ranges + + + + line2087 + col3 + file0 + + + line2087 + col21 + file0 + + + + depth0 + extended_message + Object leaked: object allocated and stored into 'value' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'value' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'value' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context465e592d4f7a187717d00b8154a614b5 + issue_context_kindfunction + issue_contexttest_objc_boxed_expressions + issue_hash_function_offset1 + location + + line2087 + col3 + file0 + + ExecutedLines + + 0 + + 2082 + 2083 + 2084 + 2086 + 2087 + + + + + path + + + kindcontrol + edges + + + start + + + line2083 + col3 + file0 + + + line2083 + col4 + file0 + + + end + + + line2086 + col3 + file0 + + + line2086 + col7 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2086 + col3 + file0 + + + line2086 + col7 + file0 + + + end + + + line2086 + col12 + file0 + + + line2086 + col12 + file0 + + + + + + + kindevent + location + + line2086 + col12 + file0 + + ranges + + + + line2086 + col12 + file0 + + + line2086 + col15 + file0 + + + + depth0 + extended_message + NSString boxed expression produces an object with a +0 retain count + message + NSString boxed expression produces an object with a +0 retain count + + + kindevent + location + + line2086 + col11 + file0 + + ranges + + + + line2086 + col11 + file0 + + + line2086 + col23 + file0 + + + + + line2086 + col12 + file0 + + + line2086 + col15 + file0 + + + + depth0 + extended_message + Reference count incremented. The object now has a +1 retain count + message + Reference count incremented. The object now has a +1 retain count + + + kindcontrol + edges + + + start + + + line2086 + col11 + file0 + + + line2086 + col11 + file0 + + + end + + + line2086 + col3 + file0 + + + line2086 + col7 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2086 + col3 + file0 + + + line2086 + col7 + file0 + + + end + + + line2087 + col3 + file0 + + + line2087 + col3 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2087 + col3 + file0 + + + line2087 + col3 + file0 + + + end + + + line2088 + col1 + file0 + + + line2088 + col1 + file0 + + + + + + + kindevent + location + + line2088 + col1 + file0 + + depth0 + extended_message + Object leaked: object allocated and stored into 'value' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'value' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'value' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_contextc701bd0c60f51d96c047aa78c9e0eb99 + issue_context_kindfunction + issue_contexttest_objc_boxed_expressions + issue_hash_function_offset4 + location + + line2088 + col1 + file0 + + ExecutedLines + + 0 + + 2082 + 2083 + 2084 + 2086 + 2087 + 2088 + + + + + path + + + kindcontrol + edges + + + start + + + line2094 + col5 + file0 + + + line2094 + col12 + file0 + + + end + + + line2095 + col5 + file0 + + + line2095 + col6 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2095 + col5 + file0 + + + line2095 + col6 + file0 + + + end + + + line2095 + col8 + file0 + + + line2095 + col8 + file0 + + + + + + + kindevent + location + + line2095 + col8 + file0 + + ranges + + + + line2095 + col8 + file0 + + + line2095 + col12 + file0 + + + + depth0 + extended_message + Assuming 'y' is <= 2 + message + Assuming 'y' is <= 2 + + + kindcontrol + edges + + + start + + + line2095 + col8 + file0 + + + line2095 + col8 + file0 + + + end + + + line2098 + col7 + file0 + + + line2098 + col17 + file0 + + + + + + + kindevent + location + + line2098 + col21 + file0 + + ranges + + + + line2098 + col21 + file0 + + + line2098 + col43 + file0 + + + + depth0 + extended_message + Method returns an instance of NSString with a +1 retain count + message + Method returns an instance of NSString with a +1 retain count + + + kindcontrol + edges + + + start + + + line2098 + col7 + file0 + + + line2098 + col17 + file0 + + + end + + + line2099 + col5 + file0 + + + line2099 + col9 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2099 + col5 + file0 + + + line2099 + col9 + file0 + + + end + + + line2100 + col5 + file0 + + + line2100 + col5 + file0 + + + + + + + kindevent + location + + line2100 + col5 + file0 + + ranges + + + + line2100 + col5 + file0 + + + line2100 + col25 + file0 + + + + + line2100 + col6 + file0 + + + line2100 + col16 + file0 + + + + depth0 + extended_message + Object released + message + Object released + + + kindcontrol + edges + + + start + + + line2100 + col5 + file0 + + + line2100 + col5 + file0 + + + end + + + line2101 + col5 + file0 + + + line2101 + col9 + file0 + + + + + + + kindevent + location + + line2101 + col5 + file0 + + ranges + + + + line2101 + col25 + file0 + + + line2101 + col35 + file0 + + + + depth0 + extended_message + Reference-counted object is used after it is released + message + Reference-counted object is used after it is released + + + descriptionReference-counted object is used after it is released + categoryMemory (Core Foundation/Objective-C/OSObject) + typeUse-after-release + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_contexta4cedbb647e9632da7a5072cb839e54a + issue_context_kindfunction + issue_contextrdar11400885 + issue_hash_function_offset9 + location + + line2101 + col5 + file0 + + ExecutedLines + + 0 + + 2091 + 2092 + 2094 + 2095 + 2098 + 2099 + 2100 + 2101 + + + + + path + + + kindcontrol + edges + + + start + + + line2119 + col3 + file0 + + + line2119 + col4 + file0 + + + end + + + line2127 + col3 + file0 + + + line2127 + col4 + file0 + + + + + + + kindevent + location + + line2127 + col19 + file0 + + ranges + + + + line2127 + col19 + file0 + + + line2127 + col21 + file0 + + + + depth0 + extended_message + NSArray literal is an object with a +0 retain count + message + NSArray literal is an object with a +0 retain count + + + kindcontrol + edges + + + start + + + line2127 + col3 + file0 + + + line2127 + col4 + file0 + + + end + + + line2128 + col3 + file0 + + + line2128 + col24 + file0 + + + + + + + kindevent + location + + line2128 + col3 + file0 + + ranges + + + + line2128 + col26 + file0 + + + line2128 + col35 + file0 + + + + depth0 + extended_message + Incorrect decrement of the reference count of an object that is not owned at this point by the caller + message + Incorrect decrement of the reference count of an object that is not owned at this point by the caller + + + descriptionIncorrect decrement of the reference count of an object that is not owned at this point by the caller + categoryMemory (Core Foundation/Objective-C/OSObject) + typeBad release + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_contextfd9427d86a2357fd92478c9c7abbc1f4 + issue_context_kindfunction + issue_contexttestConsumeAndStopTracking + issue_hash_function_offset10 + location + + line2128 + col3 + file0 + + ExecutedLines + + 0 + + 2118 + 2119 + 2120 + 2122 + 2123 + 2127 + 2128 + + + + + path + + + kindcontrol + edges + + + start + + + line2132 + col3 + file0 + + + line2132 + col4 + file0 + + + end + + + line2140 + col3 + file0 + + + line2140 + col4 + file0 + + + + + + + kindevent + location + + line2140 + col19 + file0 + + ranges + + + + line2140 + col19 + file0 + + + line2140 + col21 + file0 + + + + depth0 + extended_message + NSArray literal is an object with a +0 retain count + message + NSArray literal is an object with a +0 retain count + + + kindcontrol + edges + + + start + + + line2140 + col3 + file0 + + + line2140 + col4 + file0 + + + end + + + line2141 + col3 + file0 + + + line2141 + col26 + file0 + + + + + + + kindevent + location + + line2141 + col3 + file0 + + ranges + + + + line2141 + col28 + file0 + + + line2141 + col48 + file0 + + + + depth0 + extended_message + Incorrect decrement of the reference count of an object that is not owned at this point by the caller + message + Incorrect decrement of the reference count of an object that is not owned at this point by the caller + + + descriptionIncorrect decrement of the reference count of an object that is not owned at this point by the caller + categoryMemory (Core Foundation/Objective-C/OSObject) + typeBad release + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context0e65e51476e5671dcd37f632806e5147 + issue_context_kindfunction + issue_contexttestCFConsumeAndStopTracking + issue_hash_function_offset10 + location + + line2141 + col3 + file0 + + ExecutedLines + + 0 + + 2131 + 2132 + 2133 + 2135 + 2136 + 2140 + 2141 + + + + + path + + + kindevent + location + + line2153 + col16 + file0 + + ranges + + + + line2153 + col16 + file0 + + + line2153 + col31 + file0 + + + + depth0 + extended_message + Call to function 'CreateMyCFType' returns a Core Foundation object of type 'MyCFType' with a +1 retain count + message + Call to function 'CreateMyCFType' returns a Core Foundation object of type 'MyCFType' with a +1 retain count + + + kindcontrol + edges + + + start + + + line2153 + col3 + file0 + + + line2153 + col10 + file0 + + + end + + + line2154 + col1 + file0 + + + line2154 + col1 + file0 + + + + + + + kindevent + location + + line2154 + col1 + file0 + + depth0 + extended_message + Object leaked: object allocated and stored into 'x' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'x' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'x' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_contexta0ba9c47505e923763ea5323ad2f71b7 + issue_context_kindfunction + issue_contexttest_custom_cf + issue_hash_function_offset1 + location + + line2154 + col1 + file0 + + ExecutedLines + + 0 + + 2152 + 2153 + 2154 + + + + + path + + + kindevent + location + + line2188 + col18 + file0 + + ranges + + + + line2188 + col18 + file0 + + + line2188 + col29 + file0 + + + + depth0 + extended_message + Call to function 'makeCustom' returns a Core Foundation object of type 'MyCFType' with a +1 retain count + message + Call to function 'makeCustom' returns a Core Foundation object of type 'MyCFType' with a +1 retain count + + + kindcontrol + edges + + + start + + + line2188 + col3 + file0 + + + line2188 + col10 + file0 + + + end + + + line2189 + col1 + file0 + + + line2189 + col1 + file0 + + + + + + + kindevent + location + + line2189 + col1 + file0 + + depth0 + extended_message + Object leaked: object allocated and stored into 'obj' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'obj' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'obj' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context7a6cf8cb3c5e0ca3125d7e27695a810a + issue_context_kindfunction + issue_contexttestCustomReturnsRetained + issue_hash_function_offset1 + location + + line2189 + col1 + file0 + + ExecutedLines + + 0 + + 2187 + 2188 + 2189 + + + + + path + + + kindevent + location + + line2192 + col13 + file0 + + ranges + + + + line2192 + col13 + file0 + + + line2192 + col23 + file0 + + + + depth0 + extended_message + Call to function 'getCustom' returns a Core Foundation object of type 'MyCFType' with a +0 retain count + message + Call to function 'getCustom' returns a Core Foundation object of type 'MyCFType' with a +0 retain count + + + kindevent + location + + line2192 + col3 + file0 + + ranges + + + + line2192 + col13 + file0 + + + line2192 + col23 + file0 + + + + depth0 + extended_message + Incorrect decrement of the reference count of an object that is not owned at this point by the caller + message + Incorrect decrement of the reference count of an object that is not owned at this point by the caller + + + descriptionIncorrect decrement of the reference count of an object that is not owned at this point by the caller + categoryMemory (Core Foundation/Objective-C/OSObject) + typeBad release + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context810fce32373fe40ba8e2d0894d46f667 + issue_context_kindfunction + issue_contexttestCustomReturnsNotRetained + issue_hash_function_offset1 + location + + line2192 + col3 + file0 + + ExecutedLines + + 0 + + 2191 + 2192 + + + + + path + + + kindcontrol + edges + + + start + + + line2211 + col3 + file0 + + + line2211 + col4 + file0 + + + end + + + line2211 + col11 + file0 + + + line2211 + col11 + file0 + + + + + + + kindevent + location + + line2211 + col11 + file0 + + ranges + + + + line2211 + col11 + file0 + + + line2211 + col31 + file0 + + + + depth0 + extended_message + Method returns an instance of MyObj12706177 with a +1 retain count + message + Method returns an instance of MyObj12706177 with a +1 retain count + + + kindevent + location + + line2211 + col10 + file0 + + ranges + + + + line2211 + col10 + file0 + + + line2211 + col38 + file0 + + + + depth0 + extended_message + Calling 'initX' + message + Calling 'initX' + + + kindevent + location + + line2204 + col1 + file0 + + depth1 + extended_message + Entered call from 'test12706177' + message + Entered call from 'test12706177' + + + kindcontrol + edges + + + start + + + line2204 + col1 + file0 + + + line2204 + col1 + file0 + + + end + + + line2205 + col3 + file0 + + + line2205 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2205 + col3 + file0 + + + line2205 + col4 + file0 + + + end + + + line2205 + col7 + file0 + + + line2205 + col10 + file0 + + + + + + + kindevent + location + + line2205 + col7 + file0 + + ranges + + + + line2205 + col7 + file0 + + + line2205 + col10 + file0 + + + + depth1 + extended_message + Assuming 'Cond' is not equal to 0 + message + Assuming 'Cond' is not equal to 0 + + + kindcontrol + edges + + + start + + + line2205 + col7 + file0 + + + line2205 + col10 + file0 + + + end + + + line2206 + col5 + file0 + + + line2206 + col10 + file0 + + + + + + + kindevent + location + + line2211 + col10 + file0 + + ranges + + + + line2211 + col10 + file0 + + + line2211 + col38 + file0 + + + + depth0 + extended_message + Returning from 'initX' + message + Returning from 'initX' + + + kindcontrol + edges + + + start + + + line2211 + col10 + file0 + + + line2211 + col10 + file0 + + + end + + + line2211 + col3 + file0 + + + line2211 + col4 + file0 + + + + + + + kindevent + location + + line2211 + col3 + file0 + + ranges + + + + line2211 + col3 + file0 + + + line2211 + col6 + file0 + + + + depth0 + extended_message + Object leaked: allocated object of type 'MyObj12706177 *' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: allocated object of type 'MyObj12706177 *' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object of type 'MyObj12706177 *' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context68ee7961ffb62c575cc2298cb4836090 + issue_context_kindObjective-C method + issue_contexttest12706177 + issue_hash_function_offset1 + location + + line2211 + col3 + file0 + + ExecutedLines + + 0 + + 2204 + 2205 + 2206 + 2210 + 2211 + + + + + path + + + kindcontrol + edges + + + start + + + line2227 + col3 + file0 + + + line2227 + col8 + file0 + + + end + + + line2227 + col24 + file0 + + + line2227 + col37 + file0 + + + + + + + kindevent + location + + line2227 + col24 + file0 + + ranges + + + + line2227 + col24 + file0 + + + line2227 + col39 + file0 + + + + depth0 + extended_message + Call to function 'CFGetSomething' returns a Core Foundation object of type 'CFTypeRef' with a +0 retain count + message + Call to function 'CFGetSomething' returns a Core Foundation object of type 'CFTypeRef' with a +0 retain count + + + kindcontrol + edges + + + start + + + line2227 + col24 + file0 + + + line2227 + col37 + file0 + + + end + + + line2227 + col10 + file0 + + + line2227 + col22 + file0 + + + + + + + kindevent + location + + line2227 + col10 + file0 + + ranges + + + + line2227 + col10 + file0 + + + line2227 + col40 + file0 + + + + + line2227 + col24 + file0 + + + line2227 + col39 + file0 + + + + depth0 + extended_message + Object autoreleased + message + Object autoreleased + + + kindcontrol + edges + + + start + + + line2227 + col10 + file0 + + + line2227 + col22 + file0 + + + end + + + line2227 + col3 + file0 + + + line2227 + col8 + file0 + + + + + + + kindevent + location + + line2227 + col3 + file0 + + ranges + + + + line2227 + col3 + file0 + + + line2227 + col40 + file0 + + + + depth0 + extended_message + Object was autoreleased but has a +0 retain count + message + Object was autoreleased but has a +0 retain count + + + descriptionObject autoreleased too many times + categoryMemory (Core Foundation/Objective-C/OSObject) + typeObject autoreleased too many times + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context1dc376fbbe90d14b6766585a0e2b7bee + issue_context_kindfunction + issue_contextgetIncorrectlyAutoreleasedCFType + issue_hash_function_offset2 + location + + line2227 + col3 + file0 + + ExecutedLines + + 0 + + 2225 + 2227 + + + + + path + + + kindcontrol + edges + + + start + + + line2232 + col3 + file0 + + + line2232 + col8 + file0 + + + end + + + line2232 + col24 + file0 + + + line2232 + col40 + file0 + + + + + + + kindevent + location + + line2232 + col24 + file0 + + ranges + + + + line2232 + col24 + file0 + + + line2232 + col42 + file0 + + + + depth0 + extended_message + Call to function 'CFCreateSomething' returns a Core Foundation object of type 'CFTypeRef' with a +1 retain count + message + Call to function 'CFCreateSomething' returns a Core Foundation object of type 'CFTypeRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line2232 + col24 + file0 + + + line2232 + col40 + file0 + + + end + + + line2232 + col10 + file0 + + + line2232 + col22 + file0 + + + + + + + kindevent + location + + line2232 + col10 + file0 + + ranges + + + + line2232 + col10 + file0 + + + line2232 + col43 + file0 + + + + + line2232 + col24 + file0 + + + line2232 + col42 + file0 + + + + depth0 + extended_message + Object autoreleased + message + Object autoreleased + + + kindcontrol + edges + + + start + + + line2232 + col10 + file0 + + + line2232 + col22 + file0 + + + end + + + line2232 + col3 + file0 + + + line2232 + col8 + file0 + + + + + + + kindevent + location + + line2232 + col3 + file0 + + ranges + + + + line2232 + col3 + file0 + + + line2232 + col43 + file0 + + + + depth0 + extended_message + Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected + message + Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected + + + descriptionObject with a +0 retain count returned to caller where a +1 (owning) retain count is expected + categoryMemory (Core Foundation/Objective-C/OSObject) + typeMethod should return an owned object + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context6ae8ea9fe4bf203e6b7bfaf649a6ca6a + issue_context_kindfunction + issue_contextcreateIncorrectlyAutoreleasedCFType + issue_hash_function_offset2 + location + + line2232 + col3 + file0 + + ExecutedLines + + 0 + + 2230 + 2232 + + + + + path + + + kindevent + location + + line2247 + col19 + file0 + + ranges + + + + line2247 + col19 + file0 + + + line2247 + col37 + file0 + + + + depth0 + extended_message + Call to function 'CFCreateSomething' returns a Core Foundation object of type 'CFTypeRef' with a +1 retain count + message + Call to function 'CFCreateSomething' returns a Core Foundation object of type 'CFTypeRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line2247 + col3 + file0 + + + line2247 + col11 + file0 + + + end + + + line2248 + col3 + file0 + + + line2248 + col11 + file0 + + + + + + + kindevent + location + + line2248 + col3 + file0 + + ranges + + + + line2248 + col3 + file0 + + + line2248 + col16 + file0 + + + + + line2248 + col13 + file0 + + + line2248 + col15 + file0 + + + + depth0 + extended_message + Object released + message + Object released + + + kindcontrol + edges + + + start + + + line2248 + col3 + file0 + + + line2248 + col11 + file0 + + + end + + + line2251 + col3 + file0 + + + line2251 + col7 + file0 + + + + + + + kindevent + location + + line2251 + col3 + file0 + + ranges + + + + line2251 + col9 + file0 + + + line2251 + col11 + file0 + + + + depth0 + extended_message + Reference-counted object is used after it is released + message + Reference-counted object is used after it is released + + + descriptionReference-counted object is used after it is released + categoryMemory (Core Foundation/Objective-C/OSObject) + typeUse-after-release + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_contextd4e28f96fc8610b5b4b849f4760956eb + issue_context_kindfunction + issue_contextuseAfterRelease + issue_hash_function_offset7 + location + + line2251 + col3 + file0 + + ExecutedLines + + 0 + + 2244 + 2247 + 2248 + 2251 + + + + + path + + + kindevent + location + + line2256 + col19 + file0 + + ranges + + + + line2256 + col19 + file0 + + + line2256 + col37 + file0 + + + + depth0 + extended_message + Call to function 'CFCreateSomething' returns a Core Foundation object of type 'CFTypeRef' with a +1 retain count + message + Call to function 'CFCreateSomething' returns a Core Foundation object of type 'CFTypeRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line2256 + col3 + file0 + + + line2256 + col11 + file0 + + + end + + + line2257 + col3 + file0 + + + line2257 + col11 + file0 + + + + + + + kindevent + location + + line2257 + col22 + file0 + + ranges + + + + line2257 + col22 + file0 + + + line2257 + col39 + file0 + + + + + line2257 + col36 + file0 + + + line2257 + col38 + file0 + + + + depth0 + extended_message + Object autoreleased + message + Object autoreleased + + + kindcontrol + edges + + + start + + + line2257 + col3 + file0 + + + line2257 + col11 + file0 + + + end + + + line2258 + col3 + file0 + + + line2258 + col10 + file0 + + + + + + + kindevent + location + + line2258 + col3 + file0 + + ranges + + + + line2258 + col3 + file0 + + + line2258 + col18 + file0 + + + + + line2258 + col12 + file0 + + + line2258 + col17 + file0 + + + + depth0 + extended_message + Reference count incremented. The object now has a +2 retain count + message + Reference count incremented. The object now has a +2 retain count + + + kindcontrol + edges + + + start + + + line2258 + col3 + file0 + + + line2258 + col10 + file0 + + + end + + + line2259 + col1 + file0 + + + line2259 + col1 + file0 + + + + + + + kindevent + location + + line2259 + col1 + file0 + + depth0 + extended_message + Object leaked: object allocated and stored into 'obj' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'obj' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'obj' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context7986c4b7fb29301c109343dfe4155202 + issue_context_kindfunction + issue_contexttestAutoreleaseReturnsInput + issue_hash_function_offset2 + location + + line2259 + col1 + file0 + + ExecutedLines + + 0 + + 2254 + 2256 + 2257 + 2258 + 2259 + + + + + path + + + kindevent + location + + line2276 + col20 + file0 + + ranges + + + + line2276 + col20 + file0 + + + line2276 + col70 + file0 + + + + depth0 + extended_message + Call to function 'CFArrayCreateMutable' returns a Core Foundation object of type 'CFMutableArrayRef' with a +1 retain count + message + Call to function 'CFArrayCreateMutable' returns a Core Foundation object of type 'CFMutableArrayRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line2276 + col3 + file0 + + + line2276 + col12 + file0 + + + end + + + line2277 + col3 + file0 + + + line2277 + col12 + file0 + + + + + + + kindevent + location + + line2277 + col34 + file0 + + ranges + + + + line2277 + col34 + file0 + + + line2277 + col62 + file0 + + + + + line2277 + col48 + file0 + + + line2277 + col61 + file0 + + + + depth0 + extended_message + Object autoreleased + message + Object autoreleased + + + kindcontrol + edges + + + start + + + line2277 + col3 + file0 + + + line2277 + col12 + file0 + + + end + + + line2278 + col3 + file0 + + + line2278 + col10 + file0 + + + + + + + kindevent + location + + line2278 + col3 + file0 + + ranges + + + + line2278 + col3 + file0 + + + line2278 + col17 + file0 + + + + + line2278 + col12 + file0 + + + line2278 + col16 + file0 + + + + depth0 + extended_message + Reference count incremented. The object now has a +2 retain count + message + Reference count incremented. The object now has a +2 retain count + + + kindcontrol + edges + + + start + + + line2278 + col3 + file0 + + + line2278 + col10 + file0 + + + end + + + line2279 + col1 + file0 + + + line2279 + col1 + file0 + + + + + + + kindevent + location + + line2279 + col1 + file0 + + depth0 + extended_message + Object leaked: object allocated and stored into 'arr' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'arr' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'arr' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context2e0dbfdf379acf2f09e46db47d753e8a + issue_context_kindfunction + issue_contextautoreleaseReturningTypedObject + issue_hash_function_offset1 + location + + line2279 + col1 + file0 + + ExecutedLines + + 0 + + 2275 + 2276 + 2277 + 2278 + 2279 + + + + + path + + + kindcontrol + edges + + + start + + + line2290 + col3 + file0 + + + line2290 + col4 + file0 + + + end + + + line2293 + col3 + file0 + + + line2293 + col4 + file0 + + + + + + + kindevent + location + + line2293 + col19 + file0 + + ranges + + + + line2293 + col19 + file0 + + + line2293 + col20 + file0 + + + + depth0 + extended_message + NSNumber literal is an object with a +0 retain count + message + NSNumber literal is an object with a +0 retain count + + + kindcontrol + edges + + + start + + + line2293 + col3 + file0 + + + line2293 + col4 + file0 + + + end + + + line2294 + col3 + file0 + + + line2294 + col15 + file0 + + + + + + + kindevent + location + + line2294 + col3 + file0 + + ranges + + + + line2294 + col3 + file0 + + + line2294 + col27 + file0 + + + + + line2294 + col17 + file0 + + + line2294 + col26 + file0 + + + + depth0 + extended_message + Object autoreleased + message + Object autoreleased + + + kindcontrol + edges + + + start + + + line2294 + col3 + file0 + + + line2294 + col15 + file0 + + + end + + + line2295 + col1 + file0 + + + line2295 + col1 + file0 + + + + + + + kindevent + location + + line2295 + col1 + file0 + + depth0 + extended_message + Object was autoreleased but has a +0 retain count + message + Object was autoreleased but has a +0 retain count + + + descriptionObject autoreleased too many times + categoryMemory (Core Foundation/Objective-C/OSObject) + typeObject autoreleased too many times + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context41a2d6f91fdfa9b5f396102a60571e21 + issue_context_kindfunction + issue_contextautoreleaseObjC + issue_hash_function_offset6 + location + + line2295 + col1 + file0 + + ExecutedLines + + 0 + + 2289 + 2290 + 2291 + 2293 + 2294 + 2295 + + + + + path + + + kindcontrol + edges + + + start + + + line2345 + col3 + file0 + + + line2345 + col11 + file0 + + + end + + + line2346 + col3 + file0 + + + line2346 + col13 + file0 + + + + + + + kindevent + location + + line2346 + col3 + file0 + + ranges + + + + line2346 + col3 + file0 + + + line2346 + col19 + file0 + + + + depth0 + extended_message + Call to function 'getViaParam' returns a Core Foundation object of type 'CFTypeRef' with a +0 retain count + message + Call to function 'getViaParam' returns a Core Foundation object of type 'CFTypeRef' with a +0 retain count + + + kindcontrol + edges + + + start + + + line2346 + col3 + file0 + + + line2346 + col13 + file0 + + + end + + + line2347 + col3 + file0 + + + line2347 + col11 + file0 + + + + + + + kindevent + location + + line2347 + col3 + file0 + + ranges + + + + line2347 + col13 + file0 + + + line2347 + col15 + file0 + + + + depth0 + extended_message + Incorrect decrement of the reference count of an object that is not owned at this point by the caller + message + Incorrect decrement of the reference count of an object that is not owned at this point by the caller + + + descriptionIncorrect decrement of the reference count of an object that is not owned at this point by the caller + categoryMemory (Core Foundation/Objective-C/OSObject) + typeBad release + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context95dd5581ae4195b71e9a11f34290af5d + issue_context_kindfunction + issue_contexttestCFReturnsNotRetained + issue_hash_function_offset4 + location + + line2347 + col3 + file0 + + ExecutedLines + + 0 + + 2343 + 2345 + 2346 + 2347 + + + + + path + + + kindcontrol + edges + + + start + + + line2352 + col3 + file0 + + + line2352 + col11 + file0 + + + end + + + line2353 + col3 + file0 + + + line2353 + col14 + file0 + + + + + + + kindevent + location + + line2353 + col3 + file0 + + ranges + + + + line2353 + col3 + file0 + + + line2353 + col20 + file0 + + + + depth0 + extended_message + Call to function 'getViaParam2' returns a Core Foundation object of type 'CFTypeRef' with a +0 retain count + message + Call to function 'getViaParam2' returns a Core Foundation object of type 'CFTypeRef' with a +0 retain count + + + kindcontrol + edges + + + start + + + line2353 + col3 + file0 + + + line2353 + col14 + file0 + + + end + + + line2354 + col3 + file0 + + + line2354 + col11 + file0 + + + + + + + kindevent + location + + line2354 + col3 + file0 + + ranges + + + + line2354 + col13 + file0 + + + line2354 + col15 + file0 + + + + depth0 + extended_message + Incorrect decrement of the reference count of an object that is not owned at this point by the caller + message + Incorrect decrement of the reference count of an object that is not owned at this point by the caller + + + descriptionIncorrect decrement of the reference count of an object that is not owned at this point by the caller + categoryMemory (Core Foundation/Objective-C/OSObject) + typeBad release + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context014103674df4a8a65a96bcdf936637a2 + issue_context_kindfunction + issue_contexttestCFReturnsNotRetainedAnnotated + issue_hash_function_offset4 + location + + line2354 + col3 + file0 + + ExecutedLines + + 0 + + 2350 + 2352 + 2353 + 2354 + + + + + files + + /Volumes/Transcend/code/monorepo/llvm-project/clang/test/Analysis/retain-release.m + + + diff --git a/test/Analysis/Inputs/expected-plists/retain-release.m.objcpp.plist b/test/Analysis/Inputs/expected-plists/retain-release.m.objcpp.plist new file mode 100644 index 0000000000..a21e56cee4 --- /dev/null +++ b/test/Analysis/Inputs/expected-plists/retain-release.m.objcpp.plist @@ -0,0 +1,26182 @@ + + + + + clang_version +clang version 8.0.0 + diagnostics + + + path + + + kindcontrol + edges + + + start + + + line348 + col3 + file0 + + + line348 + col16 + file0 + + + end + + + line349 + col3 + file0 + + + line349 + col11 + file0 + + + + + + + kindevent + location + + line349 + col20 + file0 + + ranges + + + + line349 + col20 + file0 + + + line349 + col37 + file0 + + + + depth0 + extended_message + Call to function 'CFDateCreate' returns a Core Foundation object of type 'CFDateRef' with a +1 retain count + message + Call to function 'CFDateCreate' returns a Core Foundation object of type 'CFDateRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line349 + col3 + file0 + + + line349 + col11 + file0 + + + end + + + line350 + col3 + file0 + + + line350 + col10 + file0 + + + + + + + kindevent + location + + line350 + col3 + file0 + + ranges + + + + line350 + col3 + file0 + + + line350 + col16 + file0 + + + + + line350 + col12 + file0 + + + line350 + col15 + file0 + + + + depth0 + extended_message + Reference count incremented. The object now has a +2 retain count + message + Reference count incremented. The object now has a +2 retain count + + + kindcontrol + edges + + + start + + + line350 + col3 + file0 + + + line350 + col10 + file0 + + + end + + + line351 + col3 + file0 + + + line351 + col11 + file0 + + + + + + + kindevent + location + + line351 + col3 + file0 + + ranges + + + + line351 + col3 + file0 + + + line351 + col17 + file0 + + + + + line351 + col13 + file0 + + + line351 + col16 + file0 + + + + depth0 + extended_message + Reference count decremented. The object now has a +1 retain count + message + Reference count decremented. The object now has a +1 retain count + + + kindcontrol + edges + + + start + + + line351 + col3 + file0 + + + line351 + col11 + file0 + + + end + + + line353 + col3 + file0 + + + line353 + col11 + file0 + + + + + + + kindevent + location + + line353 + col3 + file0 + + ranges + + + + line353 + col3 + file0 + + + line353 + col17 + file0 + + + + + line353 + col13 + file0 + + + line353 + col16 + file0 + + + + depth0 + extended_message + Object released + message + Object released + + + kindcontrol + edges + + + start + + + line353 + col3 + file0 + + + line353 + col11 + file0 + + + end + + + line354 + col3 + file0 + + + line354 + col3 + file0 + + + + + + + kindcontrol + edges + + + start + + + line354 + col3 + file0 + + + line354 + col3 + file0 + + + end + + + line354 + col7 + file0 + + + line354 + col27 + file0 + + + + + + + kindevent + location + + line354 + col7 + file0 + + ranges + + + + line354 + col29 + file0 + + + line354 + col32 + file0 + + + + depth0 + extended_message + Reference-counted object is used after it is released + message + Reference-counted object is used after it is released + + + descriptionReference-counted object is used after it is released + categoryMemory (Core Foundation/Objective-C/OSObject) + typeUse-after-release + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context5928b2a4699cbae0686391c20e639007 + issue_context_kindfunction + issue_contextf1 + issue_hash_function_offset7 + location + + line354 + col7 + file0 + + ExecutedLines + + 0 + + 347 + 348 + 349 + 350 + 351 + 352 + 353 + 354 + + + + + path + + + kindcontrol + edges + + + start + + + line359 + col3 + file0 + + + line359 + col16 + file0 + + + end + + + line360 + col3 + file0 + + + line360 + col11 + file0 + + + + + + + kindevent + location + + line360 + col20 + file0 + + ranges + + + + line360 + col20 + file0 + + + line360 + col37 + file0 + + + + depth0 + extended_message + Call to function 'CFDateCreate' returns a Core Foundation object of type 'CFDateRef' with a +1 retain count + message + Call to function 'CFDateCreate' returns a Core Foundation object of type 'CFDateRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line360 + col3 + file0 + + + line360 + col11 + file0 + + + end + + + line361 + col3 + file0 + + + line361 + col3 + file0 + + + + + + + kindevent + location + + line361 + col3 + file0 + + ranges + + + + line361 + col3 + file0 + + + line361 + col27 + file0 + + + + + line361 + col4 + file0 + + + line361 + col19 + file0 + + + + depth0 + extended_message + Reference count incremented. The object now has a +2 retain count + message + Reference count incremented. The object now has a +2 retain count + + + kindcontrol + edges + + + start + + + line361 + col3 + file0 + + + line361 + col3 + file0 + + + end + + + line362 + col3 + file0 + + + line362 + col11 + file0 + + + + + + + kindevent + location + + line362 + col3 + file0 + + ranges + + + + line362 + col3 + file0 + + + line362 + col17 + file0 + + + + + line362 + col13 + file0 + + + line362 + col16 + file0 + + + + depth0 + extended_message + Reference count decremented. The object now has a +1 retain count + message + Reference count decremented. The object now has a +1 retain count + + + kindcontrol + edges + + + start + + + line362 + col3 + file0 + + + line362 + col11 + file0 + + + end + + + line364 + col3 + file0 + + + line364 + col3 + file0 + + + + + + + kindevent + location + + line364 + col3 + file0 + + ranges + + + + line364 + col3 + file0 + + + line364 + col28 + file0 + + + + + line364 + col4 + file0 + + + line364 + col19 + file0 + + + + depth0 + extended_message + Object released + message + Object released + + + kindcontrol + edges + + + start + + + line364 + col3 + file0 + + + line364 + col3 + file0 + + + end + + + line365 + col3 + file0 + + + line365 + col3 + file0 + + + + + + + kindcontrol + edges + + + start + + + line365 + col3 + file0 + + + line365 + col3 + file0 + + + end + + + line365 + col7 + file0 + + + line365 + col27 + file0 + + + + + + + kindevent + location + + line365 + col7 + file0 + + ranges + + + + line365 + col29 + file0 + + + line365 + col32 + file0 + + + + depth0 + extended_message + Reference-counted object is used after it is released + message + Reference-counted object is used after it is released + + + descriptionReference-counted object is used after it is released + categoryMemory (Core Foundation/Objective-C/OSObject) + typeUse-after-release + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context6b2e175938153ac041f52ebbf50b1f43 + issue_context_kindfunction + issue_contextf2 + issue_hash_function_offset7 + location + + line365 + col7 + file0 + + ExecutedLines + + 0 + + 358 + 359 + 360 + 361 + 362 + 363 + 364 + 365 + + + + + path + + + kindcontrol + edges + + + start + + + line395 + col3 + file0 + + + line395 + col16 + file0 + + + end + + + line396 + col3 + file0 + + + line396 + col11 + file0 + + + + + + + kindevent + location + + line396 + col20 + file0 + + ranges + + + + line396 + col20 + file0 + + + line396 + col37 + file0 + + + + depth0 + extended_message + Call to function 'CFDateCreate' returns a Core Foundation object of type 'CFDateRef' with a +1 retain count + message + Call to function 'CFDateCreate' returns a Core Foundation object of type 'CFDateRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line396 + col3 + file0 + + + line396 + col11 + file0 + + + end + + + line398 + col3 + file0 + + + line398 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line398 + col3 + file0 + + + line398 + col4 + file0 + + + end + + + line398 + col7 + file0 + + + line398 + col7 + file0 + + + + + + + kindevent + location + + line398 + col7 + file0 + + ranges + + + + line398 + col7 + file0 + + + line398 + col7 + file0 + + + + depth0 + extended_message + Assuming 'x' is 0 + message + Assuming 'x' is 0 + + + kindcontrol + edges + + + start + + + line398 + col7 + file0 + + + line398 + col7 + file0 + + + end + + + line401 + col3 + file0 + + + line401 + col8 + file0 + + + + + + + kindcontrol + edges + + + start + + + line401 + col3 + file0 + + + line401 + col8 + file0 + + + end + + + line401 + col10 + file0 + + + line401 + col10 + file0 + + + + + + + kindevent + location + + line401 + col10 + file0 + + ranges + + + + line401 + col10 + file0 + + + line401 + col10 + file0 + + + + depth0 + extended_message + Object leaked: object allocated and stored into 'date' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'date' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'date' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context3fdbd844ddb925306ba2bb1b3626f310 + issue_context_kindfunction + issue_contextf5 + issue_hash_function_offset2 + location + + line401 + col10 + file0 + + ExecutedLines + + 0 + + 394 + 395 + 396 + 398 + 401 + + + + + path + + + kindevent + location + + line407 + col20 + file0 + + ranges + + + + line407 + col20 + file0 + + + line407 + col62 + file0 + + + + depth0 + extended_message + Call to function 'CFDateCreate' returns a Core Foundation object of type 'CFDateRef' with a +1 retain count + message + Call to function 'CFDateCreate' returns a Core Foundation object of type 'CFDateRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line407 + col3 + file0 + + + line407 + col11 + file0 + + + end + + + line408 + col3 + file0 + + + line408 + col10 + file0 + + + + + + + kindevent + location + + line408 + col3 + file0 + + ranges + + + + line408 + col3 + file0 + + + line408 + col16 + file0 + + + + + line408 + col12 + file0 + + + line408 + col15 + file0 + + + + depth0 + extended_message + Reference count incremented. The object now has a +2 retain count + message + Reference count incremented. The object now has a +2 retain count + + + kindcontrol + edges + + + start + + + line408 + col3 + file0 + + + line408 + col10 + file0 + + + end + + + line409 + col3 + file0 + + + line409 + col8 + file0 + + + + + + + kindevent + location + + line409 + col3 + file0 + + ranges + + + + line409 + col3 + file0 + + + line409 + col13 + file0 + + + + depth0 + extended_message + Object leaked: object allocated and stored into 'date' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'date' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'date' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context8529da75e357c59fb0a7fefb0b6e0952 + issue_context_kindfunction + issue_contextf6 + issue_hash_function_offset1 + location + + line409 + col3 + file0 + + ExecutedLines + + 0 + + 406 + 407 + 408 + 409 + + + + + path + + + kindevent + location + + line415 + col20 + file0 + + ranges + + + + line415 + col20 + file0 + + + line415 + col62 + file0 + + + + depth0 + extended_message + Call to function 'CFDateCreate' returns a Core Foundation object of type 'CFDateRef' with a +1 retain count + message + Call to function 'CFDateCreate' returns a Core Foundation object of type 'CFDateRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line415 + col3 + file0 + + + line415 + col11 + file0 + + + end + + + line416 + col3 + file0 + + + line416 + col10 + file0 + + + + + + + kindevent + location + + line416 + col3 + file0 + + ranges + + + + line416 + col3 + file0 + + + line416 + col16 + file0 + + + + + line416 + col12 + file0 + + + line416 + col15 + file0 + + + + depth0 + extended_message + Reference count incremented. The object now has a +2 retain count + message + Reference count incremented. The object now has a +2 retain count + + + kindcontrol + edges + + + start + + + line416 + col3 + file0 + + + line416 + col10 + file0 + + + end + + + line418 + col3 + file0 + + + line418 + col8 + file0 + + + + + + + kindevent + location + + line418 + col3 + file0 + + ranges + + + + line418 + col3 + file0 + + + line418 + col13 + file0 + + + + depth0 + extended_message + Object leaked: object allocated and stored into 'date' is not referenced later in this execution path and has a retain count of +2 + message + Object leaked: object allocated and stored into 'date' is not referenced later in this execution path and has a retain count of +2 + + + descriptionPotential leak of an object stored into 'date' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_contexteb0faa12081b1e28b218e4c6e53d57ec + issue_context_kindfunction + issue_contextf7 + issue_hash_function_offset1 + location + + line418 + col3 + file0 + + ExecutedLines + + 0 + + 414 + 415 + 416 + 417 + 418 + + + + + path + + + kindcontrol + edges + + + start + + + line415 + col3 + file0 + + + line415 + col11 + file0 + + + end + + + line417 + col3 + file0 + + + line417 + col6 + file0 + + + + + + + kindevent + location + + line417 + col10 + file0 + + ranges + + + + line417 + col10 + file0 + + + line417 + col52 + file0 + + + + depth0 + extended_message + Call to function 'CFDateCreate' returns a Core Foundation object of type 'CFDateRef' with a +1 retain count + message + Call to function 'CFDateCreate' returns a Core Foundation object of type 'CFDateRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line417 + col3 + file0 + + + line417 + col6 + file0 + + + end + + + line418 + col3 + file0 + + + line418 + col8 + file0 + + + + + + + kindevent + location + + line418 + col3 + file0 + + ranges + + + + line418 + col3 + file0 + + + line418 + col13 + file0 + + + + depth0 + extended_message + Object leaked: object allocated and stored into 'date' is returned from a function whose name ('f7') does not contain 'Copy' or 'Create'. This violates the naming convention rules given in the Memory Management Guide for Core Foundation + message + Object leaked: object allocated and stored into 'date' is returned from a function whose name ('f7') does not contain 'Copy' or 'Create'. This violates the naming convention rules given in the Memory Management Guide for Core Foundation + + + descriptionPotential leak of an object stored into 'date' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak of returned object + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context404d4de8faa444bc52fd510380bd0a63 + issue_context_kindfunction + issue_contextf7 + issue_hash_function_offset3 + location + + line418 + col3 + file0 + + ExecutedLines + + 0 + + 414 + 415 + 416 + 417 + 418 + + + + + path + + + kindevent + location + + line426 + col20 + file0 + + ranges + + + + line426 + col20 + file0 + + + line426 + col33 + file0 + + + + depth0 + extended_message + Call to function 'MyDateCreate' returns a Core Foundation object of type 'CFDateRef' with a +1 retain count + message + Call to function 'MyDateCreate' returns a Core Foundation object of type 'CFDateRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line426 + col3 + file0 + + + line426 + col11 + file0 + + + end + + + line427 + col3 + file0 + + + line427 + col10 + file0 + + + + + + + kindevent + location + + line427 + col3 + file0 + + ranges + + + + line427 + col3 + file0 + + + line427 + col16 + file0 + + + + + line427 + col12 + file0 + + + line427 + col15 + file0 + + + + depth0 + extended_message + Reference count incremented. The object now has a +2 retain count + message + Reference count incremented. The object now has a +2 retain count + + + kindcontrol + edges + + + start + + + line427 + col3 + file0 + + + line427 + col10 + file0 + + + end + + + line428 + col3 + file0 + + + line428 + col8 + file0 + + + + + + + kindevent + location + + line428 + col3 + file0 + + ranges + + + + line428 + col3 + file0 + + + line428 + col13 + file0 + + + + depth0 + extended_message + Object leaked: object allocated and stored into 'date' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'date' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'date' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context251dff6727b3d99ec95caa28672669ea + issue_context_kindfunction + issue_contextf8 + issue_hash_function_offset1 + location + + line428 + col3 + file0 + + ExecutedLines + + 0 + + 425 + 426 + 427 + 428 + + + + + path + + + kindcontrol + edges + + + start + + + line432 + col3 + file0 + + + line432 + col11 + file0 + + + end + + + line433 + col3 + file0 + + + line433 + col5 + file0 + + + + + + + kindevent + location + + line433 + col3 + file0 + + ranges + + + + line433 + col3 + file0 + + + line433 + col8 + file0 + + + + depth0 + extended_message + 'p' initialized to a null pointer value + message + 'p' initialized to a null pointer value + + + kindcontrol + edges + + + start + + + line433 + col3 + file0 + + + line433 + col5 + file0 + + + end + + + line435 + col3 + file0 + + + line435 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line435 + col3 + file0 + + + line435 + col4 + file0 + + + end + + + line435 + col7 + file0 + + + line435 + col7 + file0 + + + + + + + kindevent + location + + line435 + col7 + file0 + + ranges + + + + line435 + col7 + file0 + + + line435 + col11 + file0 + + + + depth0 + extended_message + Assuming 'date' is null + message + Assuming 'date' is null + + + kindcontrol + edges + + + start + + + line435 + col7 + file0 + + + line435 + col7 + file0 + + + end + + + line435 + col14 + file0 + + + line435 + col14 + file0 + + + + + + + kindcontrol + edges + + + start + + + line435 + col14 + file0 + + + line435 + col14 + file0 + + + end + + + line435 + col17 + file0 + + + line435 + col17 + file0 + + + + + + + kindevent + location + + line435 + col17 + file0 + + ranges + + + + line435 + col15 + file0 + + + line435 + col15 + file0 + + + + depth0 + extended_message + Dereference of null pointer (loaded from variable 'p') + message + Dereference of null pointer (loaded from variable 'p') + + + descriptionDereference of null pointer (loaded from variable 'p') + categoryLogic error + typeDereference of null pointer + check_namecore.NullDereference + + issue_hash_content_of_line_in_context4af5d8d1438976cc7fa006af5f843b13 + issue_context_kindfunction + issue_contextf9 + issue_hash_function_offset4 + location + + line435 + col17 + file0 + + ExecutedLines + + 0 + + 431 + 432 + 433 + 435 + + + + + path + + + kindevent + location + + line444 + col20 + file0 + + ranges + + + + line444 + col20 + file0 + + + line444 + col75 + file0 + + + + depth0 + extended_message + Call to function 'DADiskCreateFromBSDName' returns a Core Foundation object of type 'DADiskRef' with a +1 retain count + message + Call to function 'DADiskCreateFromBSDName' returns a Core Foundation object of type 'DADiskRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line444 + col3 + file0 + + + line444 + col11 + file0 + + + end + + + line445 + col3 + file0 + + + line445 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line445 + col3 + file0 + + + line445 + col4 + file0 + + + end + + + line445 + col7 + file0 + + + line445 + col10 + file0 + + + + + + + kindevent + location + + line445 + col7 + file0 + + ranges + + + + line445 + col7 + file0 + + + line445 + col10 + file0 + + + + depth0 + extended_message + Assuming 'disk' is non-null + message + Assuming 'disk' is non-null + + + kindcontrol + edges + + + start + + + line445 + col7 + file0 + + + line445 + col10 + file0 + + + end + + + line445 + col13 + file0 + + + line445 + col17 + file0 + + + + + + + kindcontrol + edges + + + start + + + line445 + col13 + file0 + + + line445 + col17 + file0 + + + end + + + line447 + col3 + file0 + + + line447 + col6 + file0 + + + + + + + kindcontrol + edges + + + start + + + line447 + col3 + file0 + + + line447 + col6 + file0 + + + end + + + line448 + col3 + file0 + + + line448 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line448 + col3 + file0 + + + line448 + col4 + file0 + + + end + + + line448 + col7 + file0 + + + line448 + col10 + file0 + + + + + + + kindevent + location + + line448 + col7 + file0 + + ranges + + + + line448 + col7 + file0 + + + line448 + col10 + file0 + + + + depth0 + extended_message + Assuming 'disk' is null + message + Assuming 'disk' is null + + + kindcontrol + edges + + + start + + + line448 + col7 + file0 + + + line448 + col10 + file0 + + + end + + + line450 + col3 + file0 + + + line450 + col17 + file0 + + + + + + + kindcontrol + edges + + + start + + + line450 + col3 + file0 + + + line450 + col17 + file0 + + + end + + + line450 + col26 + file0 + + + line450 + col46 + file0 + + + + + + + kindevent + location + + line450 + col26 + file0 + + ranges + + + + line450 + col26 + file0 + + + line450 + col46 + file0 + + + + depth0 + extended_message + Object leaked: object allocated and stored into 'disk' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'disk' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'disk' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context69ae08a90fe52a921ed423df38ed7480 + issue_context_kindfunction + issue_contextf10 + issue_hash_function_offset1 + location + + line450 + col26 + file0 + + ExecutedLines + + 0 + + 443 + 444 + 445 + 447 + 448 + 450 + + + + + path + + + kindcontrol + edges + + + start + + + line444 + col3 + file0 + + + line444 + col11 + file0 + + + end + + + line445 + col3 + file0 + + + line445 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line445 + col3 + file0 + + + line445 + col4 + file0 + + + end + + + line445 + col7 + file0 + + + line445 + col10 + file0 + + + + + + + kindevent + location + + line445 + col7 + file0 + + ranges + + + + line445 + col7 + file0 + + + line445 + col10 + file0 + + + + depth0 + extended_message + Assuming 'disk' is null + message + Assuming 'disk' is null + + + kindcontrol + edges + + + start + + + line445 + col7 + file0 + + + line445 + col10 + file0 + + + end + + + line447 + col3 + file0 + + + line447 + col6 + file0 + + + + + + + kindcontrol + edges + + + start + + + line447 + col3 + file0 + + + line447 + col6 + file0 + + + end + + + line448 + col3 + file0 + + + line448 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line448 + col3 + file0 + + + line448 + col4 + file0 + + + end + + + line448 + col7 + file0 + + + line448 + col10 + file0 + + + + + + + kindevent + location + + line448 + col7 + file0 + + ranges + + + + line448 + col7 + file0 + + + line448 + col10 + file0 + + + + depth0 + extended_message + Assuming 'disk' is null + message + Assuming 'disk' is null + + + kindcontrol + edges + + + start + + + line448 + col7 + file0 + + + line448 + col10 + file0 + + + end + + + line450 + col3 + file0 + + + line450 + col17 + file0 + + + + + + + kindevent + location + + line450 + col26 + file0 + + ranges + + + + line450 + col26 + file0 + + + line450 + col49 + file0 + + + + depth0 + extended_message + Call to function 'DADiskCopyDescription' returns a Core Foundation object of type 'CFDictionaryRef' with a +1 retain count + message + Call to function 'DADiskCopyDescription' returns a Core Foundation object of type 'CFDictionaryRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line450 + col3 + file0 + + + line450 + col17 + file0 + + + end + + + line451 + col3 + file0 + + + line451 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line451 + col3 + file0 + + + line451 + col4 + file0 + + + end + + + line451 + col7 + file0 + + + line451 + col10 + file0 + + + + + + + kindevent + location + + line451 + col7 + file0 + + ranges + + + + line451 + col7 + file0 + + + line451 + col10 + file0 + + + + depth0 + extended_message + Assuming 'dict' is non-null + message + Assuming 'dict' is non-null + + + kindcontrol + edges + + + start + + + line451 + col7 + file0 + + + line451 + col10 + file0 + + + end + + + line451 + col13 + file0 + + + line451 + col17 + file0 + + + + + + + kindevent + location + + line451 + col13 + file0 + + ranges + + + + line451 + col13 + file0 + + + line451 + col17 + file0 + + + + depth0 + extended_message + Object leaked: object allocated and stored into 'dict' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'dict' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'dict' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_contexta7f8c63b1cdc39df79b7457e27ff4930 + issue_context_kindfunction + issue_contextf10 + issue_hash_function_offset7 + location + + line451 + col13 + file0 + + ExecutedLines + + 0 + + 443 + 444 + 445 + 447 + 448 + 450 + 451 + + + + + path + + + kindcontrol + edges + + + start + + + line444 + col3 + file0 + + + line444 + col11 + file0 + + + end + + + line445 + col3 + file0 + + + line445 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line445 + col3 + file0 + + + line445 + col4 + file0 + + + end + + + line445 + col7 + file0 + + + line445 + col10 + file0 + + + + + + + kindevent + location + + line445 + col7 + file0 + + ranges + + + + line445 + col7 + file0 + + + line445 + col10 + file0 + + + + depth0 + extended_message + Assuming 'disk' is null + message + Assuming 'disk' is null + + + kindcontrol + edges + + + start + + + line445 + col7 + file0 + + + line445 + col10 + file0 + + + end + + + line447 + col3 + file0 + + + line447 + col6 + file0 + + + + + + + kindcontrol + edges + + + start + + + line447 + col3 + file0 + + + line447 + col6 + file0 + + + end + + + line448 + col3 + file0 + + + line448 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line448 + col3 + file0 + + + line448 + col4 + file0 + + + end + + + line448 + col7 + file0 + + + line448 + col10 + file0 + + + + + + + kindevent + location + + line448 + col7 + file0 + + ranges + + + + line448 + col7 + file0 + + + line448 + col10 + file0 + + + + depth0 + extended_message + Assuming 'disk' is null + message + Assuming 'disk' is null + + + kindcontrol + edges + + + start + + + line448 + col7 + file0 + + + line448 + col10 + file0 + + + end + + + line450 + col3 + file0 + + + line450 + col17 + file0 + + + + + + + kindcontrol + edges + + + start + + + line450 + col3 + file0 + + + line450 + col17 + file0 + + + end + + + line451 + col3 + file0 + + + line451 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line451 + col3 + file0 + + + line451 + col4 + file0 + + + end + + + line451 + col7 + file0 + + + line451 + col10 + file0 + + + + + + + kindevent + location + + line451 + col7 + file0 + + ranges + + + + line451 + col7 + file0 + + + line451 + col10 + file0 + + + + depth0 + extended_message + Assuming 'dict' is null + message + Assuming 'dict' is null + + + kindcontrol + edges + + + start + + + line451 + col7 + file0 + + + line451 + col10 + file0 + + + end + + + line453 + col3 + file0 + + + line453 + col6 + file0 + + + + + + + kindevent + location + + line453 + col10 + file0 + + ranges + + + + line453 + col10 + file0 + + + line453 + col31 + file0 + + + + depth0 + extended_message + Call to function 'DADiskCopyWholeDisk' returns a Core Foundation object of type 'DADiskRef' with a +1 retain count + message + Call to function 'DADiskCopyWholeDisk' returns a Core Foundation object of type 'DADiskRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line453 + col3 + file0 + + + line453 + col6 + file0 + + + end + + + line454 + col3 + file0 + + + line454 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line454 + col3 + file0 + + + line454 + col4 + file0 + + + end + + + line454 + col7 + file0 + + + line454 + col10 + file0 + + + + + + + kindevent + location + + line454 + col7 + file0 + + ranges + + + + line454 + col7 + file0 + + + line454 + col10 + file0 + + + + depth0 + extended_message + Assuming 'disk' is non-null + message + Assuming 'disk' is non-null + + + kindcontrol + edges + + + start + + + line454 + col7 + file0 + + + line454 + col10 + file0 + + + end + + + line454 + col13 + file0 + + + line454 + col17 + file0 + + + + + + + kindevent + location + + line454 + col13 + file0 + + ranges + + + + line454 + col13 + file0 + + + line454 + col17 + file0 + + + + depth0 + extended_message + Object leaked: object allocated and stored into 'disk' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'disk' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'disk' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_contextcace8e35bed93ecdfa0455ac166aaa97 + issue_context_kindfunction + issue_contextf10 + issue_hash_function_offset10 + location + + line454 + col13 + file0 + + ExecutedLines + + 0 + + 443 + 444 + 445 + 447 + 448 + 450 + 451 + 453 + 454 + + + + + path + + + kindcontrol + edges + + + start + + + line444 + col3 + file0 + + + line444 + col11 + file0 + + + end + + + line445 + col3 + file0 + + + line445 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line445 + col3 + file0 + + + line445 + col4 + file0 + + + end + + + line445 + col7 + file0 + + + line445 + col10 + file0 + + + + + + + kindevent + location + + line445 + col7 + file0 + + ranges + + + + line445 + col7 + file0 + + + line445 + col10 + file0 + + + + depth0 + extended_message + Assuming 'disk' is null + message + Assuming 'disk' is null + + + kindcontrol + edges + + + start + + + line445 + col7 + file0 + + + line445 + col10 + file0 + + + end + + + line447 + col3 + file0 + + + line447 + col6 + file0 + + + + + + + kindevent + location + + line447 + col10 + file0 + + ranges + + + + line447 + col10 + file0 + + + line447 + col63 + file0 + + + + depth0 + extended_message + Call to function 'DADiskCreateFromIOMedia' returns a Core Foundation object of type 'DADiskRef' with a +1 retain count + message + Call to function 'DADiskCreateFromIOMedia' returns a Core Foundation object of type 'DADiskRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line447 + col3 + file0 + + + line447 + col6 + file0 + + + end + + + line448 + col3 + file0 + + + line448 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line448 + col3 + file0 + + + line448 + col4 + file0 + + + end + + + line448 + col7 + file0 + + + line448 + col10 + file0 + + + + + + + kindevent + location + + line448 + col7 + file0 + + ranges + + + + line448 + col7 + file0 + + + line448 + col10 + file0 + + + + depth0 + extended_message + Assuming 'disk' is non-null + message + Assuming 'disk' is non-null + + + kindcontrol + edges + + + start + + + line448 + col7 + file0 + + + line448 + col10 + file0 + + + end + + + line448 + col13 + file0 + + + line448 + col17 + file0 + + + + + + + kindcontrol + edges + + + start + + + line448 + col13 + file0 + + + line448 + col17 + file0 + + + end + + + line450 + col3 + file0 + + + line450 + col17 + file0 + + + + + + + kindcontrol + edges + + + start + + + line450 + col3 + file0 + + + line450 + col17 + file0 + + + end + + + line451 + col3 + file0 + + + line451 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line451 + col3 + file0 + + + line451 + col4 + file0 + + + end + + + line451 + col7 + file0 + + + line451 + col10 + file0 + + + + + + + kindevent + location + + line451 + col7 + file0 + + ranges + + + + line451 + col7 + file0 + + + line451 + col10 + file0 + + + + depth0 + extended_message + Assuming 'dict' is null + message + Assuming 'dict' is null + + + kindcontrol + edges + + + start + + + line451 + col7 + file0 + + + line451 + col10 + file0 + + + end + + + line453 + col3 + file0 + + + line453 + col6 + file0 + + + + + + + kindcontrol + edges + + + start + + + line453 + col3 + file0 + + + line453 + col6 + file0 + + + end + + + line454 + col3 + file0 + + + line454 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line454 + col3 + file0 + + + line454 + col4 + file0 + + + end + + + line454 + col7 + file0 + + + line454 + col10 + file0 + + + + + + + kindevent + location + + line454 + col7 + file0 + + ranges + + + + line454 + col7 + file0 + + + line454 + col10 + file0 + + + + depth0 + extended_message + Assuming 'disk' is null + message + Assuming 'disk' is null + + + kindcontrol + edges + + + start + + + line454 + col7 + file0 + + + line454 + col10 + file0 + + + end + + + line456 + col3 + file0 + + + line456 + col16 + file0 + + + + + + + kindcontrol + edges + + + start + + + line456 + col3 + file0 + + + line456 + col16 + file0 + + + end + + + line456 + col30 + file0 + + + line456 + col46 + file0 + + + + + + + kindevent + location + + line456 + col30 + file0 + + ranges + + + + line456 + col30 + file0 + + + line456 + col46 + file0 + + + + depth0 + extended_message + Object leaked: object allocated and stored into 'disk' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'disk' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'disk' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context778f70549a15e78703b4dcb3a287df33 + issue_context_kindfunction + issue_contextf10 + issue_hash_function_offset4 + location + + line456 + col30 + file0 + + ExecutedLines + + 0 + + 443 + 444 + 445 + 447 + 448 + 450 + 451 + 453 + 454 + 456 + + + + + path + + + kindcontrol + edges + + + start + + + line444 + col3 + file0 + + + line444 + col11 + file0 + + + end + + + line445 + col3 + file0 + + + line445 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line445 + col3 + file0 + + + line445 + col4 + file0 + + + end + + + line445 + col7 + file0 + + + line445 + col10 + file0 + + + + + + + kindevent + location + + line445 + col7 + file0 + + ranges + + + + line445 + col7 + file0 + + + line445 + col10 + file0 + + + + depth0 + extended_message + Assuming 'disk' is null + message + Assuming 'disk' is null + + + kindcontrol + edges + + + start + + + line445 + col7 + file0 + + + line445 + col10 + file0 + + + end + + + line447 + col3 + file0 + + + line447 + col6 + file0 + + + + + + + kindcontrol + edges + + + start + + + line447 + col3 + file0 + + + line447 + col6 + file0 + + + end + + + line448 + col3 + file0 + + + line448 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line448 + col3 + file0 + + + line448 + col4 + file0 + + + end + + + line448 + col7 + file0 + + + line448 + col10 + file0 + + + + + + + kindevent + location + + line448 + col7 + file0 + + ranges + + + + line448 + col7 + file0 + + + line448 + col10 + file0 + + + + depth0 + extended_message + Assuming 'disk' is null + message + Assuming 'disk' is null + + + kindcontrol + edges + + + start + + + line448 + col7 + file0 + + + line448 + col10 + file0 + + + end + + + line450 + col3 + file0 + + + line450 + col17 + file0 + + + + + + + kindcontrol + edges + + + start + + + line450 + col3 + file0 + + + line450 + col17 + file0 + + + end + + + line451 + col3 + file0 + + + line451 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line451 + col3 + file0 + + + line451 + col4 + file0 + + + end + + + line451 + col7 + file0 + + + line451 + col10 + file0 + + + + + + + kindevent + location + + line451 + col7 + file0 + + ranges + + + + line451 + col7 + file0 + + + line451 + col10 + file0 + + + + depth0 + extended_message + Assuming 'dict' is null + message + Assuming 'dict' is null + + + kindcontrol + edges + + + start + + + line451 + col7 + file0 + + + line451 + col10 + file0 + + + end + + + line453 + col3 + file0 + + + line453 + col6 + file0 + + + + + + + kindcontrol + edges + + + start + + + line453 + col3 + file0 + + + line453 + col6 + file0 + + + end + + + line454 + col3 + file0 + + + line454 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line454 + col3 + file0 + + + line454 + col4 + file0 + + + end + + + line454 + col7 + file0 + + + line454 + col10 + file0 + + + + + + + kindevent + location + + line454 + col7 + file0 + + ranges + + + + line454 + col7 + file0 + + + line454 + col10 + file0 + + + + depth0 + extended_message + Assuming 'disk' is null + message + Assuming 'disk' is null + + + kindcontrol + edges + + + start + + + line454 + col7 + file0 + + + line454 + col10 + file0 + + + end + + + line456 + col3 + file0 + + + line456 + col16 + file0 + + + + + + + kindcontrol + edges + + + start + + + line456 + col3 + file0 + + + line456 + col16 + file0 + + + end + + + line456 + col30 + file0 + + + line456 + col46 + file0 + + + + + + + kindevent + location + + line456 + col30 + file0 + + ranges + + + + line456 + col30 + file0 + + + line457 + col68 + file0 + + + + depth0 + extended_message + Call to function 'DADissenterCreate' returns a Core Foundation object of type 'DADissenterRef' with a +1 retain count + message + Call to function 'DADissenterCreate' returns a Core Foundation object of type 'DADissenterRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line456 + col30 + file0 + + + line456 + col46 + file0 + + + end + + + line456 + col3 + file0 + + + line456 + col16 + file0 + + + + + + + kindcontrol + edges + + + start + + + line456 + col3 + file0 + + + line456 + col16 + file0 + + + end + + + line458 + col3 + file0 + + + line458 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line458 + col3 + file0 + + + line458 + col4 + file0 + + + end + + + line458 + col7 + file0 + + + line458 + col15 + file0 + + + + + + + kindevent + location + + line458 + col7 + file0 + + ranges + + + + line458 + col7 + file0 + + + line458 + col15 + file0 + + + + depth0 + extended_message + Assuming 'dissenter' is non-null + message + Assuming 'dissenter' is non-null + + + kindcontrol + edges + + + start + + + line458 + col7 + file0 + + + line458 + col15 + file0 + + + end + + + line458 + col18 + file0 + + + line458 + col22 + file0 + + + + + + + kindevent + location + + line458 + col18 + file0 + + ranges + + + + line458 + col18 + file0 + + + line458 + col22 + file0 + + + + depth0 + extended_message + Object leaked: object allocated and stored into 'dissenter' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'dissenter' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'dissenter' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context6c188b4716e84cdc55b93d40e6c2daf3 + issue_context_kindfunction + issue_contextf10 + issue_hash_function_offset13 + location + + line458 + col18 + file0 + + ExecutedLines + + 0 + + 443 + 444 + 445 + 447 + 448 + 450 + 451 + 453 + 454 + 456 + 457 + 458 + + + + + path + + + kindcontrol + edges + + + start + + + line444 + col3 + file0 + + + line444 + col11 + file0 + + + end + + + line445 + col3 + file0 + + + line445 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line445 + col3 + file0 + + + line445 + col4 + file0 + + + end + + + line445 + col7 + file0 + + + line445 + col10 + file0 + + + + + + + kindevent + location + + line445 + col7 + file0 + + ranges + + + + line445 + col7 + file0 + + + line445 + col10 + file0 + + + + depth0 + extended_message + Assuming 'disk' is null + message + Assuming 'disk' is null + + + kindcontrol + edges + + + start + + + line445 + col7 + file0 + + + line445 + col10 + file0 + + + end + + + line447 + col3 + file0 + + + line447 + col6 + file0 + + + + + + + kindcontrol + edges + + + start + + + line447 + col3 + file0 + + + line447 + col6 + file0 + + + end + + + line448 + col3 + file0 + + + line448 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line448 + col3 + file0 + + + line448 + col4 + file0 + + + end + + + line448 + col7 + file0 + + + line448 + col10 + file0 + + + + + + + kindevent + location + + line448 + col7 + file0 + + ranges + + + + line448 + col7 + file0 + + + line448 + col10 + file0 + + + + depth0 + extended_message + Assuming 'disk' is null + message + Assuming 'disk' is null + + + kindcontrol + edges + + + start + + + line448 + col7 + file0 + + + line448 + col10 + file0 + + + end + + + line450 + col3 + file0 + + + line450 + col17 + file0 + + + + + + + kindcontrol + edges + + + start + + + line450 + col3 + file0 + + + line450 + col17 + file0 + + + end + + + line451 + col3 + file0 + + + line451 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line451 + col3 + file0 + + + line451 + col4 + file0 + + + end + + + line451 + col7 + file0 + + + line451 + col10 + file0 + + + + + + + kindevent + location + + line451 + col7 + file0 + + ranges + + + + line451 + col7 + file0 + + + line451 + col10 + file0 + + + + depth0 + extended_message + Assuming 'dict' is null + message + Assuming 'dict' is null + + + kindcontrol + edges + + + start + + + line451 + col7 + file0 + + + line451 + col10 + file0 + + + end + + + line453 + col3 + file0 + + + line453 + col6 + file0 + + + + + + + kindcontrol + edges + + + start + + + line453 + col3 + file0 + + + line453 + col6 + file0 + + + end + + + line454 + col3 + file0 + + + line454 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line454 + col3 + file0 + + + line454 + col4 + file0 + + + end + + + line454 + col7 + file0 + + + line454 + col10 + file0 + + + + + + + kindevent + location + + line454 + col7 + file0 + + ranges + + + + line454 + col7 + file0 + + + line454 + col10 + file0 + + + + depth0 + extended_message + Assuming 'disk' is null + message + Assuming 'disk' is null + + + kindcontrol + edges + + + start + + + line454 + col7 + file0 + + + line454 + col10 + file0 + + + end + + + line456 + col3 + file0 + + + line456 + col16 + file0 + + + + + + + kindcontrol + edges + + + start + + + line456 + col3 + file0 + + + line456 + col16 + file0 + + + end + + + line458 + col3 + file0 + + + line458 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line458 + col3 + file0 + + + line458 + col4 + file0 + + + end + + + line458 + col7 + file0 + + + line458 + col15 + file0 + + + + + + + kindevent + location + + line458 + col7 + file0 + + ranges + + + + line458 + col7 + file0 + + + line458 + col15 + file0 + + + + depth0 + extended_message + Assuming 'dissenter' is null + message + Assuming 'dissenter' is null + + + kindcontrol + edges + + + start + + + line458 + col7 + file0 + + + line458 + col15 + file0 + + + end + + + line460 + col3 + file0 + + + line460 + col14 + file0 + + + + + + + kindevent + location + + line460 + col26 + file0 + + ranges + + + + line460 + col26 + file0 + + + line460 + col61 + file0 + + + + depth0 + extended_message + Call to function 'DASessionCreate' returns a Core Foundation object of type 'DASessionRef' with a +1 retain count + message + Call to function 'DASessionCreate' returns a Core Foundation object of type 'DASessionRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line460 + col3 + file0 + + + line460 + col14 + file0 + + + end + + + line461 + col3 + file0 + + + line461 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line461 + col3 + file0 + + + line461 + col4 + file0 + + + end + + + line461 + col7 + file0 + + + line461 + col13 + file0 + + + + + + + kindevent + location + + line461 + col7 + file0 + + ranges + + + + line461 + col7 + file0 + + + line461 + col13 + file0 + + + + depth0 + extended_message + Assuming 'session' is non-null + message + Assuming 'session' is non-null + + + kindcontrol + edges + + + start + + + line461 + col7 + file0 + + + line461 + col13 + file0 + + + end + + + line461 + col16 + file0 + + + line461 + col20 + file0 + + + + + + + kindevent + location + + line461 + col16 + file0 + + ranges + + + + line461 + col16 + file0 + + + line461 + col20 + file0 + + + + depth0 + extended_message + Object leaked: object allocated and stored into 'session' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'session' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'session' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context35b9ac7ff198890c88d5839a898b7fea + issue_context_kindfunction + issue_contextf10 + issue_hash_function_offset17 + location + + line461 + col16 + file0 + + ExecutedLines + + 0 + + 443 + 444 + 445 + 447 + 448 + 450 + 451 + 453 + 454 + 456 + 457 + 458 + 460 + 461 + + + + + path + + + kindevent + location + + line478 + col16 + file0 + + ranges + + + + line478 + col16 + file0 + + + line478 + col31 + file0 + + + + depth0 + extended_message + Call to function 'CMCreateFooRef' returns a Core Foundation object of type 'CMFooRef' with a +1 retain count + message + Call to function 'CMCreateFooRef' returns a Core Foundation object of type 'CMFooRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line478 + col3 + file0 + + + line478 + col10 + file0 + + + end + + + line479 + col1 + file0 + + + line479 + col1 + file0 + + + + + + + kindevent + location + + line479 + col1 + file0 + + depth0 + extended_message + Object leaked: object allocated and stored into 'f' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'f' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'f' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context17d84d673b35235b52d8f8f00c1d1eea + issue_context_kindfunction + issue_contexttestLeakCoreMediaReferenceType + issue_hash_function_offset1 + location + + line479 + col1 + file0 + + ExecutedLines + + 0 + + 477 + 478 + 479 + + + + + path + + + kindevent + location + + line482 + col16 + file0 + + ranges + + + + line482 + col16 + file0 + + + line482 + col28 + file0 + + + + depth0 + extended_message + Call to function 'CMGetFooRef' returns a Core Foundation object of type 'CMFooRef' with a +0 retain count + message + Call to function 'CMGetFooRef' returns a Core Foundation object of type 'CMFooRef' with a +0 retain count + + + kindcontrol + edges + + + start + + + line482 + col3 + file0 + + + line482 + col10 + file0 + + + end + + + line483 + col3 + file0 + + + line483 + col11 + file0 + + + + + + + kindevent + location + + line483 + col3 + file0 + + ranges + + + + line483 + col13 + file0 + + + line483 + col13 + file0 + + + + depth0 + extended_message + Incorrect decrement of the reference count of an object that is not owned at this point by the caller + message + Incorrect decrement of the reference count of an object that is not owned at this point by the caller + + + descriptionIncorrect decrement of the reference count of an object that is not owned at this point by the caller + categoryMemory (Core Foundation/Objective-C/OSObject) + typeBad release + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context1702285448a953b02ab74a8eb9a610d9 + issue_context_kindfunction + issue_contexttestOverReleaseMediaReferenceType + issue_hash_function_offset2 + location + + line483 + col3 + file0 + + ExecutedLines + + 0 + + 481 + 482 + 483 + + + + + path + + + kindcontrol + edges + + + start + + + line516 + col3 + file0 + + + line516 + col13 + file0 + + + end + + + line520 + col3 + file0 + + + line520 + col21 + file0 + + + + + + + kindevent + location + + line520 + col23 + file0 + + ranges + + + + line520 + col23 + file0 + + + line520 + col57 + file0 + + + + depth0 + extended_message + Assuming 'buffer' is not equal to 'queue' + message + Assuming 'buffer' is not equal to 'queue' + + + kindevent + location + + line520 + col3 + file0 + + ranges + + + + line520 + col3 + file0 + + + line520 + col58 + file0 + + + + depth0 + extended_message + FALSE + message + FALSE + + + descriptionFALSE + categorydebug + typeChecking analyzer assumptions + check_namedebug.ExprInspection + + issue_hash_content_of_line_in_context78b71dc497a2059b950406cb2a1cfd01 + issue_context_kindfunction + issue_contexttestCMBufferQueueDequeueAndRetain + issue_hash_function_offset5 + location + + line520 + col3 + file0 + + ExecutedLines + + 0 + + 515 + 516 + 520 + + + + + path + + + kindcontrol + edges + + + start + + + line516 + col3 + file0 + + + line516 + col13 + file0 + + + end + + + line520 + col3 + file0 + + + line520 + col21 + file0 + + + + + + + kindevent + location + + line520 + col23 + file0 + + ranges + + + + line520 + col23 + file0 + + + line520 + col57 + file0 + + + + depth0 + extended_message + Assuming 'buffer' is equal to 'queue' + message + Assuming 'buffer' is equal to 'queue' + + + kindevent + location + + line520 + col3 + file0 + + ranges + + + + line520 + col3 + file0 + + + line520 + col58 + file0 + + + + depth0 + extended_message + TRUE + message + TRUE + + + descriptionTRUE + categorydebug + typeChecking analyzer assumptions + check_namedebug.ExprInspection + + issue_hash_content_of_line_in_context78b71dc497a2059b950406cb2a1cfd01 + issue_context_kindfunction + issue_contexttestCMBufferQueueDequeueAndRetain + issue_hash_function_offset5 + location + + line520 + col3 + file0 + + ExecutedLines + + 0 + + 515 + 516 + 520 + + + + + path + + + kindevent + location + + line516 + col24 + file0 + + ranges + + + + line516 + col24 + file0 + + + line516 + col59 + file0 + + + + depth0 + extended_message + Call to function 'CMBufferQueueDequeueAndRetain' returns a Core Foundation object of type 'CMBufferRef' with a +1 retain count + message + Call to function 'CMBufferQueueDequeueAndRetain' returns a Core Foundation object of type 'CMBufferRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line516 + col3 + file0 + + + line516 + col13 + file0 + + + end + + + line520 + col3 + file0 + + + line520 + col21 + file0 + + + + + + + kindevent + location + + line520 + col23 + file0 + + ranges + + + + line520 + col23 + file0 + + + line520 + col57 + file0 + + + + depth0 + extended_message + Assuming 'buffer' is not equal to 'queue' + message + Assuming 'buffer' is not equal to 'queue' + + + kindevent + location + + line520 + col3 + file0 + + ranges + + + + line520 + col3 + file0 + + + line520 + col58 + file0 + + + + depth0 + extended_message + Object leaked: object allocated and stored into 'buffer' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'buffer' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'buffer' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context402566b4ddf1683dac1aefc1ab3e76e9 + issue_context_kindfunction + issue_contexttestCMBufferQueueDequeueAndRetain + issue_hash_function_offset1 + location + + line520 + col3 + file0 + + ExecutedLines + + 0 + + 515 + 516 + 520 + + + + + path + + + kindcontrol + edges + + + start + + + line527 + col3 + file0 + + + line527 + col19 + file0 + + + end + + + line540 + col3 + file0 + + + line540 + col4 + file0 + + + + + + + kindevent + location + + line540 + col22 + file0 + + ranges + + + + line540 + col22 + file0 + + + line540 + col49 + file0 + + + + depth0 + extended_message + Call to function 'CFArrayGetValueAtIndex' returns a Core Foundation object of type 'const void *' with a +0 retain count + message + Call to function 'CFArrayGetValueAtIndex' returns a Core Foundation object of type 'const void *' with a +0 retain count + + + kindcontrol + edges + + + start + + + line540 + col3 + file0 + + + line540 + col4 + file0 + + + end + + + line546 + col3 + file0 + + + line546 + col11 + file0 + + + + + + + kindevent + location + + line546 + col3 + file0 + + ranges + + + + line546 + col13 + file0 + + + line546 + col14 + file0 + + + + depth0 + extended_message + Incorrect decrement of the reference count of an object that is not owned at this point by the caller + message + Incorrect decrement of the reference count of an object that is not owned at this point by the caller + + + descriptionIncorrect decrement of the reference count of an object that is not owned at this point by the caller + categoryMemory (Core Foundation/Objective-C/OSObject) + typeBad release + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context143ef5974bfece95e9894da5250aaff0 + issue_context_kindfunction + issue_contextf11 + issue_hash_function_offset21 + location + + line546 + col3 + file0 + + ExecutedLines + + 0 + + 525 + 527 + 530 + 531 + 534 + 537 + 540 + 543 + 546 + + + + + path + + + kindevent + location + + line554 + col17 + file0 + + ranges + + + + line554 + col17 + file0 + + + line554 + col29 + file0 + + + + depth0 + extended_message + Call to function 'MyCreateFun' returns a Core Foundation object of type 'CFTypeRef' with a +1 retain count + message + Call to function 'MyCreateFun' returns a Core Foundation object of type 'CFTypeRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line554 + col3 + file0 + + + line554 + col11 + file0 + + + end + + + line555 + col1 + file0 + + + line555 + col1 + file0 + + + + + + + kindevent + location + + line555 + col1 + file0 + + depth0 + extended_message + Object leaked: object allocated and stored into 'o' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'o' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'o' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_contextaf4ad99c5fb565d82e1b4848aaca4e24 + issue_context_kindfunction + issue_contextf12 + issue_hash_function_offset1 + location + + line555 + col1 + file0 + + ExecutedLines + + 0 + + 553 + 554 + 555 + + + + + path + + + kindevent + location + + line563 + col25 + file0 + + ranges + + + + line563 + col25 + file0 + + + line563 + col75 + file0 + + + + depth0 + extended_message + Call to function 'CFArrayCreateMutable' returns a Core Foundation object of type 'CFMutableArrayRef' with a +1 retain count + message + Call to function 'CFArrayCreateMutable' returns a Core Foundation object of type 'CFMutableArrayRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line563 + col3 + file0 + + + line563 + col19 + file0 + + + end + + + line564 + col3 + file0 + + + line564 + col3 + file0 + + + + + + + kindevent + location + + line564 + col3 + file0 + + ranges + + + + line564 + col3 + file0 + + + line564 + col22 + file0 + + + + + line564 + col4 + file0 + + + line564 + col9 + file0 + + + + depth0 + extended_message + Object autoreleased + message + Object autoreleased + + + kindcontrol + edges + + + start + + + line564 + col3 + file0 + + + line564 + col3 + file0 + + + end + + + line565 + col3 + file0 + + + line565 + col3 + file0 + + + + + + + kindevent + location + + line565 + col3 + file0 + + ranges + + + + line565 + col3 + file0 + + + line565 + col22 + file0 + + + + + line565 + col4 + file0 + + + line565 + col9 + file0 + + + + depth0 + extended_message + Object autoreleased + message + Object autoreleased + + + kindcontrol + edges + + + start + + + line565 + col3 + file0 + + + line565 + col3 + file0 + + + end + + + line566 + col1 + file0 + + + line566 + col1 + file0 + + + + + + + kindevent + location + + line566 + col1 + file0 + + depth0 + extended_message + Object was autoreleased 2 times but the object has a +1 retain count + message + Object was autoreleased 2 times but the object has a +1 retain count + + + descriptionObject autoreleased too many times + categoryMemory (Core Foundation/Objective-C/OSObject) + typeObject autoreleased too many times + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context58a0b3f8332f42561f89b11f6eb5e91f + issue_context_kindfunction + issue_contextf13_autorelease_b + issue_hash_function_offset4 + location + + line566 + col1 + file0 + + ExecutedLines + + 0 + + 562 + 563 + 564 + 565 + 566 + + + + + path + + + kindevent + location + + line569 + col25 + file0 + + ranges + + + + line569 + col25 + file0 + + + line569 + col75 + file0 + + + + depth0 + extended_message + Call to function 'CFArrayCreateMutable' returns a Core Foundation object of type 'CFMutableArrayRef' with a +1 retain count + message + Call to function 'CFArrayCreateMutable' returns a Core Foundation object of type 'CFMutableArrayRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line569 + col3 + file0 + + + line569 + col19 + file0 + + + end + + + line570 + col3 + file0 + + + line570 + col3 + file0 + + + + + + + kindevent + location + + line570 + col3 + file0 + + ranges + + + + line570 + col3 + file0 + + + line570 + col22 + file0 + + + + + line570 + col4 + file0 + + + line570 + col9 + file0 + + + + depth0 + extended_message + Object autoreleased + message + Object autoreleased + + + kindcontrol + edges + + + start + + + line570 + col3 + file0 + + + line570 + col3 + file0 + + + end + + + line571 + col3 + file0 + + + line571 + col3 + file0 + + + + + + + kindevent + location + + line571 + col3 + file0 + + ranges + + + + line571 + col3 + file0 + + + line571 + col22 + file0 + + + + + line571 + col4 + file0 + + + line571 + col9 + file0 + + + + depth0 + extended_message + Object autoreleased + message + Object autoreleased + + + kindcontrol + edges + + + start + + + line571 + col3 + file0 + + + line571 + col3 + file0 + + + end + + + line572 + col3 + file0 + + + line572 + col8 + file0 + + + + + + + kindevent + location + + line572 + col3 + file0 + + ranges + + + + line572 + col3 + file0 + + + line572 + col10 + file0 + + + + depth0 + extended_message + Object was autoreleased 2 times but the object has a +0 retain count + message + Object was autoreleased 2 times but the object has a +0 retain count + + + descriptionObject autoreleased too many times + categoryMemory (Core Foundation/Objective-C/OSObject) + typeObject autoreleased too many times + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context612dc6574d54c8010703a9776d8a4a0a + issue_context_kindfunction + issue_contextf13_autorelease_c + issue_hash_function_offset4 + location + + line572 + col3 + file0 + + ExecutedLines + + 0 + + 568 + 569 + 570 + 571 + 572 + + + + + path + + + kindevent + location + + line576 + col25 + file0 + + ranges + + + + line576 + col25 + file0 + + + line576 + col75 + file0 + + + + depth0 + extended_message + Call to function 'CFArrayCreateMutable' returns a Core Foundation object of type 'CFMutableArrayRef' with a +1 retain count + message + Call to function 'CFArrayCreateMutable' returns a Core Foundation object of type 'CFMutableArrayRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line576 + col3 + file0 + + + line576 + col19 + file0 + + + end + + + line577 + col3 + file0 + + + line577 + col3 + file0 + + + + + + + kindevent + location + + line577 + col3 + file0 + + ranges + + + + line577 + col3 + file0 + + + line577 + col22 + file0 + + + + + line577 + col4 + file0 + + + line577 + col9 + file0 + + + + depth0 + extended_message + Object autoreleased + message + Object autoreleased + + + kindcontrol + edges + + + start + + + line577 + col3 + file0 + + + line577 + col3 + file0 + + + end + + + line578 + col3 + file0 + + + line578 + col3 + file0 + + + + + + + kindevent + location + + line578 + col3 + file0 + + ranges + + + + line578 + col3 + file0 + + + line578 + col22 + file0 + + + + + line578 + col4 + file0 + + + line578 + col9 + file0 + + + + depth0 + extended_message + Object autoreleased + message + Object autoreleased + + + kindcontrol + edges + + + start + + + line578 + col3 + file0 + + + line578 + col3 + file0 + + + end + + + line579 + col3 + file0 + + + line579 + col19 + file0 + + + + + + + kindcontrol + edges + + + start + + + line579 + col3 + file0 + + + line579 + col19 + file0 + + + end + + + line579 + col25 + file0 + + + line579 + col44 + file0 + + + + + + + kindevent + location + + line579 + col25 + file0 + + ranges + + + + line579 + col25 + file0 + + + line579 + col75 + file0 + + + + depth0 + extended_message + Object was autoreleased 2 times but the object has a +1 retain count + message + Object was autoreleased 2 times but the object has a +1 retain count + + + descriptionObject autoreleased too many times + categoryMemory (Core Foundation/Objective-C/OSObject) + typeObject autoreleased too many times + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_contextc57037289bc3acc586de325df25951ed + issue_context_kindfunction + issue_contextf13_autorelease_d + issue_hash_function_offset4 + location + + line579 + col25 + file0 + + ExecutedLines + + 0 + + 575 + 576 + 577 + 578 + 579 + + + + + path + + + kindevent + location + + line587 + col3 + file0 + + ranges + + + + line587 + col3 + file0 + + + line587 + col53 + file0 + + + + depth0 + extended_message + Call to function 'CFArrayCreateMutable' returns a Core Foundation object of type 'CFMutableArrayRef' with a +1 retain count + message + Call to function 'CFArrayCreateMutable' returns a Core Foundation object of type 'CFMutableArrayRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line587 + col3 + file0 + + + line587 + col22 + file0 + + + end + + + line588 + col1 + file0 + + + line588 + col1 + file0 + + + + + + + kindevent + location + + line588 + col1 + file0 + + depth0 + extended_message + Object leaked: allocated object of type 'CFMutableArrayRef' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: allocated object of type 'CFMutableArrayRef' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object of type 'CFMutableArrayRef' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context6abb479bc4c7782a125d680fddf825ef + issue_context_kindfunction + issue_contextf14_leakimmediately + issue_hash_function_offset1 + location + + line588 + col1 + file0 + + ExecutedLines + + 0 + + 586 + 587 + 588 + + + + + path + + + kindcontrol + edges + + + start + + + line602 + col3 + file0 + + + line602 + col4 + file0 + + + end + + + line602 + col7 + file0 + + + line602 + col7 + file0 + + + + + + + kindevent + location + + line602 + col7 + file0 + + ranges + + + + line602 + col7 + file0 + + + line602 + col7 + file0 + + + + depth0 + extended_message + Assuming 'p' is null + message + Assuming 'p' is null + + + kindcontrol + edges + + + start + + + line602 + col7 + file0 + + + line602 + col7 + file0 + + + end + + + line605 + col3 + file0 + + + line605 + col8 + file0 + + + + + + + kindcontrol + edges + + + start + + + line605 + col3 + file0 + + + line605 + col8 + file0 + + + end + + + line605 + col11 + file0 + + + line605 + col11 + file0 + + + + + + + kindcontrol + edges + + + start + + + line605 + col11 + file0 + + + line605 + col11 + file0 + + + end + + + line607 + col5 + file0 + + + line607 + col13 + file0 + + + + + + + kindevent + location + + line607 + col5 + file0 + + ranges + + + + line607 + col15 + file0 + + + line607 + col15 + file0 + + + + depth0 + extended_message + Null pointer argument in call to CFRelease + message + Null pointer argument in call to CFRelease + + + descriptionNull pointer argument in call to CFRelease + categoryAPI Misuse (Apple) + typenull passed to CF memory management function + check_nameosx.coreFoundation.CFRetainRelease + + issue_hash_content_of_line_in_contexte7e2ba205af363f2c4cec7d01dcb6d6c + issue_context_kindfunction + issue_contextf16 + issue_hash_function_offset6 + location + + line607 + col5 + file0 + + ExecutedLines + + 0 + + 601 + 602 + 605 + 606 + 607 + + + + + path + + + kindcontrol + edges + + + start + + + line602 + col3 + file0 + + + line602 + col4 + file0 + + + end + + + line602 + col7 + file0 + + + line602 + col7 + file0 + + + + + + + kindevent + location + + line602 + col7 + file0 + + ranges + + + + line602 + col7 + file0 + + + line602 + col7 + file0 + + + + depth0 + extended_message + Assuming 'p' is null + message + Assuming 'p' is null + + + kindcontrol + edges + + + start + + + line602 + col7 + file0 + + + line602 + col7 + file0 + + + end + + + line605 + col3 + file0 + + + line605 + col8 + file0 + + + + + + + kindcontrol + edges + + + start + + + line605 + col3 + file0 + + + line605 + col8 + file0 + + + end + + + line605 + col11 + file0 + + + line605 + col11 + file0 + + + + + + + kindcontrol + edges + + + start + + + line605 + col11 + file0 + + + line605 + col11 + file0 + + + end + + + line610 + col5 + file0 + + + line610 + col12 + file0 + + + + + + + kindevent + location + + line610 + col5 + file0 + + ranges + + + + line610 + col14 + file0 + + + line610 + col14 + file0 + + + + depth0 + extended_message + Null pointer argument in call to CFRetain + message + Null pointer argument in call to CFRetain + + + descriptionNull pointer argument in call to CFRetain + categoryAPI Misuse (Apple) + typenull passed to CF memory management function + check_nameosx.coreFoundation.CFRetainRelease + + issue_hash_content_of_line_in_context64f4a3367d5d8e832ca8a23ca4d72717 + issue_context_kindfunction + issue_contextf16 + issue_hash_function_offset9 + location + + line610 + col5 + file0 + + ExecutedLines + + 0 + + 601 + 602 + 605 + 609 + 610 + + + + + path + + + kindcontrol + edges + + + start + + + line602 + col3 + file0 + + + line602 + col4 + file0 + + + end + + + line602 + col7 + file0 + + + line602 + col7 + file0 + + + + + + + kindevent + location + + line602 + col7 + file0 + + ranges + + + + line602 + col7 + file0 + + + line602 + col7 + file0 + + + + depth0 + extended_message + Assuming 'p' is null + message + Assuming 'p' is null + + + kindcontrol + edges + + + start + + + line602 + col7 + file0 + + + line602 + col7 + file0 + + + end + + + line605 + col3 + file0 + + + line605 + col8 + file0 + + + + + + + kindcontrol + edges + + + start + + + line605 + col3 + file0 + + + line605 + col8 + file0 + + + end + + + line605 + col11 + file0 + + + line605 + col11 + file0 + + + + + + + kindcontrol + edges + + + start + + + line605 + col11 + file0 + + + line605 + col11 + file0 + + + end + + + line613 + col5 + file0 + + + line613 + col21 + file0 + + + + + + + kindevent + location + + line613 + col5 + file0 + + ranges + + + + line613 + col23 + file0 + + + line613 + col23 + file0 + + + + depth0 + extended_message + Null pointer argument in call to CFMakeCollectable + message + Null pointer argument in call to CFMakeCollectable + + + descriptionNull pointer argument in call to CFMakeCollectable + categoryAPI Misuse (Apple) + typenull passed to CF memory management function + check_nameosx.coreFoundation.CFRetainRelease + + issue_hash_content_of_line_in_context61123dbb677396de5abbdd778c399140 + issue_context_kindfunction + issue_contextf16 + issue_hash_function_offset12 + location + + line613 + col5 + file0 + + ExecutedLines + + 0 + + 601 + 602 + 605 + 612 + 613 + + + + + path + + + kindcontrol + edges + + + start + + + line602 + col3 + file0 + + + line602 + col4 + file0 + + + end + + + line602 + col7 + file0 + + + line602 + col7 + file0 + + + + + + + kindevent + location + + line602 + col7 + file0 + + ranges + + + + line602 + col7 + file0 + + + line602 + col7 + file0 + + + + depth0 + extended_message + Assuming 'p' is null + message + Assuming 'p' is null + + + kindcontrol + edges + + + start + + + line602 + col7 + file0 + + + line602 + col7 + file0 + + + end + + + line605 + col3 + file0 + + + line605 + col8 + file0 + + + + + + + kindcontrol + edges + + + start + + + line605 + col3 + file0 + + + line605 + col8 + file0 + + + end + + + line605 + col11 + file0 + + + line605 + col11 + file0 + + + + + + + kindcontrol + edges + + + start + + + line605 + col11 + file0 + + + line605 + col11 + file0 + + + end + + + line616 + col5 + file0 + + + line616 + col17 + file0 + + + + + + + kindevent + location + + line616 + col5 + file0 + + ranges + + + + line616 + col19 + file0 + + + line616 + col19 + file0 + + + + depth0 + extended_message + Null pointer argument in call to CFAutorelease + message + Null pointer argument in call to CFAutorelease + + + descriptionNull pointer argument in call to CFAutorelease + categoryAPI Misuse (Apple) + typenull passed to CF memory management function + check_nameosx.coreFoundation.CFRetainRelease + + issue_hash_content_of_line_in_context965bca78fe04bfa55b6ea428da3c20e3 + issue_context_kindfunction + issue_contextf16 + issue_hash_function_offset15 + location + + line616 + col5 + file0 + + ExecutedLines + + 0 + + 601 + 602 + 605 + 615 + 616 + + + + + path + + + kindevent + location + + line656 + col10 + file0 + + ranges + + + + line656 + col10 + file0 + + + line656 + col32 + file0 + + + + depth0 + extended_message + Call to function 'isl_basic_map_cow' returns an object of type 'isl_basic_map *' with a +1 retain count + message + Call to function 'isl_basic_map_cow' returns an object of type 'isl_basic_map *' with a +1 retain count + + + kindcontrol + edges + + + start + + + line656 + col3 + file0 + + + line656 + col6 + file0 + + + end + + + line657 + col1 + file0 + + + line657 + col1 + file0 + + + + + + + kindevent + location + + line657 + col1 + file0 + + depth0 + extended_message + Object leaked: object allocated and stored into 'bmap' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'bmap' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'bmap' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context2cfebefee7b63ce3954419e571be4f63 + issue_context_kindfunction + issue_contextf18 + issue_hash_function_offset2 + location + + line657 + col1 + file0 + + ExecutedLines + + 0 + + 654 + 656 + 657 + + + + + path + + + kindevent + location + + line682 + col17 + file0 + + ranges + + + + line682 + col17 + file0 + + + line682 + col55 + file0 + + + + depth0 + extended_message + Method returns an Objective-C object with a +0 retain count + message + Method returns an Objective-C object with a +0 retain count + + + kindcontrol + edges + + + start + + + line682 + col3 + file0 + + + line682 + col10 + file0 + + + end + + + line683 + col3 + file0 + + + line683 + col8 + file0 + + + + + + + kindevent + location + + line683 + col3 + file0 + + ranges + + + + line683 + col3 + file0 + + + line683 + col10 + file0 + + + + depth0 + extended_message + Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected + message + Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected + + + descriptionObject with a +0 retain count returned to caller where a +1 (owning) retain count is expected + categoryMemory (Core Foundation/Objective-C/OSObject) + typeMethod should return an owned object + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_contextdcd3becc58a149abe6ade5598138d3dd + issue_context_kindObjective-C method + issue_contextnewString + issue_hash_function_offset2 + location + + line683 + col3 + file0 + + ExecutedLines + + 0 + + 681 + 682 + 683 + + + + + path + + + kindevent + location + + line696 + col20 + file0 + + ranges + + + + line696 + col20 + file0 + + + line696 + col63 + file0 + + + + depth0 + extended_message + Method returns an instance of NSString with a +1 retain count + message + Method returns an instance of NSString with a +1 retain count + + + kindcontrol + edges + + + start + + + line696 + col3 + file0 + + + line696 + col10 + file0 + + + end + + + line703 + col3 + file0 + + + line703 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line703 + col3 + file0 + + + line703 + col4 + file0 + + + end + + + line703 + col6 + file0 + + + line703 + col6 + file0 + + + + + + + kindevent + location + + line703 + col6 + file0 + + ranges + + + + line703 + col6 + file0 + + + line703 + col10 + file0 + + + + depth0 + extended_message + Assuming 'name' is nil + message + Assuming 'name' is nil + + + kindcontrol + edges + + + start + + + line703 + col6 + file0 + + + line703 + col6 + file0 + + + end + + + line704 + col5 + file0 + + + line704 + col10 + file0 + + + + + + + kindevent + location + + line704 + col5 + file0 + + ranges + + + + line704 + col5 + file0 + + + line704 + col10 + file0 + + + + depth0 + extended_message + Object leaked: object allocated and stored into 'kind' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'kind' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'kind' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context6688c9cb12f0c76ec80eb03b1d2eddf8 + issue_context_kindfunction + issue_contextrdar_6659160 + issue_hash_function_offset5 + location + + line704 + col5 + file0 + + ExecutedLines + + 0 + + 690 + 691 + 696 + 702 + 703 + 704 + + + + + path + + + kindcontrol + edges + + + start + + + line696 + col3 + file0 + + + line696 + col10 + file0 + + + end + + + line703 + col3 + file0 + + + line703 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line703 + col3 + file0 + + + line703 + col4 + file0 + + + end + + + line703 + col6 + file0 + + + line703 + col6 + file0 + + + + + + + kindevent + location + + line703 + col6 + file0 + + ranges + + + + line703 + col6 + file0 + + + line703 + col10 + file0 + + + + depth0 + extended_message + Assuming 'name' is non-nil + message + Assuming 'name' is non-nil + + + kindcontrol + edges + + + start + + + line703 + col6 + file0 + + + line703 + col6 + file0 + + + end + + + line706 + col3 + file0 + + + line706 + col7 + file0 + + + + + + + kindevent + location + + line706 + col3 + file0 + + ranges + + + + line706 + col3 + file0 + + + line706 + col19 + file0 + + + + depth0 + extended_message + 'kindC' initialized to a null pointer value + message + 'kindC' initialized to a null pointer value + + + kindcontrol + edges + + + start + + + line706 + col3 + file0 + + + line706 + col7 + file0 + + + end + + + line714 + col3 + file0 + + + line714 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line714 + col3 + file0 + + + line714 + col4 + file0 + + + end + + + line714 + col6 + file0 + + + line714 + col9 + file0 + + + + + + + kindevent + location + + line714 + col6 + file0 + + ranges + + + + line714 + col6 + file0 + + + line714 + col9 + file0 + + + + depth0 + extended_message + Assuming 'kind' is nil + message + Assuming 'kind' is nil + + + kindcontrol + edges + + + start + + + line714 + col6 + file0 + + + line714 + col9 + file0 + + + end + + + line716 + col3 + file0 + + + line716 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line716 + col3 + file0 + + + line716 + col4 + file0 + + + end + + + line717 + col5 + file0 + + + line717 + col9 + file0 + + + + + + + kindcontrol + edges + + + start + + + line717 + col5 + file0 + + + line717 + col9 + file0 + + + end + + + line718 + col3 + file0 + + + line718 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line718 + col3 + file0 + + + line718 + col4 + file0 + + + end + + + line718 + col13 + file0 + + + line718 + col17 + file0 + + + + + + + kindevent + location + + line718 + col13 + file0 + + ranges + + + + line718 + col13 + file0 + + + line718 + col17 + file0 + + + + depth0 + extended_message + Array access (from variable 'kindC') results in a null pointer dereference + message + Array access (from variable 'kindC') results in a null pointer dereference + + + descriptionArray access (from variable 'kindC') results in a null pointer dereference + categoryLogic error + typeDereference of null pointer + check_namecore.NullDereference + + issue_hash_content_of_line_in_context2824c4e1d4ab13c3ae5a0ebb2aa4ed89 + issue_context_kindfunction + issue_contextrdar_6659160 + issue_hash_function_offset27 + location + + line718 + col13 + file0 + + ExecutedLines + + 0 + + 690 + 691 + 696 + 702 + 703 + 706 + 707 + 714 + 716 + 717 + 718 + + + + + path + + + kindcontrol + edges + + + start + + + line696 + col3 + file0 + + + line696 + col10 + file0 + + + end + + + line702 + col3 + file0 + + + line702 + col10 + file0 + + + + + + + kindevent + location + + line702 + col20 + file0 + + ranges + + + + line702 + col20 + file0 + + + line702 + col57 + file0 + + + + depth0 + extended_message + Method returns an Objective-C object with a +0 retain count + message + Method returns an Objective-C object with a +0 retain count + + + kindcontrol + edges + + + start + + + line702 + col3 + file0 + + + line702 + col10 + file0 + + + end + + + line703 + col3 + file0 + + + line703 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line703 + col3 + file0 + + + line703 + col4 + file0 + + + end + + + line703 + col6 + file0 + + + line703 + col6 + file0 + + + + + + + kindevent + location + + line703 + col6 + file0 + + ranges + + + + line703 + col6 + file0 + + + line703 + col10 + file0 + + + + depth0 + extended_message + Assuming 'name' is non-nil + message + Assuming 'name' is non-nil + + + kindcontrol + edges + + + start + + + line703 + col6 + file0 + + + line703 + col6 + file0 + + + end + + + line706 + col3 + file0 + + + line706 + col7 + file0 + + + + + + + kindcontrol + edges + + + start + + + line706 + col3 + file0 + + + line706 + col7 + file0 + + + end + + + line714 + col3 + file0 + + + line714 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line714 + col3 + file0 + + + line714 + col4 + file0 + + + end + + + line714 + col6 + file0 + + + line714 + col9 + file0 + + + + + + + kindevent + location + + line714 + col6 + file0 + + ranges + + + + line714 + col6 + file0 + + + line714 + col9 + file0 + + + + depth0 + extended_message + Assuming 'kind' is non-nil + message + Assuming 'kind' is non-nil + + + kindcontrol + edges + + + start + + + line714 + col6 + file0 + + + line714 + col9 + file0 + + + end + + + line715 + col5 + file0 + + + line715 + col9 + file0 + + + + + + + kindcontrol + edges + + + start + + + line715 + col5 + file0 + + + line715 + col9 + file0 + + + end + + + line716 + col3 + file0 + + + line716 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line716 + col3 + file0 + + + line716 + col4 + file0 + + + end + + + line717 + col5 + file0 + + + line717 + col9 + file0 + + + + + + + kindcontrol + edges + + + start + + + line717 + col5 + file0 + + + line717 + col9 + file0 + + + end + + + line718 + col3 + file0 + + + line718 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line718 + col3 + file0 + + + line718 + col4 + file0 + + + end + + + line718 + col6 + file0 + + + line718 + col6 + file0 + + + + + + + kindevent + location + + line718 + col6 + file0 + + ranges + + + + line718 + col6 + file0 + + + line718 + col21 + file0 + + + + depth0 + extended_message + Assuming the condition is false + message + Assuming the condition is false + + + kindcontrol + edges + + + start + + + line718 + col6 + file0 + + + line718 + col6 + file0 + + + end + + + line720 + col3 + file0 + + + line720 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line720 + col3 + file0 + + + line720 + col4 + file0 + + + end + + + line720 + col6 + file0 + + + line720 + col6 + file0 + + + + + + + kindevent + location + + line720 + col6 + file0 + + ranges + + + + line720 + col6 + file0 + + + line720 + col21 + file0 + + + + depth0 + extended_message + Assuming the condition is false + message + Assuming the condition is false + + + kindcontrol + edges + + + start + + + line720 + col6 + file0 + + + line720 + col6 + file0 + + + end + + + line723 + col3 + file0 + + + line723 + col3 + file0 + + + + + + + kindcontrol + edges + + + start + + + line723 + col3 + file0 + + + line723 + col3 + file0 + + + end + + + line724 + col3 + file0 + + + line724 + col3 + file0 + + + + + + + kindevent + location + + line724 + col3 + file0 + + ranges + + + + line724 + col4 + file0 + + + line724 + col7 + file0 + + + + depth0 + extended_message + Incorrect decrement of the reference count of an object that is not owned at this point by the caller + message + Incorrect decrement of the reference count of an object that is not owned at this point by the caller + + + descriptionIncorrect decrement of the reference count of an object that is not owned at this point by the caller + categoryMemory (Core Foundation/Objective-C/OSObject) + typeBad release + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_contextd04966e9b8e981d8f69bf03823253033 + issue_context_kindfunction + issue_contextrdar_6659160 + issue_hash_function_offset33 + location + + line724 + col3 + file0 + + ExecutedLines + + 0 + + 690 + 691 + 696 + 702 + 703 + 706 + 707 + 714 + 715 + 716 + 717 + 718 + 720 + 723 + 724 + + + + + path + + + kindevent + location + + line746 + col12 + file0 + + ranges + + + + line746 + col12 + file0 + + + line746 + col34 + file0 + + + + depth0 + extended_message + Method returns an instance of NSString with a +1 retain count + message + Method returns an instance of NSString with a +1 retain count + + + kindcontrol + edges + + + start + + + line746 + col3 + file0 + + + line746 + col4 + file0 + + + end + + + line747 + col3 + file0 + + + line747 + col3 + file0 + + + + + + + kindevent + location + + line747 + col3 + file0 + + ranges + + + + line747 + col3 + file0 + + + line747 + col15 + file0 + + + + + line747 + col4 + file0 + + + line747 + col6 + file0 + + + + depth0 + extended_message + Object released by directly sending the '-dealloc' message + message + Object released by directly sending the '-dealloc' message + + + kindcontrol + edges + + + start + + + line747 + col3 + file0 + + + line747 + col3 + file0 + + + end + + + line748 + col3 + file0 + + + line748 + col3 + file0 + + + + + + + kindevent + location + + line748 + col3 + file0 + + ranges + + + + line748 + col4 + file0 + + + line748 + col6 + file0 + + + + depth0 + extended_message + Reference-counted object is used after it is released + message + Reference-counted object is used after it is released + + + descriptionReference-counted object is used after it is released + categoryMemory (Core Foundation/Objective-C/OSObject) + typeUse-after-release + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context1b35183a6aca4df5a8732c8da94e3205 + issue_context_kindfunction + issue_contextpr3820_ReleaseAfterDealloc + issue_hash_function_offset3 + location + + line748 + col3 + file0 + + ExecutedLines + + 0 + + 744 + 745 + 746 + 747 + 748 + + + + + path + + + kindcontrol + edges + + + start + + + line754 + col3 + file0 + + + line754 + col7 + file0 + + + end + + + line755 + col3 + file0 + + + line755 + col4 + file0 + + + + + + + kindevent + location + + line755 + col12 + file0 + + ranges + + + + line755 + col12 + file0 + + + line755 + col34 + file0 + + + + depth0 + extended_message + Method returns an instance of NSString with a +1 retain count + message + Method returns an instance of NSString with a +1 retain count + + + kindcontrol + edges + + + start + + + line755 + col3 + file0 + + + line755 + col4 + file0 + + + end + + + line756 + col3 + file0 + + + line756 + col3 + file0 + + + + + + + kindevent + location + + line756 + col3 + file0 + + ranges + + + + line756 + col3 + file0 + + + line756 + col15 + file0 + + + + + line756 + col4 + file0 + + + line756 + col6 + file0 + + + + depth0 + extended_message + Object released + message + Object released + + + kindcontrol + edges + + + start + + + line756 + col3 + file0 + + + line756 + col3 + file0 + + + end + + + line757 + col3 + file0 + + + line757 + col3 + file0 + + + + + + + kindevent + location + + line757 + col3 + file0 + + ranges + + + + line757 + col4 + file0 + + + line757 + col6 + file0 + + + + depth0 + extended_message + Reference-counted object is used after it is released + message + Reference-counted object is used after it is released + + + descriptionReference-counted object is used after it is released + categoryMemory (Core Foundation/Objective-C/OSObject) + typeUse-after-release + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context54f2bd1534fa675b58c4f8eef3120373 + issue_context_kindfunction + issue_contextpr3820_DeallocAfterRelease + issue_hash_function_offset4 + location + + line757 + col3 + file0 + + ExecutedLines + + 0 + + 752 + 753 + 754 + 755 + 756 + 757 + + + + + path + + + kindcontrol + edges + + + start + + + line809 + col2 + file0 + + + line809 + col20 + file0 + + + end + + + line809 + col31 + file0 + + + line809 + col31 + file0 + + + + + + + kindevent + location + + line809 + col31 + file0 + + ranges + + + + line809 + col31 + file0 + + + line809 + col76 + file0 + + + + depth0 + extended_message + Method returns an Objective-C object with a +0 retain count + message + Method returns an Objective-C object with a +0 retain count + + + kindevent + location + + line809 + col30 + file0 + + ranges + + + + line809 + col30 + file0 + + + line809 + col84 + file0 + + + + + line809 + col31 + file0 + + + line809 + col76 + file0 + + + + depth0 + extended_message + Reference count incremented. The object now has a +1 retain count + message + Reference count incremented. The object now has a +1 retain count + + + kindcontrol + edges + + + start + + + line809 + col30 + file0 + + + line809 + col30 + file0 + + + end + + + line809 + col2 + file0 + + + line809 + col20 + file0 + + + + + + + kindcontrol + edges + + + start + + + line809 + col2 + file0 + + + line809 + col20 + file0 + + + end + + + line813 + col2 + file0 + + + line813 + col6 + file0 + + + + + + + kindcontrol + edges + + + start + + + line813 + col2 + file0 + + + line813 + col6 + file0 + + + end + + + line814 + col1 + file0 + + + line814 + col1 + file0 + + + + + + + kindevent + location + + line814 + col1 + file0 + + depth0 + extended_message + Object leaked: object allocated and stored into 'dict' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'dict' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'dict' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context055e6f3413539276fedeac241fccd9b8 + issue_context_kindObjective-C method + issue_contextapplicationDidFinishLaunching: + issue_hash_function_offset1 + location + + line814 + col1 + file0 + + ExecutedLines + + 0 + + 808 + 809 + 811 + 813 + 814 + + + + + path + + + kindcontrol + edges + + + start + + + line821 + col2 + file0 + + + line821 + col20 + file0 + + + end + + + line821 + col31 + file0 + + + line821 + col31 + file0 + + + + + + + kindevent + location + + line821 + col31 + file0 + + ranges + + + + line821 + col31 + file0 + + + line821 + col76 + file0 + + + + depth0 + extended_message + Method returns an Objective-C object with a +0 retain count + message + Method returns an Objective-C object with a +0 retain count + + + kindevent + location + + line821 + col30 + file0 + + ranges + + + + line821 + col30 + file0 + + + line821 + col84 + file0 + + + + + line821 + col31 + file0 + + + line821 + col76 + file0 + + + + depth0 + extended_message + Reference count incremented. The object now has a +1 retain count + message + Reference count incremented. The object now has a +1 retain count + + + kindcontrol + edges + + + start + + + line821 + col30 + file0 + + + line821 + col30 + file0 + + + end + + + line821 + col2 + file0 + + + line821 + col20 + file0 + + + + + + + kindcontrol + edges + + + start + + + line821 + col2 + file0 + + + line821 + col20 + file0 + + + end + + + line822 + col2 + file0 + + + line822 + col3 + file0 + + + + + + + kindcontrol + edges + + + start + + + line822 + col2 + file0 + + + line822 + col3 + file0 + + + end + + + line822 + col6 + file0 + + + line822 + col11 + file0 + + + + + + + kindevent + location + + line822 + col6 + file0 + + ranges + + + + line822 + col6 + file0 + + + line822 + col11 + file0 + + + + depth0 + extended_message + Assuming the condition is false + message + Assuming the condition is false + + + kindcontrol + edges + + + start + + + line822 + col6 + file0 + + + line822 + col11 + file0 + + + end + + + line824 + col1 + file0 + + + line824 + col1 + file0 + + + + + + + kindevent + location + + line824 + col1 + file0 + + depth0 + extended_message + Object leaked: object allocated and stored into 'dict' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'dict' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'dict' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context444f6019b048a95dd71c6be49ecb73ff + issue_context_kindObjective-C method + issue_contextradar10102244 + issue_hash_function_offset1 + location + + line824 + col1 + file0 + + ExecutedLines + + 0 + + 820 + 821 + 822 + 824 + + + + + path + + + kindcontrol + edges + + + start + + + line832 + col3 + file0 + + + line832 + col19 + file0 + + + end + + + line833 + col3 + file0 + + + line833 + col9 + file0 + + + + + + + kindevent + location + + line833 + col20 + file0 + + ranges + + + + line833 + col20 + file0 + + + line833 + col34 + file0 + + + + depth0 + extended_message + Method returns an Objective-C object with a +0 retain count + message + Method returns an Objective-C object with a +0 retain count + + + kindcontrol + edges + + + start + + + line833 + col3 + file0 + + + line833 + col9 + file0 + + + end + + + line834 + col3 + file0 + + + line834 + col3 + file0 + + + + + + + kindevent + location + + line834 + col3 + file0 + + ranges + + + + line834 + col4 + file0 + + + line834 + col8 + file0 + + + + depth0 + extended_message + Incorrect decrement of the reference count of an object that is not owned at this point by the caller + message + Incorrect decrement of the reference count of an object that is not owned at this point by the caller + + + descriptionIncorrect decrement of the reference count of an object that is not owned at this point by the caller + categoryMemory (Core Foundation/Objective-C/OSObject) + typeBad release + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context641de26edd3d85ca241de577afbcda86 + issue_context_kindfunction + issue_contextrdar_6257780_Case1 + issue_hash_function_offset3 + location + + line834 + col3 + file0 + + ExecutedLines + + 0 + + 831 + 832 + 833 + 834 + + + + + path + + + kindcontrol + edges + + + start + + + line909 + col3 + file0 + + + line909 + col3 + file0 + + + end + + + line910 + col3 + file0 + + + line910 + col3 + file0 + + + + + + + kindevent + location + + line910 + col3 + file0 + + ranges + + + + line910 + col3 + file0 + + + line910 + col36 + file0 + + + + depth0 + extended_message + Method returns an instance of RDar6320065Subclass with a +1 retain count + message + Method returns an instance of RDar6320065Subclass with a +1 retain count + + + kindcontrol + edges + + + start + + + line910 + col3 + file0 + + + line910 + col3 + file0 + + + end + + + line911 + col3 + file0 + + + line911 + col8 + file0 + + + + + + + kindevent + location + + line911 + col3 + file0 + + ranges + + + + line911 + col3 + file0 + + + line911 + col13 + file0 + + + + depth0 + extended_message + Object leaked: allocated object of type 'RDar6320065Subclass *' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: allocated object of type 'RDar6320065Subclass *' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object of type 'RDar6320065Subclass *' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context8e8ae80fd006f27a952f77494bd1c05f + issue_context_kindObjective-C method + issue_context_initReturningNewClassBad + issue_hash_function_offset2 + location + + line911 + col3 + file0 + + ExecutedLines + + 0 + + 908 + 909 + 910 + 911 + + + + + path + + + kindcontrol + edges + + + start + + + line914 + col3 + file0 + + + line914 + col3 + file0 + + + end + + + line915 + col3 + file0 + + + line915 + col6 + file0 + + + + + + + kindevent + location + + line915 + col10 + file0 + + ranges + + + + line915 + col10 + file0 + + + line915 + col43 + file0 + + + + depth0 + extended_message + Method returns an instance of RDar6320065Subclass with a +1 retain count + message + Method returns an instance of RDar6320065Subclass with a +1 retain count + + + kindcontrol + edges + + + start + + + line915 + col3 + file0 + + + line915 + col6 + file0 + + + end + + + line916 + col3 + file0 + + + line916 + col8 + file0 + + + + + + + kindevent + location + + line916 + col10 + file0 + + ranges + + + + line916 + col10 + file0 + + + line916 + col27 + file0 + + + + + line916 + col11 + file0 + + + line916 + col14 + file0 + + + + depth0 + extended_message + Object autoreleased + message + Object autoreleased + + + kindevent + location + + line916 + col3 + file0 + + ranges + + + + line916 + col3 + file0 + + + line916 + col27 + file0 + + + + depth0 + extended_message + Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected + message + Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected + + + descriptionObject with a +0 retain count returned to caller where a +1 (owning) retain count is expected + categoryMemory (Core Foundation/Objective-C/OSObject) + typeMethod should return an owned object + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context625e26ef3ae9de238f30175e4e9f4937 + issue_context_kindObjective-C method + issue_contextinitReturningNewClassBad2 + issue_hash_function_offset3 + location + + line916 + col3 + file0 + + ExecutedLines + + 0 + + 913 + 914 + 915 + 916 + + + + + path + + + kindevent + location + + line954 + col37 + file0 + + ranges + + + + line954 + col37 + file0 + + + line954 + col59 + file0 + + + + depth0 + extended_message + Method returns an instance of NSString with a +1 retain count + message + Method returns an instance of NSString with a +1 retain count + + + kindevent + location + + line954 + col30 + file0 + + ranges + + + + line954 + col30 + file0 + + + line954 + col59 + file0 + + + + depth0 + extended_message + Object leaked: allocated object of type 'NSString *' is returned from a method whose name ('NoCopyString') does not start with 'copy', 'mutableCopy', 'alloc' or 'new'. This violates the naming convention rules given in the Memory Management Guide for Cocoa + message + Object leaked: allocated object of type 'NSString *' is returned from a method whose name ('NoCopyString') does not start with 'copy', 'mutableCopy', 'alloc' or 'new'. This violates the naming convention rules given in the Memory Management Guide for Cocoa + + + descriptionPotential leak of an object of type 'NSString *' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak of returned object + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context666dce676597e2cfa3199521864f7b96 + issue_context_kindObjective-C method + issue_contextNoCopyString + issue_hash_function_offset0 + location + + line954 + col30 + file0 + + ExecutedLines + + 0 + + 954 + + + + + path + + + kindevent + location + + line955 + col37 + file0 + + ranges + + + + line955 + col37 + file0 + + + line955 + col59 + file0 + + + + depth0 + extended_message + Method returns an instance of NSString with a +1 retain count + message + Method returns an instance of NSString with a +1 retain count + + + kindevent + location + + line955 + col30 + file0 + + ranges + + + + line955 + col30 + file0 + + + line955 + col59 + file0 + + + + depth0 + extended_message + Object leaked: allocated object of type 'NSString *' is returned from a method whose name ('noCopyString') does not start with 'copy', 'mutableCopy', 'alloc' or 'new'. This violates the naming convention rules given in the Memory Management Guide for Cocoa + message + Object leaked: allocated object of type 'NSString *' is returned from a method whose name ('noCopyString') does not start with 'copy', 'mutableCopy', 'alloc' or 'new'. This violates the naming convention rules given in the Memory Management Guide for Cocoa + + + descriptionPotential leak of an object of type 'NSString *' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak of returned object + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context31104cdb408dbc3faf693a5c31973486 + issue_context_kindObjective-C method + issue_contextnoCopyString + issue_hash_function_offset0 + location + + line955 + col30 + file0 + + ExecutedLines + + 0 + + 955 + + + + + path + + + kindevent + location + + line959 + col3 + file0 + + ranges + + + + line959 + col3 + file0 + + + line959 + col18 + file0 + + + + depth0 + extended_message + Calling 'NoCopyString' + message + Calling 'NoCopyString' + + + kindevent + location + + line954 + col1 + file0 + + depth1 + extended_message + Entered call from 'test_RDar6859457' + message + Entered call from 'test_RDar6859457' + + + kindcontrol + edges + + + start + + + line954 + col1 + file0 + + + line954 + col1 + file0 + + + end + + + line954 + col30 + file0 + + + line954 + col35 + file0 + + + + + + + kindevent + location + + line954 + col37 + file0 + + ranges + + + + line954 + col37 + file0 + + + line954 + col59 + file0 + + + + depth1 + extended_message + Method returns an instance of NSString with a +1 retain count + message + Method returns an instance of NSString with a +1 retain count + + + kindevent + location + + line959 + col3 + file0 + + ranges + + + + line959 + col3 + file0 + + + line959 + col18 + file0 + + + + depth0 + extended_message + Returning from 'NoCopyString' + message + Returning from 'NoCopyString' + + + kindcontrol + edges + + + start + + + line959 + col3 + file0 + + + line959 + col3 + file0 + + + end + + + line960 + col3 + file0 + + + line960 + col3 + file0 + + + + + + + kindevent + location + + line960 + col3 + file0 + + ranges + + + + line960 + col3 + file0 + + + line960 + col18 + file0 + + + + depth0 + extended_message + Object leaked: allocated object of type 'NSString *' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: allocated object of type 'NSString *' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object of type 'NSString *' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context909638940b4d7020f51062089653b231 + issue_context_kindfunction + issue_contexttest_RDar6859457 + issue_hash_function_offset1 + location + + line960 + col3 + file0 + + ExecutedLines + + 0 + + 954 + 958 + 959 + 960 + + + + + path + + + kindcontrol + edges + + + start + + + line959 + col3 + file0 + + + line959 + col3 + file0 + + + end + + + line960 + col3 + file0 + + + line960 + col3 + file0 + + + + + + + kindevent + location + + line960 + col3 + file0 + + ranges + + + + line960 + col3 + file0 + + + line960 + col18 + file0 + + + + depth0 + extended_message + Calling 'noCopyString' + message + Calling 'noCopyString' + + + kindevent + location + + line955 + col1 + file0 + + depth1 + extended_message + Entered call from 'test_RDar6859457' + message + Entered call from 'test_RDar6859457' + + + kindcontrol + edges + + + start + + + line955 + col1 + file0 + + + line955 + col1 + file0 + + + end + + + line955 + col30 + file0 + + + line955 + col35 + file0 + + + + + + + kindevent + location + + line955 + col37 + file0 + + ranges + + + + line955 + col37 + file0 + + + line955 + col59 + file0 + + + + depth1 + extended_message + Method returns an instance of NSString with a +1 retain count + message + Method returns an instance of NSString with a +1 retain count + + + kindevent + location + + line960 + col3 + file0 + + ranges + + + + line960 + col3 + file0 + + + line960 + col18 + file0 + + + + depth0 + extended_message + Returning from 'noCopyString' + message + Returning from 'noCopyString' + + + kindcontrol + edges + + + start + + + line960 + col3 + file0 + + + line960 + col3 + file0 + + + end + + + line961 + col3 + file0 + + + line961 + col3 + file0 + + + + + + + kindevent + location + + line961 + col3 + file0 + + ranges + + + + line961 + col3 + file0 + + + line961 + col54 + file0 + + + + depth0 + extended_message + Object leaked: allocated object of type 'NSString *' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: allocated object of type 'NSString *' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object of type 'NSString *' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context2a37743e32cfa0a86958fed215c30e87 + issue_context_kindfunction + issue_contexttest_RDar6859457 + issue_hash_function_offset2 + location + + line961 + col3 + file0 + + ExecutedLines + + 0 + + 954 + 955 + 958 + 959 + 960 + 961 + + + + + path + + + kindevent + location + + line994 + col10 + file0 + + ranges + + + + line994 + col10 + file0 + + + line994 + col32 + file0 + + + + depth0 + extended_message + Method returns an instance of NSString with a +1 retain count + message + Method returns an instance of NSString with a +1 retain count + + + kindevent + location + + line994 + col3 + file0 + + ranges + + + + line994 + col3 + file0 + + + line994 + col32 + file0 + + + + depth0 + extended_message + Object leaked: allocated object of type 'NSString *' is returned from a method whose name (':') does not start with 'copy', 'mutableCopy', 'alloc' or 'new'. This violates the naming convention rules given in the Memory Management Guide for Cocoa + message + Object leaked: allocated object of type 'NSString *' is returned from a method whose name (':') does not start with 'copy', 'mutableCopy', 'alloc' or 'new'. This violates the naming convention rules given in the Memory Management Guide for Cocoa + + + descriptionPotential leak of an object of type 'NSString *' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak of returned object + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context20b25f0ba6268e055d8491c67c6a26bd + issue_context_kindObjective-C method + issue_context: + issue_hash_function_offset1 + location + + line994 + col3 + file0 + + ExecutedLines + + 0 + + 993 + 994 + + + + + path + + + kindevent + location + + line1024 + col3 + file0 + + ranges + + + + line1024 + col3 + file0 + + + line1024 + col38 + file0 + + + + depth0 + extended_message + Method returns an Objective-C object with a +1 retain count + message + Method returns an Objective-C object with a +1 retain count + + + kindcontrol + edges + + + start + + + line1024 + col3 + file0 + + + line1024 + col3 + file0 + + + end + + + line1025 + col3 + file0 + + + line1025 + col3 + file0 + + + + + + + kindevent + location + + line1025 + col3 + file0 + + ranges + + + + line1025 + col3 + file0 + + + line1025 + col42 + file0 + + + + depth0 + extended_message + Object leaked: allocated object of type 'id' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: allocated object of type 'id' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object of type 'id' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context706b9d732ece93a88487dbbf0b82fd23 + issue_context_kindfunction + issue_contextrdar6902710 + issue_hash_function_offset1 + location + + line1025 + col3 + file0 + + ExecutedLines + + 0 + + 1021 + 1022 + 1023 + 1024 + 1025 + + + + + path + + + kindcontrol + edges + + + start + + + line1024 + col3 + file0 + + + line1024 + col3 + file0 + + + end + + + line1025 + col3 + file0 + + + line1025 + col3 + file0 + + + + + + + kindevent + location + + line1025 + col3 + file0 + + ranges + + + + line1025 + col3 + file0 + + + line1025 + col42 + file0 + + + + depth0 + extended_message + Method returns an Objective-C object with a +1 retain count + message + Method returns an Objective-C object with a +1 retain count + + + kindcontrol + edges + + + start + + + line1025 + col3 + file0 + + + line1025 + col3 + file0 + + + end + + + line1026 + col3 + file0 + + + line1026 + col3 + file0 + + + + + + + kindcontrol + edges + + + start + + + line1026 + col3 + file0 + + + line1026 + col3 + file0 + + + end + + + line1026 + col39 + file0 + + + line1026 + col42 + file0 + + + + + + + kindevent + location + + line1026 + col39 + file0 + + ranges + + + + line1026 + col39 + file0 + + + line1026 + col42 + file0 + + + + depth0 + extended_message + Object leaked: allocated object of type 'id' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: allocated object of type 'id' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object of type 'id' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context631eebb0c921191c24734f98fe93f6bf + issue_context_kindfunction + issue_contextrdar6902710 + issue_hash_function_offset2 + location + + line1026 + col39 + file0 + + ExecutedLines + + 0 + + 1021 + 1022 + 1023 + 1024 + 1025 + 1026 + + + + + path + + + kindcontrol + edges + + + start + + + line1024 + col3 + file0 + + + line1024 + col3 + file0 + + + end + + + line1026 + col3 + file0 + + + line1026 + col3 + file0 + + + + + + + kindevent + location + + line1026 + col3 + file0 + + ranges + + + + line1026 + col3 + file0 + + + line1026 + col43 + file0 + + + + depth0 + extended_message + Method returns a Core Foundation object of type 'CGImageRef' with a +1 retain count + message + Method returns a Core Foundation object of type 'CGImageRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line1026 + col3 + file0 + + + line1026 + col3 + file0 + + + end + + + line1027 + col3 + file0 + + + line1027 + col3 + file0 + + + + + + + kindcontrol + edges + + + start + + + line1027 + col3 + file0 + + + line1027 + col3 + file0 + + + end + + + line1027 + col39 + file0 + + + line1027 + col42 + file0 + + + + + + + kindevent + location + + line1027 + col39 + file0 + + ranges + + + + line1027 + col39 + file0 + + + line1027 + col42 + file0 + + + + depth0 + extended_message + Object leaked: allocated object of type 'CGImageRef' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: allocated object of type 'CGImageRef' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object of type 'CGImageRef' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_contextee36a48521a32c183a086066d3c5ae1f + issue_context_kindfunction + issue_contextrdar6902710 + issue_hash_function_offset3 + location + + line1027 + col39 + file0 + + ExecutedLines + + 0 + + 1021 + 1022 + 1023 + 1024 + 1025 + 1026 + 1027 + + + + + path + + + kindcontrol + edges + + + start + + + line1024 + col3 + file0 + + + line1024 + col3 + file0 + + + end + + + line1027 + col3 + file0 + + + line1027 + col3 + file0 + + + + + + + kindevent + location + + line1027 + col3 + file0 + + ranges + + + + line1027 + col3 + file0 + + + line1027 + col69 + file0 + + + + depth0 + extended_message + Method returns a Core Foundation object of type 'CGImageRef' with a +1 retain count + message + Method returns a Core Foundation object of type 'CGImageRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line1027 + col3 + file0 + + + line1027 + col3 + file0 + + + end + + + line1028 + col1 + file0 + + + line1028 + col1 + file0 + + + + + + + kindevent + location + + line1028 + col1 + file0 + + depth0 + extended_message + Object leaked: allocated object of type 'CGImageRef' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: allocated object of type 'CGImageRef' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object of type 'CGImageRef' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context70a2dd4ee6b6f7caad87a46dc6dd3580 + issue_context_kindfunction + issue_contextrdar6902710 + issue_hash_function_offset4 + location + + line1028 + col1 + file0 + + ExecutedLines + + 0 + + 1021 + 1022 + 1023 + 1024 + 1025 + 1026 + 1027 + 1028 + + + + + path + + + kindevent + location + + line1036 + col3 + file0 + + ranges + + + + line1036 + col3 + file0 + + + line1036 + col45 + file0 + + + + depth0 + extended_message + Method returns a Core Foundation object of type 'CGLayerRef' with a +1 retain count + message + Method returns a Core Foundation object of type 'CGLayerRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line1036 + col3 + file0 + + + line1036 + col3 + file0 + + + end + + + line1037 + col1 + file0 + + + line1037 + col1 + file0 + + + + + + + kindevent + location + + line1037 + col1 + file0 + + depth0 + extended_message + Object leaked: allocated object of type 'CGLayerRef' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: allocated object of type 'CGLayerRef' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object of type 'CGLayerRef' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_contexta82448687d1cbf5cb517914dbe6de4fe + issue_context_kindfunction + issue_contextrdar6945561 + issue_hash_function_offset1 + location + + line1037 + col1 + file0 + + ExecutedLines + + 0 + + 1035 + 1036 + 1037 + + + + + path + + + kindevent + location + + line1045 + col3 + file0 + + ranges + + + + line1045 + col3 + file0 + + + line1045 + col49 + file0 + + + + depth0 + extended_message + Call to function 'IOBSDNameMatching' returns a Core Foundation object of type 'CFMutableDictionaryRef' with a +1 retain count + message + Call to function 'IOBSDNameMatching' returns a Core Foundation object of type 'CFMutableDictionaryRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line1045 + col3 + file0 + + + line1045 + col19 + file0 + + + end + + + line1046 + col1 + file0 + + + line1046 + col1 + file0 + + + + + + + kindevent + location + + line1046 + col1 + file0 + + depth0 + extended_message + Object leaked: allocated object of type 'CFMutableDictionaryRef' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: allocated object of type 'CFMutableDictionaryRef' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object of type 'CFMutableDictionaryRef' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context540e0145994c1e14ea750fe91a497855 + issue_context_kindfunction + issue_contextIOBSDNameMatching_wrapper + issue_hash_function_offset1 + location + + line1046 + col1 + file0 + + ExecutedLines + + 0 + + 1044 + 1045 + 1046 + + + + + path + + + kindevent + location + + line1049 + col3 + file0 + + ranges + + + + line1049 + col3 + file0 + + + line1049 + col25 + file0 + + + + depth0 + extended_message + Call to function 'IOServiceMatching' returns a Core Foundation object of type 'CFMutableDictionaryRef' with a +1 retain count + message + Call to function 'IOServiceMatching' returns a Core Foundation object of type 'CFMutableDictionaryRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line1049 + col3 + file0 + + + line1049 + col19 + file0 + + + end + + + line1050 + col1 + file0 + + + line1050 + col1 + file0 + + + + + + + kindevent + location + + line1050 + col1 + file0 + + depth0 + extended_message + Object leaked: allocated object of type 'CFMutableDictionaryRef' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: allocated object of type 'CFMutableDictionaryRef' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object of type 'CFMutableDictionaryRef' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context99d7012d797e181ef8e9a289ee9099eb + issue_context_kindfunction + issue_contextIOServiceMatching_wrapper + issue_hash_function_offset1 + location + + line1050 + col1 + file0 + + ExecutedLines + + 0 + + 1048 + 1049 + 1050 + + + + + path + + + kindevent + location + + line1053 + col3 + file0 + + ranges + + + + line1053 + col3 + file0 + + + line1053 + col29 + file0 + + + + depth0 + extended_message + Call to function 'IOServiceNameMatching' returns a Core Foundation object of type 'CFMutableDictionaryRef' with a +1 retain count + message + Call to function 'IOServiceNameMatching' returns a Core Foundation object of type 'CFMutableDictionaryRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line1053 + col3 + file0 + + + line1053 + col23 + file0 + + + end + + + line1054 + col1 + file0 + + + line1054 + col1 + file0 + + + + + + + kindevent + location + + line1054 + col1 + file0 + + depth0 + extended_message + Object leaked: allocated object of type 'CFMutableDictionaryRef' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: allocated object of type 'CFMutableDictionaryRef' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object of type 'CFMutableDictionaryRef' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context5d956e58f05bcc1b67ff65e02cbba302 + issue_context_kindfunction + issue_contextIOServiceNameMatching_wrapper + issue_hash_function_offset1 + location + + line1054 + col1 + file0 + + ExecutedLines + + 0 + + 1052 + 1053 + 1054 + + + + + path + + + kindevent + location + + line1061 + col30 + file0 + + ranges + + + + line1061 + col30 + file0 + + + line1061 + col41 + file0 + + + + depth0 + extended_message + Call to function 'CreateDict' returns a Core Foundation object of type 'CFDictionaryRef' with a +1 retain count + message + Call to function 'CreateDict' returns a Core Foundation object of type 'CFDictionaryRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line1061 + col3 + file0 + + + line1061 + col17 + file0 + + + end + + + line1062 + col3 + file0 + + + line1062 + col11 + file0 + + + + + + + kindevent + location + + line1062 + col3 + file0 + + ranges + + + + line1062 + col3 + file0 + + + line1062 + col21 + file0 + + + + + line1062 + col13 + file0 + + + line1062 + col20 + file0 + + + + depth0 + extended_message + Object released + message + Object released + + + kindcontrol + edges + + + start + + + line1062 + col3 + file0 + + + line1062 + col11 + file0 + + + end + + + line1063 + col3 + file0 + + + line1063 + col26 + file0 + + + + + + + kindevent + location + + line1063 + col3 + file0 + + ranges + + + + line1063 + col58 + file0 + + + line1063 + col65 + file0 + + + + depth0 + extended_message + Reference-counted object is used after it is released + message + Reference-counted object is used after it is released + + + descriptionReference-counted object is used after it is released + categoryMemory (Core Foundation/Objective-C/OSObject) + typeUse-after-release + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context84a53bfb58a3a929535b47e28b997382 + issue_context_kindfunction + issue_contextIOServiceAddNotification_wrapper + issue_hash_function_offset4 + location + + line1063 + col3 + file0 + + ExecutedLines + + 0 + + 1058 + 1059 + 1061 + 1062 + 1063 + 1064 + + + + + path + + + kindevent + location + + line1068 + col3 + file0 + + ranges + + + + line1068 + col3 + file0 + + + line1068 + col36 + file0 + + + + depth0 + extended_message + Call to function 'IORegistryEntryIDMatching' returns a Core Foundation object of type 'CFMutableDictionaryRef' with a +1 retain count + message + Call to function 'IORegistryEntryIDMatching' returns a Core Foundation object of type 'CFMutableDictionaryRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line1068 + col3 + file0 + + + line1068 + col27 + file0 + + + end + + + line1069 + col1 + file0 + + + line1069 + col1 + file0 + + + + + + + kindevent + location + + line1069 + col1 + file0 + + depth0 + extended_message + Object leaked: allocated object of type 'CFMutableDictionaryRef' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: allocated object of type 'CFMutableDictionaryRef' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object of type 'CFMutableDictionaryRef' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context36337ff486f6a8b702e68d13393bc975 + issue_context_kindfunction + issue_contextIORegistryEntryIDMatching_wrapper + issue_hash_function_offset1 + location + + line1069 + col1 + file0 + + ExecutedLines + + 0 + + 1067 + 1068 + 1069 + + + + + path + + + kindevent + location + + line1073 + col3 + file0 + + ranges + + + + line1073 + col3 + file0 + + + line1073 + col55 + file0 + + + + depth0 + extended_message + Call to function 'IOOpenFirmwarePathMatching' returns a Core Foundation object of type 'CFMutableDictionaryRef' with a +1 retain count + message + Call to function 'IOOpenFirmwarePathMatching' returns a Core Foundation object of type 'CFMutableDictionaryRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line1073 + col3 + file0 + + + line1073 + col28 + file0 + + + end + + + line1074 + col1 + file0 + + + line1074 + col1 + file0 + + + + + + + kindevent + location + + line1074 + col1 + file0 + + depth0 + extended_message + Object leaked: allocated object of type 'CFMutableDictionaryRef' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: allocated object of type 'CFMutableDictionaryRef' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object of type 'CFMutableDictionaryRef' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_contextee83ca968ddc2ecad7ae4318ce7d1d95 + issue_context_kindfunction + issue_contextIOOpenFirmwarePathMatching_wrapper + issue_hash_function_offset1 + location + + line1074 + col1 + file0 + + ExecutedLines + + 0 + + 1071 + 1072 + 1073 + 1074 + + + + + path + + + kindevent + location + + line1077 + col30 + file0 + + ranges + + + + line1077 + col30 + file0 + + + line1077 + col41 + file0 + + + + depth0 + extended_message + Call to function 'CreateDict' returns a Core Foundation object of type 'CFDictionaryRef' with a +1 retain count + message + Call to function 'CreateDict' returns a Core Foundation object of type 'CFDictionaryRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line1077 + col3 + file0 + + + line1077 + col17 + file0 + + + end + + + line1078 + col3 + file0 + + + line1078 + col29 + file0 + + + + + + + kindevent + location + + line1078 + col3 + file0 + + ranges + + + + line1078 + col3 + file0 + + + line1078 + col51 + file0 + + + + + line1078 + col43 + file0 + + + line1078 + col50 + file0 + + + + depth0 + extended_message + Object released + message + Object released + + + kindcontrol + edges + + + start + + + line1078 + col3 + file0 + + + line1078 + col29 + file0 + + + end + + + line1079 + col3 + file0 + + + line1079 + col11 + file0 + + + + + + + kindevent + location + + line1079 + col3 + file0 + + ranges + + + + line1079 + col13 + file0 + + + line1079 + col20 + file0 + + + + depth0 + extended_message + Reference-counted object is used after it is released + message + Reference-counted object is used after it is released + + + descriptionReference-counted object is used after it is released + categoryMemory (Core Foundation/Objective-C/OSObject) + typeUse-after-release + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_contexte8c08b2b3d53f5890907888e16927805 + issue_context_kindfunction + issue_contextIOServiceGetMatchingService_wrapper + issue_hash_function_offset3 + location + + line1079 + col3 + file0 + + ExecutedLines + + 0 + + 1076 + 1077 + 1078 + 1079 + + + + + path + + + kindevent + location + + line1083 + col30 + file0 + + ranges + + + + line1083 + col30 + file0 + + + line1083 + col41 + file0 + + + + depth0 + extended_message + Call to function 'CreateDict' returns a Core Foundation object of type 'CFDictionaryRef' with a +1 retain count + message + Call to function 'CreateDict' returns a Core Foundation object of type 'CFDictionaryRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line1083 + col3 + file0 + + + line1083 + col17 + file0 + + + end + + + line1084 + col3 + file0 + + + line1084 + col30 + file0 + + + + + + + kindevent + location + + line1084 + col3 + file0 + + ranges + + + + line1084 + col3 + file0 + + + line1084 + col62 + file0 + + + + + line1084 + col44 + file0 + + + line1084 + col51 + file0 + + + + depth0 + extended_message + Object released + message + Object released + + + kindcontrol + edges + + + start + + + line1084 + col3 + file0 + + + line1084 + col30 + file0 + + + end + + + line1085 + col3 + file0 + + + line1085 + col11 + file0 + + + + + + + kindevent + location + + line1085 + col3 + file0 + + ranges + + + + line1085 + col13 + file0 + + + line1085 + col20 + file0 + + + + depth0 + extended_message + Reference-counted object is used after it is released + message + Reference-counted object is used after it is released + + + descriptionReference-counted object is used after it is released + categoryMemory (Core Foundation/Objective-C/OSObject) + typeUse-after-release + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context31664b5acc7980da73f5545fb16b0910 + issue_context_kindfunction + issue_contextIOServiceGetMatchingServices_wrapper + issue_hash_function_offset3 + location + + line1085 + col3 + file0 + + ExecutedLines + + 0 + + 1082 + 1083 + 1084 + 1085 + + + + + path + + + kindevent + location + + line1091 + col30 + file0 + + ranges + + + + line1091 + col30 + file0 + + + line1091 + col41 + file0 + + + + depth0 + extended_message + Call to function 'CreateDict' returns a Core Foundation object of type 'CFDictionaryRef' with a +1 retain count + message + Call to function 'CreateDict' returns a Core Foundation object of type 'CFDictionaryRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line1091 + col3 + file0 + + + line1091 + col17 + file0 + + + end + + + line1092 + col3 + file0 + + + line1092 + col34 + file0 + + + + + + + kindevent + location + + line1092 + col3 + file0 + + ranges + + + + line1092 + col3 + file0 + + + line1092 + col106 + file0 + + + + + line1092 + col66 + file0 + + + line1092 + col73 + file0 + + + + depth0 + extended_message + Object released + message + Object released + + + kindcontrol + edges + + + start + + + line1092 + col3 + file0 + + + line1092 + col34 + file0 + + + end + + + line1093 + col3 + file0 + + + line1093 + col11 + file0 + + + + + + + kindevent + location + + line1093 + col3 + file0 + + ranges + + + + line1093 + col13 + file0 + + + line1093 + col20 + file0 + + + + depth0 + extended_message + Reference-counted object is used after it is released + message + Reference-counted object is used after it is released + + + descriptionReference-counted object is used after it is released + categoryMemory (Core Foundation/Objective-C/OSObject) + typeUse-after-release + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context6edae46016a9671e2d5400b100d5efb5 + issue_context_kindfunction + issue_contextIOServiceAddMatchingNotification_wrapper + issue_hash_function_offset4 + location + + line1093 + col3 + file0 + + ExecutedLines + + 0 + + 1088 + 1089 + 1091 + 1092 + 1093 + + + + + path + + + kindcontrol + edges + + + start + + + line1131 + col3 + file0 + + + line1131 + col23 + file0 + + + end + + + line1134 + col3 + file0 + + + line1134 + col10 + file0 + + + + + + + kindevent + location + + line1134 + col22 + file0 + + ranges + + + + line1134 + col22 + file0 + + + line1134 + col53 + file0 + + + + depth0 + extended_message + Method returns an instance of NSNumber with a +1 retain count + message + Method returns an instance of NSNumber with a +1 retain count + + + kindcontrol + edges + + + start + + + line1134 + col3 + file0 + + + line1134 + col10 + file0 + + + end + + + line1136 + col3 + file0 + + + line1136 + col3 + file0 + + + + + + + kindevent + location + + line1136 + col3 + file0 + + ranges + + + + line1136 + col3 + file0 + + + line1136 + col18 + file0 + + + + + line1136 + col4 + file0 + + + line1136 + col9 + file0 + + + + depth0 + extended_message + Reference count decremented + message + Reference count decremented + + + kindcontrol + edges + + + start + + + line1136 + col3 + file0 + + + line1136 + col3 + file0 + + + end + + + line1137 + col3 + file0 + + + line1137 + col3 + file0 + + + + + + + kindevent + location + + line1137 + col3 + file0 + + ranges + + + + line1137 + col3 + file0 + + + line1137 + col17 + file0 + + + + + line1137 + col4 + file0 + + + line1137 + col9 + file0 + + + + depth0 + extended_message + Reference count incremented. The object now has a +1 retain count + message + Reference count incremented. The object now has a +1 retain count + + + kindcontrol + edges + + + start + + + line1137 + col3 + file0 + + + line1137 + col3 + file0 + + + end + + + line1138 + col3 + file0 + + + line1138 + col11 + file0 + + + + + + + kindevent + location + + line1138 + col3 + file0 + + ranges + + + + line1138 + col3 + file0 + + + line1138 + col23 + file0 + + + + depth0 + extended_message + Object leaked: object allocated and stored into 'number' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'number' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'number' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_contextdcec4e2bd254a3c24e84e598b5a827bf + issue_context_kindfunction + issue_contextrdar_7152619 + issue_hash_function_offset4 + location + + line1138 + col3 + file0 + + ExecutedLines + + 0 + + 63 + 67 + 68 + 69 + 70 + 71 + 1130 + 1131 + 1132 + 1133 + 1134 + 1135 + 1136 + 1137 + 1138 + + + + + path + + + kindcontrol + edges + + + start + + + line1147 + col3 + file0 + + + line1147 + col8 + file0 + + + end + + + line1158 + col3 + file0 + + + line1158 + col15 + file0 + + + + + + + kindcontrol + edges + + + start + + + line1158 + col3 + file0 + + + line1158 + col15 + file0 + + + end + + + line1159 + col41 + file0 + + + line1159 + col67 + file0 + + + + + + + kindevent + location + + line1159 + col41 + file0 + + ranges + + + + line1159 + col41 + file0 + + + line1159 + col69 + file0 + + + + depth0 + extended_message + Call to function 'CGColorSpaceCreateDeviceRGB' returns a Core Foundation object of type 'CGColorSpaceRef' with a +1 retain count + message + Call to function 'CGColorSpaceCreateDeviceRGB' returns a Core Foundation object of type 'CGColorSpaceRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line1159 + col41 + file0 + + + line1159 + col67 + file0 + + + end + + + line1158 + col3 + file0 + + + line1158 + col15 + file0 + + + + + + + kindevent + location + + line1158 + col3 + file0 + + ranges + + + + line1158 + col3 + file0 + + + line1158 + col26 + file0 + + + + depth0 + extended_message + Object leaked: allocated object of type 'CGColorSpaceRef' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: allocated object of type 'CGColorSpaceRef' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object of type 'CGColorSpaceRef' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context9317a6bf07dd10dc988f2415cc2c4ef7 + issue_context_kindfunction + issue_contextrdar_7184450 + issue_hash_function_offset13 + location + + line1158 + col3 + file0 + + ExecutedLines + + 0 + + 1145 + 1146 + 1147 + 1148 + 1149 + 1150 + 1151 + 1152 + 1153 + 1154 + 1155 + 1158 + 1159 + 1160 + + + + + path + + + kindcontrol + edges + + + start + + + line1169 + col3 + file0 + + + line1169 + col8 + file0 + + + end + + + line1180 + col3 + file0 + + + line1180 + col15 + file0 + + + + + + + kindcontrol + edges + + + start + + + line1180 + col3 + file0 + + + line1180 + col15 + file0 + + + end + + + line1181 + col40 + file0 + + + line1181 + col66 + file0 + + + + + + + kindevent + location + + line1181 + col40 + file0 + + ranges + + + + line1181 + col40 + file0 + + + line1181 + col68 + file0 + + + + depth0 + extended_message + Call to function 'CGColorSpaceCreateDeviceRGB' returns a Core Foundation object of type 'CGColorSpaceRef' with a +1 retain count + message + Call to function 'CGColorSpaceCreateDeviceRGB' returns a Core Foundation object of type 'CGColorSpaceRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line1181 + col40 + file0 + + + line1181 + col66 + file0 + + + end + + + line1180 + col3 + file0 + + + line1180 + col15 + file0 + + + + + + + kindevent + location + + line1180 + col3 + file0 + + ranges + + + + line1180 + col3 + file0 + + + line1180 + col26 + file0 + + + + depth0 + extended_message + Object leaked: allocated object of type 'CGColorSpaceRef' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: allocated object of type 'CGColorSpaceRef' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object of type 'CGColorSpaceRef' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_contextec3e6216b279aa48d8403c6aab30d996 + issue_context_kindfunction + issue_contextrdar_7184450_pos + issue_hash_function_offset13 + location + + line1180 + col3 + file0 + + ExecutedLines + + 0 + + 1167 + 1168 + 1169 + 1170 + 1171 + 1172 + 1173 + 1174 + 1175 + 1176 + 1177 + 1180 + 1181 + + + + + path + + + kindcontrol + edges + + + start + + + line1169 + col3 + file0 + + + line1169 + col8 + file0 + + + end + + + line1180 + col3 + file0 + + + line1180 + col15 + file0 + + + + + + + kindcontrol + edges + + + start + + + line1180 + col3 + file0 + + + line1180 + col15 + file0 + + + end + + + line1181 + col4 + file0 + + + line1181 + col38 + file0 + + + + + + + kindevent + location + + line1181 + col4 + file0 + + ranges + + + + line1181 + col4 + file0 + + + line1181 + col107 + file0 + + + + depth0 + extended_message + Call to function 'CGGradientCreateWithColorComponents' returns a Core Foundation object of type 'CGGradientRef' with a +1 retain count + message + Call to function 'CGGradientCreateWithColorComponents' returns a Core Foundation object of type 'CGGradientRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line1181 + col4 + file0 + + + line1181 + col38 + file0 + + + end + + + line1183 + col3 + file0 + + + line1183 + col29 + file0 + + + + + + + kindcontrol + edges + + + start + + + line1183 + col3 + file0 + + + line1183 + col29 + file0 + + + end + + + line1185 + col1 + file0 + + + line1185 + col1 + file0 + + + + + + + kindevent + location + + line1185 + col1 + file0 + + depth0 + extended_message + Object leaked: object allocated and stored into 'myGradient' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'myGradient' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'myGradient' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context4b3d6bb6b8dc5c51b7dfa8554b24eb66 + issue_context_kindfunction + issue_contextrdar_7184450_pos + issue_hash_function_offset13 + location + + line1185 + col1 + file0 + + ExecutedLines + + 0 + + 1167 + 1168 + 1169 + 1170 + 1171 + 1172 + 1173 + 1174 + 1175 + 1176 + 1177 + 1180 + 1181 + 1183 + 1184 + 1185 + + + + + path + + + kindevent + location + + line1219 + col22 + file0 + + ranges + + + + line1219 + col22 + file0 + + + line1219 + col53 + file0 + + + + depth0 + extended_message + Method returns an instance of NSNumber with a +1 retain count + message + Method returns an instance of NSNumber with a +1 retain count + + + kindcontrol + edges + + + start + + + line1219 + col3 + file0 + + + line1219 + col10 + file0 + + + end + + + line1220 + col1 + file0 + + + line1220 + col1 + file0 + + + + + + + kindevent + location + + line1220 + col1 + file0 + + depth0 + extended_message + Object leaked: object allocated and stored into 'number' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'number' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'number' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context42a83016e862ec323e24920873073a5a + issue_context_kindfunction + issue_contextrdar_7299394_positive + issue_hash_function_offset1 + location + + line1220 + col1 + file0 + + ExecutedLines + + 0 + + 1218 + 1219 + 1220 + + + + + path + + + kindcontrol + edges + + + start + + + line1454 + col5 + file0 + + + line1454 + col12 + file0 + + + end + + + line1456 + col3 + file0 + + + line1456 + col31 + file0 + + + + + + + kindevent + location + + line1456 + col3 + file0 + + ranges + + + + line1456 + col3 + file0 + + + line1457 + col60 + file0 + + + + depth0 + extended_message + Call to function 'CGBitmapContextCreateWithData' returns a Core Foundation object of type 'CGContextRef' with a +1 retain count + message + Call to function 'CGBitmapContextCreateWithData' returns a Core Foundation object of type 'CGContextRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line1456 + col3 + file0 + + + line1456 + col31 + file0 + + + end + + + line1458 + col1 + file0 + + + line1458 + col1 + file0 + + + + + + + kindevent + location + + line1458 + col1 + file0 + + depth0 + extended_message + Object leaked: allocated object of type 'CGContextRef' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: allocated object of type 'CGContextRef' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object of type 'CGContextRef' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_contexta416473fed3a9dbc6bfee885bee38216 + issue_context_kindfunction + issue_contextrdar_7358899 + issue_hash_function_offset7 + location + + line1458 + col1 + file0 + + ExecutedLines + + 0 + + 1446 + 1447 + 1448 + 1449 + 1454 + 1456 + 1457 + 1458 + + + + + path + + + kindevent + location + + line1474 + col10 + file0 + + ranges + + + + line1474 + col10 + file0 + + + line1474 + col22 + file0 + + + + depth0 + extended_message + Method returns an Objective-C object with a +1 retain count + message + Method returns an Objective-C object with a +1 retain count + + + kindcontrol + edges + + + start + + + line1474 + col3 + file0 + + + line1474 + col4 + file0 + + + end + + + line1475 + col1 + file0 + + + line1475 + col1 + file0 + + + + + + + kindevent + location + + line1475 + col1 + file0 + + depth0 + extended_message + Object leaked: object allocated and stored into 'y' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'y' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'y' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context980dd45e9cf6581dbc2be9ebfc500b7f + issue_context_kindfunction + issue_contextrdar7265711_a + issue_hash_function_offset1 + location + + line1475 + col1 + file0 + + ExecutedLines + + 0 + + 1473 + 1474 + 1475 + + + + + path + + + kindcontrol + edges + + + start + + + line1494 + col3 + file0 + + + line1494 + col10 + file0 + + + end + + + line1495 + col3 + file0 + + + line1495 + col10 + file0 + + + + + + + kindevent + location + + line1495 + col22 + file0 + + ranges + + + + line1495 + col22 + file0 + + + line1495 + col53 + file0 + + + + depth0 + extended_message + Method returns an instance of NSNumber with a +1 retain count + message + Method returns an instance of NSNumber with a +1 retain count + + + kindcontrol + edges + + + start + + + line1495 + col3 + file0 + + + line1495 + col10 + file0 + + + end + + + line1496 + col1 + file0 + + + line1496 + col1 + file0 + + + + + + + kindevent + location + + line1496 + col1 + file0 + + depth0 + extended_message + Object leaked: object allocated and stored into 'number' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'number' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'number' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_contextebf51fb2b16499cf3a5c57d251a91061 + issue_context_kindfunction + issue_contextrdar7306898 + issue_hash_function_offset4 + location + + line1496 + col1 + file0 + + ExecutedLines + + 0 + + 1491 + 1494 + 1495 + 1496 + + + + + path + + + kindevent + location + + line1505 + col3 + file0 + + ranges + + + + line1505 + col3 + file0 + + + line1505 + col23 + file0 + + + + depth0 + extended_message + The 'release' message should be sent to instances of class 'RDar7252064' and not the class directly + message + The 'release' message should be sent to instances of class 'RDar7252064' and not the class directly + + + descriptionThe 'release' message should be sent to instances of class 'RDar7252064' and not the class directly + categoryAPI Misuse (Apple) + typemessage incorrectly sent to class instead of class instance + check_nameosx.cocoa.ClassRelease + + issue_hash_content_of_line_in_contextbdc4aaf3d712232f4ae72dce230189f9 + issue_context_kindfunction + issue_contextrdar7252064 + issue_hash_function_offset1 + location + + line1505 + col3 + file0 + + ExecutedLines + + 0 + + 1504 + 1505 + + + + + path + + + kindcontrol + edges + + + start + + + line1505 + col3 + file0 + + + line1505 + col3 + file0 + + + end + + + line1506 + col3 + file0 + + + line1506 + col3 + file0 + + + + + + + kindevent + location + + line1506 + col3 + file0 + + ranges + + + + line1506 + col3 + file0 + + + line1506 + col22 + file0 + + + + depth0 + extended_message + The 'retain' message should be sent to instances of class 'RDar7252064' and not the class directly + message + The 'retain' message should be sent to instances of class 'RDar7252064' and not the class directly + + + descriptionThe 'retain' message should be sent to instances of class 'RDar7252064' and not the class directly + categoryAPI Misuse (Apple) + typemessage incorrectly sent to class instead of class instance + check_nameosx.cocoa.ClassRelease + + issue_hash_content_of_line_in_contextb767178ef573c7bd520dc62faabc32fc + issue_context_kindfunction + issue_contextrdar7252064 + issue_hash_function_offset2 + location + + line1506 + col3 + file0 + + ExecutedLines + + 0 + + 1504 + 1505 + 1506 + + + + + path + + + kindcontrol + edges + + + start + + + line1505 + col3 + file0 + + + line1505 + col3 + file0 + + + end + + + line1507 + col3 + file0 + + + line1507 + col3 + file0 + + + + + + + kindevent + location + + line1507 + col3 + file0 + + ranges + + + + line1507 + col3 + file0 + + + line1507 + col27 + file0 + + + + depth0 + extended_message + The 'autorelease' message should be sent to instances of class 'RDar7252064' and not the class directly + message + The 'autorelease' message should be sent to instances of class 'RDar7252064' and not the class directly + + + descriptionThe 'autorelease' message should be sent to instances of class 'RDar7252064' and not the class directly + categoryAPI Misuse (Apple) + typemessage incorrectly sent to class instead of class instance + check_nameosx.cocoa.ClassRelease + + issue_hash_content_of_line_in_context3dbe304966f8bffa6bdefc5f3ada7df6 + issue_context_kindfunction + issue_contextrdar7252064 + issue_hash_function_offset3 + location + + line1507 + col3 + file0 + + ExecutedLines + + 0 + + 1504 + 1505 + 1506 + 1507 + + + + + path + + + kindcontrol + edges + + + start + + + line1505 + col3 + file0 + + + line1505 + col3 + file0 + + + end + + + line1508 + col3 + file0 + + + line1508 + col3 + file0 + + + + + + + kindevent + location + + line1508 + col3 + file0 + + ranges + + + + line1508 + col3 + file0 + + + line1508 + col27 + file0 + + + + depth0 + extended_message + The 'drain' message should be sent to instances of class 'NSAutoreleasePool' and not the class directly + message + The 'drain' message should be sent to instances of class 'NSAutoreleasePool' and not the class directly + + + descriptionThe 'drain' message should be sent to instances of class 'NSAutoreleasePool' and not the class directly + categoryAPI Misuse (Apple) + typemessage incorrectly sent to class instead of class instance + check_nameosx.cocoa.ClassRelease + + issue_hash_content_of_line_in_contextc519bce30f1da4bb6e3ecc46453d6958 + issue_context_kindfunction + issue_contextrdar7252064 + issue_hash_function_offset4 + location + + line1508 + col3 + file0 + + ExecutedLines + + 0 + + 1504 + 1505 + 1506 + 1507 + 1508 + + + + + path + + + kindevent + location + + line1535 + col19 + file0 + + ranges + + + + line1535 + col19 + file0 + + + line1535 + col42 + file0 + + + + depth0 + extended_message + Method returns an instance of NSString with a +1 retain count + message + Method returns an instance of NSString with a +1 retain count + + + kindcontrol + edges + + + start + + + line1535 + col3 + file0 + + + line1535 + col10 + file0 + + + end + + + line1536 + col1 + file0 + + + line1536 + col1 + file0 + + + + + + + kindevent + location + + line1536 + col1 + file0 + + depth0 + extended_message + Object leaked: object allocated and stored into 'str' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'str' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'str' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context1174ccc2a30887ebf80fe25fc6722b1a + issue_context_kindfunction + issue_contexttest_attr_1 + issue_hash_function_offset1 + location + + line1536 + col1 + file0 + + ExecutedLines + + 0 + + 1534 + 1535 + 1536 + + + + + path + + + kindevent + location + + line1539 + col19 + file0 + + ranges + + + + line1539 + col19 + file0 + + + line1539 + col44 + file0 + + + + depth0 + extended_message + Method returns a Core Foundation object of type 'NSString *' with a +1 retain count + message + Method returns a Core Foundation object of type 'NSString *' with a +1 retain count + + + kindcontrol + edges + + + start + + + line1539 + col3 + file0 + + + line1539 + col10 + file0 + + + end + + + line1540 + col1 + file0 + + + line1540 + col1 + file0 + + + + + + + kindevent + location + + line1540 + col1 + file0 + + depth0 + extended_message + Object leaked: object allocated and stored into 'str' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'str' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'str' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_contextce9963dd1c85ac22cea4e4fef615354e + issue_context_kindfunction + issue_contexttest_attr_1b + issue_hash_function_offset1 + location + + line1540 + col1 + file0 + + ExecutedLines + + 0 + + 1538 + 1539 + 1540 + + + + + path + + + kindcontrol + edges + + + start + + + line1543 + col3 + file0 + + + line1543 + col10 + file0 + + + end + + + line1544 + col3 + file0 + + + line1544 + col10 + file0 + + + + + + + kindevent + location + + line1544 + col20 + file0 + + ranges + + + + line1544 + col20 + file0 + + + line1544 + col38 + file0 + + + + depth0 + extended_message + Method returns an instance of NSString with a +1 retain count + message + Method returns an instance of NSString with a +1 retain count + + + kindcontrol + edges + + + start + + + line1544 + col3 + file0 + + + line1544 + col10 + file0 + + + end + + + line1545 + col3 + file0 + + + line1545 + col10 + file0 + + + + + + + kindcontrol + edges + + + start + + + line1545 + col3 + file0 + + + line1545 + col10 + file0 + + + end + + + line1545 + col20 + file0 + + + line1545 + col20 + file0 + + + + + + + kindevent + location + + line1545 + col20 + file0 + + ranges + + + + line1545 + col20 + file0 + + + line1545 + col37 + file0 + + + + depth0 + extended_message + Object leaked: object allocated and stored into 'str2' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'str2' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'str2' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context0183088266857082f35eb17f1377fd69 + issue_context_kindfunction + issue_contexttest_attr1c + issue_hash_function_offset2 + location + + line1545 + col20 + file0 + + ExecutedLines + + 0 + + 1542 + 1543 + 1544 + 1545 + + + + + path + + + kindcontrol + edges + + + start + + + line1543 + col3 + file0 + + + line1543 + col10 + file0 + + + end + + + line1546 + col3 + file0 + + + line1546 + col10 + file0 + + + + + + + kindcontrol + edges + + + start + + + line1546 + col3 + file0 + + + line1546 + col10 + file0 + + + end + + + line1546 + col21 + file0 + + + line1546 + col21 + file0 + + + + + + + kindevent + location + + line1546 + col21 + file0 + + ranges + + + + line1546 + col21 + file0 + + + line1546 + col38 + file0 + + + + depth0 + extended_message + Method returns an instance of NSString with a +0 retain count + message + Method returns an instance of NSString with a +0 retain count + + + kindevent + location + + line1546 + col20 + file0 + + ranges + + + + line1546 + col20 + file0 + + + line1546 + col46 + file0 + + + + + line1546 + col21 + file0 + + + line1546 + col38 + file0 + + + + depth0 + extended_message + Reference count incremented. The object now has a +1 retain count + message + Reference count incremented. The object now has a +1 retain count + + + kindcontrol + edges + + + start + + + line1546 + col20 + file0 + + + line1546 + col20 + file0 + + + end + + + line1546 + col3 + file0 + + + line1546 + col10 + file0 + + + + + + + kindcontrol + edges + + + start + + + line1546 + col3 + file0 + + + line1546 + col10 + file0 + + + end + + + line1547 + col1 + file0 + + + line1547 + col1 + file0 + + + + + + + kindevent + location + + line1547 + col1 + file0 + + depth0 + extended_message + Object leaked: object allocated and stored into 'str4' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'str4' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'str4' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context352a17ef8eddd3aa5f7f6e74a74a4df3 + issue_context_kindfunction + issue_contexttest_attr1c + issue_hash_function_offset4 + location + + line1547 + col1 + file0 + + ExecutedLines + + 0 + + 1542 + 1543 + 1544 + 1545 + 1546 + 1547 + + + + + path + + + kindevent + location + + line1550 + col26 + file0 + + ranges + + + + line1550 + col26 + file0 + + + line1550 + col50 + file0 + + + + depth0 + extended_message + Method returns an instance of TestOwnershipAttr with a +1 retain count + message + Method returns an instance of TestOwnershipAttr with a +1 retain count + + + kindcontrol + edges + + + start + + + line1550 + col3 + file0 + + + line1550 + col19 + file0 + + + end + + + line1551 + col1 + file0 + + + line1551 + col1 + file0 + + + + + + + kindevent + location + + line1551 + col1 + file0 + + depth0 + extended_message + Object leaked: object allocated and stored into 'x' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'x' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'x' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_contextd0e564404585060990202acb33f0bb1e + issue_context_kindfunction + issue_contexttestattr2_a + issue_hash_function_offset1 + location + + line1551 + col1 + file0 + + ExecutedLines + + 0 + + 1549 + 1550 + 1551 + + + + + path + + + kindevent + location + + line1554 + col26 + file0 + + ranges + + + + line1554 + col26 + file0 + + + line1554 + col63 + file0 + + + + depth0 + extended_message + Method returns an Objective-C object with a +1 retain count + message + Method returns an Objective-C object with a +1 retain count + + + kindcontrol + edges + + + start + + + line1554 + col3 + file0 + + + line1554 + col19 + file0 + + + end + + + line1555 + col1 + file0 + + + line1555 + col1 + file0 + + + + + + + kindevent + location + + line1555 + col1 + file0 + + depth0 + extended_message + Object leaked: object allocated and stored into 'x' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'x' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'x' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context567dfcbc22471ca4ba9f2fccd9ff14fb + issue_context_kindfunction + issue_contexttestattr2_b + issue_hash_function_offset1 + location + + line1555 + col1 + file0 + + ExecutedLines + + 0 + + 1553 + 1554 + 1555 + + + + + path + + + kindevent + location + + line1558 + col26 + file0 + + ranges + + + + line1558 + col26 + file0 + + + line1558 + col63 + file0 + + + + depth0 + extended_message + Method returns an Objective-C object with a +1 retain count + message + Method returns an Objective-C object with a +1 retain count + + + kindcontrol + edges + + + start + + + line1558 + col3 + file0 + + + line1558 + col19 + file0 + + + end + + + line1559 + col3 + file0 + + + line1559 + col3 + file0 + + + + + + + kindcontrol + edges + + + start + + + line1559 + col3 + file0 + + + line1559 + col3 + file0 + + + end + + + line1560 + col1 + file0 + + + line1560 + col1 + file0 + + + + + + + kindevent + location + + line1560 + col1 + file0 + + depth0 + extended_message + Object leaked: object allocated and stored into 'x' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'x' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'x' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context83cd2670977d513443836653fee8147b + issue_context_kindfunction + issue_contexttestattr2_b_11358224_self_assign_looses_the_leak + issue_hash_function_offset1 + location + + line1560 + col1 + file0 + + ExecutedLines + + 0 + + 1557 + 1558 + 1559 + 1560 + + + + + path + + + kindevent + location + + line1590 + col10 + file0 + + ranges + + + + line1590 + col10 + file0 + + + line1590 + col25 + file0 + + + + depth0 + extended_message + Method returns an instance of NSString with a +1 retain count + message + Method returns an instance of NSString with a +1 retain count + + + kindevent + location + + line1590 + col3 + file0 + + ranges + + + + line1590 + col3 + file0 + + + line1590 + col25 + file0 + + + + depth0 + extended_message + Object leaked: allocated object of type 'NSString *' is returned from a method that is annotated as NS_RETURNS_NOT_RETAINED + message + Object leaked: allocated object of type 'NSString *' is returned from a method that is annotated as NS_RETURNS_NOT_RETAINED + + + descriptionPotential leak of an object of type 'NSString *' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak of returned object + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_contextf83246e7e738918426df1adc915f4eca + issue_context_kindObjective-C method + issue_contextnewString + issue_hash_function_offset1 + location + + line1590 + col3 + file0 + + ExecutedLines + + 0 + + 1589 + 1590 + + + + + path + + + kindcontrol + edges + + + start + + + line1623 + col3 + file0 + + + line1623 + col8 + file0 + + + end + + + line1623 + col26 + file0 + + + line1623 + col26 + file0 + + + + + + + kindevent + location + + line1623 + col26 + file0 + + ranges + + + + line1623 + col26 + file0 + + + line1623 + col53 + file0 + + + + depth0 + extended_message + Calling 'returnsCFRetainedAsCF' + message + Calling 'returnsCFRetainedAsCF' + + + kindevent + location + + line1614 + col1 + file0 + + depth1 + extended_message + Entered call from 'newCFRetainedAsCFNoAttr' + message + Entered call from 'newCFRetainedAsCFNoAttr' + + + kindcontrol + edges + + + start + + + line1614 + col1 + file0 + + + line1614 + col1 + file0 + + + end + + + line1615 + col3 + file0 + + + line1615 + col8 + file0 + + + + + + + kindcontrol + edges + + + start + + + line1615 + col3 + file0 + + + line1615 + col8 + file0 + + + end + + + line1615 + col10 + file0 + + + line1615 + col30 + file0 + + + + + + + kindevent + location + + line1615 + col10 + file0 + + ranges + + + + line1615 + col10 + file0 + + + line1615 + col32 + file0 + + + + depth1 + extended_message + Calling 'returnsRetainedCFDate' + message + Calling 'returnsRetainedCFDate' + + + kindevent + location + + line1604 + col1 + file0 + + depth2 + extended_message + Entered call from 'returnsCFRetainedAsCF' + message + Entered call from 'returnsCFRetainedAsCF' + + + kindcontrol + edges + + + start + + + line1604 + col1 + file0 + + + line1604 + col19 + file0 + + + end + + + line1606 + col3 + file0 + + + line1606 + col8 + file0 + + + + + + + kindevent + location + + line1606 + col10 + file0 + + ranges + + + + line1606 + col10 + file0 + + + line1606 + col52 + file0 + + + + depth2 + extended_message + Call to function 'CFDateCreate' returns a Core Foundation object of type 'CFDateRef' with a +1 retain count + message + Call to function 'CFDateCreate' returns a Core Foundation object of type 'CFDateRef' with a +1 retain count + + + kindevent + location + + line1615 + col10 + file0 + + ranges + + + + line1615 + col10 + file0 + + + line1615 + col32 + file0 + + + + depth1 + extended_message + Returning from 'returnsRetainedCFDate' + message + Returning from 'returnsRetainedCFDate' + + + kindcontrol + edges + + + start + + + line1615 + col10 + file0 + + + line1615 + col30 + file0 + + + end + + + line1615 + col3 + file0 + + + line1615 + col8 + file0 + + + + + + + kindevent + location + + line1623 + col26 + file0 + + ranges + + + + line1623 + col26 + file0 + + + line1623 + col53 + file0 + + + + depth0 + extended_message + Returning from 'returnsCFRetainedAsCF' + message + Returning from 'returnsCFRetainedAsCF' + + + kindcontrol + edges + + + start + + + line1623 + col26 + file0 + + + line1623 + col26 + file0 + + + end + + + line1623 + col21 + file0 + + + line1623 + col21 + file0 + + + + + + + kindevent + location + + line1623 + col21 + file0 + + ranges + + + + line1623 + col21 + file0 + + + line1623 + col66 + file0 + + + + + line1623 + col22 + file0 + + + line1623 + col53 + file0 + + + + depth0 + extended_message + Object autoreleased + message + Object autoreleased + + + kindcontrol + edges + + + start + + + line1623 + col21 + file0 + + + line1623 + col21 + file0 + + + end + + + line1623 + col3 + file0 + + + line1623 + col8 + file0 + + + + + + + kindevent + location + + line1623 + col3 + file0 + + ranges + + + + line1623 + col3 + file0 + + + line1623 + col66 + file0 + + + + depth0 + extended_message + Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected + message + Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected + + + descriptionObject with a +0 retain count returned to caller where a +1 (owning) retain count is expected + categoryMemory (Core Foundation/Objective-C/OSObject) + typeMethod should return an owned object + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context5f233261d96f1d461af36fc3e0efc8eb + issue_context_kindObjective-C method + issue_contextnewCFRetainedAsCFNoAttr + issue_hash_function_offset1 + location + + line1623 + col3 + file0 + + ExecutedLines + + 0 + + 1604 + 1605 + 1606 + 1614 + 1615 + 1622 + 1623 + + + + + path + + + kindcontrol + edges + + + start + + + line1627 + col3 + file0 + + + line1627 + col8 + file0 + + + end + + + line1627 + col20 + file0 + + + line1627 + col40 + file0 + + + + + + + kindevent + location + + line1627 + col20 + file0 + + ranges + + + + line1627 + col20 + file0 + + + line1627 + col42 + file0 + + + + depth0 + extended_message + Calling 'returnsRetainedCFDate' + message + Calling 'returnsRetainedCFDate' + + + kindevent + location + + line1604 + col1 + file0 + + depth1 + extended_message + Entered call from 'alsoReturnsRetained' + message + Entered call from 'alsoReturnsRetained' + + + kindcontrol + edges + + + start + + + line1604 + col1 + file0 + + + line1604 + col19 + file0 + + + end + + + line1606 + col3 + file0 + + + line1606 + col8 + file0 + + + + + + + kindevent + location + + line1606 + col10 + file0 + + ranges + + + + line1606 + col10 + file0 + + + line1606 + col52 + file0 + + + + depth1 + extended_message + Call to function 'CFDateCreate' returns a Core Foundation object of type 'CFDateRef' with a +1 retain count + message + Call to function 'CFDateCreate' returns a Core Foundation object of type 'CFDateRef' with a +1 retain count + + + kindevent + location + + line1627 + col20 + file0 + + ranges + + + + line1627 + col20 + file0 + + + line1627 + col42 + file0 + + + + depth0 + extended_message + Returning from 'returnsRetainedCFDate' + message + Returning from 'returnsRetainedCFDate' + + + kindcontrol + edges + + + start + + + line1627 + col20 + file0 + + + line1627 + col40 + file0 + + + end + + + line1627 + col3 + file0 + + + line1627 + col8 + file0 + + + + + + + kindevent + location + + line1627 + col3 + file0 + + ranges + + + + line1627 + col3 + file0 + + + line1627 + col42 + file0 + + + + depth0 + extended_message + Object leaked: allocated object of type 'CFDateRef' is returned from a method whose name ('alsoReturnsRetained') does not start with 'copy', 'mutableCopy', 'alloc' or 'new'. This violates the naming convention rules given in the Memory Management Guide for Cocoa + message + Object leaked: allocated object of type 'CFDateRef' is returned from a method whose name ('alsoReturnsRetained') does not start with 'copy', 'mutableCopy', 'alloc' or 'new'. This violates the naming convention rules given in the Memory Management Guide for Cocoa + + + descriptionPotential leak of an object of type 'CFDateRef' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak of returned object + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context7ee55b74b5ee01c6ffa2a3d83c8cf88b + issue_context_kindObjective-C method + issue_contextalsoReturnsRetained + issue_hash_function_offset1 + location + + line1627 + col3 + file0 + + ExecutedLines + + 0 + + 1604 + 1605 + 1606 + 1626 + 1627 + + + + + path + + + kindcontrol + edges + + + start + + + line1631 + col3 + file0 + + + line1631 + col8 + file0 + + + end + + + line1631 + col10 + file0 + + + line1631 + col30 + file0 + + + + + + + kindevent + location + + line1631 + col10 + file0 + + ranges + + + + line1631 + col10 + file0 + + + line1631 + col32 + file0 + + + + depth0 + extended_message + Calling 'returnsRetainedCFDate' + message + Calling 'returnsRetainedCFDate' + + + kindevent + location + + line1604 + col1 + file0 + + depth1 + extended_message + Entered call from 'alsoReturnsRetainedAsCF' + message + Entered call from 'alsoReturnsRetainedAsCF' + + + kindcontrol + edges + + + start + + + line1604 + col1 + file0 + + + line1604 + col19 + file0 + + + end + + + line1606 + col3 + file0 + + + line1606 + col8 + file0 + + + + + + + kindevent + location + + line1606 + col10 + file0 + + ranges + + + + line1606 + col10 + file0 + + + line1606 + col52 + file0 + + + + depth1 + extended_message + Call to function 'CFDateCreate' returns a Core Foundation object of type 'CFDateRef' with a +1 retain count + message + Call to function 'CFDateCreate' returns a Core Foundation object of type 'CFDateRef' with a +1 retain count + + + kindevent + location + + line1631 + col10 + file0 + + ranges + + + + line1631 + col10 + file0 + + + line1631 + col32 + file0 + + + + depth0 + extended_message + Returning from 'returnsRetainedCFDate' + message + Returning from 'returnsRetainedCFDate' + + + kindcontrol + edges + + + start + + + line1631 + col10 + file0 + + + line1631 + col30 + file0 + + + end + + + line1631 + col3 + file0 + + + line1631 + col8 + file0 + + + + + + + kindevent + location + + line1631 + col3 + file0 + + ranges + + + + line1631 + col3 + file0 + + + line1631 + col32 + file0 + + + + depth0 + extended_message + Object leaked: allocated object of type 'CFDateRef' is returned from a method whose name ('alsoReturnsRetainedAsCF') does not start with 'copy', 'mutableCopy', 'alloc' or 'new'. This violates the naming convention rules given in the Memory Management Guide for Cocoa + message + Object leaked: allocated object of type 'CFDateRef' is returned from a method whose name ('alsoReturnsRetainedAsCF') does not start with 'copy', 'mutableCopy', 'alloc' or 'new'. This violates the naming convention rules given in the Memory Management Guide for Cocoa + + + descriptionPotential leak of an object of type 'CFDateRef' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak of returned object + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context177b2cf7eb3d8334393ee0861f5a38ac + issue_context_kindObjective-C method + issue_contextalsoReturnsRetainedAsCF + issue_hash_function_offset1 + location + + line1631 + col3 + file0 + + ExecutedLines + + 0 + + 1604 + 1605 + 1606 + 1630 + 1631 + + + + + path + + + kindcontrol + edges + + + start + + + line1651 + col3 + file0 + + + line1651 + col8 + file0 + + + end + + + line1652 + col3 + file0 + + + line1652 + col13 + file0 + + + + + + + kindevent + location + + line1652 + col23 + file0 + + ranges + + + + line1652 + col23 + file0 + + + line1652 + col82 + file0 + + + + depth0 + extended_message + Call to function 'CFNumberCreate' returns a Core Foundation object of type 'CFNumberRef' with a +1 retain count + message + Call to function 'CFNumberCreate' returns a Core Foundation object of type 'CFNumberRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line1652 + col3 + file0 + + + line1652 + col13 + file0 + + + end + + + line1653 + col1 + file0 + + + line1653 + col1 + file0 + + + + + + + kindevent + location + + line1653 + col1 + file0 + + depth0 + extended_message + Object leaked: object allocated and stored into 'value' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'value' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'value' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context85e9d8130a1f1ec37f0ba26746abd749 + issue_context_kindfunction + issue_contexttest_panic_negative + issue_hash_function_offset2 + location + + line1653 + col1 + file0 + + ExecutedLines + + 0 + + 1650 + 1651 + 1652 + 1653 + + + + + path + + + kindcontrol + edges + + + start + + + line1662 + col3 + file0 + + + line1662 + col8 + file0 + + + end + + + line1663 + col3 + file0 + + + line1663 + col13 + file0 + + + + + + + kindevent + location + + line1663 + col23 + file0 + + ranges + + + + line1663 + col23 + file0 + + + line1663 + col82 + file0 + + + + depth0 + extended_message + Call to function 'CFNumberCreate' returns a Core Foundation object of type 'CFNumberRef' with a +1 retain count + message + Call to function 'CFNumberCreate' returns a Core Foundation object of type 'CFNumberRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line1663 + col3 + file0 + + + line1663 + col13 + file0 + + + end + + + line1664 + col3 + file0 + + + line1664 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line1664 + col3 + file0 + + + line1664 + col4 + file0 + + + end + + + line1664 + col7 + file0 + + + line1664 + col7 + file0 + + + + + + + kindevent + location + + line1664 + col7 + file0 + + ranges + + + + line1664 + col7 + file0 + + + line1664 + col7 + file0 + + + + depth0 + extended_message + Assuming 'x' is 0 + message + Assuming 'x' is 0 + + + kindcontrol + edges + + + start + + + line1664 + col7 + file0 + + + line1664 + col7 + file0 + + + end + + + line1666 + col1 + file0 + + + line1666 + col1 + file0 + + + + + + + kindevent + location + + line1666 + col1 + file0 + + depth0 + extended_message + Object leaked: object allocated and stored into 'value' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'value' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'value' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context4a0b16976e0517b38b2ccc16e2928c2e + issue_context_kindfunction + issue_contexttest_panic_neg_2 + issue_hash_function_offset2 + location + + line1666 + col1 + file0 + + ExecutedLines + + 0 + + 1661 + 1662 + 1663 + 1664 + 1666 + + + + + path + + + kindevent + location + + line1686 + col22 + file0 + + ranges + + + + line1686 + col22 + file0 + + + line1686 + col53 + file0 + + + + depth0 + extended_message + Method returns an instance of NSNumber with a +1 retain count + message + Method returns an instance of NSNumber with a +1 retain count + + + kindcontrol + edges + + + start + + + line1686 + col3 + file0 + + + line1686 + col10 + file0 + + + end + + + line1687 + col3 + file0 + + + line1687 + col3 + file0 + + + + + + + kindevent + location + + line1687 + col3 + file0 + + ranges + + + + line1687 + col3 + file0 + + + line1687 + col7 + file0 + + + + depth0 + extended_message + Object leaked: object allocated and stored into 'number' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'number' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'number' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_contextaf73d9c62952a300a7c393ebd5073f75 + issue_context_kindfunction + issue_contexttest_blocks_1_pos + issue_hash_function_offset1 + location + + line1687 + col3 + file0 + + ExecutedLines + + 0 + + 1685 + 1686 + 1687 + + + + + path + + + kindevent + location + + line1707 + col22 + file0 + + ranges + + + + line1707 + col22 + file0 + + + line1707 + col53 + file0 + + + + depth0 + extended_message + Method returns an instance of NSNumber with a +1 retain count + message + Method returns an instance of NSNumber with a +1 retain count + + + kindcontrol + edges + + + start + + + line1707 + col3 + file0 + + + line1707 + col10 + file0 + + + end + + + line1708 + col3 + file0 + + + line1708 + col3 + file0 + + + + + + + kindevent + location + + line1708 + col3 + file0 + + ranges + + + + line1708 + col3 + file0 + + + line1708 + col39 + file0 + + + + depth0 + extended_message + Calling anonymous block + message + Calling anonymous block + + + kindevent + location + + line1708 + col3 + file0 + + depth1 + extended_message + Entered call from 'test_blocks_1_indirect_retain_via_call' + message + Entered call from 'test_blocks_1_indirect_retain_via_call' + + + kindcontrol + edges + + + start + + + line1708 + col3 + file0 + + + line1708 + col3 + file0 + + + end + + + line1708 + col19 + file0 + + + line1708 + col19 + file0 + + + + + + + kindevent + location + + line1708 + col19 + file0 + + ranges + + + + line1708 + col19 + file0 + + + line1708 + col28 + file0 + + + + + line1708 + col20 + file0 + + + line1708 + col20 + file0 + + + + depth1 + extended_message + Reference count incremented. The object now has a +2 retain count + message + Reference count incremented. The object now has a +2 retain count + + + kindevent + location + + line1708 + col3 + file0 + + ranges + + + + line1708 + col3 + file0 + + + line1708 + col39 + file0 + + + + depth0 + extended_message + Returning to caller + message + Returning to caller + + + kindcontrol + edges + + + start + + + line1708 + col3 + file0 + + + line1708 + col3 + file0 + + + end + + + line1709 + col1 + file0 + + + line1709 + col1 + file0 + + + + + + + kindevent + location + + line1709 + col1 + file0 + + depth0 + extended_message + Object leaked: object allocated and stored into 'number' is not referenced later in this execution path and has a retain count of +2 + message + Object leaked: object allocated and stored into 'number' is not referenced later in this execution path and has a retain count of +2 + + + descriptionPotential leak of an object stored into 'number' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context771b2a332053388ffbdd9ba74ea84c5e + issue_context_kindfunction + issue_contexttest_blocks_1_indirect_retain_via_call + issue_hash_function_offset1 + location + + line1709 + col1 + file0 + + ExecutedLines + + 0 + + 1706 + 1707 + 1708 + 1709 + + + + + path + + + kindcontrol + edges + + + start + + + line1759 + col5 + file0 + + + line1759 + col14 + file0 + + + end + + + line1762 + col5 + file0 + + + line1762 + col9 + file0 + + + + + + + kindcontrol + edges + + + start + + + line1762 + col5 + file0 + + + line1762 + col9 + file0 + + + end + + + line1762 + col12 + file0 + + + line1762 + col24 + file0 + + + + + + + kindevent + location + + line1762 + col12 + file0 + + ranges + + + + line1762 + col12 + file0 + + + line1762 + col38 + file0 + + + + depth0 + extended_message + Assuming 'error_to_dump' is not equal to null + message + Assuming 'error_to_dump' is not equal to null + + + kindevent + location + + line1762 + col12 + file0 + + ranges + + + + line1762 + col12 + file0 + + + line1762 + col38 + file0 + + + + depth0 + extended_message + Entering loop body + message + Entering loop body + + + kindcontrol + edges + + + start + + + line1762 + col12 + file0 + + + line1762 + col24 + file0 + + + end + + + line1763 + col9 + file0 + + + line1763 + col23 + file0 + + + + + + + kindcontrol + edges + + + start + + + line1763 + col9 + file0 + + + line1763 + col23 + file0 + + + end + + + line1765 + col9 + file0 + + + line1765 + col12 + file0 + + + + + + + kindevent + location + + line1765 + col16 + file0 + + ranges + + + + line1765 + col16 + file0 + + + line1765 + col49 + file0 + + + + depth0 + extended_message + Call to function 'CFErrorCopyUserInfo' returns a Core Foundation object of type 'CFDictionaryRef' with a +1 retain count + message + Call to function 'CFErrorCopyUserInfo' returns a Core Foundation object of type 'CFDictionaryRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line1765 + col9 + file0 + + + line1765 + col12 + file0 + + + end + + + line1767 + col9 + file0 + + + line1767 + col10 + file0 + + + + + + + kindcontrol + edges + + + start + + + line1767 + col9 + file0 + + + line1767 + col10 + file0 + + + end + + + line1767 + col13 + file0 + + + line1767 + col16 + file0 + + + + + + + kindevent + location + + line1767 + col13 + file0 + + ranges + + + + line1767 + col13 + file0 + + + line1767 + col30 + file0 + + + + depth0 + extended_message + Assuming 'info' is not equal to null + message + Assuming 'info' is not equal to null + + + kindcontrol + edges + + + start + + + line1767 + col13 + file0 + + + line1767 + col16 + file0 + + + end + + + line1770 + col23 + file0 + + + line1770 + col23 + file0 + + + + + + + kindevent + location + + line1770 + col23 + file0 + + depth0 + extended_message + Object leaked: object allocated and stored into 'info' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'info' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'info' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context39f8c30f7436f678d5259c0fdd3a0dad + issue_context_kindfunction + issue_contextrdar_8724287 + issue_hash_function_offset7 + location + + line1770 + col23 + file0 + + ExecutedLines + + 0 + + 1757 + 1758 + 1759 + 1761 + 1762 + 1763 + 1765 + 1767 + 1770 + + + + + path + + + kindevent + location + + line1815 + col10 + file0 + + ranges + + + + line1815 + col10 + file0 + + + line1815 + col60 + file0 + + + + depth0 + extended_message + Call to function 'CFArrayCreateMutable' returns a Core Foundation object of type 'CFMutableArrayRef' with a +1 retain count + message + Call to function 'CFArrayCreateMutable' returns a Core Foundation object of type 'CFMutableArrayRef' with a +1 retain count + + + kindevent + location + + line1815 + col3 + file0 + + ranges + + + + line1815 + col3 + file0 + + + line1815 + col60 + file0 + + + + depth0 + extended_message + Object leaked: allocated object of type 'CFMutableArrayRef' is returned from a function whose name ('camelcase_createno') does not contain 'Copy' or 'Create'. This violates the naming convention rules given in the Memory Management Guide for Core Foundation + message + Object leaked: allocated object of type 'CFMutableArrayRef' is returned from a function whose name ('camelcase_createno') does not contain 'Copy' or 'Create'. This violates the naming convention rules given in the Memory Management Guide for Core Foundation + + + descriptionPotential leak of an object of type 'CFMutableArrayRef' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak of returned object + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context107e3efdeb8cdff4bef4c64183c4f6fa + issue_context_kindfunction + issue_contextcamelcase_createno + issue_hash_function_offset1 + location + + line1815 + col3 + file0 + + ExecutedLines + + 0 + + 1814 + 1815 + + + + + path + + + kindevent + location + + line1823 + col10 + file0 + + ranges + + + + line1823 + col10 + file0 + + + line1823 + col60 + file0 + + + + depth0 + extended_message + Call to function 'CFArrayCreateMutable' returns a Core Foundation object of type 'CFMutableArrayRef' with a +1 retain count + message + Call to function 'CFArrayCreateMutable' returns a Core Foundation object of type 'CFMutableArrayRef' with a +1 retain count + + + kindevent + location + + line1823 + col3 + file0 + + ranges + + + + line1823 + col3 + file0 + + + line1823 + col60 + file0 + + + + depth0 + extended_message + Object leaked: allocated object of type 'CFMutableArrayRef' is returned from a function whose name ('camelcase_copying') does not contain 'Copy' or 'Create'. This violates the naming convention rules given in the Memory Management Guide for Core Foundation + message + Object leaked: allocated object of type 'CFMutableArrayRef' is returned from a function whose name ('camelcase_copying') does not contain 'Copy' or 'Create'. This violates the naming convention rules given in the Memory Management Guide for Core Foundation + + + descriptionPotential leak of an object of type 'CFMutableArrayRef' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak of returned object + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context20c973a013858abb0a926276c956f858 + issue_context_kindfunction + issue_contextcamelcase_copying + issue_hash_function_offset1 + location + + line1823 + col3 + file0 + + ExecutedLines + + 0 + + 1822 + 1823 + + + + + path + + + kindevent + location + + line1844 + col10 + file0 + + ranges + + + + line1844 + col10 + file0 + + + line1844 + col60 + file0 + + + + depth0 + extended_message + Call to function 'CFArrayCreateMutable' returns a Core Foundation object of type 'CFMutableArrayRef' with a +1 retain count + message + Call to function 'CFArrayCreateMutable' returns a Core Foundation object of type 'CFMutableArrayRef' with a +1 retain count + + + kindevent + location + + line1844 + col3 + file0 + + ranges + + + + line1844 + col3 + file0 + + + line1844 + col60 + file0 + + + + depth0 + extended_message + Object leaked: allocated object of type 'CFMutableArrayRef' is returned from a function whose name ('camel_creat') does not contain 'Copy' or 'Create'. This violates the naming convention rules given in the Memory Management Guide for Core Foundation + message + Object leaked: allocated object of type 'CFMutableArrayRef' is returned from a function whose name ('camel_creat') does not contain 'Copy' or 'Create'. This violates the naming convention rules given in the Memory Management Guide for Core Foundation + + + descriptionPotential leak of an object of type 'CFMutableArrayRef' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak of returned object + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context80ee99e51561a37297429740e3a4da0c + issue_context_kindfunction + issue_contextcamel_creat + issue_hash_function_offset1 + location + + line1844 + col3 + file0 + + ExecutedLines + + 0 + + 1843 + 1844 + + + + + path + + + kindevent + location + + line1856 + col10 + file0 + + ranges + + + + line1856 + col10 + file0 + + + line1856 + col60 + file0 + + + + depth0 + extended_message + Call to function 'CFArrayCreateMutable' returns a Core Foundation object of type 'CFMutableArrayRef' with a +1 retain count + message + Call to function 'CFArrayCreateMutable' returns a Core Foundation object of type 'CFMutableArrayRef' with a +1 retain count + + + kindevent + location + + line1856 + col3 + file0 + + ranges + + + + line1856 + col3 + file0 + + + line1856 + col60 + file0 + + + + depth0 + extended_message + Object leaked: allocated object of type 'CFMutableArrayRef' is returned from a function whose name ('camel_copymachine') does not contain 'Copy' or 'Create'. This violates the naming convention rules given in the Memory Management Guide for Core Foundation + message + Object leaked: allocated object of type 'CFMutableArrayRef' is returned from a function whose name ('camel_copymachine') does not contain 'Copy' or 'Create'. This violates the naming convention rules given in the Memory Management Guide for Core Foundation + + + descriptionPotential leak of an object of type 'CFMutableArrayRef' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak of returned object + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_contexta4e28a04f6a8d87c8aaf4d71c37cac0f + issue_context_kindfunction + issue_contextcamel_copymachine + issue_hash_function_offset1 + location + + line1856 + col3 + file0 + + ExecutedLines + + 0 + + 1855 + 1856 + + + + + path + + + kindcontrol + edges + + + start + + + line1876 + col3 + file0 + + + line1876 + col16 + file0 + + + end + + + line1877 + col3 + file0 + + + line1877 + col11 + file0 + + + + + + + kindevent + location + + line1877 + col24 + file0 + + ranges + + + + line1877 + col24 + file0 + + + line1877 + col41 + file0 + + + + depth0 + extended_message + Call to function 'CFDateCreate' returns a Core Foundation object of type 'CFDateRef' with a +1 retain count + message + Call to function 'CFDateCreate' returns a Core Foundation object of type 'CFDateRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line1877 + col3 + file0 + + + line1877 + col11 + file0 + + + end + + + line1878 + col1 + file0 + + + line1878 + col1 + file0 + + + + + + + kindevent + location + + line1878 + col1 + file0 + + depth0 + extended_message + Object leaked: object allocated and stored into 'vals' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'vals' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'vals' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context6b727a438d8411c058fd32867b9402bc + issue_context_kindfunction + issue_contextrdar6582778 + issue_hash_function_offset2 + location + + line1878 + col1 + file0 + + ExecutedLines + + 0 + + 1875 + 1876 + 1877 + 1878 + + + + + path + + + kindcontrol + edges + + + start + + + line1902 + col3 + file0 + + + line1902 + col16 + file0 + + + end + + + line1904 + col3 + file0 + + + line1904 + col10 + file0 + + + + + + + kindevent + location + + line1904 + col22 + file0 + + ranges + + + + line1904 + col22 + file0 + + + line1904 + col64 + file0 + + + + depth0 + extended_message + Method returns an instance of NSString with a +1 retain count + message + Method returns an instance of NSString with a +1 retain count + + + kindcontrol + edges + + + start + + + line1904 + col3 + file0 + + + line1904 + col10 + file0 + + + end + + + line1905 + col3 + file0 + + + line1905 + col3 + file0 + + + + + + + kindevent + location + + line1905 + col3 + file0 + + ranges + + + + line1905 + col3 + file0 + + + line1905 + col18 + file0 + + + + + line1905 + col4 + file0 + + + line1905 + col9 + file0 + + + + depth0 + extended_message + Object released + message + Object released + + + kindcontrol + edges + + + start + + + line1905 + col3 + file0 + + + line1905 + col3 + file0 + + + end + + + line1907 + col3 + file0 + + + line1907 + col10 + file0 + + + + + + + kindcontrol + edges + + + start + + + line1907 + col3 + file0 + + + line1907 + col10 + file0 + + + end + + + line1907 + col27 + file0 + + + line1907 + col27 + file0 + + + + + + + kindevent + location + + line1907 + col27 + file0 + + ranges + + + + line1907 + col28 + file0 + + + line1907 + col33 + file0 + + + + depth0 + extended_message + Reference-counted object is used after it is released + message + Reference-counted object is used after it is released + + + descriptionReference-counted object is used after it is released + categoryMemory (Core Foundation/Objective-C/OSObject) + typeUse-after-release + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_contextb39dcf9df7cec8dd73cbbe25b2a7d6c5 + issue_context_kindfunction + issue_contextrdar10232019_positive + issue_hash_function_offset6 + location + + line1907 + col27 + file0 + + ExecutedLines + + 0 + + 1901 + 1902 + 1904 + 1905 + 1907 + + + + + path + + + kindcontrol + edges + + + start + + + line2034 + col9 + file0 + + + line2034 + col16 + file0 + + + end + + + line2035 + col9 + file0 + + + line2035 + col15 + file0 + + + + + + + kindevent + location + + line2035 + col22 + file0 + + ranges + + + + line2035 + col22 + file0 + + + line2035 + col66 + file0 + + + + depth0 + extended_message + Method returns an instance of NSArray with a +1 retain count + message + Method returns an instance of NSArray with a +1 retain count + + + kindcontrol + edges + + + start + + + line2035 + col9 + file0 + + + line2035 + col15 + file0 + + + end + + + line2038 + col9 + file0 + + + line2038 + col9 + file0 + + + + + + + kindevent + location + + line2038 + col9 + file0 + + ranges + + + + line2038 + col9 + file0 + + + line2038 + col23 + file0 + + + + depth0 + extended_message + Object leaked: object allocated and stored into 'a' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'a' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'a' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_contexta501f743b22f1feb5dc317fcad4f7556 + issue_context_kindfunction + issue_contexttest_objc_arrays + issue_hash_function_offset3 + location + + line2038 + col9 + file0 + + ExecutedLines + + 0 + + 2032 + 2034 + 2035 + 2036 + 2037 + 2038 + + + + + path + + + kindcontrol + edges + + + start + + + line2034 + col9 + file0 + + + line2034 + col16 + file0 + + + end + + + line2038 + col9 + file0 + + + line2038 + col9 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2038 + col9 + file0 + + + line2038 + col9 + file0 + + + end + + + line2042 + col9 + file0 + + + line2042 + col16 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2042 + col9 + file0 + + + line2042 + col16 + file0 + + + end + + + line2044 + col9 + file0 + + + line2044 + col15 + file0 + + + + + + + kindevent + location + + line2044 + col23 + file0 + + ranges + + + + line2044 + col23 + file0 + + + line2044 + col56 + file0 + + + + depth0 + extended_message + Method returns an instance of NSArray with a +1 retain count + message + Method returns an instance of NSArray with a +1 retain count + + + kindcontrol + edges + + + start + + + line2044 + col9 + file0 + + + line2044 + col15 + file0 + + + end + + + line2047 + col9 + file0 + + + line2047 + col9 + file0 + + + + + + + kindevent + location + + line2047 + col9 + file0 + + ranges + + + + line2047 + col9 + file0 + + + line2047 + col23 + file0 + + + + depth0 + extended_message + Object leaked: object allocated and stored into 'a2' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'a2' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'a2' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_contexta141a6ad33e8ff2ae3b13da0ad36ebc5 + issue_context_kindfunction + issue_contexttest_objc_arrays + issue_hash_function_offset12 + location + + line2047 + col9 + file0 + + ExecutedLines + + 0 + + 2032 + 2034 + 2035 + 2036 + 2037 + 2038 + 2042 + 2043 + 2044 + 2045 + 2046 + 2047 + + + + + path + + + kindcontrol + edges + + + start + + + line2034 + col9 + file0 + + + line2034 + col16 + file0 + + + end + + + line2038 + col9 + file0 + + + line2038 + col9 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2038 + col9 + file0 + + + line2038 + col9 + file0 + + + end + + + line2042 + col9 + file0 + + + line2042 + col16 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2042 + col9 + file0 + + + line2042 + col16 + file0 + + + end + + + line2047 + col9 + file0 + + + line2047 + col9 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2047 + col9 + file0 + + + line2047 + col9 + file0 + + + end + + + line2051 + col9 + file0 + + + line2051 + col16 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2051 + col9 + file0 + + + line2051 + col16 + file0 + + + end + + + line2052 + col9 + file0 + + + line2052 + col15 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2052 + col9 + file0 + + + line2052 + col15 + file0 + + + end + + + line2052 + col24 + file0 + + + line2052 + col24 + file0 + + + + + + + kindevent + location + + line2052 + col24 + file0 + + ranges + + + + line2052 + col24 + file0 + + + line2052 + col27 + file0 + + + + depth0 + extended_message + NSArray literal is an object with a +0 retain count + message + NSArray literal is an object with a +0 retain count + + + kindevent + location + + line2052 + col23 + file0 + + ranges + + + + line2052 + col23 + file0 + + + line2052 + col35 + file0 + + + + + line2052 + col24 + file0 + + + line2052 + col27 + file0 + + + + depth0 + extended_message + Reference count incremented. The object now has a +1 retain count + message + Reference count incremented. The object now has a +1 retain count + + + kindcontrol + edges + + + start + + + line2052 + col23 + file0 + + + line2052 + col23 + file0 + + + end + + + line2052 + col9 + file0 + + + line2052 + col15 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2052 + col9 + file0 + + + line2052 + col15 + file0 + + + end + + + line2055 + col9 + file0 + + + line2055 + col9 + file0 + + + + + + + kindevent + location + + line2055 + col9 + file0 + + ranges + + + + line2055 + col9 + file0 + + + line2055 + col23 + file0 + + + + depth0 + extended_message + Object leaked: object allocated and stored into 'a3' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'a3' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'a3' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context2b072d75e8da8e3fe8f7968a85efb37c + issue_context_kindfunction + issue_contexttest_objc_arrays + issue_hash_function_offset20 + location + + line2055 + col9 + file0 + + ExecutedLines + + 0 + + 2032 + 2034 + 2035 + 2036 + 2037 + 2038 + 2042 + 2043 + 2044 + 2045 + 2046 + 2047 + 2051 + 2052 + 2053 + 2054 + 2055 + + + + + path + + + kindcontrol + edges + + + start + + + line2034 + col9 + file0 + + + line2034 + col16 + file0 + + + end + + + line2038 + col9 + file0 + + + line2038 + col9 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2038 + col9 + file0 + + + line2038 + col9 + file0 + + + end + + + line2042 + col9 + file0 + + + line2042 + col16 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2042 + col9 + file0 + + + line2042 + col16 + file0 + + + end + + + line2047 + col9 + file0 + + + line2047 + col9 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2047 + col9 + file0 + + + line2047 + col9 + file0 + + + end + + + line2051 + col9 + file0 + + + line2051 + col16 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2051 + col9 + file0 + + + line2051 + col16 + file0 + + + end + + + line2055 + col9 + file0 + + + line2055 + col9 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2055 + col9 + file0 + + + line2055 + col9 + file0 + + + end + + + line2059 + col9 + file0 + + + line2059 + col16 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2059 + col9 + file0 + + + line2059 + col16 + file0 + + + end + + + line2060 + col9 + file0 + + + line2060 + col15 + file0 + + + + + + + kindevent + location + + line2060 + col22 + file0 + + ranges + + + + line2060 + col22 + file0 + + + line2060 + col57 + file0 + + + + depth0 + extended_message + Method returns an instance of NSArray with a +1 retain count + message + Method returns an instance of NSArray with a +1 retain count + + + kindcontrol + edges + + + start + + + line2060 + col9 + file0 + + + line2060 + col15 + file0 + + + end + + + line2064 + col9 + file0 + + + line2064 + col9 + file0 + + + + + + + kindevent + location + + line2064 + col9 + file0 + + ranges + + + + line2064 + col9 + file0 + + + line2064 + col23 + file0 + + + + depth0 + extended_message + Object leaked: object allocated and stored into 'a' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'a' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'a' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context0bfdfb7e392626e0fccc6ab9f58f1ca8 + issue_context_kindfunction + issue_contexttest_objc_arrays + issue_hash_function_offset28 + location + + line2064 + col9 + file0 + + ExecutedLines + + 0 + + 2032 + 2034 + 2035 + 2036 + 2037 + 2038 + 2042 + 2043 + 2044 + 2045 + 2046 + 2047 + 2051 + 2052 + 2053 + 2054 + 2055 + 2059 + 2060 + 2061 + 2063 + 2064 + + + + + path + + + kindcontrol + edges + + + start + + + line2034 + col9 + file0 + + + line2034 + col16 + file0 + + + end + + + line2038 + col9 + file0 + + + line2038 + col9 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2038 + col9 + file0 + + + line2038 + col9 + file0 + + + end + + + line2042 + col9 + file0 + + + line2042 + col16 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2042 + col9 + file0 + + + line2042 + col16 + file0 + + + end + + + line2047 + col9 + file0 + + + line2047 + col9 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2047 + col9 + file0 + + + line2047 + col9 + file0 + + + end + + + line2051 + col9 + file0 + + + line2051 + col16 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2051 + col9 + file0 + + + line2051 + col16 + file0 + + + end + + + line2055 + col9 + file0 + + + line2055 + col9 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2055 + col9 + file0 + + + line2055 + col9 + file0 + + + end + + + line2059 + col9 + file0 + + + line2059 + col16 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2059 + col9 + file0 + + + line2059 + col16 + file0 + + + end + + + line2064 + col9 + file0 + + + line2064 + col9 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2064 + col9 + file0 + + + line2064 + col9 + file0 + + + end + + + line2068 + col9 + file0 + + + line2068 + col15 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2068 + col9 + file0 + + + line2068 + col15 + file0 + + + end + + + line2069 + col9 + file0 + + + line2069 + col20 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2069 + col9 + file0 + + + line2069 + col20 + file0 + + + end + + + line2069 + col28 + file0 + + + line2069 + col28 + file0 + + + + + + + kindevent + location + + line2069 + col28 + file0 + + ranges + + + + line2069 + col28 + file0 + + + line2069 + col35 + file0 + + + + depth0 + extended_message + NSDictionary literal is an object with a +0 retain count + message + NSDictionary literal is an object with a +0 retain count + + + kindevent + location + + line2069 + col27 + file0 + + ranges + + + + line2069 + col27 + file0 + + + line2069 + col43 + file0 + + + + + line2069 + col28 + file0 + + + line2069 + col35 + file0 + + + + depth0 + extended_message + Reference count incremented. The object now has a +1 retain count + message + Reference count incremented. The object now has a +1 retain count + + + kindcontrol + edges + + + start + + + line2069 + col27 + file0 + + + line2069 + col27 + file0 + + + end + + + line2069 + col9 + file0 + + + line2069 + col20 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2069 + col9 + file0 + + + line2069 + col20 + file0 + + + end + + + line2073 + col9 + file0 + + + line2073 + col9 + file0 + + + + + + + kindevent + location + + line2073 + col9 + file0 + + ranges + + + + line2073 + col9 + file0 + + + line2073 + col23 + file0 + + + + depth0 + extended_message + Object leaked: object allocated and stored into 'a' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'a' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'a' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_contextff7c34e661a42d06a7fb3e9669e70339 + issue_context_kindfunction + issue_contexttest_objc_arrays + issue_hash_function_offset37 + location + + line2073 + col9 + file0 + + ExecutedLines + + 0 + + 2032 + 2034 + 2035 + 2036 + 2037 + 2038 + 2042 + 2043 + 2044 + 2045 + 2046 + 2047 + 2051 + 2052 + 2053 + 2054 + 2055 + 2059 + 2060 + 2061 + 2063 + 2064 + 2068 + 2069 + 2070 + 2072 + 2073 + + + + + path + + + kindcontrol + edges + + + start + + + line2078 + col3 + file0 + + + line2078 + col4 + file0 + + + end + + + line2078 + col15 + file0 + + + line2078 + col15 + file0 + + + + + + + kindevent + location + + line2078 + col15 + file0 + + ranges + + + + line2078 + col15 + file0 + + + line2078 + col16 + file0 + + + + depth0 + extended_message + NSNumber literal is an object with a +0 retain count + message + NSNumber literal is an object with a +0 retain count + + + kindevent + location + + line2078 + col14 + file0 + + ranges + + + + line2078 + col14 + file0 + + + line2078 + col24 + file0 + + + + + line2078 + col15 + file0 + + + line2078 + col16 + file0 + + + + depth0 + extended_message + Reference count incremented. The object now has a +1 retain count + message + Reference count incremented. The object now has a +1 retain count + + + kindcontrol + edges + + + start + + + line2078 + col14 + file0 + + + line2078 + col14 + file0 + + + end + + + line2078 + col3 + file0 + + + line2078 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2078 + col3 + file0 + + + line2078 + col4 + file0 + + + end + + + line2079 + col3 + file0 + + + line2079 + col3 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2079 + col3 + file0 + + + line2079 + col3 + file0 + + + end + + + line2080 + col1 + file0 + + + line2080 + col1 + file0 + + + + + + + kindevent + location + + line2080 + col1 + file0 + + depth0 + extended_message + Object leaked: object allocated and stored into 'value' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'value' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'value' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context73e84c042932d2e17e00f00dc3d36d5a + issue_context_kindfunction + issue_contexttest_objc_integer_literals + issue_hash_function_offset1 + location + + line2080 + col1 + file0 + + ExecutedLines + + 0 + + 2077 + 2078 + 2079 + 2080 + + + + + path + + + kindcontrol + edges + + + start + + + line2083 + col3 + file0 + + + line2083 + col4 + file0 + + + end + + + line2083 + col15 + file0 + + + line2083 + col15 + file0 + + + + + + + kindevent + location + + line2083 + col15 + file0 + + ranges + + + + line2083 + col15 + file0 + + + line2083 + col18 + file0 + + + + depth0 + extended_message + NSNumber boxed expression produces an object with a +0 retain count + message + NSNumber boxed expression produces an object with a +0 retain count + + + kindevent + location + + line2083 + col14 + file0 + + ranges + + + + line2083 + col14 + file0 + + + line2083 + col26 + file0 + + + + + line2083 + col15 + file0 + + + line2083 + col18 + file0 + + + + depth0 + extended_message + Reference count incremented. The object now has a +1 retain count + message + Reference count incremented. The object now has a +1 retain count + + + kindcontrol + edges + + + start + + + line2083 + col14 + file0 + + + line2083 + col14 + file0 + + + end + + + line2083 + col3 + file0 + + + line2083 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2083 + col3 + file0 + + + line2083 + col4 + file0 + + + end + + + line2087 + col3 + file0 + + + line2087 + col3 + file0 + + + + + + + kindevent + location + + line2087 + col3 + file0 + + ranges + + + + line2087 + col3 + file0 + + + line2087 + col21 + file0 + + + + depth0 + extended_message + Object leaked: object allocated and stored into 'value' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'value' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'value' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context465e592d4f7a187717d00b8154a614b5 + issue_context_kindfunction + issue_contexttest_objc_boxed_expressions + issue_hash_function_offset1 + location + + line2087 + col3 + file0 + + ExecutedLines + + 0 + + 2082 + 2083 + 2084 + 2086 + 2087 + + + + + path + + + kindcontrol + edges + + + start + + + line2083 + col3 + file0 + + + line2083 + col4 + file0 + + + end + + + line2086 + col3 + file0 + + + line2086 + col7 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2086 + col3 + file0 + + + line2086 + col7 + file0 + + + end + + + line2086 + col12 + file0 + + + line2086 + col12 + file0 + + + + + + + kindevent + location + + line2086 + col12 + file0 + + ranges + + + + line2086 + col12 + file0 + + + line2086 + col15 + file0 + + + + depth0 + extended_message + NSString boxed expression produces an object with a +0 retain count + message + NSString boxed expression produces an object with a +0 retain count + + + kindevent + location + + line2086 + col11 + file0 + + ranges + + + + line2086 + col11 + file0 + + + line2086 + col23 + file0 + + + + + line2086 + col12 + file0 + + + line2086 + col15 + file0 + + + + depth0 + extended_message + Reference count incremented. The object now has a +1 retain count + message + Reference count incremented. The object now has a +1 retain count + + + kindcontrol + edges + + + start + + + line2086 + col11 + file0 + + + line2086 + col11 + file0 + + + end + + + line2086 + col3 + file0 + + + line2086 + col7 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2086 + col3 + file0 + + + line2086 + col7 + file0 + + + end + + + line2087 + col3 + file0 + + + line2087 + col3 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2087 + col3 + file0 + + + line2087 + col3 + file0 + + + end + + + line2088 + col1 + file0 + + + line2088 + col1 + file0 + + + + + + + kindevent + location + + line2088 + col1 + file0 + + depth0 + extended_message + Object leaked: object allocated and stored into 'value' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'value' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'value' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_contextc701bd0c60f51d96c047aa78c9e0eb99 + issue_context_kindfunction + issue_contexttest_objc_boxed_expressions + issue_hash_function_offset4 + location + + line2088 + col1 + file0 + + ExecutedLines + + 0 + + 2082 + 2083 + 2084 + 2086 + 2087 + 2088 + + + + + path + + + kindcontrol + edges + + + start + + + line2094 + col5 + file0 + + + line2094 + col12 + file0 + + + end + + + line2095 + col5 + file0 + + + line2095 + col6 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2095 + col5 + file0 + + + line2095 + col6 + file0 + + + end + + + line2095 + col8 + file0 + + + line2095 + col8 + file0 + + + + + + + kindevent + location + + line2095 + col8 + file0 + + ranges + + + + line2095 + col8 + file0 + + + line2095 + col12 + file0 + + + + depth0 + extended_message + Assuming 'y' is <= 2 + message + Assuming 'y' is <= 2 + + + kindcontrol + edges + + + start + + + line2095 + col8 + file0 + + + line2095 + col8 + file0 + + + end + + + line2098 + col7 + file0 + + + line2098 + col17 + file0 + + + + + + + kindevent + location + + line2098 + col21 + file0 + + ranges + + + + line2098 + col21 + file0 + + + line2098 + col43 + file0 + + + + depth0 + extended_message + Method returns an instance of NSString with a +1 retain count + message + Method returns an instance of NSString with a +1 retain count + + + kindcontrol + edges + + + start + + + line2098 + col7 + file0 + + + line2098 + col17 + file0 + + + end + + + line2099 + col5 + file0 + + + line2099 + col9 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2099 + col5 + file0 + + + line2099 + col9 + file0 + + + end + + + line2100 + col5 + file0 + + + line2100 + col5 + file0 + + + + + + + kindevent + location + + line2100 + col5 + file0 + + ranges + + + + line2100 + col5 + file0 + + + line2100 + col25 + file0 + + + + + line2100 + col6 + file0 + + + line2100 + col16 + file0 + + + + depth0 + extended_message + Object released + message + Object released + + + kindcontrol + edges + + + start + + + line2100 + col5 + file0 + + + line2100 + col5 + file0 + + + end + + + line2101 + col5 + file0 + + + line2101 + col9 + file0 + + + + + + + kindevent + location + + line2101 + col5 + file0 + + ranges + + + + line2101 + col25 + file0 + + + line2101 + col35 + file0 + + + + depth0 + extended_message + Reference-counted object is used after it is released + message + Reference-counted object is used after it is released + + + descriptionReference-counted object is used after it is released + categoryMemory (Core Foundation/Objective-C/OSObject) + typeUse-after-release + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_contexta4cedbb647e9632da7a5072cb839e54a + issue_context_kindfunction + issue_contextrdar11400885 + issue_hash_function_offset9 + location + + line2101 + col5 + file0 + + ExecutedLines + + 0 + + 2091 + 2092 + 2094 + 2095 + 2098 + 2099 + 2100 + 2101 + + + + + path + + + kindcontrol + edges + + + start + + + line2119 + col3 + file0 + + + line2119 + col4 + file0 + + + end + + + line2127 + col3 + file0 + + + line2127 + col4 + file0 + + + + + + + kindevent + location + + line2127 + col19 + file0 + + ranges + + + + line2127 + col19 + file0 + + + line2127 + col21 + file0 + + + + depth0 + extended_message + NSArray literal is an object with a +0 retain count + message + NSArray literal is an object with a +0 retain count + + + kindcontrol + edges + + + start + + + line2127 + col3 + file0 + + + line2127 + col4 + file0 + + + end + + + line2128 + col3 + file0 + + + line2128 + col24 + file0 + + + + + + + kindevent + location + + line2128 + col3 + file0 + + ranges + + + + line2128 + col26 + file0 + + + line2128 + col35 + file0 + + + + depth0 + extended_message + Incorrect decrement of the reference count of an object that is not owned at this point by the caller + message + Incorrect decrement of the reference count of an object that is not owned at this point by the caller + + + descriptionIncorrect decrement of the reference count of an object that is not owned at this point by the caller + categoryMemory (Core Foundation/Objective-C/OSObject) + typeBad release + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_contextfd9427d86a2357fd92478c9c7abbc1f4 + issue_context_kindfunction + issue_contexttestConsumeAndStopTracking + issue_hash_function_offset10 + location + + line2128 + col3 + file0 + + ExecutedLines + + 0 + + 2118 + 2119 + 2120 + 2122 + 2123 + 2127 + 2128 + + + + + path + + + kindcontrol + edges + + + start + + + line2132 + col3 + file0 + + + line2132 + col4 + file0 + + + end + + + line2140 + col3 + file0 + + + line2140 + col4 + file0 + + + + + + + kindevent + location + + line2140 + col19 + file0 + + ranges + + + + line2140 + col19 + file0 + + + line2140 + col21 + file0 + + + + depth0 + extended_message + NSArray literal is an object with a +0 retain count + message + NSArray literal is an object with a +0 retain count + + + kindcontrol + edges + + + start + + + line2140 + col3 + file0 + + + line2140 + col4 + file0 + + + end + + + line2141 + col3 + file0 + + + line2141 + col26 + file0 + + + + + + + kindevent + location + + line2141 + col3 + file0 + + ranges + + + + line2141 + col28 + file0 + + + line2141 + col48 + file0 + + + + depth0 + extended_message + Incorrect decrement of the reference count of an object that is not owned at this point by the caller + message + Incorrect decrement of the reference count of an object that is not owned at this point by the caller + + + descriptionIncorrect decrement of the reference count of an object that is not owned at this point by the caller + categoryMemory (Core Foundation/Objective-C/OSObject) + typeBad release + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context0e65e51476e5671dcd37f632806e5147 + issue_context_kindfunction + issue_contexttestCFConsumeAndStopTracking + issue_hash_function_offset10 + location + + line2141 + col3 + file0 + + ExecutedLines + + 0 + + 2131 + 2132 + 2133 + 2135 + 2136 + 2140 + 2141 + + + + + path + + + kindevent + location + + line2153 + col16 + file0 + + ranges + + + + line2153 + col16 + file0 + + + line2153 + col31 + file0 + + + + depth0 + extended_message + Call to function 'CreateMyCFType' returns a Core Foundation object of type 'MyCFType' with a +1 retain count + message + Call to function 'CreateMyCFType' returns a Core Foundation object of type 'MyCFType' with a +1 retain count + + + kindcontrol + edges + + + start + + + line2153 + col3 + file0 + + + line2153 + col10 + file0 + + + end + + + line2154 + col1 + file0 + + + line2154 + col1 + file0 + + + + + + + kindevent + location + + line2154 + col1 + file0 + + depth0 + extended_message + Object leaked: object allocated and stored into 'x' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'x' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'x' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_contexta0ba9c47505e923763ea5323ad2f71b7 + issue_context_kindfunction + issue_contexttest_custom_cf + issue_hash_function_offset1 + location + + line2154 + col1 + file0 + + ExecutedLines + + 0 + + 2152 + 2153 + 2154 + + + + + path + + + kindevent + location + + line2188 + col18 + file0 + + ranges + + + + line2188 + col18 + file0 + + + line2188 + col29 + file0 + + + + depth0 + extended_message + Call to function 'makeCustom' returns a Core Foundation object of type 'MyCFType' with a +1 retain count + message + Call to function 'makeCustom' returns a Core Foundation object of type 'MyCFType' with a +1 retain count + + + kindcontrol + edges + + + start + + + line2188 + col3 + file0 + + + line2188 + col10 + file0 + + + end + + + line2189 + col1 + file0 + + + line2189 + col1 + file0 + + + + + + + kindevent + location + + line2189 + col1 + file0 + + depth0 + extended_message + Object leaked: object allocated and stored into 'obj' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'obj' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'obj' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context7a6cf8cb3c5e0ca3125d7e27695a810a + issue_context_kindfunction + issue_contexttestCustomReturnsRetained + issue_hash_function_offset1 + location + + line2189 + col1 + file0 + + ExecutedLines + + 0 + + 2187 + 2188 + 2189 + + + + + path + + + kindevent + location + + line2192 + col13 + file0 + + ranges + + + + line2192 + col13 + file0 + + + line2192 + col23 + file0 + + + + depth0 + extended_message + Call to function 'getCustom' returns a Core Foundation object of type 'MyCFType' with a +0 retain count + message + Call to function 'getCustom' returns a Core Foundation object of type 'MyCFType' with a +0 retain count + + + kindevent + location + + line2192 + col3 + file0 + + ranges + + + + line2192 + col13 + file0 + + + line2192 + col23 + file0 + + + + depth0 + extended_message + Incorrect decrement of the reference count of an object that is not owned at this point by the caller + message + Incorrect decrement of the reference count of an object that is not owned at this point by the caller + + + descriptionIncorrect decrement of the reference count of an object that is not owned at this point by the caller + categoryMemory (Core Foundation/Objective-C/OSObject) + typeBad release + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context810fce32373fe40ba8e2d0894d46f667 + issue_context_kindfunction + issue_contexttestCustomReturnsNotRetained + issue_hash_function_offset1 + location + + line2192 + col3 + file0 + + ExecutedLines + + 0 + + 2191 + 2192 + + + + + path + + + kindcontrol + edges + + + start + + + line2211 + col3 + file0 + + + line2211 + col4 + file0 + + + end + + + line2211 + col11 + file0 + + + line2211 + col11 + file0 + + + + + + + kindevent + location + + line2211 + col11 + file0 + + ranges + + + + line2211 + col11 + file0 + + + line2211 + col31 + file0 + + + + depth0 + extended_message + Method returns an instance of MyObj12706177 with a +1 retain count + message + Method returns an instance of MyObj12706177 with a +1 retain count + + + kindevent + location + + line2211 + col10 + file0 + + ranges + + + + line2211 + col10 + file0 + + + line2211 + col38 + file0 + + + + depth0 + extended_message + Calling 'initX' + message + Calling 'initX' + + + kindevent + location + + line2204 + col1 + file0 + + depth1 + extended_message + Entered call from 'test12706177' + message + Entered call from 'test12706177' + + + kindcontrol + edges + + + start + + + line2204 + col1 + file0 + + + line2204 + col1 + file0 + + + end + + + line2205 + col3 + file0 + + + line2205 + col4 + file0 + + + + + + + kindcontrol + edges + + + start + + + line2205 + col3 + file0 + + + line2205 + col4 + file0 + + + end + + + line2205 + col7 + file0 + + + line2205 + col10 + file0 + + + + + + + kindevent + location + + line2205 + col7 + file0 + + ranges + + + + line2205 + col7 + file0 + + + line2205 + col10 + file0 + + + + depth1 + extended_message + Assuming 'Cond' is not equal to 0 + message + Assuming 'Cond' is not equal to 0 + + + kindcontrol + edges + + + start + + + line2205 + col7 + file0 + + + line2205 + col10 + file0 + + + end + + + line2206 + col5 + file0 + + + line2206 + col10 + file0 + + + + + + + kindevent + location + + line2211 + col10 + file0 + + ranges + + + + line2211 + col10 + file0 + + + line2211 + col38 + file0 + + + + depth0 + extended_message + Returning from 'initX' + message + Returning from 'initX' + + + kindcontrol + edges + + + start + + + line2211 + col10 + file0 + + + line2211 + col10 + file0 + + + end + + + line2211 + col3 + file0 + + + line2211 + col4 + file0 + + + + + + + kindevent + location + + line2211 + col3 + file0 + + ranges + + + + line2211 + col3 + file0 + + + line2211 + col6 + file0 + + + + depth0 + extended_message + Object leaked: allocated object of type 'MyObj12706177 *' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: allocated object of type 'MyObj12706177 *' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object of type 'MyObj12706177 *' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context68ee7961ffb62c575cc2298cb4836090 + issue_context_kindObjective-C method + issue_contexttest12706177 + issue_hash_function_offset1 + location + + line2211 + col3 + file0 + + ExecutedLines + + 0 + + 2204 + 2205 + 2206 + 2210 + 2211 + + + + + path + + + kindcontrol + edges + + + start + + + line2227 + col3 + file0 + + + line2227 + col8 + file0 + + + end + + + line2227 + col24 + file0 + + + line2227 + col37 + file0 + + + + + + + kindevent + location + + line2227 + col24 + file0 + + ranges + + + + line2227 + col24 + file0 + + + line2227 + col39 + file0 + + + + depth0 + extended_message + Call to function 'CFGetSomething' returns a Core Foundation object of type 'CFTypeRef' with a +0 retain count + message + Call to function 'CFGetSomething' returns a Core Foundation object of type 'CFTypeRef' with a +0 retain count + + + kindcontrol + edges + + + start + + + line2227 + col24 + file0 + + + line2227 + col37 + file0 + + + end + + + line2227 + col10 + file0 + + + line2227 + col22 + file0 + + + + + + + kindevent + location + + line2227 + col10 + file0 + + ranges + + + + line2227 + col10 + file0 + + + line2227 + col40 + file0 + + + + + line2227 + col24 + file0 + + + line2227 + col39 + file0 + + + + depth0 + extended_message + Object autoreleased + message + Object autoreleased + + + kindcontrol + edges + + + start + + + line2227 + col10 + file0 + + + line2227 + col22 + file0 + + + end + + + line2227 + col3 + file0 + + + line2227 + col8 + file0 + + + + + + + kindevent + location + + line2227 + col3 + file0 + + ranges + + + + line2227 + col3 + file0 + + + line2227 + col40 + file0 + + + + depth0 + extended_message + Object was autoreleased but has a +0 retain count + message + Object was autoreleased but has a +0 retain count + + + descriptionObject autoreleased too many times + categoryMemory (Core Foundation/Objective-C/OSObject) + typeObject autoreleased too many times + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context1dc376fbbe90d14b6766585a0e2b7bee + issue_context_kindfunction + issue_contextgetIncorrectlyAutoreleasedCFType + issue_hash_function_offset2 + location + + line2227 + col3 + file0 + + ExecutedLines + + 0 + + 2225 + 2227 + + + + + path + + + kindcontrol + edges + + + start + + + line2232 + col3 + file0 + + + line2232 + col8 + file0 + + + end + + + line2232 + col24 + file0 + + + line2232 + col40 + file0 + + + + + + + kindevent + location + + line2232 + col24 + file0 + + ranges + + + + line2232 + col24 + file0 + + + line2232 + col42 + file0 + + + + depth0 + extended_message + Call to function 'CFCreateSomething' returns a Core Foundation object of type 'CFTypeRef' with a +1 retain count + message + Call to function 'CFCreateSomething' returns a Core Foundation object of type 'CFTypeRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line2232 + col24 + file0 + + + line2232 + col40 + file0 + + + end + + + line2232 + col10 + file0 + + + line2232 + col22 + file0 + + + + + + + kindevent + location + + line2232 + col10 + file0 + + ranges + + + + line2232 + col10 + file0 + + + line2232 + col43 + file0 + + + + + line2232 + col24 + file0 + + + line2232 + col42 + file0 + + + + depth0 + extended_message + Object autoreleased + message + Object autoreleased + + + kindcontrol + edges + + + start + + + line2232 + col10 + file0 + + + line2232 + col22 + file0 + + + end + + + line2232 + col3 + file0 + + + line2232 + col8 + file0 + + + + + + + kindevent + location + + line2232 + col3 + file0 + + ranges + + + + line2232 + col3 + file0 + + + line2232 + col43 + file0 + + + + depth0 + extended_message + Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected + message + Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected + + + descriptionObject with a +0 retain count returned to caller where a +1 (owning) retain count is expected + categoryMemory (Core Foundation/Objective-C/OSObject) + typeMethod should return an owned object + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context6ae8ea9fe4bf203e6b7bfaf649a6ca6a + issue_context_kindfunction + issue_contextcreateIncorrectlyAutoreleasedCFType + issue_hash_function_offset2 + location + + line2232 + col3 + file0 + + ExecutedLines + + 0 + + 2230 + 2232 + + + + + path + + + kindevent + location + + line2247 + col19 + file0 + + ranges + + + + line2247 + col19 + file0 + + + line2247 + col37 + file0 + + + + depth0 + extended_message + Call to function 'CFCreateSomething' returns a Core Foundation object of type 'CFTypeRef' with a +1 retain count + message + Call to function 'CFCreateSomething' returns a Core Foundation object of type 'CFTypeRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line2247 + col3 + file0 + + + line2247 + col11 + file0 + + + end + + + line2248 + col3 + file0 + + + line2248 + col11 + file0 + + + + + + + kindevent + location + + line2248 + col3 + file0 + + ranges + + + + line2248 + col3 + file0 + + + line2248 + col16 + file0 + + + + + line2248 + col13 + file0 + + + line2248 + col15 + file0 + + + + depth0 + extended_message + Object released + message + Object released + + + kindcontrol + edges + + + start + + + line2248 + col3 + file0 + + + line2248 + col11 + file0 + + + end + + + line2251 + col3 + file0 + + + line2251 + col7 + file0 + + + + + + + kindevent + location + + line2251 + col3 + file0 + + ranges + + + + line2251 + col9 + file0 + + + line2251 + col11 + file0 + + + + depth0 + extended_message + Reference-counted object is used after it is released + message + Reference-counted object is used after it is released + + + descriptionReference-counted object is used after it is released + categoryMemory (Core Foundation/Objective-C/OSObject) + typeUse-after-release + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_contextd4e28f96fc8610b5b4b849f4760956eb + issue_context_kindfunction + issue_contextuseAfterRelease + issue_hash_function_offset7 + location + + line2251 + col3 + file0 + + ExecutedLines + + 0 + + 2244 + 2247 + 2248 + 2251 + + + + + path + + + kindevent + location + + line2256 + col19 + file0 + + ranges + + + + line2256 + col19 + file0 + + + line2256 + col37 + file0 + + + + depth0 + extended_message + Call to function 'CFCreateSomething' returns a Core Foundation object of type 'CFTypeRef' with a +1 retain count + message + Call to function 'CFCreateSomething' returns a Core Foundation object of type 'CFTypeRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line2256 + col3 + file0 + + + line2256 + col11 + file0 + + + end + + + line2257 + col3 + file0 + + + line2257 + col11 + file0 + + + + + + + kindevent + location + + line2257 + col22 + file0 + + ranges + + + + line2257 + col22 + file0 + + + line2257 + col39 + file0 + + + + + line2257 + col36 + file0 + + + line2257 + col38 + file0 + + + + depth0 + extended_message + Object autoreleased + message + Object autoreleased + + + kindcontrol + edges + + + start + + + line2257 + col3 + file0 + + + line2257 + col11 + file0 + + + end + + + line2258 + col3 + file0 + + + line2258 + col10 + file0 + + + + + + + kindevent + location + + line2258 + col3 + file0 + + ranges + + + + line2258 + col3 + file0 + + + line2258 + col18 + file0 + + + + + line2258 + col12 + file0 + + + line2258 + col17 + file0 + + + + depth0 + extended_message + Reference count incremented. The object now has a +2 retain count + message + Reference count incremented. The object now has a +2 retain count + + + kindcontrol + edges + + + start + + + line2258 + col3 + file0 + + + line2258 + col10 + file0 + + + end + + + line2259 + col1 + file0 + + + line2259 + col1 + file0 + + + + + + + kindevent + location + + line2259 + col1 + file0 + + depth0 + extended_message + Object leaked: object allocated and stored into 'obj' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'obj' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'obj' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context7986c4b7fb29301c109343dfe4155202 + issue_context_kindfunction + issue_contexttestAutoreleaseReturnsInput + issue_hash_function_offset2 + location + + line2259 + col1 + file0 + + ExecutedLines + + 0 + + 2254 + 2256 + 2257 + 2258 + 2259 + + + + + path + + + kindevent + location + + line2276 + col20 + file0 + + ranges + + + + line2276 + col20 + file0 + + + line2276 + col70 + file0 + + + + depth0 + extended_message + Call to function 'CFArrayCreateMutable' returns a Core Foundation object of type 'CFMutableArrayRef' with a +1 retain count + message + Call to function 'CFArrayCreateMutable' returns a Core Foundation object of type 'CFMutableArrayRef' with a +1 retain count + + + kindcontrol + edges + + + start + + + line2276 + col3 + file0 + + + line2276 + col12 + file0 + + + end + + + line2277 + col3 + file0 + + + line2277 + col12 + file0 + + + + + + + kindevent + location + + line2277 + col34 + file0 + + ranges + + + + line2277 + col34 + file0 + + + line2277 + col62 + file0 + + + + + line2277 + col48 + file0 + + + line2277 + col61 + file0 + + + + depth0 + extended_message + Object autoreleased + message + Object autoreleased + + + kindcontrol + edges + + + start + + + line2277 + col3 + file0 + + + line2277 + col12 + file0 + + + end + + + line2278 + col3 + file0 + + + line2278 + col10 + file0 + + + + + + + kindevent + location + + line2278 + col3 + file0 + + ranges + + + + line2278 + col3 + file0 + + + line2278 + col17 + file0 + + + + + line2278 + col12 + file0 + + + line2278 + col16 + file0 + + + + depth0 + extended_message + Reference count incremented. The object now has a +2 retain count + message + Reference count incremented. The object now has a +2 retain count + + + kindcontrol + edges + + + start + + + line2278 + col3 + file0 + + + line2278 + col10 + file0 + + + end + + + line2279 + col1 + file0 + + + line2279 + col1 + file0 + + + + + + + kindevent + location + + line2279 + col1 + file0 + + depth0 + extended_message + Object leaked: object allocated and stored into 'arr' is not referenced later in this execution path and has a retain count of +1 + message + Object leaked: object allocated and stored into 'arr' is not referenced later in this execution path and has a retain count of +1 + + + descriptionPotential leak of an object stored into 'arr' + categoryMemory (Core Foundation/Objective-C/OSObject) + typeLeak + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context2e0dbfdf379acf2f09e46db47d753e8a + issue_context_kindfunction + issue_contextautoreleaseReturningTypedObject + issue_hash_function_offset1 + location + + line2279 + col1 + file0 + + ExecutedLines + + 0 + + 2275 + 2276 + 2277 + 2278 + 2279 + + + + + path + + + kindcontrol + edges + + + start + + + line2290 + col3 + file0 + + + line2290 + col4 + file0 + + + end + + + line2293 + col3 + file0 + + + line2293 + col4 + file0 + + + + + + + kindevent + location + + line2293 + col19 + file0 + + ranges + + + + line2293 + col19 + file0 + + + line2293 + col20 + file0 + + + + depth0 + extended_message + NSNumber literal is an object with a +0 retain count + message + NSNumber literal is an object with a +0 retain count + + + kindcontrol + edges + + + start + + + line2293 + col3 + file0 + + + line2293 + col4 + file0 + + + end + + + line2294 + col3 + file0 + + + line2294 + col15 + file0 + + + + + + + kindevent + location + + line2294 + col3 + file0 + + ranges + + + + line2294 + col3 + file0 + + + line2294 + col27 + file0 + + + + + line2294 + col17 + file0 + + + line2294 + col26 + file0 + + + + depth0 + extended_message + Object autoreleased + message + Object autoreleased + + + kindcontrol + edges + + + start + + + line2294 + col3 + file0 + + + line2294 + col15 + file0 + + + end + + + line2295 + col1 + file0 + + + line2295 + col1 + file0 + + + + + + + kindevent + location + + line2295 + col1 + file0 + + depth0 + extended_message + Object was autoreleased but has a +0 retain count + message + Object was autoreleased but has a +0 retain count + + + descriptionObject autoreleased too many times + categoryMemory (Core Foundation/Objective-C/OSObject) + typeObject autoreleased too many times + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context41a2d6f91fdfa9b5f396102a60571e21 + issue_context_kindfunction + issue_contextautoreleaseObjC + issue_hash_function_offset6 + location + + line2295 + col1 + file0 + + ExecutedLines + + 0 + + 2289 + 2290 + 2291 + 2293 + 2294 + 2295 + + + + + path + + + kindcontrol + edges + + + start + + + line2345 + col3 + file0 + + + line2345 + col11 + file0 + + + end + + + line2346 + col3 + file0 + + + line2346 + col13 + file0 + + + + + + + kindevent + location + + line2346 + col3 + file0 + + ranges + + + + line2346 + col3 + file0 + + + line2346 + col19 + file0 + + + + depth0 + extended_message + Call to function 'getViaParam' returns a Core Foundation object of type 'CFTypeRef' with a +0 retain count + message + Call to function 'getViaParam' returns a Core Foundation object of type 'CFTypeRef' with a +0 retain count + + + kindcontrol + edges + + + start + + + line2346 + col3 + file0 + + + line2346 + col13 + file0 + + + end + + + line2347 + col3 + file0 + + + line2347 + col11 + file0 + + + + + + + kindevent + location + + line2347 + col3 + file0 + + ranges + + + + line2347 + col13 + file0 + + + line2347 + col15 + file0 + + + + depth0 + extended_message + Incorrect decrement of the reference count of an object that is not owned at this point by the caller + message + Incorrect decrement of the reference count of an object that is not owned at this point by the caller + + + descriptionIncorrect decrement of the reference count of an object that is not owned at this point by the caller + categoryMemory (Core Foundation/Objective-C/OSObject) + typeBad release + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context95dd5581ae4195b71e9a11f34290af5d + issue_context_kindfunction + issue_contexttestCFReturnsNotRetained + issue_hash_function_offset4 + location + + line2347 + col3 + file0 + + ExecutedLines + + 0 + + 2343 + 2345 + 2346 + 2347 + + + + + path + + + kindcontrol + edges + + + start + + + line2352 + col3 + file0 + + + line2352 + col11 + file0 + + + end + + + line2353 + col3 + file0 + + + line2353 + col14 + file0 + + + + + + + kindevent + location + + line2353 + col3 + file0 + + ranges + + + + line2353 + col3 + file0 + + + line2353 + col20 + file0 + + + + depth0 + extended_message + Call to function 'getViaParam2' returns a Core Foundation object of type 'CFTypeRef' with a +0 retain count + message + Call to function 'getViaParam2' returns a Core Foundation object of type 'CFTypeRef' with a +0 retain count + + + kindcontrol + edges + + + start + + + line2353 + col3 + file0 + + + line2353 + col14 + file0 + + + end + + + line2354 + col3 + file0 + + + line2354 + col11 + file0 + + + + + + + kindevent + location + + line2354 + col3 + file0 + + ranges + + + + line2354 + col13 + file0 + + + line2354 + col15 + file0 + + + + depth0 + extended_message + Incorrect decrement of the reference count of an object that is not owned at this point by the caller + message + Incorrect decrement of the reference count of an object that is not owned at this point by the caller + + + descriptionIncorrect decrement of the reference count of an object that is not owned at this point by the caller + categoryMemory (Core Foundation/Objective-C/OSObject) + typeBad release + check_nameosx.cocoa.RetainCount + + issue_hash_content_of_line_in_context014103674df4a8a65a96bcdf936637a2 + issue_context_kindfunction + issue_contexttestCFReturnsNotRetainedAnnotated + issue_hash_function_offset4 + location + + line2354 + col3 + file0 + + ExecutedLines + + 0 + + 2350 + 2352 + 2353 + 2354 + + + + + files + + /Volumes/Transcend/code/monorepo/llvm-project/clang/test/Analysis/retain-release.m + + + diff --git a/test/Analysis/retain-release.m b/test/Analysis/retain-release.m index 4a3695d42a..5e858f9f54 100644 --- a/test/Analysis/retain-release.m +++ b/test/Analysis/retain-release.m @@ -3,15 +3,15 @@ // RUN: -analyzer-checker=core,osx.coreFoundation.CFRetainRelease\ // RUN: -analyzer-checker=osx.cocoa.ClassRelease,osx.cocoa.RetainCount\ // RUN: -analyzer-checker=debug.ExprInspection -fblocks -verify %s\ -// RUN: -Wno-objc-root-class -analyzer-output=plist -o %t.objcpp.plist +// RUN: -Wno-objc-root-class -analyzer-output=plist -o %t.objc.plist // RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10\ // RUN: -analyzer-checker=core,osx.coreFoundation.CFRetainRelease\ // RUN: -analyzer-checker=osx.cocoa.ClassRelease,osx.cocoa.RetainCount\ // RUN: -analyzer-checker=debug.ExprInspection -fblocks -verify %s\ // RUN: -Wno-objc-root-class -analyzer-output=plist -o %t.objcpp.plist\ // RUN: -x objective-c++ -std=gnu++98 -// FIXLATER: cat %t.objc.plist ; FileCheck --input-file=%t.objc.plist %s -// FIXLATER: cat %t.objcpp.plist ; FileCheck --input-file=%t.objcpp.plist %s +// RUN: cat %t.objcpp.plist | %diff_plist %S/Inputs/expected-plists/retain-release.m.objcpp.plist - +// RUN: cat %t.objc.plist | %diff_plist %S/Inputs/expected-plists/retain-release.m.objc.plist - void clang_analyzer_eval(int); @@ -2369,24032 +2369,3 @@ void testCFReturnsRetainedError() { return; // no-warning CFRelease(obj); } - -// CHECK: diagnostics -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line334 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line334 -// CHECK-NEXT: col16 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line335 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line335 -// CHECK-NEXT: col11 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line335 -// CHECK-NEXT: col20 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line335 -// CHECK-NEXT: col20 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line335 -// CHECK-NEXT: col37 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Call to function 'CFDateCreate' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Call to function 'CFDateCreate' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line335 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line335 -// CHECK-NEXT: col11 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line336 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line336 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line336 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line336 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line336 -// CHECK-NEXT: col16 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line336 -// CHECK-NEXT: col12 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line336 -// CHECK-NEXT: col15 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Reference count incremented. The object now has a +2 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Reference count incremented. The object now has a +2 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line336 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line336 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line337 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line337 -// CHECK-NEXT: col11 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line337 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line337 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line337 -// CHECK-NEXT: col17 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line337 -// CHECK-NEXT: col13 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line337 -// CHECK-NEXT: col16 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Reference count decremented. The object now has a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Reference count decremented. The object now has a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line337 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line337 -// CHECK-NEXT: col11 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line339 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line339 -// CHECK-NEXT: col11 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line339 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line339 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line339 -// CHECK-NEXT: col17 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line339 -// CHECK-NEXT: col13 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line339 -// CHECK-NEXT: col16 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object released -// CHECK-NEXT: message -// CHECK-NEXT: Object released -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line339 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line339 -// CHECK-NEXT: col11 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line340 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line340 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line340 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line340 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line340 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line340 -// CHECK-NEXT: col27 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line340 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line340 -// CHECK-NEXT: col29 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line340 -// CHECK-NEXT: col32 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Reference-counted object is used after it is released -// CHECK-NEXT: message -// CHECK-NEXT: Reference-counted object is used after it is released -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionReference-counted object is used after it is released -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeUse-after-release -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextf1 -// CHECK-NEXT: issue_hash7 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line340 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line345 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line345 -// CHECK-NEXT: col16 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line346 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line346 -// CHECK-NEXT: col11 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line346 -// CHECK-NEXT: col20 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line346 -// CHECK-NEXT: col20 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line346 -// CHECK-NEXT: col37 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Call to function 'CFDateCreate' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Call to function 'CFDateCreate' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line346 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line346 -// CHECK-NEXT: col11 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line347 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line347 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line347 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line347 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line347 -// CHECK-NEXT: col27 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line347 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line347 -// CHECK-NEXT: col19 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Reference count incremented. The object now has a +2 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Reference count incremented. The object now has a +2 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line347 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line347 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line348 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line348 -// CHECK-NEXT: col11 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line348 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line348 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line348 -// CHECK-NEXT: col17 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line348 -// CHECK-NEXT: col13 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line348 -// CHECK-NEXT: col16 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Reference count decremented. The object now has a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Reference count decremented. The object now has a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line348 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line348 -// CHECK-NEXT: col11 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line350 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line350 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line350 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line350 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line350 -// CHECK-NEXT: col28 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line350 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line350 -// CHECK-NEXT: col19 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object released -// CHECK-NEXT: message -// CHECK-NEXT: Object released -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line350 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line350 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line351 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line351 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line351 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line351 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line351 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line351 -// CHECK-NEXT: col27 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line351 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line351 -// CHECK-NEXT: col29 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line351 -// CHECK-NEXT: col32 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Reference-counted object is used after it is released -// CHECK-NEXT: message -// CHECK-NEXT: Reference-counted object is used after it is released -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionReference-counted object is used after it is released -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeUse-after-release -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextf2 -// CHECK-NEXT: issue_hash7 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line351 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line381 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line381 -// CHECK-NEXT: col16 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line382 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line382 -// CHECK-NEXT: col11 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line382 -// CHECK-NEXT: col20 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line382 -// CHECK-NEXT: col20 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line382 -// CHECK-NEXT: col37 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Call to function 'CFDateCreate' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Call to function 'CFDateCreate' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line382 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line382 -// CHECK-NEXT: col11 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line384 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line384 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line384 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line384 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line384 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line384 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line384 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line384 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line384 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Assuming 'x' is 0 -// CHECK-NEXT: message -// CHECK-NEXT: Assuming 'x' is 0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line384 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line384 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line387 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line387 -// CHECK-NEXT: col8 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line387 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line387 -// CHECK-NEXT: col8 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line387 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line387 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line387 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line387 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line387 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: object allocated and stored into 'date' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: object allocated and stored into 'date' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object stored into 'date' -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextf5 -// CHECK-NEXT: issue_hash2 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line387 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line393 -// CHECK-NEXT: col20 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line393 -// CHECK-NEXT: col20 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line393 -// CHECK-NEXT: col62 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Call to function 'CFDateCreate' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Call to function 'CFDateCreate' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line393 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line393 -// CHECK-NEXT: col11 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line394 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line394 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line394 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line394 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line394 -// CHECK-NEXT: col16 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line394 -// CHECK-NEXT: col12 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line394 -// CHECK-NEXT: col15 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Reference count incremented. The object now has a +2 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Reference count incremented. The object now has a +2 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line394 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line394 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line395 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line395 -// CHECK-NEXT: col8 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line395 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line395 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line395 -// CHECK-NEXT: col13 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line395 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line395 -// CHECK-NEXT: col13 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object returned to caller as an owning reference (single retain count transferred to caller) -// CHECK-NEXT: message -// CHECK-NEXT: Object returned to caller as an owning reference (single retain count transferred to caller) -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line395 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line395 -// CHECK-NEXT: col8 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line396 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line396 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line396 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: object allocated and stored into 'date' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: object allocated and stored into 'date' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object stored into 'date' -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextf6 -// CHECK-NEXT: issue_hash1 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line396 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line401 -// CHECK-NEXT: col20 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line401 -// CHECK-NEXT: col20 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line401 -// CHECK-NEXT: col62 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Call to function 'CFDateCreate' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Call to function 'CFDateCreate' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line401 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line401 -// CHECK-NEXT: col11 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line402 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line402 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line402 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line402 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line402 -// CHECK-NEXT: col16 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line402 -// CHECK-NEXT: col12 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line402 -// CHECK-NEXT: col15 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Reference count incremented. The object now has a +2 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Reference count incremented. The object now has a +2 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line402 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line402 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line404 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line404 -// CHECK-NEXT: col8 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line404 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line404 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line404 -// CHECK-NEXT: col13 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: object allocated and stored into 'date' is not referenced later in this execution path and has a retain count of +2 -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: object allocated and stored into 'date' is not referenced later in this execution path and has a retain count of +2 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object stored into 'date' -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextf7 -// CHECK-NEXT: issue_hash1 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line404 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line401 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line401 -// CHECK-NEXT: col11 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line403 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line403 -// CHECK-NEXT: col6 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line403 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line403 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line403 -// CHECK-NEXT: col52 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Call to function 'CFDateCreate' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Call to function 'CFDateCreate' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line403 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line403 -// CHECK-NEXT: col6 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line404 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line404 -// CHECK-NEXT: col8 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line404 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line404 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line404 -// CHECK-NEXT: col13 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line404 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line404 -// CHECK-NEXT: col13 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object returned to caller as an owning reference (single retain count transferred to caller) -// CHECK-NEXT: message -// CHECK-NEXT: Object returned to caller as an owning reference (single retain count transferred to caller) -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line404 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line404 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line404 -// CHECK-NEXT: col13 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: object allocated and stored into 'date' is returned from a function whose name ('f7') does not contain 'Copy' or 'Create'. This violates the naming convention rules given in the Memory Management Guide for Core Foundation -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: object allocated and stored into 'date' is returned from a function whose name ('f7') does not contain 'Copy' or 'Create'. This violates the naming convention rules given in the Memory Management Guide for Core Foundation -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object stored into 'date' -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak of returned object -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextf7 -// CHECK-NEXT: issue_hash3 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line404 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line412 -// CHECK-NEXT: col20 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line412 -// CHECK-NEXT: col20 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line412 -// CHECK-NEXT: col33 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Call to function 'MyDateCreate' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Call to function 'MyDateCreate' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line412 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line412 -// CHECK-NEXT: col11 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line413 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line413 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line413 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line413 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line413 -// CHECK-NEXT: col16 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line413 -// CHECK-NEXT: col12 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line413 -// CHECK-NEXT: col15 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Reference count incremented. The object now has a +2 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Reference count incremented. The object now has a +2 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line413 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line413 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line414 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line414 -// CHECK-NEXT: col8 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line414 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line414 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line414 -// CHECK-NEXT: col13 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line414 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line414 -// CHECK-NEXT: col13 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object returned to caller as an owning reference (single retain count transferred to caller) -// CHECK-NEXT: message -// CHECK-NEXT: Object returned to caller as an owning reference (single retain count transferred to caller) -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line414 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line414 -// CHECK-NEXT: col8 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line415 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line415 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line415 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: object allocated and stored into 'date' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: object allocated and stored into 'date' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object stored into 'date' -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextf8 -// CHECK-NEXT: issue_hash1 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line415 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line418 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line418 -// CHECK-NEXT: col11 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line419 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line419 -// CHECK-NEXT: col5 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line419 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line419 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line419 -// CHECK-NEXT: col8 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: 'p' initialized to a null pointer value -// CHECK-NEXT: message -// CHECK-NEXT: 'p' initialized to a null pointer value -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line419 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line419 -// CHECK-NEXT: col5 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line421 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line421 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line421 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line421 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line421 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line421 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line421 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line421 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line421 -// CHECK-NEXT: col11 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Assuming 'date' is null -// CHECK-NEXT: message -// CHECK-NEXT: Assuming 'date' is null -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line421 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line421 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line421 -// CHECK-NEXT: col14 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line421 -// CHECK-NEXT: col14 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line421 -// CHECK-NEXT: col14 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line421 -// CHECK-NEXT: col14 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line421 -// CHECK-NEXT: col17 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line421 -// CHECK-NEXT: col17 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line421 -// CHECK-NEXT: col17 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line421 -// CHECK-NEXT: col15 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line421 -// CHECK-NEXT: col15 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Dereference of null pointer (loaded from variable 'p') -// CHECK-NEXT: message -// CHECK-NEXT: Dereference of null pointer (loaded from variable 'p') -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionDereference of null pointer (loaded from variable 'p') -// CHECK-NEXT: categoryLogic error -// CHECK-NEXT: typeDereference of null pointer -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextf9 -// CHECK-NEXT: issue_hash4 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line421 -// CHECK-NEXT: col17 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line430 -// CHECK-NEXT: col20 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line430 -// CHECK-NEXT: col20 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line430 -// CHECK-NEXT: col75 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Call to function 'DADiskCreateFromBSDName' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Call to function 'DADiskCreateFromBSDName' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line430 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line430 -// CHECK-NEXT: col11 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Assuming 'disk' is non-null -// CHECK-NEXT: message -// CHECK-NEXT: Assuming 'disk' is non-null -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col13 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col17 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col13 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col17 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line433 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line433 -// CHECK-NEXT: col6 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line433 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line433 -// CHECK-NEXT: col6 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Assuming 'disk' is null -// CHECK-NEXT: message -// CHECK-NEXT: Assuming 'disk' is null -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line436 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line436 -// CHECK-NEXT: col17 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line436 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line436 -// CHECK-NEXT: col17 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line436 -// CHECK-NEXT: col26 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line436 -// CHECK-NEXT: col46 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line436 -// CHECK-NEXT: col26 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line436 -// CHECK-NEXT: col26 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line436 -// CHECK-NEXT: col46 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: object allocated and stored into 'disk' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: object allocated and stored into 'disk' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object stored into 'disk' -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextf10 -// CHECK-NEXT: issue_hash1 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line436 -// CHECK-NEXT: col26 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line430 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line430 -// CHECK-NEXT: col11 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Assuming 'disk' is null -// CHECK-NEXT: message -// CHECK-NEXT: Assuming 'disk' is null -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line433 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line433 -// CHECK-NEXT: col6 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line433 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line433 -// CHECK-NEXT: col6 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Assuming 'disk' is null -// CHECK-NEXT: message -// CHECK-NEXT: Assuming 'disk' is null -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line436 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line436 -// CHECK-NEXT: col17 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line436 -// CHECK-NEXT: col26 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line436 -// CHECK-NEXT: col26 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line436 -// CHECK-NEXT: col49 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Call to function 'DADiskCopyDescription' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Call to function 'DADiskCopyDescription' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line436 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line436 -// CHECK-NEXT: col17 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line437 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line437 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line437 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line437 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line437 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line437 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line437 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line437 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line437 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Assuming 'dict' is non-null -// CHECK-NEXT: message -// CHECK-NEXT: Assuming 'dict' is non-null -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line437 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line437 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line437 -// CHECK-NEXT: col13 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line437 -// CHECK-NEXT: col17 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line437 -// CHECK-NEXT: col13 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line437 -// CHECK-NEXT: col13 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line437 -// CHECK-NEXT: col17 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: object allocated and stored into 'dict' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: object allocated and stored into 'dict' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object stored into 'dict' -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextf10 -// CHECK-NEXT: issue_hash7 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line437 -// CHECK-NEXT: col13 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line430 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line430 -// CHECK-NEXT: col11 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Assuming 'disk' is null -// CHECK-NEXT: message -// CHECK-NEXT: Assuming 'disk' is null -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line433 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line433 -// CHECK-NEXT: col6 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line433 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line433 -// CHECK-NEXT: col6 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Assuming 'disk' is null -// CHECK-NEXT: message -// CHECK-NEXT: Assuming 'disk' is null -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line436 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line436 -// CHECK-NEXT: col17 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line436 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line436 -// CHECK-NEXT: col17 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line437 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line437 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line437 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line437 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line437 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line437 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line437 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line437 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line437 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Assuming 'dict' is null -// CHECK-NEXT: message -// CHECK-NEXT: Assuming 'dict' is null -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line437 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line437 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line439 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line439 -// CHECK-NEXT: col6 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line439 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line439 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line439 -// CHECK-NEXT: col31 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Call to function 'DADiskCopyWholeDisk' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Call to function 'DADiskCopyWholeDisk' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line439 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line439 -// CHECK-NEXT: col6 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line440 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line440 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line440 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line440 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line440 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line440 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line440 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line440 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line440 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Assuming 'disk' is non-null -// CHECK-NEXT: message -// CHECK-NEXT: Assuming 'disk' is non-null -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line440 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line440 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line440 -// CHECK-NEXT: col13 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line440 -// CHECK-NEXT: col17 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line440 -// CHECK-NEXT: col13 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line440 -// CHECK-NEXT: col13 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line440 -// CHECK-NEXT: col17 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: object allocated and stored into 'disk' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: object allocated and stored into 'disk' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object stored into 'disk' -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextf10 -// CHECK-NEXT: issue_hash10 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line440 -// CHECK-NEXT: col13 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line430 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line430 -// CHECK-NEXT: col11 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Assuming 'disk' is null -// CHECK-NEXT: message -// CHECK-NEXT: Assuming 'disk' is null -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line433 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line433 -// CHECK-NEXT: col6 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line433 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line433 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line433 -// CHECK-NEXT: col63 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Call to function 'DADiskCreateFromIOMedia' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Call to function 'DADiskCreateFromIOMedia' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line433 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line433 -// CHECK-NEXT: col6 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Assuming 'disk' is non-null -// CHECK-NEXT: message -// CHECK-NEXT: Assuming 'disk' is non-null -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col13 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col17 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col13 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col17 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line436 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line436 -// CHECK-NEXT: col17 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line436 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line436 -// CHECK-NEXT: col17 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line437 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line437 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line437 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line437 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line437 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line437 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line437 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line437 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line437 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Assuming 'dict' is null -// CHECK-NEXT: message -// CHECK-NEXT: Assuming 'dict' is null -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line437 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line437 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line439 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line439 -// CHECK-NEXT: col6 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line439 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line439 -// CHECK-NEXT: col6 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line440 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line440 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line440 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line440 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line440 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line440 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line440 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line440 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line440 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Assuming 'disk' is null -// CHECK-NEXT: message -// CHECK-NEXT: Assuming 'disk' is null -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line440 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line440 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line442 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line442 -// CHECK-NEXT: col16 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line442 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line442 -// CHECK-NEXT: col16 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line442 -// CHECK-NEXT: col30 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line442 -// CHECK-NEXT: col46 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line442 -// CHECK-NEXT: col30 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line442 -// CHECK-NEXT: col30 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line442 -// CHECK-NEXT: col46 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: object allocated and stored into 'disk' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: object allocated and stored into 'disk' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object stored into 'disk' -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextf10 -// CHECK-NEXT: issue_hash4 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line442 -// CHECK-NEXT: col30 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line430 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line430 -// CHECK-NEXT: col11 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Assuming 'disk' is null -// CHECK-NEXT: message -// CHECK-NEXT: Assuming 'disk' is null -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line433 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line433 -// CHECK-NEXT: col6 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line433 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line433 -// CHECK-NEXT: col6 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Assuming 'disk' is null -// CHECK-NEXT: message -// CHECK-NEXT: Assuming 'disk' is null -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line436 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line436 -// CHECK-NEXT: col17 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line436 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line436 -// CHECK-NEXT: col17 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line437 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line437 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line437 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line437 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line437 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line437 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line437 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line437 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line437 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Assuming 'dict' is null -// CHECK-NEXT: message -// CHECK-NEXT: Assuming 'dict' is null -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line437 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line437 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line439 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line439 -// CHECK-NEXT: col6 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line439 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line439 -// CHECK-NEXT: col6 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line440 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line440 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line440 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line440 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line440 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line440 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line440 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line440 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line440 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Assuming 'disk' is null -// CHECK-NEXT: message -// CHECK-NEXT: Assuming 'disk' is null -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line440 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line440 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line442 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line442 -// CHECK-NEXT: col16 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line442 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line442 -// CHECK-NEXT: col16 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line442 -// CHECK-NEXT: col30 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line442 -// CHECK-NEXT: col46 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line442 -// CHECK-NEXT: col30 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line442 -// CHECK-NEXT: col30 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line443 -// CHECK-NEXT: col68 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Call to function 'DADissenterCreate' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Call to function 'DADissenterCreate' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line442 -// CHECK-NEXT: col30 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line442 -// CHECK-NEXT: col46 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line442 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line442 -// CHECK-NEXT: col16 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line442 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line442 -// CHECK-NEXT: col16 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line444 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line444 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line444 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line444 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line444 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line444 -// CHECK-NEXT: col15 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line444 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line444 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line444 -// CHECK-NEXT: col15 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Assuming 'dissenter' is non-null -// CHECK-NEXT: message -// CHECK-NEXT: Assuming 'dissenter' is non-null -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line444 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line444 -// CHECK-NEXT: col15 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line444 -// CHECK-NEXT: col18 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line444 -// CHECK-NEXT: col22 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line444 -// CHECK-NEXT: col18 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line444 -// CHECK-NEXT: col18 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line444 -// CHECK-NEXT: col22 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: object allocated and stored into 'dissenter' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: object allocated and stored into 'dissenter' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object stored into 'dissenter' -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextf10 -// CHECK-NEXT: issue_hash13 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line444 -// CHECK-NEXT: col18 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line430 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line430 -// CHECK-NEXT: col11 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Assuming 'disk' is null -// CHECK-NEXT: message -// CHECK-NEXT: Assuming 'disk' is null -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line431 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line433 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line433 -// CHECK-NEXT: col6 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line433 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line433 -// CHECK-NEXT: col6 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Assuming 'disk' is null -// CHECK-NEXT: message -// CHECK-NEXT: Assuming 'disk' is null -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line434 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line436 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line436 -// CHECK-NEXT: col17 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line436 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line436 -// CHECK-NEXT: col17 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line437 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line437 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line437 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line437 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line437 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line437 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line437 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line437 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line437 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Assuming 'dict' is null -// CHECK-NEXT: message -// CHECK-NEXT: Assuming 'dict' is null -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line437 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line437 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line439 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line439 -// CHECK-NEXT: col6 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line439 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line439 -// CHECK-NEXT: col6 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line440 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line440 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line440 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line440 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line440 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line440 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line440 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line440 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line440 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Assuming 'disk' is null -// CHECK-NEXT: message -// CHECK-NEXT: Assuming 'disk' is null -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line440 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line440 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line442 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line442 -// CHECK-NEXT: col16 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line442 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line442 -// CHECK-NEXT: col16 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line444 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line444 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line444 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line444 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line444 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line444 -// CHECK-NEXT: col15 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line444 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line444 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line444 -// CHECK-NEXT: col15 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Assuming 'dissenter' is null -// CHECK-NEXT: message -// CHECK-NEXT: Assuming 'dissenter' is null -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line444 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line444 -// CHECK-NEXT: col15 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line446 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line446 -// CHECK-NEXT: col14 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line446 -// CHECK-NEXT: col26 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line446 -// CHECK-NEXT: col26 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line446 -// CHECK-NEXT: col61 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Call to function 'DASessionCreate' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Call to function 'DASessionCreate' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line446 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line446 -// CHECK-NEXT: col14 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line447 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line447 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line447 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line447 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line447 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line447 -// CHECK-NEXT: col13 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line447 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line447 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line447 -// CHECK-NEXT: col13 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Assuming 'session' is non-null -// CHECK-NEXT: message -// CHECK-NEXT: Assuming 'session' is non-null -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line447 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line447 -// CHECK-NEXT: col13 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line447 -// CHECK-NEXT: col16 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line447 -// CHECK-NEXT: col20 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line447 -// CHECK-NEXT: col16 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line447 -// CHECK-NEXT: col16 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line447 -// CHECK-NEXT: col20 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: object allocated and stored into 'session' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: object allocated and stored into 'session' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object stored into 'session' -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextf10 -// CHECK-NEXT: issue_hash17 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line447 -// CHECK-NEXT: col16 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line453 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line453 -// CHECK-NEXT: col19 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line466 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line466 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line466 -// CHECK-NEXT: col22 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line466 -// CHECK-NEXT: col22 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line466 -// CHECK-NEXT: col49 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Call to function 'CFArrayGetValueAtIndex' returns a Core Foundation object with a +0 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Call to function 'CFArrayGetValueAtIndex' returns a Core Foundation object with a +0 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line466 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line466 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line472 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line472 -// CHECK-NEXT: col11 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line472 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line472 -// CHECK-NEXT: col13 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line472 -// CHECK-NEXT: col14 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Incorrect decrement of the reference count of an object that is not owned at this point by the caller -// CHECK-NEXT: message -// CHECK-NEXT: Incorrect decrement of the reference count of an object that is not owned at this point by the caller -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionIncorrect decrement of the reference count of an object that is not owned at this point by the caller -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeBad release -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextf11 -// CHECK-NEXT: issue_hash21 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line472 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line480 -// CHECK-NEXT: col17 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line480 -// CHECK-NEXT: col17 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line480 -// CHECK-NEXT: col29 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Call to function 'MyCreateFun' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Call to function 'MyCreateFun' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line480 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line480 -// CHECK-NEXT: col11 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line481 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line481 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line481 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: object allocated and stored into 'o' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: object allocated and stored into 'o' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object stored into 'o' -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextf12 -// CHECK-NEXT: issue_hash1 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line481 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line489 -// CHECK-NEXT: col25 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line489 -// CHECK-NEXT: col25 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line489 -// CHECK-NEXT: col75 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Call to function 'CFArrayCreateMutable' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Call to function 'CFArrayCreateMutable' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line489 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line489 -// CHECK-NEXT: col19 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line490 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line490 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line490 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line490 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line490 -// CHECK-NEXT: col22 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line490 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line490 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object autoreleased -// CHECK-NEXT: message -// CHECK-NEXT: Object autoreleased -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line490 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line490 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line491 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line491 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line491 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line491 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line491 -// CHECK-NEXT: col22 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line491 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line491 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object autoreleased -// CHECK-NEXT: message -// CHECK-NEXT: Object autoreleased -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line491 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line491 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line492 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line492 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line492 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object was autoreleased 2 times but the object has a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Object was autoreleased 2 times but the object has a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionObject autoreleased too many times -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeObject autoreleased too many times -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextf13_autorelease_b -// CHECK-NEXT: issue_hash4 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line492 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line495 -// CHECK-NEXT: col25 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line495 -// CHECK-NEXT: col25 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line495 -// CHECK-NEXT: col75 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Call to function 'CFArrayCreateMutable' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Call to function 'CFArrayCreateMutable' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line495 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line495 -// CHECK-NEXT: col19 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line496 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line496 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line496 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line496 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line496 -// CHECK-NEXT: col22 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line496 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line496 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object autoreleased -// CHECK-NEXT: message -// CHECK-NEXT: Object autoreleased -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line496 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line496 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line497 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line497 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line497 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line497 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line497 -// CHECK-NEXT: col22 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line497 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line497 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object autoreleased -// CHECK-NEXT: message -// CHECK-NEXT: Object autoreleased -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line497 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line497 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line498 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line498 -// CHECK-NEXT: col8 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line498 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line498 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line498 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object was autoreleased 2 times but the object has a +0 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Object was autoreleased 2 times but the object has a +0 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionObject autoreleased too many times -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeObject autoreleased too many times -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextf13_autorelease_c -// CHECK-NEXT: issue_hash4 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line498 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line502 -// CHECK-NEXT: col25 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line502 -// CHECK-NEXT: col25 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line502 -// CHECK-NEXT: col75 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Call to function 'CFArrayCreateMutable' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Call to function 'CFArrayCreateMutable' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line502 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line502 -// CHECK-NEXT: col19 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line503 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line503 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line503 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line503 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line503 -// CHECK-NEXT: col22 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line503 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line503 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object autoreleased -// CHECK-NEXT: message -// CHECK-NEXT: Object autoreleased -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line503 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line503 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line504 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line504 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line504 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line504 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line504 -// CHECK-NEXT: col22 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line504 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line504 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object autoreleased -// CHECK-NEXT: message -// CHECK-NEXT: Object autoreleased -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line504 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line504 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line505 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line505 -// CHECK-NEXT: col19 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line505 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line505 -// CHECK-NEXT: col19 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line505 -// CHECK-NEXT: col25 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line505 -// CHECK-NEXT: col44 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line505 -// CHECK-NEXT: col25 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line505 -// CHECK-NEXT: col25 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line505 -// CHECK-NEXT: col75 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object was autoreleased 2 times but the object has a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Object was autoreleased 2 times but the object has a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionObject autoreleased too many times -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeObject autoreleased too many times -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextf13_autorelease_d -// CHECK-NEXT: issue_hash4 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line505 -// CHECK-NEXT: col25 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line513 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line513 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line513 -// CHECK-NEXT: col53 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Call to function 'CFArrayCreateMutable' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Call to function 'CFArrayCreateMutable' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line513 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line513 -// CHECK-NEXT: col22 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line514 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line514 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line514 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextf14_leakimmediately -// CHECK-NEXT: issue_hash1 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line514 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line528 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line528 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line528 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line528 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line528 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line528 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line528 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Assuming 'p' is null -// CHECK-NEXT: message -// CHECK-NEXT: Assuming 'p' is null -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line528 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line528 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line531 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line531 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line531 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line531 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line531 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line531 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line531 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line531 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line531 -// CHECK-NEXT: col11 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Assuming 'x' is > 0 -// CHECK-NEXT: message -// CHECK-NEXT: Assuming 'x' is > 0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line531 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line531 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line532 -// CHECK-NEXT: col5 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line532 -// CHECK-NEXT: col13 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line532 -// CHECK-NEXT: col5 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line532 -// CHECK-NEXT: col15 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line532 -// CHECK-NEXT: col15 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Null pointer argument in call to CFRelease -// CHECK-NEXT: message -// CHECK-NEXT: Null pointer argument in call to CFRelease -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionNull pointer argument in call to CFRelease -// CHECK-NEXT: categoryAPI Misuse (Apple) -// CHECK-NEXT: typenull passed to CF memory management function -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextf16 -// CHECK-NEXT: issue_hash5 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line532 -// CHECK-NEXT: col5 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line528 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line528 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line528 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line528 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line528 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line528 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line528 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Assuming 'p' is null -// CHECK-NEXT: message -// CHECK-NEXT: Assuming 'p' is null -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line528 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line528 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line531 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line531 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line531 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line531 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line531 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line531 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line531 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line531 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line531 -// CHECK-NEXT: col11 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Assuming 'x' is <= 0 -// CHECK-NEXT: message -// CHECK-NEXT: Assuming 'x' is <= 0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line531 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line531 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line534 -// CHECK-NEXT: col8 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line534 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line534 -// CHECK-NEXT: col8 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line534 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line534 -// CHECK-NEXT: col12 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line534 -// CHECK-NEXT: col12 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line534 -// CHECK-NEXT: col12 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line534 -// CHECK-NEXT: col12 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line534 -// CHECK-NEXT: col16 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Assuming 'x' is < 0 -// CHECK-NEXT: message -// CHECK-NEXT: Assuming 'x' is < 0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line534 -// CHECK-NEXT: col12 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line534 -// CHECK-NEXT: col12 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line535 -// CHECK-NEXT: col5 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line535 -// CHECK-NEXT: col12 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line535 -// CHECK-NEXT: col5 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line535 -// CHECK-NEXT: col14 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line535 -// CHECK-NEXT: col14 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Null pointer argument in call to CFRetain -// CHECK-NEXT: message -// CHECK-NEXT: Null pointer argument in call to CFRetain -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionNull pointer argument in call to CFRetain -// CHECK-NEXT: categoryAPI Misuse (Apple) -// CHECK-NEXT: typenull passed to CF memory management function -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextf16 -// CHECK-NEXT: issue_hash8 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line535 -// CHECK-NEXT: col5 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line528 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line528 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line528 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line528 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line528 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line528 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line528 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Assuming 'p' is null -// CHECK-NEXT: message -// CHECK-NEXT: Assuming 'p' is null -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line528 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line528 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line531 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line531 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line531 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line531 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line531 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line531 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line531 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line531 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line531 -// CHECK-NEXT: col11 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Assuming 'x' is <= 0 -// CHECK-NEXT: message -// CHECK-NEXT: Assuming 'x' is <= 0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line531 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line531 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line534 -// CHECK-NEXT: col8 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line534 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line534 -// CHECK-NEXT: col8 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line534 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line534 -// CHECK-NEXT: col12 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line534 -// CHECK-NEXT: col12 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line534 -// CHECK-NEXT: col12 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line534 -// CHECK-NEXT: col12 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line534 -// CHECK-NEXT: col16 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Assuming 'x' is >= 0 -// CHECK-NEXT: message -// CHECK-NEXT: Assuming 'x' is >= 0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line534 -// CHECK-NEXT: col12 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line534 -// CHECK-NEXT: col12 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line538 -// CHECK-NEXT: col5 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line538 -// CHECK-NEXT: col21 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line538 -// CHECK-NEXT: col5 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line538 -// CHECK-NEXT: col23 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line538 -// CHECK-NEXT: col23 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Null pointer argument in call to CFMakeCollectable -// CHECK-NEXT: message -// CHECK-NEXT: Null pointer argument in call to CFMakeCollectable -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionNull pointer argument in call to CFMakeCollectable -// CHECK-NEXT: categoryAPI Misuse (Apple) -// CHECK-NEXT: typenull passed to CF memory management function -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextf16 -// CHECK-NEXT: issue_hash11 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line538 -// CHECK-NEXT: col5 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line584 -// CHECK-NEXT: col17 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line584 -// CHECK-NEXT: col17 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line584 -// CHECK-NEXT: col55 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Method returns an Objective-C object with a +0 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Method returns an Objective-C object with a +0 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line584 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line584 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line585 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line585 -// CHECK-NEXT: col8 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line585 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line585 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line585 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line585 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line585 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object returned to caller with a +0 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Object returned to caller with a +0 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line585 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line585 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line585 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected -// CHECK-NEXT: message -// CHECK-NEXT: Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionObject with a +0 retain count returned to caller where a +1 (owning) retain count is expected -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeMethod should return an owned object -// CHECK-NEXT: issue_context_kindObjective-C method -// CHECK-NEXT: issue_contextnewString -// CHECK-NEXT: issue_hash2 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line585 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line598 -// CHECK-NEXT: col20 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line598 -// CHECK-NEXT: col20 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line598 -// CHECK-NEXT: col63 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Method returns an Objective-C object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Method returns an Objective-C object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line598 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line598 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line605 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line605 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line605 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line605 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line605 -// CHECK-NEXT: col6 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line605 -// CHECK-NEXT: col6 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line605 -// CHECK-NEXT: col6 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line605 -// CHECK-NEXT: col6 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line605 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Assuming 'name' is nil -// CHECK-NEXT: message -// CHECK-NEXT: Assuming 'name' is nil -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line605 -// CHECK-NEXT: col6 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line605 -// CHECK-NEXT: col6 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line606 -// CHECK-NEXT: col5 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line606 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line606 -// CHECK-NEXT: col5 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line606 -// CHECK-NEXT: col5 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line606 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: object allocated and stored into 'kind' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: object allocated and stored into 'kind' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object stored into 'kind' -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextrdar_6659160 -// CHECK-NEXT: issue_hash5 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line606 -// CHECK-NEXT: col5 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line598 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line598 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line605 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line605 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line605 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line605 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line605 -// CHECK-NEXT: col6 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line605 -// CHECK-NEXT: col6 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line605 -// CHECK-NEXT: col6 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line605 -// CHECK-NEXT: col6 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line605 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Assuming 'name' is non-nil -// CHECK-NEXT: message -// CHECK-NEXT: Assuming 'name' is non-nil -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line605 -// CHECK-NEXT: col6 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line605 -// CHECK-NEXT: col6 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line608 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line608 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line608 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line608 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line608 -// CHECK-NEXT: col19 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: 'kindC' initialized to a null pointer value -// CHECK-NEXT: message -// CHECK-NEXT: 'kindC' initialized to a null pointer value -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line608 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line608 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line616 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line616 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line616 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line616 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line616 -// CHECK-NEXT: col6 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line616 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line616 -// CHECK-NEXT: col6 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line616 -// CHECK-NEXT: col6 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line616 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Assuming 'kind' is nil -// CHECK-NEXT: message -// CHECK-NEXT: Assuming 'kind' is nil -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line616 -// CHECK-NEXT: col6 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line616 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line618 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line618 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line618 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line618 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line619 -// CHECK-NEXT: col5 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line619 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line619 -// CHECK-NEXT: col5 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line619 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line620 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line620 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line620 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line620 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line620 -// CHECK-NEXT: col13 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line620 -// CHECK-NEXT: col17 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line620 -// CHECK-NEXT: col13 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line620 -// CHECK-NEXT: col13 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line620 -// CHECK-NEXT: col17 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Array access (from variable 'kindC') results in a null pointer dereference -// CHECK-NEXT: message -// CHECK-NEXT: Array access (from variable 'kindC') results in a null pointer dereference -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionArray access (from variable 'kindC') results in a null pointer dereference -// CHECK-NEXT: categoryLogic error -// CHECK-NEXT: typeDereference of null pointer -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextrdar_6659160 -// CHECK-NEXT: issue_hash27 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line620 -// CHECK-NEXT: col13 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line598 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line598 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line604 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line604 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line604 -// CHECK-NEXT: col20 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line604 -// CHECK-NEXT: col20 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line604 -// CHECK-NEXT: col57 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Method returns an Objective-C object with a +0 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Method returns an Objective-C object with a +0 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line604 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line604 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line605 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line605 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line605 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line605 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line605 -// CHECK-NEXT: col6 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line605 -// CHECK-NEXT: col6 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line605 -// CHECK-NEXT: col6 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line605 -// CHECK-NEXT: col6 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line605 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Assuming 'name' is non-nil -// CHECK-NEXT: message -// CHECK-NEXT: Assuming 'name' is non-nil -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line605 -// CHECK-NEXT: col6 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line605 -// CHECK-NEXT: col6 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line608 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line608 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line608 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line608 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line616 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line616 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line616 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line616 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line616 -// CHECK-NEXT: col6 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line616 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line616 -// CHECK-NEXT: col6 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line616 -// CHECK-NEXT: col6 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line616 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Assuming 'kind' is non-nil -// CHECK-NEXT: message -// CHECK-NEXT: Assuming 'kind' is non-nil -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line616 -// CHECK-NEXT: col6 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line616 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line617 -// CHECK-NEXT: col5 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line617 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line617 -// CHECK-NEXT: col5 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line617 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line618 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line618 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line618 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line618 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line619 -// CHECK-NEXT: col5 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line619 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line619 -// CHECK-NEXT: col5 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line619 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line620 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line620 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line620 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line620 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line622 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line622 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line622 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line622 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line625 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line625 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line625 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line625 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line626 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line626 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line626 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line626 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line626 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Incorrect decrement of the reference count of an object that is not owned at this point by the caller -// CHECK-NEXT: message -// CHECK-NEXT: Incorrect decrement of the reference count of an object that is not owned at this point by the caller -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionIncorrect decrement of the reference count of an object that is not owned at this point by the caller -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeBad release -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextrdar_6659160 -// CHECK-NEXT: issue_hash33 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line626 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line648 -// CHECK-NEXT: col12 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line648 -// CHECK-NEXT: col12 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line648 -// CHECK-NEXT: col34 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Method returns an Objective-C object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Method returns an Objective-C object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line648 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line648 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line649 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line649 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line649 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line649 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line649 -// CHECK-NEXT: col15 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line649 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line649 -// CHECK-NEXT: col6 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object released by directly sending the '-dealloc' message -// CHECK-NEXT: message -// CHECK-NEXT: Object released by directly sending the '-dealloc' message -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line649 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line649 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line650 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line650 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line650 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line650 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line650 -// CHECK-NEXT: col6 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Reference-counted object is used after it is released -// CHECK-NEXT: message -// CHECK-NEXT: Reference-counted object is used after it is released -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionReference-counted object is used after it is released -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeUse-after-release -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextpr3820_ReleaseAfterDealloc -// CHECK-NEXT: issue_hash3 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line650 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line656 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line656 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line657 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line657 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line657 -// CHECK-NEXT: col12 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line657 -// CHECK-NEXT: col12 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line657 -// CHECK-NEXT: col34 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Method returns an Objective-C object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Method returns an Objective-C object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line657 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line657 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line658 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line658 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line658 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line658 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line658 -// CHECK-NEXT: col15 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line658 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line658 -// CHECK-NEXT: col6 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object released -// CHECK-NEXT: message -// CHECK-NEXT: Object released -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line658 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line658 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line659 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line659 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line659 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line659 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line659 -// CHECK-NEXT: col6 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Reference-counted object is used after it is released -// CHECK-NEXT: message -// CHECK-NEXT: Reference-counted object is used after it is released -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionReference-counted object is used after it is released -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeUse-after-release -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextpr3820_DeallocAfterRelease -// CHECK-NEXT: issue_hash4 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line659 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line711 -// CHECK-NEXT: col2 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line711 -// CHECK-NEXT: col20 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line711 -// CHECK-NEXT: col31 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line711 -// CHECK-NEXT: col31 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line711 -// CHECK-NEXT: col31 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line711 -// CHECK-NEXT: col31 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line711 -// CHECK-NEXT: col76 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Method returns an Objective-C object with a +0 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Method returns an Objective-C object with a +0 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line711 -// CHECK-NEXT: col30 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line711 -// CHECK-NEXT: col30 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line711 -// CHECK-NEXT: col84 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line711 -// CHECK-NEXT: col31 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line711 -// CHECK-NEXT: col76 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Reference count incremented. The object now has a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Reference count incremented. The object now has a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line711 -// CHECK-NEXT: col30 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line711 -// CHECK-NEXT: col30 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line711 -// CHECK-NEXT: col2 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line711 -// CHECK-NEXT: col20 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line711 -// CHECK-NEXT: col2 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line711 -// CHECK-NEXT: col20 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line715 -// CHECK-NEXT: col2 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line715 -// CHECK-NEXT: col6 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line715 -// CHECK-NEXT: col2 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line715 -// CHECK-NEXT: col6 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line716 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line716 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line716 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: object allocated and stored into 'dict' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: object allocated and stored into 'dict' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object stored into 'dict' -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak -// CHECK-NEXT: issue_context_kindObjective-C method -// CHECK-NEXT: issue_contextapplicationDidFinishLaunching: -// CHECK-NEXT: issue_hash1 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line716 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line723 -// CHECK-NEXT: col2 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line723 -// CHECK-NEXT: col20 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line723 -// CHECK-NEXT: col31 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line723 -// CHECK-NEXT: col31 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line723 -// CHECK-NEXT: col31 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line723 -// CHECK-NEXT: col31 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line723 -// CHECK-NEXT: col76 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Method returns an Objective-C object with a +0 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Method returns an Objective-C object with a +0 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line723 -// CHECK-NEXT: col30 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line723 -// CHECK-NEXT: col30 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line723 -// CHECK-NEXT: col84 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line723 -// CHECK-NEXT: col31 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line723 -// CHECK-NEXT: col76 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Reference count incremented. The object now has a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Reference count incremented. The object now has a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line723 -// CHECK-NEXT: col30 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line723 -// CHECK-NEXT: col30 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line723 -// CHECK-NEXT: col2 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line723 -// CHECK-NEXT: col20 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line723 -// CHECK-NEXT: col2 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line723 -// CHECK-NEXT: col20 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line724 -// CHECK-NEXT: col2 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line724 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line724 -// CHECK-NEXT: col2 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line724 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line724 -// CHECK-NEXT: col6 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line724 -// CHECK-NEXT: col11 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line724 -// CHECK-NEXT: col6 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line724 -// CHECK-NEXT: col11 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line726 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line726 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line726 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: object allocated and stored into 'dict' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: object allocated and stored into 'dict' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object stored into 'dict' -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak -// CHECK-NEXT: issue_context_kindObjective-C method -// CHECK-NEXT: issue_contextradar10102244 -// CHECK-NEXT: issue_hash1 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line726 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line734 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line734 -// CHECK-NEXT: col19 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line735 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line735 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line735 -// CHECK-NEXT: col20 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line735 -// CHECK-NEXT: col20 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line735 -// CHECK-NEXT: col34 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Method returns an Objective-C object with a +0 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Method returns an Objective-C object with a +0 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line735 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line735 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line736 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line736 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line736 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line736 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line736 -// CHECK-NEXT: col8 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Incorrect decrement of the reference count of an object that is not owned at this point by the caller -// CHECK-NEXT: message -// CHECK-NEXT: Incorrect decrement of the reference count of an object that is not owned at this point by the caller -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionIncorrect decrement of the reference count of an object that is not owned at this point by the caller -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeBad release -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextrdar_6257780_Case1 -// CHECK-NEXT: issue_hash3 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line736 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line811 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line811 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line812 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line812 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line812 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line812 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line812 -// CHECK-NEXT: col36 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Method returns an Objective-C object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Method returns an Objective-C object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line812 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line812 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line813 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line813 -// CHECK-NEXT: col8 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line813 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line813 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line813 -// CHECK-NEXT: col13 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak -// CHECK-NEXT: issue_context_kindObjective-C method -// CHECK-NEXT: issue_context_initReturningNewClassBad -// CHECK-NEXT: issue_hash2 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line813 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line816 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line816 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line817 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line817 -// CHECK-NEXT: col6 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line817 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line817 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line817 -// CHECK-NEXT: col43 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Method returns an Objective-C object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Method returns an Objective-C object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line817 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line817 -// CHECK-NEXT: col6 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line818 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line818 -// CHECK-NEXT: col8 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line818 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line818 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line818 -// CHECK-NEXT: col27 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line818 -// CHECK-NEXT: col11 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line818 -// CHECK-NEXT: col14 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object autoreleased -// CHECK-NEXT: message -// CHECK-NEXT: Object autoreleased -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line818 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line818 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line818 -// CHECK-NEXT: col27 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected -// CHECK-NEXT: message -// CHECK-NEXT: Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionObject with a +0 retain count returned to caller where a +1 (owning) retain count is expected -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeMethod should return an owned object -// CHECK-NEXT: issue_context_kindObjective-C method -// CHECK-NEXT: issue_contextinitReturningNewClassBad2 -// CHECK-NEXT: issue_hash3 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line818 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line856 -// CHECK-NEXT: col37 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line856 -// CHECK-NEXT: col37 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line856 -// CHECK-NEXT: col59 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Method returns an Objective-C object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Method returns an Objective-C object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line856 -// CHECK-NEXT: col30 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line856 -// CHECK-NEXT: col30 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line856 -// CHECK-NEXT: col59 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line856 -// CHECK-NEXT: col37 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line856 -// CHECK-NEXT: col59 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object returned to caller as an owning reference (single retain count transferred to caller) -// CHECK-NEXT: message -// CHECK-NEXT: Object returned to caller as an owning reference (single retain count transferred to caller) -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line856 -// CHECK-NEXT: col30 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line856 -// CHECK-NEXT: col30 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line856 -// CHECK-NEXT: col59 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: allocated object is returned from a method whose name ('NoCopyString') does not start with 'copy', 'mutableCopy', 'alloc' or 'new'. This violates the naming convention rules given in the Memory Management Guide for Cocoa -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: allocated object is returned from a method whose name ('NoCopyString') does not start with 'copy', 'mutableCopy', 'alloc' or 'new'. This violates the naming convention rules given in the Memory Management Guide for Cocoa -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak of returned object -// CHECK-NEXT: issue_context_kindObjective-C method -// CHECK-NEXT: issue_contextNoCopyString -// CHECK-NEXT: issue_hash0 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line856 -// CHECK-NEXT: col30 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line857 -// CHECK-NEXT: col37 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line857 -// CHECK-NEXT: col37 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line857 -// CHECK-NEXT: col59 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Method returns an Objective-C object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Method returns an Objective-C object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line857 -// CHECK-NEXT: col30 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line857 -// CHECK-NEXT: col30 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line857 -// CHECK-NEXT: col59 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line857 -// CHECK-NEXT: col37 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line857 -// CHECK-NEXT: col59 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object returned to caller as an owning reference (single retain count transferred to caller) -// CHECK-NEXT: message -// CHECK-NEXT: Object returned to caller as an owning reference (single retain count transferred to caller) -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line857 -// CHECK-NEXT: col30 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line857 -// CHECK-NEXT: col30 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line857 -// CHECK-NEXT: col59 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: allocated object is returned from a method whose name ('noCopyString') does not start with 'copy', 'mutableCopy', 'alloc' or 'new'. This violates the naming convention rules given in the Memory Management Guide for Cocoa -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: allocated object is returned from a method whose name ('noCopyString') does not start with 'copy', 'mutableCopy', 'alloc' or 'new'. This violates the naming convention rules given in the Memory Management Guide for Cocoa -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak of returned object -// CHECK-NEXT: issue_context_kindObjective-C method -// CHECK-NEXT: issue_contextnoCopyString -// CHECK-NEXT: issue_hash0 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line857 -// CHECK-NEXT: col30 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line861 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line861 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line861 -// CHECK-NEXT: col18 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Calling 'NoCopyString' -// CHECK-NEXT: message -// CHECK-NEXT: Calling 'NoCopyString' -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line856 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: depth1 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Entered call from 'test_RDar6859457' -// CHECK-NEXT: message -// CHECK-NEXT: Entered call from 'test_RDar6859457' -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line856 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line856 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line856 -// CHECK-NEXT: col30 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line856 -// CHECK-NEXT: col35 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line856 -// CHECK-NEXT: col37 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line856 -// CHECK-NEXT: col37 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line856 -// CHECK-NEXT: col59 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth1 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Method returns an Objective-C object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Method returns an Objective-C object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line861 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line861 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line861 -// CHECK-NEXT: col18 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Returning from 'NoCopyString' -// CHECK-NEXT: message -// CHECK-NEXT: Returning from 'NoCopyString' -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line861 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line861 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line862 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line862 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line862 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line862 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line862 -// CHECK-NEXT: col18 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contexttest_RDar6859457 -// CHECK-NEXT: issue_hash1 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line862 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line861 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line861 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line862 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line862 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line862 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line862 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line862 -// CHECK-NEXT: col18 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Calling 'noCopyString' -// CHECK-NEXT: message -// CHECK-NEXT: Calling 'noCopyString' -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line857 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: depth1 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Entered call from 'test_RDar6859457' -// CHECK-NEXT: message -// CHECK-NEXT: Entered call from 'test_RDar6859457' -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line857 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line857 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line857 -// CHECK-NEXT: col30 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line857 -// CHECK-NEXT: col35 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line857 -// CHECK-NEXT: col37 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line857 -// CHECK-NEXT: col37 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line857 -// CHECK-NEXT: col59 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth1 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Method returns an Objective-C object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Method returns an Objective-C object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line862 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line862 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line862 -// CHECK-NEXT: col18 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Returning from 'noCopyString' -// CHECK-NEXT: message -// CHECK-NEXT: Returning from 'noCopyString' -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line862 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line862 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line863 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line863 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line863 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line863 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line863 -// CHECK-NEXT: col54 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contexttest_RDar6859457 -// CHECK-NEXT: issue_hash2 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line863 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line896 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line896 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line896 -// CHECK-NEXT: col32 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Method returns an Objective-C object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Method returns an Objective-C object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line896 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line896 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line896 -// CHECK-NEXT: col32 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line896 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line896 -// CHECK-NEXT: col32 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object returned to caller as an owning reference (single retain count transferred to caller) -// CHECK-NEXT: message -// CHECK-NEXT: Object returned to caller as an owning reference (single retain count transferred to caller) -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line896 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line896 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line896 -// CHECK-NEXT: col32 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: allocated object is returned from a method whose name (':') does not start with 'copy', 'mutableCopy', 'alloc' or 'new'. This violates the naming convention rules given in the Memory Management Guide for Cocoa -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: allocated object is returned from a method whose name (':') does not start with 'copy', 'mutableCopy', 'alloc' or 'new'. This violates the naming convention rules given in the Memory Management Guide for Cocoa -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak of returned object -// CHECK-NEXT: issue_context_kindObjective-C method -// CHECK-NEXT: issue_context: -// CHECK-NEXT: issue_hash1 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line896 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line926 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line926 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line926 -// CHECK-NEXT: col38 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Method returns an Objective-C object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Method returns an Objective-C object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line926 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line926 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line927 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line927 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line927 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line927 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line927 -// CHECK-NEXT: col42 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextrdar6902710 -// CHECK-NEXT: issue_hash1 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line927 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line926 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line926 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line927 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line927 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line927 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line927 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line927 -// CHECK-NEXT: col42 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Method returns an Objective-C object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Method returns an Objective-C object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line927 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line927 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line928 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line928 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line928 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line928 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line928 -// CHECK-NEXT: col12 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line928 -// CHECK-NEXT: col24 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line928 -// CHECK-NEXT: col12 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line928 -// CHECK-NEXT: col12 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line928 -// CHECK-NEXT: col42 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextrdar6902710 -// CHECK-NEXT: issue_hash2 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line928 -// CHECK-NEXT: col12 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line926 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line926 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line928 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line928 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line928 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line928 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line928 -// CHECK-NEXT: col43 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Method returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Method returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line928 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line928 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line929 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line929 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line929 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line929 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line929 -// CHECK-NEXT: col12 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line929 -// CHECK-NEXT: col24 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line929 -// CHECK-NEXT: col12 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line929 -// CHECK-NEXT: col12 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line929 -// CHECK-NEXT: col42 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextrdar6902710 -// CHECK-NEXT: issue_hash3 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line929 -// CHECK-NEXT: col12 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line926 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line926 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line929 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line929 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line929 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line929 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line929 -// CHECK-NEXT: col69 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Method returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Method returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line929 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line929 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line930 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line930 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line930 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextrdar6902710 -// CHECK-NEXT: issue_hash4 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line930 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line938 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line938 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line938 -// CHECK-NEXT: col45 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Method returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Method returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line938 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line938 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line939 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line939 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line939 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextrdar6945561 -// CHECK-NEXT: issue_hash1 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line939 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line947 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line947 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line947 -// CHECK-NEXT: col49 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Call to function 'IOBSDNameMatching' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Call to function 'IOBSDNameMatching' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line947 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line947 -// CHECK-NEXT: col19 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line948 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line948 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line948 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextIOBSDNameMatching_wrapper -// CHECK-NEXT: issue_hash1 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line948 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line951 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line951 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line951 -// CHECK-NEXT: col25 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Call to function 'IOServiceMatching' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Call to function 'IOServiceMatching' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line951 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line951 -// CHECK-NEXT: col19 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line952 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line952 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line952 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextIOServiceMatching_wrapper -// CHECK-NEXT: issue_hash1 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line952 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line955 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line955 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line955 -// CHECK-NEXT: col29 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Call to function 'IOServiceNameMatching' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Call to function 'IOServiceNameMatching' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line955 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line955 -// CHECK-NEXT: col23 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line956 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line956 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line956 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextIOServiceNameMatching_wrapper -// CHECK-NEXT: issue_hash1 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line956 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line963 -// CHECK-NEXT: col30 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line963 -// CHECK-NEXT: col30 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line963 -// CHECK-NEXT: col41 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Call to function 'CreateDict' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Call to function 'CreateDict' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line963 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line963 -// CHECK-NEXT: col17 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line964 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line964 -// CHECK-NEXT: col11 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line964 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line964 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line964 -// CHECK-NEXT: col21 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line964 -// CHECK-NEXT: col13 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line964 -// CHECK-NEXT: col20 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object released -// CHECK-NEXT: message -// CHECK-NEXT: Object released -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line964 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line964 -// CHECK-NEXT: col11 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line965 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line965 -// CHECK-NEXT: col26 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line965 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line965 -// CHECK-NEXT: col58 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line965 -// CHECK-NEXT: col65 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Reference-counted object is used after it is released -// CHECK-NEXT: message -// CHECK-NEXT: Reference-counted object is used after it is released -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionReference-counted object is used after it is released -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeUse-after-release -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextIOServiceAddNotification_wrapper -// CHECK-NEXT: issue_hash4 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line965 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line970 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line970 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line970 -// CHECK-NEXT: col36 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Call to function 'IORegistryEntryIDMatching' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Call to function 'IORegistryEntryIDMatching' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line970 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line970 -// CHECK-NEXT: col27 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line971 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line971 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line971 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextIORegistryEntryIDMatching_wrapper -// CHECK-NEXT: issue_hash1 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line971 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line975 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line975 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line975 -// CHECK-NEXT: col55 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Call to function 'IOOpenFirmwarePathMatching' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Call to function 'IOOpenFirmwarePathMatching' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line975 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line975 -// CHECK-NEXT: col28 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line976 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line976 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line976 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextIOOpenFirmwarePathMatching_wrapper -// CHECK-NEXT: issue_hash1 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line976 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line979 -// CHECK-NEXT: col30 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line979 -// CHECK-NEXT: col30 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line979 -// CHECK-NEXT: col41 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Call to function 'CreateDict' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Call to function 'CreateDict' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line979 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line979 -// CHECK-NEXT: col17 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line980 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line980 -// CHECK-NEXT: col29 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line980 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line980 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line980 -// CHECK-NEXT: col51 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line980 -// CHECK-NEXT: col43 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line980 -// CHECK-NEXT: col50 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object released -// CHECK-NEXT: message -// CHECK-NEXT: Object released -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line980 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line980 -// CHECK-NEXT: col29 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line981 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line981 -// CHECK-NEXT: col11 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line981 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line981 -// CHECK-NEXT: col13 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line981 -// CHECK-NEXT: col20 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Reference-counted object is used after it is released -// CHECK-NEXT: message -// CHECK-NEXT: Reference-counted object is used after it is released -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionReference-counted object is used after it is released -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeUse-after-release -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextIOServiceGetMatchingService_wrapper -// CHECK-NEXT: issue_hash3 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line981 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line985 -// CHECK-NEXT: col30 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line985 -// CHECK-NEXT: col30 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line985 -// CHECK-NEXT: col41 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Call to function 'CreateDict' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Call to function 'CreateDict' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line985 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line985 -// CHECK-NEXT: col17 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line986 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line986 -// CHECK-NEXT: col30 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line986 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line986 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line986 -// CHECK-NEXT: col62 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line986 -// CHECK-NEXT: col44 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line986 -// CHECK-NEXT: col51 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object released -// CHECK-NEXT: message -// CHECK-NEXT: Object released -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line986 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line986 -// CHECK-NEXT: col30 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line987 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line987 -// CHECK-NEXT: col11 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line987 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line987 -// CHECK-NEXT: col13 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line987 -// CHECK-NEXT: col20 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Reference-counted object is used after it is released -// CHECK-NEXT: message -// CHECK-NEXT: Reference-counted object is used after it is released -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionReference-counted object is used after it is released -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeUse-after-release -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextIOServiceGetMatchingServices_wrapper -// CHECK-NEXT: issue_hash3 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line987 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line993 -// CHECK-NEXT: col30 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line993 -// CHECK-NEXT: col30 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line993 -// CHECK-NEXT: col41 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Call to function 'CreateDict' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Call to function 'CreateDict' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line993 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line993 -// CHECK-NEXT: col17 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line994 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line994 -// CHECK-NEXT: col34 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line994 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line994 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line994 -// CHECK-NEXT: col106 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line994 -// CHECK-NEXT: col66 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line994 -// CHECK-NEXT: col73 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object released -// CHECK-NEXT: message -// CHECK-NEXT: Object released -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line994 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line994 -// CHECK-NEXT: col34 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line995 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line995 -// CHECK-NEXT: col11 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line995 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line995 -// CHECK-NEXT: col13 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line995 -// CHECK-NEXT: col20 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Reference-counted object is used after it is released -// CHECK-NEXT: message -// CHECK-NEXT: Reference-counted object is used after it is released -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionReference-counted object is used after it is released -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeUse-after-release -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextIOServiceAddMatchingNotification_wrapper -// CHECK-NEXT: issue_hash4 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line995 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1033 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1033 -// CHECK-NEXT: col23 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1036 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1036 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1036 -// CHECK-NEXT: col22 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1036 -// CHECK-NEXT: col22 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1036 -// CHECK-NEXT: col53 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Method returns an Objective-C object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Method returns an Objective-C object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1036 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1036 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1038 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1038 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1038 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1038 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1038 -// CHECK-NEXT: col18 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1038 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1038 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Reference count decremented -// CHECK-NEXT: message -// CHECK-NEXT: Reference count decremented -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1038 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1038 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1039 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1039 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1039 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1039 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1039 -// CHECK-NEXT: col17 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1039 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1039 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Reference count incremented. The object now has a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Reference count incremented. The object now has a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1039 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1039 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1040 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1040 -// CHECK-NEXT: col11 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1040 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1040 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1040 -// CHECK-NEXT: col23 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: object allocated and stored into 'number' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: object allocated and stored into 'number' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object stored into 'number' -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextrdar_7152619 -// CHECK-NEXT: issue_hash4 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1040 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1049 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1049 -// CHECK-NEXT: col8 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1060 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1060 -// CHECK-NEXT: col15 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1060 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1060 -// CHECK-NEXT: col15 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1061 -// CHECK-NEXT: col41 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1061 -// CHECK-NEXT: col67 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1061 -// CHECK-NEXT: col41 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1061 -// CHECK-NEXT: col41 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1061 -// CHECK-NEXT: col69 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Call to function 'CGColorSpaceCreateDeviceRGB' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Call to function 'CGColorSpaceCreateDeviceRGB' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1061 -// CHECK-NEXT: col41 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1061 -// CHECK-NEXT: col67 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1060 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1060 -// CHECK-NEXT: col15 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1060 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1060 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1060 -// CHECK-NEXT: col26 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextrdar_7184450 -// CHECK-NEXT: issue_hash13 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1060 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1071 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1071 -// CHECK-NEXT: col8 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1082 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1082 -// CHECK-NEXT: col15 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1082 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1082 -// CHECK-NEXT: col15 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1083 -// CHECK-NEXT: col40 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1083 -// CHECK-NEXT: col66 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1083 -// CHECK-NEXT: col40 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1083 -// CHECK-NEXT: col40 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1083 -// CHECK-NEXT: col68 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Call to function 'CGColorSpaceCreateDeviceRGB' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Call to function 'CGColorSpaceCreateDeviceRGB' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1083 -// CHECK-NEXT: col40 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1083 -// CHECK-NEXT: col66 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1082 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1082 -// CHECK-NEXT: col15 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1082 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1082 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1082 -// CHECK-NEXT: col26 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextrdar_7184450_pos -// CHECK-NEXT: issue_hash13 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1082 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1071 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1071 -// CHECK-NEXT: col8 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1082 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1082 -// CHECK-NEXT: col15 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1082 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1082 -// CHECK-NEXT: col15 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1083 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1083 -// CHECK-NEXT: col38 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1083 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1083 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1083 -// CHECK-NEXT: col107 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Call to function 'CGGradientCreateWithColorComponents' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Call to function 'CGGradientCreateWithColorComponents' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1083 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1083 -// CHECK-NEXT: col38 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1085 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1085 -// CHECK-NEXT: col29 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1085 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1085 -// CHECK-NEXT: col29 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1087 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1087 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1087 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: object allocated and stored into 'myGradient' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: object allocated and stored into 'myGradient' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object stored into 'myGradient' -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextrdar_7184450_pos -// CHECK-NEXT: issue_hash13 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1087 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1121 -// CHECK-NEXT: col22 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1121 -// CHECK-NEXT: col22 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1121 -// CHECK-NEXT: col53 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Method returns an Objective-C object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Method returns an Objective-C object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1121 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1121 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1122 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1122 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1122 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: object allocated and stored into 'number' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: object allocated and stored into 'number' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object stored into 'number' -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextrdar_7299394_positive -// CHECK-NEXT: issue_hash1 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1122 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1254 -// CHECK-NEXT: col5 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1254 -// CHECK-NEXT: col12 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1256 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1256 -// CHECK-NEXT: col31 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1256 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1256 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1257 -// CHECK-NEXT: col60 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Call to function 'CGBitmapContextCreateWithData' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Call to function 'CGBitmapContextCreateWithData' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1256 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1256 -// CHECK-NEXT: col31 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1258 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1258 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1258 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextrdar_7358899 -// CHECK-NEXT: issue_hash7 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1258 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1274 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1274 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1274 -// CHECK-NEXT: col22 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Method returns an Objective-C object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Method returns an Objective-C object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1274 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1274 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1275 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1275 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1275 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: object allocated and stored into 'y' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: object allocated and stored into 'y' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object stored into 'y' -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextrdar7265711_a -// CHECK-NEXT: issue_hash1 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1275 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1294 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1294 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1295 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1295 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1295 -// CHECK-NEXT: col22 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1295 -// CHECK-NEXT: col22 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1295 -// CHECK-NEXT: col53 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Method returns an Objective-C object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Method returns an Objective-C object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1295 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1295 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1296 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1296 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1296 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: object allocated and stored into 'number' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: object allocated and stored into 'number' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object stored into 'number' -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextrdar7306898 -// CHECK-NEXT: issue_hash4 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1296 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1305 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1305 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1305 -// CHECK-NEXT: col23 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: The 'release' message should be sent to instances of class 'RDar7252064' and not the class directly -// CHECK-NEXT: message -// CHECK-NEXT: The 'release' message should be sent to instances of class 'RDar7252064' and not the class directly -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionThe 'release' message should be sent to instances of class 'RDar7252064' and not the class directly -// CHECK-NEXT: categoryAPI Misuse (Apple) -// CHECK-NEXT: typemessage incorrectly sent to class instead of class instance -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextrdar7252064 -// CHECK-NEXT: issue_hash1 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1305 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1305 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1305 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1306 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1306 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1306 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1306 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1306 -// CHECK-NEXT: col22 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: The 'retain' message should be sent to instances of class 'RDar7252064' and not the class directly -// CHECK-NEXT: message -// CHECK-NEXT: The 'retain' message should be sent to instances of class 'RDar7252064' and not the class directly -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionThe 'retain' message should be sent to instances of class 'RDar7252064' and not the class directly -// CHECK-NEXT: categoryAPI Misuse (Apple) -// CHECK-NEXT: typemessage incorrectly sent to class instead of class instance -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextrdar7252064 -// CHECK-NEXT: issue_hash2 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1306 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1305 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1305 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1307 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1307 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1307 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1307 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1307 -// CHECK-NEXT: col27 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: The 'autorelease' message should be sent to instances of class 'RDar7252064' and not the class directly -// CHECK-NEXT: message -// CHECK-NEXT: The 'autorelease' message should be sent to instances of class 'RDar7252064' and not the class directly -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionThe 'autorelease' message should be sent to instances of class 'RDar7252064' and not the class directly -// CHECK-NEXT: categoryAPI Misuse (Apple) -// CHECK-NEXT: typemessage incorrectly sent to class instead of class instance -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextrdar7252064 -// CHECK-NEXT: issue_hash3 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1307 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1305 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1305 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1308 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1308 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1308 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1308 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1308 -// CHECK-NEXT: col27 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: The 'drain' message should be sent to instances of class 'NSAutoreleasePool' and not the class directly -// CHECK-NEXT: message -// CHECK-NEXT: The 'drain' message should be sent to instances of class 'NSAutoreleasePool' and not the class directly -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionThe 'drain' message should be sent to instances of class 'NSAutoreleasePool' and not the class directly -// CHECK-NEXT: categoryAPI Misuse (Apple) -// CHECK-NEXT: typemessage incorrectly sent to class instead of class instance -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextrdar7252064 -// CHECK-NEXT: issue_hash4 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1308 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1335 -// CHECK-NEXT: col19 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1335 -// CHECK-NEXT: col19 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1335 -// CHECK-NEXT: col42 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Method returns an Objective-C object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Method returns an Objective-C object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1335 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1335 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1336 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1336 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1336 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: object allocated and stored into 'str' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: object allocated and stored into 'str' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object stored into 'str' -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contexttest_attr_1 -// CHECK-NEXT: issue_hash1 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1336 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1339 -// CHECK-NEXT: col19 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1339 -// CHECK-NEXT: col19 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1339 -// CHECK-NEXT: col44 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Method returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Method returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1339 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1339 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1340 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1340 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1340 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: object allocated and stored into 'str' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: object allocated and stored into 'str' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object stored into 'str' -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contexttest_attr_1b -// CHECK-NEXT: issue_hash1 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1340 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1343 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1343 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1344 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1344 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1344 -// CHECK-NEXT: col20 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1344 -// CHECK-NEXT: col20 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1344 -// CHECK-NEXT: col38 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Method returns an Objective-C object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Method returns an Objective-C object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1344 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1344 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1345 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1345 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1345 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1345 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1345 -// CHECK-NEXT: col20 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1345 -// CHECK-NEXT: col20 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1345 -// CHECK-NEXT: col20 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1345 -// CHECK-NEXT: col20 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1345 -// CHECK-NEXT: col37 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: object allocated and stored into 'str2' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: object allocated and stored into 'str2' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object stored into 'str2' -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contexttest_attr1c -// CHECK-NEXT: issue_hash2 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1345 -// CHECK-NEXT: col20 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1343 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1343 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1346 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1346 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1346 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1346 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1346 -// CHECK-NEXT: col21 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1346 -// CHECK-NEXT: col21 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1346 -// CHECK-NEXT: col21 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1346 -// CHECK-NEXT: col21 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1346 -// CHECK-NEXT: col38 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Method returns an Objective-C object with a +0 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Method returns an Objective-C object with a +0 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1346 -// CHECK-NEXT: col20 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1346 -// CHECK-NEXT: col20 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1346 -// CHECK-NEXT: col46 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1346 -// CHECK-NEXT: col21 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1346 -// CHECK-NEXT: col38 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Reference count incremented. The object now has a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Reference count incremented. The object now has a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1346 -// CHECK-NEXT: col20 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1346 -// CHECK-NEXT: col20 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1346 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1346 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1346 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1346 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1347 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1347 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1347 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: object allocated and stored into 'str4' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: object allocated and stored into 'str4' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object stored into 'str4' -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contexttest_attr1c -// CHECK-NEXT: issue_hash4 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1347 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1350 -// CHECK-NEXT: col26 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1350 -// CHECK-NEXT: col26 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1350 -// CHECK-NEXT: col50 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Method returns an Objective-C object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Method returns an Objective-C object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1350 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1350 -// CHECK-NEXT: col19 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1351 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1351 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1351 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: object allocated and stored into 'x' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: object allocated and stored into 'x' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object stored into 'x' -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contexttestattr2_a -// CHECK-NEXT: issue_hash1 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1351 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1354 -// CHECK-NEXT: col26 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1354 -// CHECK-NEXT: col26 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1354 -// CHECK-NEXT: col63 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Method returns an Objective-C object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Method returns an Objective-C object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1354 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1354 -// CHECK-NEXT: col19 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1355 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1355 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1355 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: object allocated and stored into 'x' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: object allocated and stored into 'x' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object stored into 'x' -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contexttestattr2_b -// CHECK-NEXT: issue_hash1 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1355 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1358 -// CHECK-NEXT: col26 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1358 -// CHECK-NEXT: col26 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1358 -// CHECK-NEXT: col63 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Method returns an Objective-C object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Method returns an Objective-C object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1358 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1358 -// CHECK-NEXT: col19 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1359 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1359 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1359 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1359 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1360 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1360 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1360 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: object allocated and stored into 'x' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: object allocated and stored into 'x' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object stored into 'x' -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contexttestattr2_b_11358224_self_assign_looses_the_leak -// CHECK-NEXT: issue_hash1 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1360 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1390 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1390 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1390 -// CHECK-NEXT: col25 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Method returns an Objective-C object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Method returns an Objective-C object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1390 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1390 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1390 -// CHECK-NEXT: col25 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1390 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1390 -// CHECK-NEXT: col25 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object returned to caller as an owning reference (single retain count transferred to caller) -// CHECK-NEXT: message -// CHECK-NEXT: Object returned to caller as an owning reference (single retain count transferred to caller) -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1390 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1390 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1390 -// CHECK-NEXT: col25 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: allocated object is returned from a method that is annotated as NS_RETURNS_NOT_RETAINED -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: allocated object is returned from a method that is annotated as NS_RETURNS_NOT_RETAINED -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak of returned object -// CHECK-NEXT: issue_context_kindObjective-C method -// CHECK-NEXT: issue_contextnewString -// CHECK-NEXT: issue_hash1 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1390 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1423 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1423 -// CHECK-NEXT: col8 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1423 -// CHECK-NEXT: col26 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1423 -// CHECK-NEXT: col26 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1423 -// CHECK-NEXT: col26 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1423 -// CHECK-NEXT: col26 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1423 -// CHECK-NEXT: col53 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Calling 'returnsCFRetainedAsCF' -// CHECK-NEXT: message -// CHECK-NEXT: Calling 'returnsCFRetainedAsCF' -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1414 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: depth1 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Entered call from 'newCFRetainedAsCFNoAttr' -// CHECK-NEXT: message -// CHECK-NEXT: Entered call from 'newCFRetainedAsCFNoAttr' -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1414 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1414 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1415 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1415 -// CHECK-NEXT: col8 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1415 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1415 -// CHECK-NEXT: col8 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1415 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1415 -// CHECK-NEXT: col30 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1415 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1415 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1415 -// CHECK-NEXT: col32 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth1 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Calling 'returnsRetainedCFDate' -// CHECK-NEXT: message -// CHECK-NEXT: Calling 'returnsRetainedCFDate' -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1404 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: depth2 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Entered call from 'returnsCFRetainedAsCF' -// CHECK-NEXT: message -// CHECK-NEXT: Entered call from 'returnsCFRetainedAsCF' -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1404 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1404 -// CHECK-NEXT: col19 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1406 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1406 -// CHECK-NEXT: col8 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1406 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1406 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1406 -// CHECK-NEXT: col52 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth2 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Call to function 'CFDateCreate' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Call to function 'CFDateCreate' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1415 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1415 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1415 -// CHECK-NEXT: col32 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth1 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Returning from 'returnsRetainedCFDate' -// CHECK-NEXT: message -// CHECK-NEXT: Returning from 'returnsRetainedCFDate' -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1415 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1415 -// CHECK-NEXT: col30 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1415 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1415 -// CHECK-NEXT: col8 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1423 -// CHECK-NEXT: col26 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1423 -// CHECK-NEXT: col26 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1423 -// CHECK-NEXT: col53 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Returning from 'returnsCFRetainedAsCF' -// CHECK-NEXT: message -// CHECK-NEXT: Returning from 'returnsCFRetainedAsCF' -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1423 -// CHECK-NEXT: col26 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1423 -// CHECK-NEXT: col26 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1423 -// CHECK-NEXT: col21 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1423 -// CHECK-NEXT: col21 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1423 -// CHECK-NEXT: col21 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1423 -// CHECK-NEXT: col21 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1423 -// CHECK-NEXT: col66 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1423 -// CHECK-NEXT: col22 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1423 -// CHECK-NEXT: col53 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object autoreleased -// CHECK-NEXT: message -// CHECK-NEXT: Object autoreleased -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1423 -// CHECK-NEXT: col21 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1423 -// CHECK-NEXT: col21 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1423 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1423 -// CHECK-NEXT: col8 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1423 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1423 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1423 -// CHECK-NEXT: col66 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected -// CHECK-NEXT: message -// CHECK-NEXT: Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionObject with a +0 retain count returned to caller where a +1 (owning) retain count is expected -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeMethod should return an owned object -// CHECK-NEXT: issue_context_kindObjective-C method -// CHECK-NEXT: issue_contextnewCFRetainedAsCFNoAttr -// CHECK-NEXT: issue_hash1 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1423 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1427 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1427 -// CHECK-NEXT: col8 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1427 -// CHECK-NEXT: col20 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1427 -// CHECK-NEXT: col40 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1427 -// CHECK-NEXT: col20 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1427 -// CHECK-NEXT: col20 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1427 -// CHECK-NEXT: col42 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Calling 'returnsRetainedCFDate' -// CHECK-NEXT: message -// CHECK-NEXT: Calling 'returnsRetainedCFDate' -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1404 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: depth1 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Entered call from 'alsoReturnsRetained' -// CHECK-NEXT: message -// CHECK-NEXT: Entered call from 'alsoReturnsRetained' -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1404 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1404 -// CHECK-NEXT: col19 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1406 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1406 -// CHECK-NEXT: col8 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1406 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1406 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1406 -// CHECK-NEXT: col52 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth1 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Call to function 'CFDateCreate' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Call to function 'CFDateCreate' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1427 -// CHECK-NEXT: col20 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1427 -// CHECK-NEXT: col20 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1427 -// CHECK-NEXT: col42 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Returning from 'returnsRetainedCFDate' -// CHECK-NEXT: message -// CHECK-NEXT: Returning from 'returnsRetainedCFDate' -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1427 -// CHECK-NEXT: col20 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1427 -// CHECK-NEXT: col40 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1427 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1427 -// CHECK-NEXT: col8 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1427 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1427 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1427 -// CHECK-NEXT: col42 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1427 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1427 -// CHECK-NEXT: col42 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object returned to caller as an owning reference (single retain count transferred to caller) -// CHECK-NEXT: message -// CHECK-NEXT: Object returned to caller as an owning reference (single retain count transferred to caller) -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1427 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1427 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1427 -// CHECK-NEXT: col42 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: allocated object is returned from a method whose name ('alsoReturnsRetained') does not start with 'copy', 'mutableCopy', 'alloc' or 'new'. This violates the naming convention rules given in the Memory Management Guide for Cocoa -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: allocated object is returned from a method whose name ('alsoReturnsRetained') does not start with 'copy', 'mutableCopy', 'alloc' or 'new'. This violates the naming convention rules given in the Memory Management Guide for Cocoa -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak of returned object -// CHECK-NEXT: issue_context_kindObjective-C method -// CHECK-NEXT: issue_contextalsoReturnsRetained -// CHECK-NEXT: issue_hash1 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1427 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1431 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1431 -// CHECK-NEXT: col8 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1431 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1431 -// CHECK-NEXT: col30 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1431 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1431 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1431 -// CHECK-NEXT: col32 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Calling 'returnsRetainedCFDate' -// CHECK-NEXT: message -// CHECK-NEXT: Calling 'returnsRetainedCFDate' -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1404 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: depth1 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Entered call from 'alsoReturnsRetainedAsCF' -// CHECK-NEXT: message -// CHECK-NEXT: Entered call from 'alsoReturnsRetainedAsCF' -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1404 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1404 -// CHECK-NEXT: col19 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1406 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1406 -// CHECK-NEXT: col8 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1406 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1406 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1406 -// CHECK-NEXT: col52 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth1 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Call to function 'CFDateCreate' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Call to function 'CFDateCreate' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1431 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1431 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1431 -// CHECK-NEXT: col32 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Returning from 'returnsRetainedCFDate' -// CHECK-NEXT: message -// CHECK-NEXT: Returning from 'returnsRetainedCFDate' -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1431 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1431 -// CHECK-NEXT: col30 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1431 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1431 -// CHECK-NEXT: col8 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1431 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1431 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1431 -// CHECK-NEXT: col32 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1431 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1431 -// CHECK-NEXT: col32 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object returned to caller as an owning reference (single retain count transferred to caller) -// CHECK-NEXT: message -// CHECK-NEXT: Object returned to caller as an owning reference (single retain count transferred to caller) -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1431 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1431 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1431 -// CHECK-NEXT: col32 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: allocated object is returned from a method whose name ('alsoReturnsRetainedAsCF') does not start with 'copy', 'mutableCopy', 'alloc' or 'new'. This violates the naming convention rules given in the Memory Management Guide for Cocoa -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: allocated object is returned from a method whose name ('alsoReturnsRetainedAsCF') does not start with 'copy', 'mutableCopy', 'alloc' or 'new'. This violates the naming convention rules given in the Memory Management Guide for Cocoa -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak of returned object -// CHECK-NEXT: issue_context_kindObjective-C method -// CHECK-NEXT: issue_contextalsoReturnsRetainedAsCF -// CHECK-NEXT: issue_hash1 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1431 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1451 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1451 -// CHECK-NEXT: col8 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1452 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1452 -// CHECK-NEXT: col13 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1452 -// CHECK-NEXT: col23 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1452 -// CHECK-NEXT: col23 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1452 -// CHECK-NEXT: col82 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Call to function 'CFNumberCreate' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Call to function 'CFNumberCreate' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1452 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1452 -// CHECK-NEXT: col13 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1453 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1453 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1453 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: object allocated and stored into 'value' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: object allocated and stored into 'value' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object stored into 'value' -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contexttest_panic_negative -// CHECK-NEXT: issue_hash2 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1453 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1462 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1462 -// CHECK-NEXT: col8 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1463 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1463 -// CHECK-NEXT: col13 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1463 -// CHECK-NEXT: col23 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1463 -// CHECK-NEXT: col23 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1463 -// CHECK-NEXT: col82 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Call to function 'CFNumberCreate' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Call to function 'CFNumberCreate' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1463 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1463 -// CHECK-NEXT: col13 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1464 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1464 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1464 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1464 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1464 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1464 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1464 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1464 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1464 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Assuming 'x' is 0 -// CHECK-NEXT: message -// CHECK-NEXT: Assuming 'x' is 0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1464 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1464 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1466 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1466 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1466 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: object allocated and stored into 'value' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: object allocated and stored into 'value' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object stored into 'value' -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contexttest_panic_neg_2 -// CHECK-NEXT: issue_hash2 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1466 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1486 -// CHECK-NEXT: col22 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1486 -// CHECK-NEXT: col22 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1486 -// CHECK-NEXT: col53 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Method returns an Objective-C object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Method returns an Objective-C object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1486 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1486 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1487 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1487 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1487 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1487 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1487 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: object allocated and stored into 'number' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: object allocated and stored into 'number' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object stored into 'number' -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contexttest_blocks_1_pos -// CHECK-NEXT: issue_hash1 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1487 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1507 -// CHECK-NEXT: col22 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1507 -// CHECK-NEXT: col22 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1507 -// CHECK-NEXT: col53 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Method returns an Objective-C object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Method returns an Objective-C object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1507 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1507 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1508 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1508 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1508 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1508 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1508 -// CHECK-NEXT: col39 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Calling anonymous block -// CHECK-NEXT: message -// CHECK-NEXT: Calling anonymous block -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1508 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: depth1 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Entered call from 'test_blocks_1_indirect_retain_via_call' -// CHECK-NEXT: message -// CHECK-NEXT: Entered call from 'test_blocks_1_indirect_retain_via_call' -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1508 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1508 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1508 -// CHECK-NEXT: col19 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1508 -// CHECK-NEXT: col19 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1508 -// CHECK-NEXT: col19 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1508 -// CHECK-NEXT: col19 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1508 -// CHECK-NEXT: col28 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1508 -// CHECK-NEXT: col20 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1508 -// CHECK-NEXT: col20 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth1 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Reference count incremented. The object now has a +2 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Reference count incremented. The object now has a +2 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1508 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1508 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1508 -// CHECK-NEXT: col39 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Returning to caller -// CHECK-NEXT: message -// CHECK-NEXT: Returning to caller -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1508 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1508 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1509 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1509 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1509 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: object allocated and stored into 'number' is not referenced later in this execution path and has a retain count of +2 -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: object allocated and stored into 'number' is not referenced later in this execution path and has a retain count of +2 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object stored into 'number' -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contexttest_blocks_1_indirect_retain_via_call -// CHECK-NEXT: issue_hash1 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1509 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1559 -// CHECK-NEXT: col5 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1559 -// CHECK-NEXT: col14 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1562 -// CHECK-NEXT: col5 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1562 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1562 -// CHECK-NEXT: col12 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1562 -// CHECK-NEXT: col12 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1562 -// CHECK-NEXT: col38 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Entering loop body -// CHECK-NEXT: message -// CHECK-NEXT: Entering loop body -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1562 -// CHECK-NEXT: col5 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1562 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1563 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1563 -// CHECK-NEXT: col23 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1563 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1563 -// CHECK-NEXT: col23 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1565 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1565 -// CHECK-NEXT: col12 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1565 -// CHECK-NEXT: col16 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1565 -// CHECK-NEXT: col16 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1565 -// CHECK-NEXT: col49 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Call to function 'CFErrorCopyUserInfo' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Call to function 'CFErrorCopyUserInfo' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1565 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1565 -// CHECK-NEXT: col12 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1567 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1567 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1567 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1567 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1567 -// CHECK-NEXT: col13 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1567 -// CHECK-NEXT: col16 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1567 -// CHECK-NEXT: col13 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1567 -// CHECK-NEXT: col13 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1567 -// CHECK-NEXT: col30 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Assuming 'info' is not equal to null -// CHECK-NEXT: message -// CHECK-NEXT: Assuming 'info' is not equal to null -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1567 -// CHECK-NEXT: col13 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1567 -// CHECK-NEXT: col16 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1570 -// CHECK-NEXT: col23 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1570 -// CHECK-NEXT: col23 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1570 -// CHECK-NEXT: col23 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: object allocated and stored into 'info' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: object allocated and stored into 'info' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object stored into 'info' -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextrdar_8724287 -// CHECK-NEXT: issue_hash7 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1570 -// CHECK-NEXT: col23 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1615 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1615 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1615 -// CHECK-NEXT: col60 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Call to function 'CFArrayCreateMutable' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Call to function 'CFArrayCreateMutable' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1615 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1615 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1615 -// CHECK-NEXT: col60 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1615 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1615 -// CHECK-NEXT: col60 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object returned to caller as an owning reference (single retain count transferred to caller) -// CHECK-NEXT: message -// CHECK-NEXT: Object returned to caller as an owning reference (single retain count transferred to caller) -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1615 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1615 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1615 -// CHECK-NEXT: col60 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: allocated object is returned from a function whose name ('camelcase_createno') does not contain 'Copy' or 'Create'. This violates the naming convention rules given in the Memory Management Guide for Core Foundation -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: allocated object is returned from a function whose name ('camelcase_createno') does not contain 'Copy' or 'Create'. This violates the naming convention rules given in the Memory Management Guide for Core Foundation -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak of returned object -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextcamelcase_createno -// CHECK-NEXT: issue_hash1 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1615 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1623 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1623 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1623 -// CHECK-NEXT: col60 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Call to function 'CFArrayCreateMutable' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Call to function 'CFArrayCreateMutable' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1623 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1623 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1623 -// CHECK-NEXT: col60 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1623 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1623 -// CHECK-NEXT: col60 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object returned to caller as an owning reference (single retain count transferred to caller) -// CHECK-NEXT: message -// CHECK-NEXT: Object returned to caller as an owning reference (single retain count transferred to caller) -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1623 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1623 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1623 -// CHECK-NEXT: col60 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: allocated object is returned from a function whose name ('camelcase_copying') does not contain 'Copy' or 'Create'. This violates the naming convention rules given in the Memory Management Guide for Core Foundation -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: allocated object is returned from a function whose name ('camelcase_copying') does not contain 'Copy' or 'Create'. This violates the naming convention rules given in the Memory Management Guide for Core Foundation -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak of returned object -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextcamelcase_copying -// CHECK-NEXT: issue_hash1 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1623 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1644 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1644 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1644 -// CHECK-NEXT: col60 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Call to function 'CFArrayCreateMutable' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Call to function 'CFArrayCreateMutable' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1644 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1644 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1644 -// CHECK-NEXT: col60 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1644 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1644 -// CHECK-NEXT: col60 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object returned to caller as an owning reference (single retain count transferred to caller) -// CHECK-NEXT: message -// CHECK-NEXT: Object returned to caller as an owning reference (single retain count transferred to caller) -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1644 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1644 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1644 -// CHECK-NEXT: col60 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: allocated object is returned from a function whose name ('camel_creat') does not contain 'Copy' or 'Create'. This violates the naming convention rules given in the Memory Management Guide for Core Foundation -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: allocated object is returned from a function whose name ('camel_creat') does not contain 'Copy' or 'Create'. This violates the naming convention rules given in the Memory Management Guide for Core Foundation -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak of returned object -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextcamel_creat -// CHECK-NEXT: issue_hash1 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1644 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1656 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1656 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1656 -// CHECK-NEXT: col60 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Call to function 'CFArrayCreateMutable' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Call to function 'CFArrayCreateMutable' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1656 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1656 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1656 -// CHECK-NEXT: col60 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1656 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1656 -// CHECK-NEXT: col60 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object returned to caller as an owning reference (single retain count transferred to caller) -// CHECK-NEXT: message -// CHECK-NEXT: Object returned to caller as an owning reference (single retain count transferred to caller) -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1656 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1656 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1656 -// CHECK-NEXT: col60 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: allocated object is returned from a function whose name ('camel_copymachine') does not contain 'Copy' or 'Create'. This violates the naming convention rules given in the Memory Management Guide for Core Foundation -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: allocated object is returned from a function whose name ('camel_copymachine') does not contain 'Copy' or 'Create'. This violates the naming convention rules given in the Memory Management Guide for Core Foundation -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak of returned object -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextcamel_copymachine -// CHECK-NEXT: issue_hash1 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1656 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1676 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1676 -// CHECK-NEXT: col16 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1677 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1677 -// CHECK-NEXT: col11 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1677 -// CHECK-NEXT: col24 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1677 -// CHECK-NEXT: col24 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1677 -// CHECK-NEXT: col41 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Call to function 'CFDateCreate' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Call to function 'CFDateCreate' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1677 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1677 -// CHECK-NEXT: col11 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1678 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1678 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1678 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: object allocated and stored into 'vals' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: object allocated and stored into 'vals' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object stored into 'vals' -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextrdar6582778 -// CHECK-NEXT: issue_hash2 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1678 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1702 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1702 -// CHECK-NEXT: col16 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1704 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1704 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1704 -// CHECK-NEXT: col22 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1704 -// CHECK-NEXT: col22 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1704 -// CHECK-NEXT: col64 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Method returns an Objective-C object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Method returns an Objective-C object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1704 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1704 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1705 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1705 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1705 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1705 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1705 -// CHECK-NEXT: col18 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1705 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1705 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object released -// CHECK-NEXT: message -// CHECK-NEXT: Object released -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1705 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1705 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1707 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1707 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1707 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1707 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1707 -// CHECK-NEXT: col27 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1707 -// CHECK-NEXT: col27 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1707 -// CHECK-NEXT: col27 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1707 -// CHECK-NEXT: col28 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1707 -// CHECK-NEXT: col33 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Reference-counted object is used after it is released -// CHECK-NEXT: message -// CHECK-NEXT: Reference-counted object is used after it is released -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionReference-counted object is used after it is released -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeUse-after-release -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextrdar10232019_positive -// CHECK-NEXT: issue_hash6 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1707 -// CHECK-NEXT: col27 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1834 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1834 -// CHECK-NEXT: col16 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1835 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1835 -// CHECK-NEXT: col15 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1835 -// CHECK-NEXT: col22 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1835 -// CHECK-NEXT: col22 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1835 -// CHECK-NEXT: col66 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Method returns an Objective-C object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Method returns an Objective-C object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1835 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1835 -// CHECK-NEXT: col15 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1838 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1838 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1838 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1838 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1838 -// CHECK-NEXT: col23 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: object allocated and stored into 'a' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: object allocated and stored into 'a' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object stored into 'a' -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contexttest_objc_arrays -// CHECK-NEXT: issue_hash3 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1838 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1834 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1834 -// CHECK-NEXT: col16 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1838 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1838 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1838 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1838 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1842 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1842 -// CHECK-NEXT: col16 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1842 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1842 -// CHECK-NEXT: col16 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1844 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1844 -// CHECK-NEXT: col15 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1844 -// CHECK-NEXT: col23 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1844 -// CHECK-NEXT: col23 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1844 -// CHECK-NEXT: col56 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Method returns an Objective-C object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Method returns an Objective-C object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1844 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1844 -// CHECK-NEXT: col15 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1847 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1847 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1847 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1847 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1847 -// CHECK-NEXT: col23 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: object allocated and stored into 'a2' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: object allocated and stored into 'a2' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object stored into 'a2' -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contexttest_objc_arrays -// CHECK-NEXT: issue_hash12 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1847 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1834 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1834 -// CHECK-NEXT: col16 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1838 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1838 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1838 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1838 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1842 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1842 -// CHECK-NEXT: col16 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1842 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1842 -// CHECK-NEXT: col16 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1847 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1847 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1847 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1847 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1851 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1851 -// CHECK-NEXT: col16 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1851 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1851 -// CHECK-NEXT: col16 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1852 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1852 -// CHECK-NEXT: col15 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1852 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1852 -// CHECK-NEXT: col15 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1852 -// CHECK-NEXT: col24 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1852 -// CHECK-NEXT: col24 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1852 -// CHECK-NEXT: col24 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1852 -// CHECK-NEXT: col24 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1852 -// CHECK-NEXT: col27 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: NSArray literal is an object with a +0 retain count -// CHECK-NEXT: message -// CHECK-NEXT: NSArray literal is an object with a +0 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1852 -// CHECK-NEXT: col23 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1852 -// CHECK-NEXT: col23 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1852 -// CHECK-NEXT: col35 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1852 -// CHECK-NEXT: col24 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1852 -// CHECK-NEXT: col27 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Reference count incremented. The object now has a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Reference count incremented. The object now has a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1852 -// CHECK-NEXT: col23 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1852 -// CHECK-NEXT: col23 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1852 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1852 -// CHECK-NEXT: col15 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1852 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1852 -// CHECK-NEXT: col15 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1855 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1855 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1855 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1855 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1855 -// CHECK-NEXT: col23 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: object allocated and stored into 'a3' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: object allocated and stored into 'a3' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object stored into 'a3' -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contexttest_objc_arrays -// CHECK-NEXT: issue_hash20 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1855 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1834 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1834 -// CHECK-NEXT: col16 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1838 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1838 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1838 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1838 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1842 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1842 -// CHECK-NEXT: col16 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1842 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1842 -// CHECK-NEXT: col16 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1847 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1847 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1847 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1847 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1851 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1851 -// CHECK-NEXT: col16 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1851 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1851 -// CHECK-NEXT: col16 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1855 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1855 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1855 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1855 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1859 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1859 -// CHECK-NEXT: col16 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1859 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1859 -// CHECK-NEXT: col16 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1860 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1860 -// CHECK-NEXT: col15 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1860 -// CHECK-NEXT: col22 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1860 -// CHECK-NEXT: col22 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1860 -// CHECK-NEXT: col57 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Method returns an Objective-C object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Method returns an Objective-C object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1860 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1860 -// CHECK-NEXT: col15 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1864 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1864 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1864 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1864 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1864 -// CHECK-NEXT: col23 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: object allocated and stored into 'a' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: object allocated and stored into 'a' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object stored into 'a' -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contexttest_objc_arrays -// CHECK-NEXT: issue_hash28 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1864 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1834 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1834 -// CHECK-NEXT: col16 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1838 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1838 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1838 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1838 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1842 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1842 -// CHECK-NEXT: col16 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1842 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1842 -// CHECK-NEXT: col16 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1847 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1847 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1847 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1847 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1851 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1851 -// CHECK-NEXT: col16 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1851 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1851 -// CHECK-NEXT: col16 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1855 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1855 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1855 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1855 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1859 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1859 -// CHECK-NEXT: col16 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1859 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1859 -// CHECK-NEXT: col16 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1864 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1864 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1864 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1864 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1868 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1868 -// CHECK-NEXT: col15 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1868 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1868 -// CHECK-NEXT: col15 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1869 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1869 -// CHECK-NEXT: col20 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1869 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1869 -// CHECK-NEXT: col20 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1869 -// CHECK-NEXT: col28 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1869 -// CHECK-NEXT: col28 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1869 -// CHECK-NEXT: col28 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1869 -// CHECK-NEXT: col28 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1869 -// CHECK-NEXT: col35 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: NSDictionary literal is an object with a +0 retain count -// CHECK-NEXT: message -// CHECK-NEXT: NSDictionary literal is an object with a +0 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1869 -// CHECK-NEXT: col27 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1869 -// CHECK-NEXT: col27 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1869 -// CHECK-NEXT: col43 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1869 -// CHECK-NEXT: col28 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1869 -// CHECK-NEXT: col35 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Reference count incremented. The object now has a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Reference count incremented. The object now has a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1869 -// CHECK-NEXT: col27 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1869 -// CHECK-NEXT: col27 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1869 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1869 -// CHECK-NEXT: col20 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1869 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1869 -// CHECK-NEXT: col20 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1873 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1873 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1873 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1873 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1873 -// CHECK-NEXT: col23 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: object allocated and stored into 'a' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: object allocated and stored into 'a' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object stored into 'a' -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contexttest_objc_arrays -// CHECK-NEXT: issue_hash37 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1873 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1878 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1878 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1878 -// CHECK-NEXT: col15 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1878 -// CHECK-NEXT: col15 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1878 -// CHECK-NEXT: col15 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1878 -// CHECK-NEXT: col15 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1878 -// CHECK-NEXT: col16 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: NSNumber literal is an object with a +0 retain count -// CHECK-NEXT: message -// CHECK-NEXT: NSNumber literal is an object with a +0 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1878 -// CHECK-NEXT: col14 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1878 -// CHECK-NEXT: col14 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1878 -// CHECK-NEXT: col24 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1878 -// CHECK-NEXT: col15 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1878 -// CHECK-NEXT: col16 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Reference count incremented. The object now has a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Reference count incremented. The object now has a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1878 -// CHECK-NEXT: col14 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1878 -// CHECK-NEXT: col14 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1878 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1878 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1878 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1878 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1879 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1879 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1879 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1879 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1880 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1880 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1880 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: object allocated and stored into 'value' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: object allocated and stored into 'value' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object stored into 'value' -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contexttest_objc_integer_literals -// CHECK-NEXT: issue_hash1 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1880 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1883 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1883 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1883 -// CHECK-NEXT: col15 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1883 -// CHECK-NEXT: col15 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1883 -// CHECK-NEXT: col15 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1883 -// CHECK-NEXT: col15 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1883 -// CHECK-NEXT: col18 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: NSNumber boxed expression produces an object with a +0 retain count -// CHECK-NEXT: message -// CHECK-NEXT: NSNumber boxed expression produces an object with a +0 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1883 -// CHECK-NEXT: col14 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1883 -// CHECK-NEXT: col14 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1883 -// CHECK-NEXT: col26 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1883 -// CHECK-NEXT: col15 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1883 -// CHECK-NEXT: col18 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Reference count incremented. The object now has a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Reference count incremented. The object now has a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1883 -// CHECK-NEXT: col14 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1883 -// CHECK-NEXT: col14 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1883 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1883 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1883 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1883 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1887 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1887 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1887 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1887 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1887 -// CHECK-NEXT: col21 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: object allocated and stored into 'value' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: object allocated and stored into 'value' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object stored into 'value' -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contexttest_objc_boxed_expressions -// CHECK-NEXT: issue_hash1 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1887 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1883 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1883 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1886 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1886 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1886 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1886 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1886 -// CHECK-NEXT: col12 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1886 -// CHECK-NEXT: col12 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1886 -// CHECK-NEXT: col12 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1886 -// CHECK-NEXT: col12 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1886 -// CHECK-NEXT: col15 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: NSString boxed expression produces an object with a +0 retain count -// CHECK-NEXT: message -// CHECK-NEXT: NSString boxed expression produces an object with a +0 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1886 -// CHECK-NEXT: col11 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1886 -// CHECK-NEXT: col11 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1886 -// CHECK-NEXT: col23 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1886 -// CHECK-NEXT: col12 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1886 -// CHECK-NEXT: col15 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Reference count incremented. The object now has a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Reference count incremented. The object now has a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1886 -// CHECK-NEXT: col11 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1886 -// CHECK-NEXT: col11 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1886 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1886 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1886 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1886 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1887 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1887 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1887 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1887 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1888 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1888 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1888 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: object allocated and stored into 'value' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: object allocated and stored into 'value' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object stored into 'value' -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contexttest_objc_boxed_expressions -// CHECK-NEXT: issue_hash4 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1888 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1894 -// CHECK-NEXT: col5 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1894 -// CHECK-NEXT: col12 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1895 -// CHECK-NEXT: col5 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1895 -// CHECK-NEXT: col6 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1895 -// CHECK-NEXT: col5 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1895 -// CHECK-NEXT: col6 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1895 -// CHECK-NEXT: col8 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1895 -// CHECK-NEXT: col8 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1895 -// CHECK-NEXT: col8 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1895 -// CHECK-NEXT: col8 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1895 -// CHECK-NEXT: col12 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Assuming 'y' is <= 2 -// CHECK-NEXT: message -// CHECK-NEXT: Assuming 'y' is <= 2 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1895 -// CHECK-NEXT: col8 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1895 -// CHECK-NEXT: col8 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1898 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1898 -// CHECK-NEXT: col17 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1898 -// CHECK-NEXT: col21 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1898 -// CHECK-NEXT: col21 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1898 -// CHECK-NEXT: col43 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Method returns an Objective-C object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Method returns an Objective-C object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1898 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1898 -// CHECK-NEXT: col17 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1899 -// CHECK-NEXT: col5 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1899 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1899 -// CHECK-NEXT: col5 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1899 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1900 -// CHECK-NEXT: col5 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1900 -// CHECK-NEXT: col5 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1900 -// CHECK-NEXT: col5 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1900 -// CHECK-NEXT: col5 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1900 -// CHECK-NEXT: col25 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1900 -// CHECK-NEXT: col6 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1900 -// CHECK-NEXT: col16 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object released -// CHECK-NEXT: message -// CHECK-NEXT: Object released -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1900 -// CHECK-NEXT: col5 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1900 -// CHECK-NEXT: col5 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1901 -// CHECK-NEXT: col5 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1901 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1901 -// CHECK-NEXT: col5 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1901 -// CHECK-NEXT: col25 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1901 -// CHECK-NEXT: col35 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Reference-counted object is used after it is released -// CHECK-NEXT: message -// CHECK-NEXT: Reference-counted object is used after it is released -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionReference-counted object is used after it is released -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeUse-after-release -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextrdar11400885 -// CHECK-NEXT: issue_hash9 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1901 -// CHECK-NEXT: col5 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1920 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1920 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1928 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1928 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1928 -// CHECK-NEXT: col19 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1928 -// CHECK-NEXT: col19 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1928 -// CHECK-NEXT: col21 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: NSArray literal is an object with a +0 retain count -// CHECK-NEXT: message -// CHECK-NEXT: NSArray literal is an object with a +0 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1928 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1928 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1929 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1929 -// CHECK-NEXT: col24 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1929 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1929 -// CHECK-NEXT: col26 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1929 -// CHECK-NEXT: col35 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Incorrect decrement of the reference count of an object that is not owned at this point by the caller -// CHECK-NEXT: message -// CHECK-NEXT: Incorrect decrement of the reference count of an object that is not owned at this point by the caller -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionIncorrect decrement of the reference count of an object that is not owned at this point by the caller -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeBad release -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contexttestConsumeAndStopTracking -// CHECK-NEXT: issue_hash10 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1929 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1933 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1933 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1941 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1941 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1941 -// CHECK-NEXT: col19 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1941 -// CHECK-NEXT: col19 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1941 -// CHECK-NEXT: col21 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: NSArray literal is an object with a +0 retain count -// CHECK-NEXT: message -// CHECK-NEXT: NSArray literal is an object with a +0 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1941 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1941 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1942 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1942 -// CHECK-NEXT: col26 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1942 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1942 -// CHECK-NEXT: col28 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1942 -// CHECK-NEXT: col48 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Incorrect decrement of the reference count of an object that is not owned at this point by the caller -// CHECK-NEXT: message -// CHECK-NEXT: Incorrect decrement of the reference count of an object that is not owned at this point by the caller -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionIncorrect decrement of the reference count of an object that is not owned at this point by the caller -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeBad release -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contexttestCFConsumeAndStopTracking -// CHECK-NEXT: issue_hash10 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1942 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1954 -// CHECK-NEXT: col16 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1954 -// CHECK-NEXT: col16 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1954 -// CHECK-NEXT: col31 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Call to function 'CreateMyCFType' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Call to function 'CreateMyCFType' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1954 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1954 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1955 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1955 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1955 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: object allocated and stored into 'x' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: object allocated and stored into 'x' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object stored into 'x' -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contexttest_custom_cf -// CHECK-NEXT: issue_hash1 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1955 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1989 -// CHECK-NEXT: col18 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1989 -// CHECK-NEXT: col18 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1989 -// CHECK-NEXT: col29 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Call to function 'makeCustom' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Call to function 'makeCustom' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1989 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1989 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1990 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1990 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1990 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: object allocated and stored into 'obj' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: object allocated and stored into 'obj' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object stored into 'obj' -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contexttestCustomReturnsRetained -// CHECK-NEXT: issue_hash1 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1990 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1993 -// CHECK-NEXT: col13 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1993 -// CHECK-NEXT: col13 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1993 -// CHECK-NEXT: col23 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Call to function 'getCustom' returns a Core Foundation object with a +0 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Call to function 'getCustom' returns a Core Foundation object with a +0 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1993 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1993 -// CHECK-NEXT: col13 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line1993 -// CHECK-NEXT: col23 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Incorrect decrement of the reference count of an object that is not owned at this point by the caller -// CHECK-NEXT: message -// CHECK-NEXT: Incorrect decrement of the reference count of an object that is not owned at this point by the caller -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionIncorrect decrement of the reference count of an object that is not owned at this point by the caller -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeBad release -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contexttestCustomReturnsNotRetained -// CHECK-NEXT: issue_hash1 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line1993 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2012 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2012 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2012 -// CHECK-NEXT: col11 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2012 -// CHECK-NEXT: col11 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line2012 -// CHECK-NEXT: col11 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2012 -// CHECK-NEXT: col11 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2012 -// CHECK-NEXT: col31 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Method returns an Objective-C object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Method returns an Objective-C object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line2012 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2012 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2012 -// CHECK-NEXT: col38 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Calling 'initX' -// CHECK-NEXT: message -// CHECK-NEXT: Calling 'initX' -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line2005 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: depth1 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Entered call from 'test12706177' -// CHECK-NEXT: message -// CHECK-NEXT: Entered call from 'test12706177' -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2005 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2005 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2006 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2006 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2006 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2006 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2006 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2006 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line2006 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2006 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2006 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth1 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Assuming 'Cond' is not equal to 0 -// CHECK-NEXT: message -// CHECK-NEXT: Assuming 'Cond' is not equal to 0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2006 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2006 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2007 -// CHECK-NEXT: col5 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2007 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line2012 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2012 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2012 -// CHECK-NEXT: col38 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Returning from 'initX' -// CHECK-NEXT: message -// CHECK-NEXT: Returning from 'initX' -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2012 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2012 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2012 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2012 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line2012 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2012 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2012 -// CHECK-NEXT: col6 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak -// CHECK-NEXT: issue_context_kindObjective-C method -// CHECK-NEXT: issue_contexttest12706177 -// CHECK-NEXT: issue_hash1 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line2012 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2028 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2028 -// CHECK-NEXT: col8 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2028 -// CHECK-NEXT: col24 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2028 -// CHECK-NEXT: col37 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line2028 -// CHECK-NEXT: col24 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2028 -// CHECK-NEXT: col24 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2028 -// CHECK-NEXT: col39 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Call to function 'CFGetSomething' returns a Core Foundation object with a +0 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Call to function 'CFGetSomething' returns a Core Foundation object with a +0 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2028 -// CHECK-NEXT: col24 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2028 -// CHECK-NEXT: col37 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2028 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2028 -// CHECK-NEXT: col22 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line2028 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2028 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2028 -// CHECK-NEXT: col40 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2028 -// CHECK-NEXT: col24 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2028 -// CHECK-NEXT: col39 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object autoreleased -// CHECK-NEXT: message -// CHECK-NEXT: Object autoreleased -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2028 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2028 -// CHECK-NEXT: col22 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2028 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2028 -// CHECK-NEXT: col8 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line2028 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2028 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2028 -// CHECK-NEXT: col40 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2028 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2028 -// CHECK-NEXT: col40 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object returned to caller with a +0 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Object returned to caller with a +0 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line2028 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2028 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2028 -// CHECK-NEXT: col40 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object was autoreleased but has a +0 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Object was autoreleased but has a +0 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionObject autoreleased too many times -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeObject autoreleased too many times -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextgetIncorrectlyAutoreleasedCFType -// CHECK-NEXT: issue_hash2 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line2028 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2033 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2033 -// CHECK-NEXT: col8 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2033 -// CHECK-NEXT: col24 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2033 -// CHECK-NEXT: col40 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line2033 -// CHECK-NEXT: col24 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2033 -// CHECK-NEXT: col24 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2033 -// CHECK-NEXT: col42 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2033 -// CHECK-NEXT: col24 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2033 -// CHECK-NEXT: col40 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2033 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2033 -// CHECK-NEXT: col22 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line2033 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2033 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2033 -// CHECK-NEXT: col43 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2033 -// CHECK-NEXT: col24 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2033 -// CHECK-NEXT: col42 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object autoreleased -// CHECK-NEXT: message -// CHECK-NEXT: Object autoreleased -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2033 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2033 -// CHECK-NEXT: col22 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2033 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2033 -// CHECK-NEXT: col8 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line2033 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2033 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2033 -// CHECK-NEXT: col43 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected -// CHECK-NEXT: message -// CHECK-NEXT: Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionObject with a +0 retain count returned to caller where a +1 (owning) retain count is expected -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeMethod should return an owned object -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextcreateIncorrectlyAutoreleasedCFType -// CHECK-NEXT: issue_hash2 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line2033 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line2048 -// CHECK-NEXT: col19 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2048 -// CHECK-NEXT: col19 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2048 -// CHECK-NEXT: col37 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2048 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2048 -// CHECK-NEXT: col11 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2049 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2049 -// CHECK-NEXT: col11 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line2049 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2049 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2049 -// CHECK-NEXT: col16 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2049 -// CHECK-NEXT: col13 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2049 -// CHECK-NEXT: col15 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object released -// CHECK-NEXT: message -// CHECK-NEXT: Object released -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2049 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2049 -// CHECK-NEXT: col11 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2052 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2052 -// CHECK-NEXT: col7 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line2052 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2052 -// CHECK-NEXT: col9 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2052 -// CHECK-NEXT: col11 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Reference-counted object is used after it is released -// CHECK-NEXT: message -// CHECK-NEXT: Reference-counted object is used after it is released -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionReference-counted object is used after it is released -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeUse-after-release -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextuseAfterRelease -// CHECK-NEXT: issue_hash7 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line2052 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line2057 -// CHECK-NEXT: col19 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2057 -// CHECK-NEXT: col19 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2057 -// CHECK-NEXT: col37 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2057 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2057 -// CHECK-NEXT: col11 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2058 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2058 -// CHECK-NEXT: col11 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line2058 -// CHECK-NEXT: col22 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2058 -// CHECK-NEXT: col22 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2058 -// CHECK-NEXT: col39 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2058 -// CHECK-NEXT: col36 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2058 -// CHECK-NEXT: col38 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object autoreleased -// CHECK-NEXT: message -// CHECK-NEXT: Object autoreleased -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2058 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2058 -// CHECK-NEXT: col11 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2059 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2059 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line2059 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2059 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2059 -// CHECK-NEXT: col18 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2059 -// CHECK-NEXT: col12 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2059 -// CHECK-NEXT: col17 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Reference count incremented. The object now has a +2 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Reference count incremented. The object now has a +2 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2059 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2059 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2060 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2060 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line2060 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: object allocated and stored into 'obj' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: object allocated and stored into 'obj' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object stored into 'obj' -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contexttestAutoreleaseReturnsInput -// CHECK-NEXT: issue_hash2 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line2060 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line2077 -// CHECK-NEXT: col20 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2077 -// CHECK-NEXT: col20 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2077 -// CHECK-NEXT: col70 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Call to function 'CFArrayCreateMutable' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Call to function 'CFArrayCreateMutable' returns a Core Foundation object with a +1 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2077 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2077 -// CHECK-NEXT: col12 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2078 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2078 -// CHECK-NEXT: col12 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line2078 -// CHECK-NEXT: col34 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2078 -// CHECK-NEXT: col34 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2078 -// CHECK-NEXT: col62 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2078 -// CHECK-NEXT: col48 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2078 -// CHECK-NEXT: col61 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object autoreleased -// CHECK-NEXT: message -// CHECK-NEXT: Object autoreleased -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2078 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2078 -// CHECK-NEXT: col12 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2079 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2079 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line2079 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2079 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2079 -// CHECK-NEXT: col17 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2079 -// CHECK-NEXT: col12 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2079 -// CHECK-NEXT: col16 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Reference count incremented. The object now has a +2 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Reference count incremented. The object now has a +2 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2079 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2079 -// CHECK-NEXT: col10 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2080 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2080 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line2080 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object leaked: object allocated and stored into 'arr' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: message -// CHECK-NEXT: Object leaked: object allocated and stored into 'arr' is not referenced later in this execution path and has a retain count of +1 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionPotential leak of an object stored into 'arr' -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeLeak -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextautoreleaseReturningTypedObject -// CHECK-NEXT: issue_hash1 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line2080 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: path -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2091 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2091 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2094 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2094 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line2094 -// CHECK-NEXT: col19 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2094 -// CHECK-NEXT: col19 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2094 -// CHECK-NEXT: col20 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: NSNumber literal is an object with a +0 retain count -// CHECK-NEXT: message -// CHECK-NEXT: NSNumber literal is an object with a +0 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2094 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2094 -// CHECK-NEXT: col4 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2095 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2095 -// CHECK-NEXT: col15 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line2095 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: ranges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2095 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2095 -// CHECK-NEXT: col27 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2095 -// CHECK-NEXT: col17 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2095 -// CHECK-NEXT: col26 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object autoreleased -// CHECK-NEXT: message -// CHECK-NEXT: Object autoreleased -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindcontrol -// CHECK-NEXT: edges -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: start -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2095 -// CHECK-NEXT: col3 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2095 -// CHECK-NEXT: col15 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: end -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2096 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: line2096 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: kindevent -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line2096 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: depth0 -// CHECK-NEXT: extended_message -// CHECK-NEXT: Object was autoreleased but has a +0 retain count -// CHECK-NEXT: message -// CHECK-NEXT: Object was autoreleased but has a +0 retain count -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: descriptionObject autoreleased too many times -// CHECK-NEXT: categoryMemory (Core Foundation/Objective-C) -// CHECK-NEXT: typeObject autoreleased too many times -// CHECK-NEXT: issue_context_kindfunction -// CHECK-NEXT: issue_contextautoreleaseObjC -// CHECK-NEXT: issue_hash6 -// CHECK-NEXT: location -// CHECK-NEXT: -// CHECK-NEXT: line2096 -// CHECK-NEXT: col1 -// CHECK-NEXT: file0 -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -// CHECK-NEXT: -- cgit v1.2.3 From 05aaf6c929cb1df38620383bc9d79d1fd1a2e571 Mon Sep 17 00:00:00 2001 From: Teresa Johnson Date: Fri, 11 Jan 2019 18:32:07 +0000 Subject: [LTO] Add option to enable LTOUnit splitting, and disable unless needed Summary: Adds a new -f[no]split-lto-unit flag that is disabled by default to control module splitting during ThinLTO. It is automatically enabled for -fsanitize=cfi and -fwhole-program-vtables. The new EnableSplitLTOUnit codegen flag is passed down to llvm via a new module flag of the same name. Depends on D53890. Reviewers: pcc Subscribers: ormris, mehdi_amini, inglorion, eraman, steven_wu, dexonsmith, cfe-commits, llvm-commits Differential Revision: https://reviews.llvm.org/D53891 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350949 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/CodeGenOptions.def | 4 ++++ include/clang/Driver/Options.td | 5 +++++ include/clang/Driver/SanitizerArgs.h | 1 + lib/CodeGen/BackendUtil.cpp | 30 +++++++++++++++++--------- lib/Driver/SanitizerArgs.cpp | 2 ++ lib/Driver/ToolChains/Clang.cpp | 11 ++++++++++ lib/Frontend/CompilerInvocation.cpp | 1 + test/CodeGen/thinlto-distributed-cfi-devirt.ll | 2 +- test/CodeGen/thinlto-distributed-cfi.ll | 2 +- test/CodeGenCXX/no-lto-unit.cpp | 2 ++ test/CodeGenCXX/type-metadata-thinlto.cpp | 4 +++- test/Driver/split-lto-unit.c | 10 +++++++++ 12 files changed, 61 insertions(+), 13 deletions(-) create mode 100644 test/Driver/split-lto-unit.c diff --git a/include/clang/Basic/CodeGenOptions.def b/include/clang/Basic/CodeGenOptions.def index 952aa588b6..ed2387b9a2 100644 --- a/include/clang/Basic/CodeGenOptions.def +++ b/include/clang/Basic/CodeGenOptions.def @@ -116,6 +116,10 @@ CODEGENOPT(PrepareForThinLTO , 1, 0) ///< Set when -flto=thin is enabled on the ///< compile step. CODEGENOPT(LTOUnit, 1, 0) ///< Emit IR to support LTO unit features (CFI, whole ///< program vtable opt). +CODEGENOPT(EnableSplitLTOUnit, 1, 0) ///< Enable LTO unit splitting to support + /// CFI and traditional whole program + /// devirtualization that require whole + /// program IR support. CODEGENOPT(IncrementalLinkerCompatible, 1, 0) ///< Emit an object file which can ///< be used with an incremental ///< linker. diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td index bb4436a638..72ded521bd 100644 --- a/include/clang/Driver/Options.td +++ b/include/clang/Driver/Options.td @@ -1776,6 +1776,11 @@ def fwhole_program_vtables : Flag<["-"], "fwhole-program-vtables">, Group; def fno_whole_program_vtables : Flag<["-"], "fno-whole-program-vtables">, Group, Flags<[CoreOption]>; +def fsplit_lto_unit : Flag<["-"], "fsplit-lto-unit">, Group, + Flags<[CoreOption, CC1Option]>, + HelpText<"Enables splitting of the LTO unit.">; +def fno_split_lto_unit : Flag<["-"], "fno-split-lto-unit">, Group, + Flags<[CoreOption]>; def fforce_emit_vtables : Flag<["-"], "fforce-emit-vtables">, Group, Flags<[CC1Option]>, HelpText<"Emits more virtual tables to improve devirtualization">; diff --git a/include/clang/Driver/SanitizerArgs.h b/include/clang/Driver/SanitizerArgs.h index 02338c2216..e590a49dee 100644 --- a/include/clang/Driver/SanitizerArgs.h +++ b/include/clang/Driver/SanitizerArgs.h @@ -81,6 +81,7 @@ class SanitizerArgs { bool requiresPIE() const; bool needsUnwindTables() const; + bool needsLTO() const; bool linkCXXRuntimes() const { return LinkCXXRuntimes; } bool hasCrossDsoCfi() const { return CfiCrossDso; } bool hasAnySanitizer() const { return !Sanitizers.empty(); } diff --git a/lib/CodeGen/BackendUtil.cpp b/lib/CodeGen/BackendUtil.cpp index 1311af9168..3e0651978b 100644 --- a/lib/CodeGen/BackendUtil.cpp +++ b/lib/CodeGen/BackendUtil.cpp @@ -814,6 +814,8 @@ void EmitAssemblyHelper::EmitAssembly(BackendAction Action, if (!ThinLinkOS) return; } + TheModule->addModuleFlag(Module::Error, "EnableSplitLTOUnit", + CodeGenOpts.EnableSplitLTOUnit); PerModulePasses.add(createWriteThinLTOBitcodePass( *OS, ThinLinkOS ? &ThinLinkOS->os() : nullptr)); } else { @@ -824,12 +826,15 @@ void EmitAssemblyHelper::EmitAssembly(BackendAction Action, !CodeGenOpts.DisableLLVMPasses && llvm::Triple(TheModule->getTargetTriple()).getVendor() != llvm::Triple::Apple); - if (EmitLTOSummary && !TheModule->getModuleFlag("ThinLTO")) - TheModule->addModuleFlag(Module::Error, "ThinLTO", uint32_t(0)); + if (EmitLTOSummary) { + if (!TheModule->getModuleFlag("ThinLTO")) + TheModule->addModuleFlag(Module::Error, "ThinLTO", uint32_t(0)); + TheModule->addModuleFlag(Module::Error, "EnableSplitLTOUnit", + CodeGenOpts.EnableSplitLTOUnit); + } - PerModulePasses.add( - createBitcodeWriterPass(*OS, CodeGenOpts.EmitLLVMUseLists, - EmitLTOSummary)); + PerModulePasses.add(createBitcodeWriterPass( + *OS, CodeGenOpts.EmitLLVMUseLists, EmitLTOSummary)); } break; @@ -1054,6 +1059,8 @@ void EmitAssemblyHelper::EmitAssemblyWithNewPassManager( if (!ThinLinkOS) return; } + TheModule->addModuleFlag(Module::Error, "EnableSplitLTOUnit", + CodeGenOpts.EnableSplitLTOUnit); MPM.addPass(ThinLTOBitcodeWriterPass(*OS, ThinLinkOS ? &ThinLinkOS->os() : nullptr)); } else { @@ -1064,11 +1071,14 @@ void EmitAssemblyHelper::EmitAssemblyWithNewPassManager( !CodeGenOpts.DisableLLVMPasses && llvm::Triple(TheModule->getTargetTriple()).getVendor() != llvm::Triple::Apple); - if (EmitLTOSummary && !TheModule->getModuleFlag("ThinLTO")) - TheModule->addModuleFlag(Module::Error, "ThinLTO", uint32_t(0)); - - MPM.addPass(BitcodeWriterPass(*OS, CodeGenOpts.EmitLLVMUseLists, - EmitLTOSummary)); + if (EmitLTOSummary) { + if (!TheModule->getModuleFlag("ThinLTO")) + TheModule->addModuleFlag(Module::Error, "ThinLTO", uint32_t(0)); + TheModule->addModuleFlag(Module::Error, "EnableSplitLTOUnit", + CodeGenOpts.EnableSplitLTOUnit); + } + MPM.addPass( + BitcodeWriterPass(*OS, CodeGenOpts.EmitLLVMUseLists, EmitLTOSummary)); } break; diff --git a/lib/Driver/SanitizerArgs.cpp b/lib/Driver/SanitizerArgs.cpp index 6667cbb347..1a46073aaa 100644 --- a/lib/Driver/SanitizerArgs.cpp +++ b/lib/Driver/SanitizerArgs.cpp @@ -207,6 +207,8 @@ bool SanitizerArgs::needsUnwindTables() const { return Sanitizers.Mask & NeedsUnwindTables; } +bool SanitizerArgs::needsLTO() const { return Sanitizers.Mask & NeedsLTO; } + SanitizerArgs::SanitizerArgs(const ToolChain &TC, const llvm::opt::ArgList &Args) { SanitizerMask AllRemove = 0; // During the loop below, the accumulated set of diff --git a/lib/Driver/ToolChains/Clang.cpp b/lib/Driver/ToolChains/Clang.cpp index eb88a71e49..4b99992527 100644 --- a/lib/Driver/ToolChains/Clang.cpp +++ b/lib/Driver/ToolChains/Clang.cpp @@ -5226,6 +5226,17 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-fwhole-program-vtables"); } + bool RequiresSplitLTOUnit = WholeProgramVTables || Sanitize.needsLTO(); + bool SplitLTOUnit = + Args.hasFlag(options::OPT_fsplit_lto_unit, + options::OPT_fno_split_lto_unit, RequiresSplitLTOUnit); + if (RequiresSplitLTOUnit && !SplitLTOUnit) + D.Diag(diag::err_drv_argument_not_allowed_with) + << "-fno-split-lto-unit" + << (WholeProgramVTables ? "-fwhole-program-vtables" : "-fsanitize=cfi"); + if (SplitLTOUnit) + CmdArgs.push_back("-fsplit-lto-unit"); + if (Arg *A = Args.getLastArg(options::OPT_fexperimental_isel, options::OPT_fno_experimental_isel)) { CmdArgs.push_back("-mllvm"); diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 1e857355b3..3e6528c259 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -907,6 +907,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << S; } Opts.LTOUnit = Args.hasFlag(OPT_flto_unit, OPT_fno_lto_unit, false); + Opts.EnableSplitLTOUnit = Args.hasArg(OPT_fsplit_lto_unit); if (Arg *A = Args.getLastArg(OPT_fthinlto_index_EQ)) { if (IK.getLanguage() != InputKind::LLVM_IR) Diags.Report(diag::err_drv_argument_only_allowed_with) diff --git a/test/CodeGen/thinlto-distributed-cfi-devirt.ll b/test/CodeGen/thinlto-distributed-cfi-devirt.ll index fbcaa773ba..2ecf149b06 100644 --- a/test/CodeGen/thinlto-distributed-cfi-devirt.ll +++ b/test/CodeGen/thinlto-distributed-cfi-devirt.ll @@ -4,7 +4,7 @@ ; It additionally enables -fwhole-program-vtables to get more information in ; TYPE_IDs of GLOBALVAL_SUMMARY_BLOCK. -; RUN: opt -thinlto-bc -o %t.o %s +; RUN: opt -thinlto-bc -thinlto-split-lto-unit -o %t.o %s ; FIXME: Fix machine verifier issues and remove -verify-machineinstrs=0. PR39436. ; RUN: llvm-lto2 run -thinlto-distributed-indexes %t.o \ diff --git a/test/CodeGen/thinlto-distributed-cfi.ll b/test/CodeGen/thinlto-distributed-cfi.ll index 055b5971eb..b2ede5395d 100644 --- a/test/CodeGen/thinlto-distributed-cfi.ll +++ b/test/CodeGen/thinlto-distributed-cfi.ll @@ -2,7 +2,7 @@ ; Backend test for distribute ThinLTO with CFI. -; RUN: opt -thinlto-bc -o %t.o %s +; RUN: opt -thinlto-bc -thinlto-split-lto-unit -o %t.o %s ; RUN: llvm-lto2 run -thinlto-distributed-indexes %t.o \ ; RUN: -o %t2.index \ diff --git a/test/CodeGenCXX/no-lto-unit.cpp b/test/CodeGenCXX/no-lto-unit.cpp index 24b8fd0154..3797f0742e 100644 --- a/test/CodeGenCXX/no-lto-unit.cpp +++ b/test/CodeGenCXX/no-lto-unit.cpp @@ -2,6 +2,8 @@ // RUN: llvm-dis -o - %t | FileCheck %s // RUN: %clang_cc1 -flto=thin -flto-unit -fno-lto-unit -triple x86_64-unknown-linux -fvisibility hidden -emit-llvm-bc -o %t %s // RUN: llvm-dis -o - %t | FileCheck %s +// RUN: llvm-bcanalyzer -dump %t | FileCheck %s --check-prefix=NOLTOUNIT +// NOLTOUNIT: // CHECK-NOT: !type class A { diff --git a/test/CodeGenCXX/type-metadata-thinlto.cpp b/test/CodeGenCXX/type-metadata-thinlto.cpp index 2a586fc4c3..8bf39f129c 100644 --- a/test/CodeGenCXX/type-metadata-thinlto.cpp +++ b/test/CodeGenCXX/type-metadata-thinlto.cpp @@ -1,5 +1,7 @@ -// RUN: %clang_cc1 -flto=thin -flto-unit -triple x86_64-unknown-linux -fvisibility hidden -emit-llvm-bc -o %t %s +// RUN: %clang_cc1 -flto=thin -flto-unit -fsplit-lto-unit -triple x86_64-unknown-linux -fvisibility hidden -emit-llvm-bc -o %t %s // RUN: llvm-modextract -o - -n 1 %t | llvm-dis | FileCheck %s +// RUN: llvm-modextract -b -o - -n 1 %t | llvm-bcanalyzer -dump | FileCheck %s --check-prefix=LTOUNIT +// LTOUNIT: // CHECK: @_ZTV1A = linkonce_odr class A { diff --git a/test/Driver/split-lto-unit.c b/test/Driver/split-lto-unit.c new file mode 100644 index 0000000000..fab5790c26 --- /dev/null +++ b/test/Driver/split-lto-unit.c @@ -0,0 +1,10 @@ +// RUN: %clang -target x86_64-unknown-linux -### %s -flto=thin 2>&1 | FileCheck --check-prefix=NOUNIT %s +// RUN: %clang -target x86_64-unknown-linux -### %s -flto=thin -fsplit-lto-unit 2>&1 | FileCheck --check-prefix=UNIT %s +// RUN: %clang -target x86_64-unknown-linux -### %s -flto=thin -fno-split-lto-unit 2>&1 | FileCheck --check-prefix=NOUNIT %s +// RUN: %clang -target x86_64-unknown-linux -### %s -flto=thin -fno-split-lto-unit -fwhole-program-vtables 2>&1 | FileCheck --check-prefix=ERROR1 %s +// RUN: %clang -target x86_64-unknown-linux -### %s -flto=thin -fno-split-lto-unit -fsanitize=cfi 2>&1 | FileCheck --check-prefix=ERROR2 %s + +// UNIT: "-fsplit-lto-unit" +// NOUNIT-NOT: "-fsplit-lto-unit" +// ERROR1: error: invalid argument '-fno-split-lto-unit' not allowed with '-fwhole-program-vtables' +// ERROR2: error: invalid argument '-fno-split-lto-unit' not allowed with '-fsanitize=cfi' -- cgit v1.2.3 From 1e1d2639a45788c521e9476987031db6e5b65650 Mon Sep 17 00:00:00 2001 From: Vedant Kumar Date: Fri, 11 Jan 2019 18:51:02 +0000 Subject: [MergeFunc] Update clang test for r350939 In r350939, the MergeFunc pass learned to erase duplicate functions which are discardable if unused. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350952 91177308-0d34-0410-b5e6-96231b3b80d8 --- test/CodeGenCXX/merge-functions.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/test/CodeGenCXX/merge-functions.cpp b/test/CodeGenCXX/merge-functions.cpp index 2137f19c40..20a286e022 100644 --- a/test/CodeGenCXX/merge-functions.cpp +++ b/test/CodeGenCXX/merge-functions.cpp @@ -1,5 +1,5 @@ // REQUIRES: x86-registered-target -// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -O1 -fmerge-functions -emit-llvm -o - -x c++ < %s | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -O1 -fmerge-functions -emit-llvm -o - -x c++ < %s | FileCheck %s -implicit-check-not=_ZN1A1gEiPi // Basic functionality test. Function merging doesn't kick in on functions that // are too simple. @@ -9,6 +9,4 @@ struct A { virtual int g(int x, int *p) { return x ? *p : 1; } } a; -// CHECK: define {{.*}} @_ZN1A1gEiPi -// CHECK-NEXT: tail call i32 @_ZN1A1fEiPi -// CHECK-NEXT: ret +// CHECK: define {{.*}} @_ZN1A1fEiPi -- cgit v1.2.3 From e234e3263d0bf538e9c5682ff0b50c230ebe7b24 Mon Sep 17 00:00:00 2001 From: Evandro Menezes Date: Fri, 11 Jan 2019 18:54:41 +0000 Subject: [test] Update support for Exynos M4 (NFC) Update test cases for Exynos M4. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350954 91177308-0d34-0410-b5e6-96231b3b80d8 --- test/CodeGen/arm-target-features.c | 4 +++- test/Driver/aarch64-cpus.c | 9 ++++++--- test/Driver/arm-cortex-cpus.c | 30 ++++++++++++++++------------- test/Preprocessor/aarch64-target-features.c | 3 ++- 4 files changed, 28 insertions(+), 18 deletions(-) diff --git a/test/CodeGen/arm-target-features.c b/test/CodeGen/arm-target-features.c index 6bc56be4f4..ca574cc05d 100644 --- a/test/CodeGen/arm-target-features.c +++ b/test/CodeGen/arm-target-features.c @@ -28,9 +28,11 @@ // RUN: %clang_cc1 -triple thumbv8-linux-gnueabihf -target-cpu exynos-m1 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-BASIC-V8 // RUN: %clang_cc1 -triple thumbv8-linux-gnueabihf -target-cpu exynos-m2 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-BASIC-V8 // RUN: %clang_cc1 -triple thumbv8-linux-gnueabihf -target-cpu exynos-m3 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-BASIC-V8 -// RUN: %clang_cc1 -triple thumbv8-linux-gnueabihf -target-cpu exynos-m4 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-BASIC-V8 // CHECK-BASIC-V8: "target-features"="+armv8-a,+crc,+crypto,+dsp,+fp-armv8,+hwdiv,+hwdiv-arm,+neon,+thumb-mode" +// RUN: %clang_cc1 -triple thumbv8-linux-gnueabihf -target-cpu exynos-m4 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-BASIC-V82 +// CHECK-BASIC-V82: "target-features"="+armv8.2-a,+crc,+crypto,+dotprod,+dsp,+fp-armv8,+hwdiv,+hwdiv-arm,+neon,+ras,+thumb-mode" + // RUN: %clang_cc1 -triple armv8-linux-gnueabi -target-cpu cortex-a53 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-BASIC-V8-ARM // CHECK-BASIC-V8-ARM: "target-features"="+armv8-a,+crc,+crypto,+dsp,+fp-armv8,+hwdiv,+hwdiv-arm,+neon,-thumb-mode" diff --git a/test/Driver/aarch64-cpus.c b/test/Driver/aarch64-cpus.c index 75174b7904..900162f954 100644 --- a/test/Driver/aarch64-cpus.c +++ b/test/Driver/aarch64-cpus.c @@ -169,8 +169,9 @@ // RUN: %clang -target aarch64_be -mtune=exynos-m4 -### -c %s 2>&1 | FileCheck -check-prefix=M4-TUNE %s // RUN: %clang -target aarch64 -mbig-endian -mtune=exynos-m4 -### -c %s 2>&1 | FileCheck -check-prefix=M4-TUNE %s // RUN: %clang -target aarch64_be -mbig-endian -mtune=exynos-m4 -### -c %s 2>&1 | FileCheck -check-prefix=M4-TUNE %s -// M4: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "exynos-m4" +// M4: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "exynos-m4" "-target-feature" "+v8.2a" // M4-TUNE: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" +// M4-TUNE-NOT: "+v8.2a" // RUN: %clang -target arm64 -mcpu=exynos-m1 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-M1 %s // RUN: %clang -target arm64 -mlittle-endian -mcpu=exynos-m1 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-M1 %s @@ -197,8 +198,9 @@ // RUN: %clang -target arm64 -mlittle-endian -mcpu=exynos-m4 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-M4 %s // RUN: %clang -target arm64 -mtune=exynos-m4 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-M4-TUNE %s // RUN: %clang -target arm64 -mlittle-endian -mtune=exynos-m4 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-M4-TUNE %s -// ARM64-M4: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "exynos-m4" +// ARM64-M4: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "exynos-m4" "-target-feature" "+v8.2a" // ARM64-M4-TUNE: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "generic" +// ARM64-M4-TUNE-NOT: "+v8.2a" // RUN: %clang -target aarch64 -mcpu=falkor -### -c %s 2>&1 | FileCheck -check-prefix=FALKOR %s // RUN: %clang -target aarch64 -mlittle-endian -mcpu=falkor -### -c %s 2>&1 | FileCheck -check-prefix=FALKOR %s @@ -338,8 +340,9 @@ // RUN: %clang -target aarch64_be -mtune=exynos-m4 -### -c %s 2>&1 | FileCheck -check-prefix=M4-BE-TUNE %s // RUN: %clang -target aarch64 -mbig-endian -mtune=exynos-m4 -### -c %s 2>&1 | FileCheck -check-prefix=M4-BE-TUNE %s // RUN: %clang -target aarch64_be -mbig-endian -mtune=exynos-m4 -### -c %s 2>&1 | FileCheck -check-prefix=M4-BE-TUNE %s -// M4-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "exynos-m4" +// M4-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "exynos-m4" "-target-feature" "+v8.2a" // M4-BE-TUNE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic" +// M4-BE-TUNE-NOT: "+v8.2a" // RUN: %clang -target aarch64_be -mcpu=thunderx2t99 -### -c %s 2>&1 | FileCheck -check-prefix=THUNDERX2T99-BE %s // RUN: %clang -target aarch64 -mbig-endian -mcpu=thunderx2t99 -### -c %s 2>&1 | FileCheck -check-prefix=THUNDERX2T99-BE %s diff --git a/test/Driver/arm-cortex-cpus.c b/test/Driver/arm-cortex-cpus.c index 5eb95f5fd6..04554ee3bd 100644 --- a/test/Driver/arm-cortex-cpus.c +++ b/test/Driver/arm-cortex-cpus.c @@ -660,17 +660,18 @@ // RUN: %clang -target arm -mcpu=exynos-m1 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV8A %s // RUN: %clang -target arm -mcpu=exynos-m2 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV8A %s // RUN: %clang -target arm -mcpu=exynos-m3 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV8A %s -// RUN: %clang -target arm -mcpu=exynos-m4 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV8A %s // RUN: %clang -target arm -mcpu=exynos-m1 -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV8A %s // RUN: %clang -target arm -mcpu=exynos-m2 -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV8A %s // RUN: %clang -target arm -mcpu=exynos-m3 -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV8A %s -// RUN: %clang -target arm -mcpu=exynos-m4 -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV8A %s // CHECK-CPUV8A: "-cc1"{{.*}} "-triple" "armv8-{{.*}} // RUN: %clang -target arm -mcpu=cortex-a55 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV82A %s // RUN: %clang -target arm -mcpu=cortex-a75 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV82A %s // RUN: %clang -target arm -mcpu=cortex-a55 -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV82A %s // RUN: %clang -target arm -mcpu=cortex-a75 -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV82A %s +// +// RUN: %clang -target arm -mcpu=exynos-m4 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV82A %s +// RUN: %clang -target arm -mcpu=exynos-m4 -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV82A %s // CHECK-CPUV82A: "-cc1"{{.*}} "-triple" "armv8.2a-{{.*}} // RUN: %clang -target armeb -mcpu=cortex-a32 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV8A %s @@ -689,17 +690,18 @@ // RUN: %clang -target armeb -mcpu=exynos-m1 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV8A %s // RUN: %clang -target armeb -mcpu=exynos-m2 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV8A %s // RUN: %clang -target armeb -mcpu=exynos-m3 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV8A %s -// RUN: %clang -target armeb -mcpu=exynos-m4 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV8A %s // RUN: %clang -target arm -mcpu=exynos-m1 -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV8A %s // RUN: %clang -target arm -mcpu=exynos-m2 -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV8A %s // RUN: %clang -target arm -mcpu=exynos-m3 -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV8A %s -// RUN: %clang -target arm -mcpu=exynos-m4 -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV8A %s // CHECK-BE-CPUV8A: "-cc1"{{.*}} "-triple" "armebv8-{{.*}} // RUN: %clang -target armeb -mcpu=cortex-a55 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A %s // RUN: %clang -target armeb -mcpu=cortex-a75 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A %s // RUN: %clang -target arm -mcpu=cortex-a55 -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A %s // RUN: %clang -target arm -mcpu=cortex-a75 -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A %s +// +// RUN: %clang -target armeb -mcpu=exynos-m4 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A %s +// RUN: %clang -target arm -mcpu=exynos-m4 -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A %s // CHECK-BE-CPUV82A: "-cc1"{{.*}} "-triple" "armebv8.2a-{{.*}} // RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-r52 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV8R %s @@ -721,18 +723,19 @@ // RUN: %clang -target arm -mcpu=exynos-m1 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV8A-THUMB %s // RUN: %clang -target arm -mcpu=exynos-m2 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV8A-THUMB %s // RUN: %clang -target arm -mcpu=exynos-m3 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV8A-THUMB %s -// RUN: %clang -target arm -mcpu=exynos-m4 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV8A-THUMB %s // RUN: %clang -target arm -mcpu=exynos-m1 -mlittle-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV8A-THUMB %s // RUN: %clang -target arm -mcpu=exynos-m2 -mlittle-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV8A-THUMB %s // RUN: %clang -target arm -mcpu=exynos-m3 -mlittle-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV8A-THUMB %s -// RUN: %clang -target arm -mcpu=exynos-m4 -mlittle-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV8A-THUMB %s // CHECK-CPUV8A-THUMB: "-cc1"{{.*}} "-triple" "thumbv8-{{.*}} -// RUN: %clang -target arm -mcpu=cortex-a55 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECKCPUV82A-THUMB %s -// RUN: %clang -target arm -mcpu=cortex-a75 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECKCPUV82A-THUMB %s -// RUN: %clang -target arm -mcpu=cortex-a55 -mlittle-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECKCPUV82A-THUMB %s -// RUN: %clang -target arm -mcpu=cortex-a75 -mlittle-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECKCPUV82A-THUMB %s -// CHECKCPUV82A-THUMB: "-cc1"{{.*}} "-triple" "thumbv8.2a-{{.*}} +// RUN: %clang -target arm -mcpu=cortex-a55 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV82A-THUMB %s +// RUN: %clang -target arm -mcpu=cortex-a75 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV82A-THUMB %s +// RUN: %clang -target arm -mcpu=cortex-a55 -mlittle-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV82A-THUMB %s +// RUN: %clang -target arm -mcpu=cortex-a75 -mlittle-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV82A-THUMB %s +// +// RUN: %clang -target arm -mcpu=exynos-m4 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV82A-THUMB %s +// RUN: %clang -target arm -mcpu=exynos-m4 -mlittle-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV82A-THUMB %s +// CHECK-CPUV82A-THUMB: "-cc1"{{.*}} "-triple" "thumbv8.2a-{{.*}} // RUN: %clang -target armeb -mcpu=cortex-a32 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV8A-THUMB %s // RUN: %clang -target armeb -mcpu=cortex-a35 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV8A-THUMB %s @@ -750,17 +753,18 @@ // RUN: %clang -target armeb -mcpu=exynos-m1 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV8A-THUMB %s // RUN: %clang -target armeb -mcpu=exynos-m2 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV8A-THUMB %s // RUN: %clang -target armeb -mcpu=exynos-m3 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV8A-THUMB %s -// RUN: %clang -target armeb -mcpu=exynos-m4 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV8A-THUMB %s // RUN: %clang -target arm -mcpu=exynos-m1 -mbig-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV8A-THUMB %s // RUN: %clang -target arm -mcpu=exynos-m2 -mbig-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV8A-THUMB %s // RUN: %clang -target arm -mcpu=exynos-m3 -mbig-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV8A-THUMB %s -// RUN: %clang -target arm -mcpu=exynos-m4 -mbig-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV8A-THUMB %s // CHECK-BE-CPUV8A-THUMB: "-cc1"{{.*}} "-triple" "thumbebv8-{{.*}} // RUN: %clang -target armeb -mcpu=cortex-a55 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A-THUMB %s // RUN: %clang -target armeb -mcpu=cortex-a75 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A-THUMB %s // RUN: %clang -target arm -mcpu=cortex-a55 -mbig-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A-THUMB %s // RUN: %clang -target arm -mcpu=cortex-a75 -mbig-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A-THUMB %s +// +// RUN: %clang -target armeb -mcpu=exynos-m4 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A-THUMB %s +// RUN: %clang -target arm -mcpu=exynos-m4 -mbig-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A-THUMB %s // CHECK-BE-CPUV82A-THUMB: "-cc1"{{.*}} "-triple" "thumbebv8.2a-{{.*}} // RUN: %clang -target armv8a-arm-none-eabi -mcpu=cortex-a73 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CORTEX-A73 %s diff --git a/test/Preprocessor/aarch64-target-features.c b/test/Preprocessor/aarch64-target-features.c index 1616b7fc8a..5ab4331346 100644 --- a/test/Preprocessor/aarch64-target-features.c +++ b/test/Preprocessor/aarch64-target-features.c @@ -151,7 +151,7 @@ // RUN: %clang -target aarch64 -mcpu=exynos-m1 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MCPU-M1 %s // RUN: %clang -target aarch64 -mcpu=exynos-m2 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MCPU-M1 %s // RUN: %clang -target aarch64 -mcpu=exynos-m3 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MCPU-M1 %s -// RUN: %clang -target aarch64 -mcpu=exynos-m4 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MCPU-M1 %s +// RUN: %clang -target aarch64 -mcpu=exynos-m4 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MCPU-M4 %s // RUN: %clang -target aarch64 -mcpu=kryo -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MCPU-KRYO %s // RUN: %clang -target aarch64 -mcpu=thunderx2t99 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MCPU-THUNDERX2T99 %s // CHECK-MCPU-CYCLONE: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+neon" "-target-feature" "+crypto" "-target-feature" "+zcm" "-target-feature" "+zcz" @@ -161,6 +161,7 @@ // CHECK-MCPU-A72: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+neon" "-target-feature" "+crc" "-target-feature" "+crypto" // CHECK-MCPU-CORTEX-A73: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+neon" "-target-feature" "+crc" "-target-feature" "+crypto" // CHECK-MCPU-M1: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+neon" "-target-feature" "+crc" "-target-feature" "+crypto" +// CHECK-MCPU-M4: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+neon" "-target-feature" "+crc" "-target-feature" "+crypto" "-target-feature" "+dotprod" "-target-feature" "+fullfp16" // CHECK-MCPU-KRYO: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+neon" "-target-feature" "+crc" "-target-feature" "+crypto" // CHECK-MCPU-THUNDERX2T99: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+neon" "-target-feature" "+crc" "-target-feature" "+crypto" -- cgit v1.2.3 From 0b641d6dce94c10f49c8c6cda512e145cfbf05eb Mon Sep 17 00:00:00 2001 From: Serge Guelton Date: Fri, 11 Jan 2019 19:04:48 +0000 Subject: [Bug 39548][Clang] PGO bootstrap fails with python3: errors in perf-helper.py Current clang fail to bootstrap in PGO mode when only python3 is available, because perf-helper.py is not compatible with python3. Commited on behalf of Romain Geissler. Differential Revision: https://reviews.llvm.org/D54071 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350955 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/perf-training/perf-helper.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/utils/perf-training/perf-helper.py b/utils/perf-training/perf-helper.py index 72b4b4e5a0..65afbb6ed5 100644 --- a/utils/perf-training/perf-helper.py +++ b/utils/perf-training/perf-helper.py @@ -114,7 +114,7 @@ def get_cc1_command_for_args(cmd, env): # Find the cc1 command used by the compiler. To do this we execute the # compiler with '-###' to figure out what it wants to do. cmd = cmd + ['-###'] - cc_output = subprocess.check_output(cmd, stderr=subprocess.STDOUT, env=env).strip() + cc_output = subprocess.check_output(cmd, stderr=subprocess.STDOUT, env=env, universal_newlines=True).strip() cc_commands = [] for ln in cc_output.split('\n'): # Filter out known garbage. @@ -340,7 +340,7 @@ def genOrderFile(args): # If the user gave us a binary, get all the symbols in the binary by # snarfing 'nm' output. if opts.binary_path is not None: - output = subprocess.check_output(['nm', '-P', opts.binary_path]) + output = subprocess.check_output(['nm', '-P', opts.binary_path], universal_newlines=True) lines = output.split("\n") all_symbols = [ln.split(' ',1)[0] for ln in lines -- cgit v1.2.3 From ad55bb6be08026ed754f2c2e7b7c3546b1de9962 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Fri, 11 Jan 2019 19:11:17 +0000 Subject: [ASTDump] Add utility for dumping a label with child nodes Summary: Use it to add optional label nodes to Stmt dumps. This preserves behavior of InitExprList dump: // CHECK-NEXT: `-InitListExpr {{.+}} 'U [3]' // CHECK-NEXT: |-array_filler: InitListExpr {{.+}} 'U' field Field {{.+}} 'i' 'int' // CHECK-NEXT: `-InitListExpr {{.+}} 'U' field Field {{.+}} 'i' 'int' // CHECK-NEXT: `-IntegerLiteral {{.+}} 'int' 1 Reviewers: aaron.ballman Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D55488 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350957 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/TextNodeDumper.h | 14 +++++++++++++- lib/AST/ASTDumper.cpp | 14 +++++++------- test/AST/ast-dump-stmt.cpp | 3 +-- 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/include/clang/AST/TextNodeDumper.h b/include/clang/AST/TextNodeDumper.h index 8b6fde938d..7948fdc696 100644 --- a/include/clang/AST/TextNodeDumper.h +++ b/include/clang/AST/TextNodeDumper.h @@ -41,6 +41,12 @@ class TextTreeStructure { public: /// Add a child of the current node. Calls DoAddChild without arguments template void AddChild(Fn DoAddChild) { + return AddChild("", DoAddChild); + } + + /// Add a child of the current node with an optional label. + /// Calls DoAddChild without arguments. + template void AddChild(StringRef Label, Fn DoAddChild) { // If we're at the top level, there's nothing interesting to do; just // run the dumper. if (TopLevel) { @@ -56,7 +62,10 @@ public: return; } - auto DumpWithIndent = [this, DoAddChild](bool IsLastChild) { + // We need to capture an owning-string in the lambda because the lambda + // is invoked in a deferred manner. + std::string LabelStr = Label; + auto DumpWithIndent = [this, DoAddChild, LabelStr](bool IsLastChild) { // Print out the appropriate tree structure and work out the prefix for // children of this node. For instance: // @@ -73,6 +82,9 @@ public: OS << '\n'; ColorScope Color(OS, ShowColors, IndentColor); OS << Prefix << (IsLastChild ? '`' : '|') << '-'; + if (!LabelStr.empty()) + OS << LabelStr << ": "; + this->Prefix.push_back(IsLastChild ? ' ' : '|'); this->Prefix.push_back(' '); } diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp index 698fca0b33..91ca716bad 100644 --- a/lib/AST/ASTDumper.cpp +++ b/lib/AST/ASTDumper.cpp @@ -61,6 +61,9 @@ namespace { template void dumpChild(Fn DoDumpChild) { NodeDumper.AddChild(DoDumpChild); } + template void dumpChild(StringRef Label, Fn DoDumpChild) { + NodeDumper.AddChild(Label, DoDumpChild); + } public: ASTDumper(raw_ostream &OS, const CommandTraits *Traits, @@ -80,7 +83,7 @@ namespace { void setDeserialize(bool D) { Deserialize = D; } void dumpDecl(const Decl *D); - void dumpStmt(const Stmt *S); + void dumpStmt(const Stmt *S, StringRef Label = {}); // Utilities void dumpType(QualType T) { NodeDumper.dumpType(T); } @@ -1685,8 +1688,8 @@ void ASTDumper::VisitBlockDecl(const BlockDecl *D) { // Stmt dumping methods. //===----------------------------------------------------------------------===// -void ASTDumper::dumpStmt(const Stmt *S) { - dumpChild([=] { +void ASTDumper::dumpStmt(const Stmt *S, StringRef Label) { + dumpChild(Label, [=] { if (!S) { ColorScope Color(OS, ShowColors, NullColor); OS << "<<>>"; @@ -1957,10 +1960,7 @@ void ASTDumper::VisitInitListExpr(const InitListExpr *ILE) { NodeDumper.dumpBareDeclRef(Field); } if (auto *Filler = ILE->getArrayFiller()) { - dumpChild([=] { - OS << "array filler"; - dumpStmt(Filler); - }); + dumpStmt(Filler, "array_filler"); } } diff --git a/test/AST/ast-dump-stmt.cpp b/test/AST/ast-dump-stmt.cpp index 671bdd6454..9df4ee26cd 100644 --- a/test/AST/ast-dump-stmt.cpp +++ b/test/AST/ast-dump-stmt.cpp @@ -91,8 +91,7 @@ void TestUnionInitList() U us[3] = {1}; // CHECK: VarDecl {{.+}} col:5 us 'U [3]' cinit // CHECK-NEXT: `-InitListExpr {{.+}} 'U [3]' -// CHECK-NEXT: |-array filler -// CHECK-NEXT: | `-InitListExpr {{.+}} 'U' field Field {{.+}} 'i' 'int' +// CHECK-NEXT: |-array_filler: InitListExpr {{.+}} 'U' field Field {{.+}} 'i' 'int' // CHECK-NEXT: `-InitListExpr {{.+}} 'U' field Field {{.+}} 'i' 'int' // CHECK-NEXT: `-IntegerLiteral {{.+}} 'int' 1 } -- cgit v1.2.3 From 4c57533ba3d00d3c41b96258eb7b6a4755b55b38 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Fri, 11 Jan 2019 19:16:01 +0000 Subject: Implement Attr dumping in terms of visitors Remove now-vestigial dumpType and dumpBareDeclRef methods. The old tablegen generated code used to expect them to be present, but the new generated code has no such requirement. Reviewers: aaron.ballman Subscribers: mgorny, cfe-commits Differential Revision: https://reviews.llvm.org/D55492 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350958 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/AttrVisitor.h | 76 ++++++++++++++++++++++++++++++++ include/clang/AST/CMakeLists.txt | 9 +++- include/clang/AST/TextNodeDumper.h | 9 +++- lib/AST/ASTDumper.cpp | 27 ++++-------- lib/AST/TextNodeDumper.cpp | 23 ++++++++++ utils/TableGen/ClangAttrEmitter.cpp | 87 ++++++++++++++++++++++++------------- utils/TableGen/TableGen.cpp | 16 ++++--- utils/TableGen/TableGenBackends.h | 5 ++- 8 files changed, 195 insertions(+), 57 deletions(-) create mode 100644 include/clang/AST/AttrVisitor.h diff --git a/include/clang/AST/AttrVisitor.h b/include/clang/AST/AttrVisitor.h new file mode 100644 index 0000000000..867f9e7ad1 --- /dev/null +++ b/include/clang/AST/AttrVisitor.h @@ -0,0 +1,76 @@ +//===- AttrVisitor.h - Visitor for Attr subclasses --------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the AttrVisitor interface. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_ATTRVISITOR_H +#define LLVM_CLANG_AST_ATTRVISITOR_H + +#include "clang/AST/Attr.h" + +namespace clang { + +namespace attrvisitor { + +/// A simple visitor class that helps create attribute visitors. +template