From owner-svn-src-vendor@freebsd.org Thu Jun 1 20:58:54 2017 Return-Path: Delivered-To: svn-src-vendor@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 2C4BBB7EAC2; Thu, 1 Jun 2017 20:58:54 +0000 (UTC) (envelope-from dim@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id B1A6167CBF; Thu, 1 Jun 2017 20:58:53 +0000 (UTC) (envelope-from dim@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v51KwqLY035097; Thu, 1 Jun 2017 20:58:52 GMT (envelope-from dim@FreeBSD.org) Received: (from dim@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v51KwnaF035068; Thu, 1 Jun 2017 20:58:49 GMT (envelope-from dim@FreeBSD.org) Message-Id: <201706012058.v51KwnaF035068@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: dim set sender to dim@FreeBSD.org using -f From: Dimitry Andric Date: Thu, 1 Jun 2017 20:58:49 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-vendor@freebsd.org Subject: svn commit: r319463 - in vendor/clang/dist: docs include/clang/AST include/clang/Basic include/clang/Driver include/clang/Lex lib/AST lib/Basic lib/CodeGen lib/Driver/ToolChains lib/Format lib/Fron... X-SVN-Group: vendor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-vendor@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for the vendor work area tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 01 Jun 2017 20:58:54 -0000 Author: dim Date: Thu Jun 1 20:58:49 2017 New Revision: 319463 URL: https://svnweb.freebsd.org/changeset/base/319463 Log: Vendor import of clang trunk r304460: https://llvm.org/svn/llvm-project/cfe/trunk@304460 Added: vendor/clang/dist/test/CodeGen/ubsan-pointer-overflow.m vendor/clang/dist/test/CodeGenCoroutines/coro-await-domination.cpp (contents, props changed) vendor/clang/dist/test/CodeGenOpenCL/kernels-have-spir-cc-by-default.cl vendor/clang/dist/test/Driver/cl-cc-flags.c (contents, props changed) vendor/clang/dist/test/Driver/cl-diagnostics.c (contents, props changed) vendor/clang/dist/test/Driver/cl-include.c (contents, props changed) vendor/clang/dist/test/SemaCXX/coroutine-uninitialized-warning-crash.cpp (contents, props changed) Modified: vendor/clang/dist/docs/Modules.rst vendor/clang/dist/docs/ThinLTO.rst vendor/clang/dist/docs/UndefinedBehaviorSanitizer.rst vendor/clang/dist/include/clang/AST/VTableBuilder.h vendor/clang/dist/include/clang/Basic/DiagnosticGroups.td vendor/clang/dist/include/clang/Basic/DiagnosticIDs.h vendor/clang/dist/include/clang/Basic/DiagnosticSemaKinds.td vendor/clang/dist/include/clang/Basic/Module.h vendor/clang/dist/include/clang/Basic/Sanitizers.def vendor/clang/dist/include/clang/Basic/TokenKinds.def vendor/clang/dist/include/clang/Basic/TypeTraits.h vendor/clang/dist/include/clang/Driver/CLCompatOptions.td vendor/clang/dist/include/clang/Driver/Options.td vendor/clang/dist/include/clang/Lex/HeaderSearch.h vendor/clang/dist/lib/AST/ODRHash.cpp vendor/clang/dist/lib/Basic/Targets.cpp vendor/clang/dist/lib/CodeGen/ABIInfo.h vendor/clang/dist/lib/CodeGen/CGCall.cpp vendor/clang/dist/lib/CodeGen/CGCleanup.cpp vendor/clang/dist/lib/CodeGen/CGExpr.cpp vendor/clang/dist/lib/CodeGen/CGExprScalar.cpp vendor/clang/dist/lib/CodeGen/CGObjCRuntime.cpp vendor/clang/dist/lib/CodeGen/CGVTables.cpp vendor/clang/dist/lib/CodeGen/CodeGenFunction.h vendor/clang/dist/lib/CodeGen/CodeGenModule.cpp vendor/clang/dist/lib/CodeGen/CodeGenModule.h vendor/clang/dist/lib/CodeGen/ItaniumCXXABI.cpp vendor/clang/dist/lib/CodeGen/MicrosoftCXXABI.cpp vendor/clang/dist/lib/CodeGen/TargetInfo.cpp vendor/clang/dist/lib/Driver/ToolChains/Clang.cpp vendor/clang/dist/lib/Driver/ToolChains/Gnu.cpp vendor/clang/dist/lib/Format/UnwrappedLineParser.cpp vendor/clang/dist/lib/Frontend/CompilerInvocation.cpp vendor/clang/dist/lib/Frontend/FrontendAction.cpp vendor/clang/dist/lib/Lex/HeaderSearch.cpp vendor/clang/dist/lib/Sema/SemaCoroutine.cpp vendor/clang/dist/lib/Sema/SemaDecl.cpp vendor/clang/dist/lib/Sema/SemaDeclObjC.cpp vendor/clang/dist/lib/Sema/SemaExprCXX.cpp vendor/clang/dist/lib/Sema/SemaOverload.cpp vendor/clang/dist/lib/Sema/SemaType.cpp vendor/clang/dist/lib/Serialization/ASTWriter.cpp vendor/clang/dist/test/CodeGen/arm_neon_intrinsics.c vendor/clang/dist/test/CodeGenCXX/stmtexpr.cpp vendor/clang/dist/test/CodeGenCXX/strict-vtable-pointers.cpp vendor/clang/dist/test/CodeGenCXX/vtable-available-externally.cpp vendor/clang/dist/test/CodeGenCXX/vtable-linkage.cpp vendor/clang/dist/test/CodeGenObjC/parameterized_classes.m vendor/clang/dist/test/CodeGenOpenCL/bool_cast.cl vendor/clang/dist/test/CodeGenOpenCL/kernel-attributes.cl vendor/clang/dist/test/CodeGenOpenCL/kernel-metadata.cl vendor/clang/dist/test/CodeGenOpenCL/pipe_types.cl vendor/clang/dist/test/CodeGenOpenCL/ptx-calls.cl vendor/clang/dist/test/CodeGenOpenCL/ptx-kernels.cl vendor/clang/dist/test/Driver/arm-cortex-cpus.c vendor/clang/dist/test/Driver/cl-zc.cpp vendor/clang/dist/test/Driver/fsanitize.c vendor/clang/dist/test/Driver/gold-lto.c vendor/clang/dist/test/Driver/nacl-direct.c vendor/clang/dist/test/Driver/openmp-offload.c vendor/clang/dist/test/Misc/diag-mapping2.c vendor/clang/dist/test/Modules/odr_hash.cpp vendor/clang/dist/test/Modules/preprocess-module.cpp vendor/clang/dist/test/Modules/preprocess-nested.cpp vendor/clang/dist/test/Modules/preprocess-unavailable.cpp vendor/clang/dist/test/SemaCXX/attr-require-constant-initialization.cpp vendor/clang/dist/test/SemaCXX/coreturn.cpp vendor/clang/dist/test/SemaCXX/coroutines.cpp vendor/clang/dist/test/SemaCXX/type-traits.cpp vendor/clang/dist/test/SemaObjC/attr-deprecated.m vendor/clang/dist/test/SemaObjC/class-unavail-warning.m vendor/clang/dist/test/SemaObjC/warn-deprecated-implementations.m vendor/clang/dist/unittests/Format/FormatTestJS.cpp vendor/clang/dist/utils/TableGen/ClangAttrEmitter.cpp vendor/clang/dist/utils/TableGen/ClangDiagnosticsEmitter.cpp vendor/clang/dist/utils/TableGen/ClangOptionDocEmitter.cpp vendor/clang/dist/utils/TableGen/ClangSACheckersEmitter.cpp Modified: vendor/clang/dist/docs/Modules.rst ============================================================================== --- vendor/clang/dist/docs/Modules.rst Thu Jun 1 20:58:42 2017 (r319462) +++ vendor/clang/dist/docs/Modules.rst Thu Jun 1 20:58:49 2017 (r319463) @@ -403,7 +403,7 @@ A *requires-declaration* specifies the requirements th *feature*: ``!``:sub:`opt` *identifier* -The requirements clause allows specific modules or submodules to specify that they are only accessible with certain language dialects or on certain platforms. The feature list is a set of identifiers, defined below. If any of the features is not available in a given translation unit, that translation unit shall not import the module. The optional ``!`` indicates that a feature is incompatible with the module. +The requirements clause allows specific modules or submodules to specify that they are only accessible with certain language dialects or on certain platforms. The feature list is a set of identifiers, defined below. If any of the features is not available in a given translation unit, that translation unit shall not import the module. When building a module for use by a compilation, submodules requiring unavailable features are ignored. The optional ``!`` indicates that a feature is incompatible with the module. The following features are defined: Modified: vendor/clang/dist/docs/ThinLTO.rst ============================================================================== --- vendor/clang/dist/docs/ThinLTO.rst Thu Jun 1 20:58:42 2017 (r319462) +++ vendor/clang/dist/docs/ThinLTO.rst Thu Jun 1 20:58:49 2017 (r319463) @@ -123,6 +123,8 @@ which currently must be enabled through a linker optio ``-Wl,-plugin-opt,cache-dir=/path/to/cache`` - ld64 (support in clang 3.9 and Xcode 8): ``-Wl,-cache_path_lto,/path/to/cache`` +- lld (as of LLVM r296702): + ``-Wl,--thinlto-cache-dir=/path/to/cache`` Clang Bootstrap --------------- Modified: vendor/clang/dist/docs/UndefinedBehaviorSanitizer.rst ============================================================================== --- vendor/clang/dist/docs/UndefinedBehaviorSanitizer.rst Thu Jun 1 20:58:42 2017 (r319462) +++ vendor/clang/dist/docs/UndefinedBehaviorSanitizer.rst Thu Jun 1 20:58:49 2017 (r319463) @@ -106,6 +106,8 @@ Available checks are: invalid pointers. These checks are made in terms of ``__builtin_object_size``, and consequently may be able to detect more problems at higher optimization levels. + - ``-fsanitize=pointer-overflow``: Performing pointer arithmetic which + overflows. - ``-fsanitize=return``: In C++, reaching the end of a value-returning function without returning a value. - ``-fsanitize=returns-nonnull-attribute``: Returning null pointer Modified: vendor/clang/dist/include/clang/AST/VTableBuilder.h ============================================================================== --- vendor/clang/dist/include/clang/AST/VTableBuilder.h Thu Jun 1 20:58:42 2017 (r319462) +++ vendor/clang/dist/include/clang/AST/VTableBuilder.h Thu Jun 1 20:58:49 2017 (r319463) @@ -154,6 +154,28 @@ class VTableComponent { (public) bool isRTTIKind() const { return isRTTIKind(getKind()); } + GlobalDecl getGlobalDecl() const { + assert(isUsedFunctionPointerKind() && + "GlobalDecl can be created only from virtual function"); + + auto *DtorDecl = dyn_cast(getFunctionDecl()); + switch (getKind()) { + case CK_FunctionPointer: + return GlobalDecl(getFunctionDecl()); + case CK_CompleteDtorPointer: + return GlobalDecl(DtorDecl, CXXDtorType::Dtor_Complete); + case CK_DeletingDtorPointer: + return GlobalDecl(DtorDecl, CXXDtorType::Dtor_Deleting); + case CK_VCallOffset: + case CK_VBaseOffset: + case CK_OffsetToTop: + case CK_RTTI: + case CK_UnusedFunctionPointer: + llvm_unreachable("Only function pointers kinds"); + } + llvm_unreachable("Should already return"); + } + private: static bool isFunctionPointerKind(Kind ComponentKind) { return isUsedFunctionPointerKind(ComponentKind) || Modified: vendor/clang/dist/include/clang/Basic/DiagnosticGroups.td ============================================================================== --- vendor/clang/dist/include/clang/Basic/DiagnosticGroups.td Thu Jun 1 20:58:42 2017 (r319462) +++ vendor/clang/dist/include/clang/Basic/DiagnosticGroups.td Thu Jun 1 20:58:49 2017 (r319463) @@ -733,6 +733,7 @@ def Pedantic : DiagGroup<"pedantic">; // Aliases. def : DiagGroup<"", [Extra]>; // -W = -Wextra def : DiagGroup<"endif-labels", [ExtraTokens]>; // -Wendif-labels=-Wextra-tokens +def : DiagGroup<"cpp", [PoundWarning]>; // -Wcpp = -W#warnings def : DiagGroup<"comments", [Comment]>; // -Wcomments = -Wcomment def : DiagGroup<"conversion-null", [NullConversion]>; // -Wconversion-null = -Wnull-conversion Modified: vendor/clang/dist/include/clang/Basic/DiagnosticIDs.h ============================================================================== --- vendor/clang/dist/include/clang/Basic/DiagnosticIDs.h Thu Jun 1 20:58:42 2017 (r319462) +++ vendor/clang/dist/include/clang/Basic/DiagnosticIDs.h Thu Jun 1 20:58:49 2017 (r319463) @@ -32,7 +32,7 @@ namespace clang { DIAG_START_FRONTEND = DIAG_START_DRIVER + 200, DIAG_START_SERIALIZATION = DIAG_START_FRONTEND + 100, DIAG_START_LEX = DIAG_START_SERIALIZATION + 120, - DIAG_START_PARSE = DIAG_START_LEX + 300, + DIAG_START_PARSE = DIAG_START_LEX + 400, DIAG_START_AST = DIAG_START_PARSE + 500, DIAG_START_COMMENT = DIAG_START_AST + 110, DIAG_START_SEMA = DIAG_START_COMMENT + 100, Modified: vendor/clang/dist/include/clang/Basic/DiagnosticSemaKinds.td ============================================================================== --- vendor/clang/dist/include/clang/Basic/DiagnosticSemaKinds.td Thu Jun 1 20:58:42 2017 (r319462) +++ vendor/clang/dist/include/clang/Basic/DiagnosticSemaKinds.td Thu Jun 1 20:58:49 2017 (r319463) @@ -8979,10 +8979,10 @@ def err_coroutine_promise_new_requires_nothrow : Error def note_coroutine_promise_call_implicitly_required : Note< "call to %0 implicitly required by coroutine function here">; def err_await_suspend_invalid_return_type : Error< - "the return type of 'await_suspend' is required to be 'void' or 'bool' (have %0)" + "return type of 'await_suspend' is required to be 'void' or 'bool' (have %0)" >; def note_await_ready_no_bool_conversion : Note< - "the return type of 'await_ready' is required to be contextually convertible to 'bool'" + "return type of 'await_ready' is required to be contextually convertible to 'bool'" >; } Modified: vendor/clang/dist/include/clang/Basic/Module.h ============================================================================== --- vendor/clang/dist/include/clang/Basic/Module.h Thu Jun 1 20:58:42 2017 (r319462) +++ vendor/clang/dist/include/clang/Basic/Module.h Thu Jun 1 20:58:49 2017 (r319463) @@ -83,6 +83,10 @@ class Module { (public) /// are found. const DirectoryEntry *Directory; + /// \brief The presumed file name for the module map defining this module. + /// Only non-empty when building from preprocessed source. + std::string PresumedModuleMapFile; + /// \brief The umbrella header or directory. llvm::PointerUnion Umbrella; Modified: vendor/clang/dist/include/clang/Basic/Sanitizers.def ============================================================================== --- vendor/clang/dist/include/clang/Basic/Sanitizers.def Thu Jun 1 20:58:42 2017 (r319462) +++ vendor/clang/dist/include/clang/Basic/Sanitizers.def Thu Jun 1 20:58:49 2017 (r319463) @@ -73,6 +73,7 @@ SANITIZER("nullability-return", NullabilityReturn) SANITIZER_GROUP("nullability", Nullability, NullabilityArg | NullabilityAssign | NullabilityReturn) SANITIZER("object-size", ObjectSize) +SANITIZER("pointer-overflow", PointerOverflow) SANITIZER("return", Return) SANITIZER("returns-nonnull-attribute", ReturnsNonnullAttribute) SANITIZER("shift-base", ShiftBase) @@ -108,9 +109,9 @@ SANITIZER("safe-stack", SafeStack) SANITIZER_GROUP("undefined", Undefined, Alignment | Bool | ArrayBounds | Enum | FloatCastOverflow | FloatDivideByZero | IntegerDivideByZero | NonnullAttribute | - Null | ObjectSize | Return | ReturnsNonnullAttribute | - Shift | SignedIntegerOverflow | Unreachable | VLABound | - Function | Vptr) + Null | ObjectSize | PointerOverflow | Return | + ReturnsNonnullAttribute | Shift | SignedIntegerOverflow | + Unreachable | VLABound | Function | Vptr) // -fsanitize=undefined-trap is an alias for -fsanitize=undefined. SANITIZER_GROUP("undefined-trap", UndefinedTrap, Undefined) Modified: vendor/clang/dist/include/clang/Basic/TokenKinds.def ============================================================================== --- vendor/clang/dist/include/clang/Basic/TokenKinds.def Thu Jun 1 20:58:42 2017 (r319462) +++ vendor/clang/dist/include/clang/Basic/TokenKinds.def Thu Jun 1 20:58:49 2017 (r319463) @@ -411,6 +411,7 @@ TYPE_TRAIT_1(__is_sealed, IsSealed, KEYMS) // MSVC12.0 / VS2013 Type Traits TYPE_TRAIT_1(__is_destructible, IsDestructible, KEYMS) +TYPE_TRAIT_1(__is_trivially_destructible, IsTriviallyDestructible, KEYCXX) TYPE_TRAIT_1(__is_nothrow_destructible, IsNothrowDestructible, KEYMS) TYPE_TRAIT_2(__is_nothrow_assignable, IsNothrowAssignable, KEYCXX) TYPE_TRAIT_N(__is_constructible, IsConstructible, KEYCXX) @@ -439,7 +440,6 @@ TYPE_TRAIT_2(__is_convertible_to, IsConvertibleTo, KEY TYPE_TRAIT_1(__is_empty, IsEmpty, KEYCXX) TYPE_TRAIT_1(__is_enum, IsEnum, KEYCXX) TYPE_TRAIT_1(__is_final, IsFinal, KEYCXX) -// Tentative name - there's no implementation of std::is_literal_type yet. TYPE_TRAIT_1(__is_literal, IsLiteral, KEYCXX) // Name for GCC 4.6 compatibility - people have already written libraries using // this name unfortunately. Modified: vendor/clang/dist/include/clang/Basic/TypeTraits.h ============================================================================== --- vendor/clang/dist/include/clang/Basic/TypeTraits.h Thu Jun 1 20:58:42 2017 (r319462) +++ vendor/clang/dist/include/clang/Basic/TypeTraits.h Thu Jun 1 20:58:49 2017 (r319463) @@ -65,6 +65,7 @@ namespace clang { UTT_IsStandardLayout, UTT_IsTrivial, UTT_IsTriviallyCopyable, + UTT_IsTriviallyDestructible, UTT_IsUnion, UTT_IsUnsigned, UTT_IsVoid, Modified: vendor/clang/dist/include/clang/Driver/CLCompatOptions.td ============================================================================== --- vendor/clang/dist/include/clang/Driver/CLCompatOptions.td Thu Jun 1 20:58:42 2017 (r319462) +++ vendor/clang/dist/include/clang/Driver/CLCompatOptions.td Thu Jun 1 20:58:49 2017 (r319463) @@ -63,6 +63,12 @@ def _SLASH_C : CLFlag<"C">, def _SLASH_c : CLFlag<"c">, HelpText<"Compile only">, Alias; def _SLASH_d1reportAllClassLayout : CLFlag<"d1reportAllClassLayout">, HelpText<"Dump record layout information">, Alias; +def _SLASH_diagnostics_caret : CLFlag<"diagnostics:caret">, + HelpText<"Enable caret and column diagnostics (on by default)">; +def _SLASH_diagnostics_column : CLFlag<"diagnostics:column">, + HelpText<"Disable caret diagnostics but keep column info">; +def _SLASH_diagnostics_classic : CLFlag<"diagnostics:classic">, + HelpText<"Disable column and caret diagnostics">; def _SLASH_D : CLJoinedOrSeparate<"D">, HelpText<"Define macro">, MetaVarName<"">, Alias; def _SLASH_E : CLFlag<"E">, HelpText<"Preprocess to stdout">, Alias; @@ -324,6 +330,7 @@ def _SLASH_Zc_forScope : CLIgnoredFlag<"Zc:forScope">; def _SLASH_Zc_inline : CLIgnoredFlag<"Zc:inline">; def _SLASH_Zc_rvalueCast : CLIgnoredFlag<"Zc:rvalueCast">; def _SLASH_Zc_wchar_t : CLIgnoredFlag<"Zc:wchar_t">; +def _SLASH_Zc_ternary : CLIgnoredFlag<"Zc:ternary">; def _SLASH_Zm : CLIgnoredJoined<"Zm">; def _SLASH_Zo : CLIgnoredFlag<"Zo">; def _SLASH_Zo_ : CLIgnoredFlag<"Zo-">; Modified: vendor/clang/dist/include/clang/Driver/Options.td ============================================================================== --- vendor/clang/dist/include/clang/Driver/Options.td Thu Jun 1 20:58:42 2017 (r319462) +++ vendor/clang/dist/include/clang/Driver/Options.td Thu Jun 1 20:58:49 2017 (r319463) @@ -2084,7 +2084,7 @@ def no_cpp_precomp : Flag<["-"], "no-cpp-precomp">, Gr def no_integrated_cpp : Flag<["-", "--"], "no-integrated-cpp">, Flags<[DriverOption]>; def no_pedantic : Flag<["-", "--"], "no-pedantic">, Group; def no__dead__strip__inits__and__terms : Flag<["-"], "no_dead_strip_inits_and_terms">; -def nobuiltininc : Flag<["-"], "nobuiltininc">, Flags<[CC1Option]>, +def nobuiltininc : Flag<["-"], "nobuiltininc">, Flags<[CC1Option, CoreOption]>, HelpText<"Disable builtin #include directories">; def nocudainc : Flag<["-"], "nocudainc">; def nocudalib : Flag<["-"], "nocudalib">; @@ -2096,7 +2096,7 @@ def nopie : Flag<["-"], "nopie">; def noprebind : Flag<["-"], "noprebind">; def noseglinkedit : Flag<["-"], "noseglinkedit">; def nostartfiles : Flag<["-"], "nostartfiles">; -def nostdinc : Flag<["-"], "nostdinc">; +def nostdinc : Flag<["-"], "nostdinc">, Flags<[CoreOption]>; def nostdlibinc : Flag<["-"], "nostdlibinc">; def nostdincxx : Flag<["-"], "nostdinc++">, Flags<[CC1Option]>, HelpText<"Disable standard #include directories for the C++ standard library">; Modified: vendor/clang/dist/include/clang/Lex/HeaderSearch.h ============================================================================== --- vendor/clang/dist/include/clang/Lex/HeaderSearch.h Thu Jun 1 20:58:42 2017 (r319462) +++ vendor/clang/dist/include/clang/Lex/HeaderSearch.h Thu Jun 1 20:58:49 2017 (r319463) @@ -543,10 +543,13 @@ class HeaderSearch { (public) /// \param Offset [inout] An offset within ID to start parsing. On exit, /// filled by the end of the parsed contents (either EOF or the /// location of an end-of-module-map pragma). - /// + /// \param OriginalModuleMapFile The original path to the module map file, + /// used to resolve paths within the module (this is required when + /// building the module from preprocessed source). /// \returns true if an error occurred, false otherwise. bool loadModuleMapFile(const FileEntry *File, bool IsSystem, - FileID ID = FileID(), unsigned *Offset = nullptr); + FileID ID = FileID(), unsigned *Offset = nullptr, + StringRef OriginalModuleMapFile = StringRef()); /// \brief Collect the set of all known, top-level modules. /// Modified: vendor/clang/dist/lib/AST/ODRHash.cpp ============================================================================== --- vendor/clang/dist/lib/AST/ODRHash.cpp Thu Jun 1 20:58:42 2017 (r319462) +++ vendor/clang/dist/lib/AST/ODRHash.cpp Thu Jun 1 20:58:49 2017 (r319463) @@ -110,7 +110,24 @@ void ODRHash::AddNestedNameSpecifier(const NestedNameS } } -void ODRHash::AddTemplateName(TemplateName Name) {} +void ODRHash::AddTemplateName(TemplateName Name) { + auto Kind = Name.getKind(); + ID.AddInteger(Kind); + + switch (Kind) { + case TemplateName::Template: + AddDecl(Name.getAsTemplateDecl()); + break; + // TODO: Support these cases. + case TemplateName::OverloadedTemplate: + case TemplateName::QualifiedTemplate: + case TemplateName::DependentTemplate: + case TemplateName::SubstTemplateTemplateParm: + case TemplateName::SubstTemplateTemplateParmPack: + break; + } +} + void ODRHash::AddTemplateArgument(TemplateArgument TA) {} void ODRHash::AddTemplateParameterList(const TemplateParameterList *TPL) {} @@ -491,6 +508,15 @@ class ODRTypeVisitor : public TypeVisitorgetQualifier()); AddQualType(T->getNamedType()); VisitTypeWithKeyword(T); + } + + void VisitTemplateSpecializationType(const TemplateSpecializationType *T) { + ID.AddInteger(T->getNumArgs()); + for (const auto &TA : T->template_arguments()) { + Hash.AddTemplateArgument(TA); + } + Hash.AddTemplateName(T->getTemplateName()); + VisitType(T); } }; Modified: vendor/clang/dist/lib/Basic/Targets.cpp ============================================================================== --- vendor/clang/dist/lib/Basic/Targets.cpp Thu Jun 1 20:58:42 2017 (r319462) +++ vendor/clang/dist/lib/Basic/Targets.cpp Thu Jun 1 20:58:49 2017 (r319463) @@ -3123,6 +3123,7 @@ class X86TargetInfo : public TargetInfo { (public) case CC_Swift: case CC_X86Pascal: case CC_IntelOclBicc: + case CC_OpenCLKernel: return CCCR_OK; default: return CCCR_Warning; @@ -4834,6 +4835,7 @@ class X86_64TargetInfo : public X86TargetInfo { (publi case CC_PreserveMost: case CC_PreserveAll: case CC_X86RegCall: + case CC_OpenCLKernel: return CCCR_OK; default: return CCCR_Warning; @@ -4907,6 +4909,7 @@ class WindowsX86_64TargetInfo : public WindowsTargetIn case CC_X86_64SysV: case CC_Swift: case CC_X86RegCall: + case CC_OpenCLKernel: return CCCR_OK; default: return CCCR_Warning; @@ -5860,6 +5863,7 @@ class ARMTargetInfo : public TargetInfo { (public) case CC_AAPCS: case CC_AAPCS_VFP: case CC_Swift: + case CC_OpenCLKernel: return CCCR_OK; default: return CCCR_Warning; @@ -6019,6 +6023,7 @@ class WindowsARMTargetInfo : public WindowsTargetInfo< case CC_X86VectorCall: return CCCR_Ignore; case CC_C: + case CC_OpenCLKernel: return CCCR_OK; default: return CCCR_Warning; @@ -6329,6 +6334,7 @@ class AArch64TargetInfo : public TargetInfo { (public) case CC_Swift: case CC_PreserveMost: case CC_PreserveAll: + case CC_OpenCLKernel: return CCCR_OK; default: return CCCR_Warning; @@ -7380,6 +7386,7 @@ class SystemZTargetInfo : public TargetInfo { (public) switch (CC) { case CC_C: case CC_Swift: + case CC_OpenCLKernel: return CCCR_OK; default: return CCCR_Warning; @@ -7662,6 +7669,15 @@ class BPFTargetInfo : public TargetInfo { (public) } ArrayRef getGCCRegAliases() const override { return None; + } + CallingConvCheckResult checkCallingConvention(CallingConv CC) const override { + switch (CC) { + default: + return CCCR_Warning; + case CC_C: + case CC_OpenCLKernel: + return CCCR_OK; + } } }; Modified: vendor/clang/dist/lib/CodeGen/ABIInfo.h ============================================================================== --- vendor/clang/dist/lib/CodeGen/ABIInfo.h Thu Jun 1 20:58:42 2017 (r319462) +++ vendor/clang/dist/lib/CodeGen/ABIInfo.h Thu Jun 1 20:58:49 2017 (r319463) @@ -149,7 +149,6 @@ namespace swiftcall { return info->supportsSwift(); } }; - } // end namespace CodeGen } // end namespace clang Modified: vendor/clang/dist/lib/CodeGen/CGCall.cpp ============================================================================== --- vendor/clang/dist/lib/CodeGen/CGCall.cpp Thu Jun 1 20:58:42 2017 (r319462) +++ vendor/clang/dist/lib/CodeGen/CGCall.cpp Thu Jun 1 20:58:49 2017 (r319463) @@ -707,6 +707,12 @@ CodeGenTypes::arrangeCall(const CGFunctionInfo &signat signature.getRequiredArgs()); } +namespace clang { +namespace CodeGen { +void computeSPIRKernelABIInfo(CodeGenModule &CGM, CGFunctionInfo &FI); +} +} + /// Arrange the argument and result information for an abstract value /// of a given function type. This is the method which all of the /// above functions ultimately defer to. @@ -741,12 +747,16 @@ CodeGenTypes::arrangeLLVMFunctionInfo(CanQualType resu bool inserted = FunctionsBeingProcessed.insert(FI).second; (void)inserted; assert(inserted && "Recursively being processed?"); - + // Compute ABI information. - if (info.getCC() != CC_Swift) { - getABIInfo().computeInfo(*FI); - } else { + if (CC == llvm::CallingConv::SPIR_KERNEL) { + // Force target independent argument handling for the host visible + // kernel functions. + computeSPIRKernelABIInfo(CGM, *FI); + } else if (info.getCC() == CC_Swift) { swiftcall::computeABIInfo(CGM, *FI); + } else { + getABIInfo().computeInfo(*FI); } // Loop over all of the computed argument and return value info. If any of Modified: vendor/clang/dist/lib/CodeGen/CGCleanup.cpp ============================================================================== --- vendor/clang/dist/lib/CodeGen/CGCleanup.cpp Thu Jun 1 20:58:42 2017 (r319462) +++ vendor/clang/dist/lib/CodeGen/CGCleanup.cpp Thu Jun 1 20:58:49 2017 (r319463) @@ -448,6 +448,13 @@ void CodeGenFunction::PopCleanupBlocks( auto *Inst = dyn_cast_or_null(*ReloadedValue); if (!Inst) continue; + + // Don't spill static allocas, they dominate all cleanups. These are created + // by binding a reference to a local variable or temporary. + auto *AI = dyn_cast(Inst); + if (AI && AI->isStaticAlloca()) + continue; + Address Tmp = CreateDefaultAlignTempAlloca(Inst->getType(), "tmp.exprcleanup"); Modified: vendor/clang/dist/lib/CodeGen/CGExpr.cpp ============================================================================== --- vendor/clang/dist/lib/CodeGen/CGExpr.cpp Thu Jun 1 20:58:42 2017 (r319462) +++ vendor/clang/dist/lib/CodeGen/CGExpr.cpp Thu Jun 1 20:58:49 2017 (r319463) @@ -3002,9 +3002,10 @@ static llvm::Value *emitArraySubscriptGEP(CodeGenFunct llvm::Value *ptr, ArrayRef indices, bool inbounds, + SourceLocation loc, const llvm::Twine &name = "arrayidx") { if (inbounds) { - return CGF.Builder.CreateInBoundsGEP(ptr, indices, name); + return CGF.EmitCheckedInBoundsGEP(ptr, indices, loc, name); } else { return CGF.Builder.CreateGEP(ptr, indices, name); } @@ -3035,8 +3036,9 @@ static QualType getFixedSizeElementType(const ASTConte } static Address emitArraySubscriptGEP(CodeGenFunction &CGF, Address addr, - ArrayRef indices, + ArrayRef indices, QualType eltType, bool inbounds, + SourceLocation loc, const llvm::Twine &name = "arrayidx") { // All the indices except that last must be zero. #ifndef NDEBUG @@ -3057,7 +3059,7 @@ static Address emitArraySubscriptGEP(CodeGenFunction & getArrayElementAlign(addr.getAlignment(), indices.back(), eltSize); llvm::Value *eltPtr = - emitArraySubscriptGEP(CGF, addr.getPointer(), indices, inbounds, name); + emitArraySubscriptGEP(CGF, addr.getPointer(), indices, inbounds, loc, name); return Address(eltPtr, eltAlign); } @@ -3110,7 +3112,8 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const A Address Addr = EmitExtVectorElementLValue(LV); QualType EltType = LV.getType()->castAs()->getElementType(); - Addr = emitArraySubscriptGEP(*this, Addr, Idx, EltType, /*inbounds*/ true); + Addr = emitArraySubscriptGEP(*this, Addr, Idx, EltType, /*inbounds*/ true, + E->getExprLoc()); return MakeAddrLValue(Addr, EltType, LV.getBaseInfo()); } @@ -3138,7 +3141,8 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const A } Addr = emitArraySubscriptGEP(*this, Addr, Idx, vla->getElementType(), - !getLangOpts().isSignedOverflowDefined()); + !getLangOpts().isSignedOverflowDefined(), + E->getExprLoc()); } else if (const ObjCObjectType *OIT = E->getType()->getAs()){ // Indexing over an interface, as in "NSString *P; P[4];" @@ -3163,8 +3167,8 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const A // Do the GEP. CharUnits EltAlign = getArrayElementAlign(Addr.getAlignment(), Idx, InterfaceSize); - llvm::Value *EltPtr = - emitArraySubscriptGEP(*this, Addr.getPointer(), ScaledIdx, false); + llvm::Value *EltPtr = emitArraySubscriptGEP( + *this, Addr.getPointer(), ScaledIdx, false, E->getExprLoc()); Addr = Address(EltPtr, EltAlign); // Cast back. @@ -3189,14 +3193,16 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const A Addr = emitArraySubscriptGEP(*this, ArrayLV.getAddress(), {CGM.getSize(CharUnits::Zero()), Idx}, E->getType(), - !getLangOpts().isSignedOverflowDefined()); + !getLangOpts().isSignedOverflowDefined(), + E->getExprLoc()); BaseInfo = ArrayLV.getBaseInfo(); } else { // The base must be a pointer; emit it with an estimate of its alignment. Addr = EmitPointerWithAlignment(E->getBase(), &BaseInfo); auto *Idx = EmitIdxAfterBase(/*Promote*/true); Addr = emitArraySubscriptGEP(*this, Addr, Idx, E->getType(), - !getLangOpts().isSignedOverflowDefined()); + !getLangOpts().isSignedOverflowDefined(), + E->getExprLoc()); } LValue LV = MakeAddrLValue(Addr, E->getType(), BaseInfo); @@ -3368,7 +3374,8 @@ LValue CodeGenFunction::EmitOMPArraySectionExpr(const else Idx = Builder.CreateNSWMul(Idx, NumElements); EltPtr = emitArraySubscriptGEP(*this, Base, Idx, VLA->getElementType(), - !getLangOpts().isSignedOverflowDefined()); + !getLangOpts().isSignedOverflowDefined(), + E->getExprLoc()); } else if (const Expr *Array = isSimpleArrayDecayOperand(E->getBase())) { // If this is A[i] where A is an array, the frontend will have decayed the // base to be a ArrayToPointerDecay implicit cast. While correct, it is @@ -3387,13 +3394,15 @@ LValue CodeGenFunction::EmitOMPArraySectionExpr(const // Propagate the alignment from the array itself to the result. EltPtr = emitArraySubscriptGEP( *this, ArrayLV.getAddress(), {CGM.getSize(CharUnits::Zero()), Idx}, - ResultExprTy, !getLangOpts().isSignedOverflowDefined()); + ResultExprTy, !getLangOpts().isSignedOverflowDefined(), + E->getExprLoc()); BaseInfo = ArrayLV.getBaseInfo(); } else { Address Base = emitOMPArraySectionBase(*this, E->getBase(), BaseInfo, BaseTy, ResultExprTy, IsLowerBound); EltPtr = emitArraySubscriptGEP(*this, Base, Idx, ResultExprTy, - !getLangOpts().isSignedOverflowDefined()); + !getLangOpts().isSignedOverflowDefined(), + E->getExprLoc()); } return MakeAddrLValue(EltPtr, ResultExprTy, BaseInfo); @@ -3530,6 +3539,25 @@ static Address emitAddrOfFieldStorage(CodeGenFunction return CGF.Builder.CreateStructGEP(base, idx, offset, field->getName()); } +static bool hasAnyVptr(const QualType Type, const ASTContext &Context) { + const auto *RD = Type.getTypePtr()->getAsCXXRecordDecl(); + if (!RD) + return false; + + if (RD->isDynamicClass()) + return true; + + for (const auto &Base : RD->bases()) + if (hasAnyVptr(Base.getType(), Context)) + return true; + + for (const FieldDecl *Field : RD->fields()) + if (hasAnyVptr(Field->getType(), Context)) + return true; + + return false; +} + LValue CodeGenFunction::EmitLValueForField(LValue base, const FieldDecl *field) { LValueBaseInfo BaseInfo = base.getBaseInfo(); @@ -3572,6 +3600,14 @@ LValue CodeGenFunction::EmitLValueForField(LValue base assert(!type->isReferenceType() && "union has reference member"); // TODO: handle path-aware TBAA for union. TBAAPath = false; + + const auto FieldType = field->getType(); + if (CGM.getCodeGenOpts().StrictVTablePointers && + hasAnyVptr(FieldType, getContext())) + // Because unions can easily skip invariant.barriers, we need to add + // a barrier every time CXXRecord field with vptr is referenced. + addr = Address(Builder.CreateInvariantGroupBarrier(addr.getPointer()), + addr.getAlignment()); } else { // For structs, we GEP to the field that the record layout suggests. addr = emitAddrOfFieldStorage(*this, addr, field); Modified: vendor/clang/dist/lib/CodeGen/CGExprScalar.cpp ============================================================================== --- vendor/clang/dist/lib/CodeGen/CGExprScalar.cpp Thu Jun 1 20:58:42 2017 (r319462) +++ vendor/clang/dist/lib/CodeGen/CGExprScalar.cpp Thu Jun 1 20:58:49 2017 (r319463) @@ -30,6 +30,7 @@ #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/Function.h" +#include "llvm/IR/GetElementPtrTypeIterator.h" #include "llvm/IR/GlobalVariable.h" #include "llvm/IR/Intrinsics.h" #include "llvm/IR/Module.h" @@ -44,6 +45,43 @@ using llvm::Value; //===----------------------------------------------------------------------===// namespace { + +/// Determine whether the given binary operation may overflow. +/// Sets \p Result to the value of the operation for BO_Add, BO_Sub, BO_Mul, +/// and signed BO_{Div,Rem}. For these opcodes, and for unsigned BO_{Div,Rem}, +/// the returned overflow check is precise. The returned value is 'true' for +/// all other opcodes, to be conservative. +bool mayHaveIntegerOverflow(llvm::ConstantInt *LHS, llvm::ConstantInt *RHS, + BinaryOperator::Opcode Opcode, bool Signed, + llvm::APInt &Result) { + // Assume overflow is possible, unless we can prove otherwise. + bool Overflow = true; + const auto &LHSAP = LHS->getValue(); + const auto &RHSAP = RHS->getValue(); + if (Opcode == BO_Add) { + if (Signed) + Result = LHSAP.sadd_ov(RHSAP, Overflow); + else + Result = LHSAP.uadd_ov(RHSAP, Overflow); + } else if (Opcode == BO_Sub) { + if (Signed) + Result = LHSAP.ssub_ov(RHSAP, Overflow); + else + Result = LHSAP.usub_ov(RHSAP, Overflow); + } else if (Opcode == BO_Mul) { + if (Signed) + Result = LHSAP.smul_ov(RHSAP, Overflow); + else + Result = LHSAP.umul_ov(RHSAP, Overflow); + } else if (Opcode == BO_Div || Opcode == BO_Rem) { + if (Signed && !RHS->isZero()) + Result = LHSAP.sdiv_ov(RHSAP, Overflow); + else + return false; + } + return Overflow; +} + struct BinOpInfo { Value *LHS; Value *RHS; @@ -55,37 +93,14 @@ struct BinOpInfo { /// Check if the binop can result in integer overflow. bool mayHaveIntegerOverflow() const { // Without constant input, we can't rule out overflow. - const auto *LHSCI = dyn_cast(LHS); - const auto *RHSCI = dyn_cast(RHS); + auto *LHSCI = dyn_cast(LHS); + auto *RHSCI = dyn_cast(RHS); if (!LHSCI || !RHSCI) return true; - // Assume overflow is possible, unless we can prove otherwise. - bool Overflow = true; - const auto &LHSAP = LHSCI->getValue(); - const auto &RHSAP = RHSCI->getValue(); - if (Opcode == BO_Add) { - if (Ty->hasSignedIntegerRepresentation()) - (void)LHSAP.sadd_ov(RHSAP, Overflow); - else - (void)LHSAP.uadd_ov(RHSAP, Overflow); - } else if (Opcode == BO_Sub) { - if (Ty->hasSignedIntegerRepresentation()) - (void)LHSAP.ssub_ov(RHSAP, Overflow); - else - (void)LHSAP.usub_ov(RHSAP, Overflow); - } else if (Opcode == BO_Mul) { - if (Ty->hasSignedIntegerRepresentation()) - (void)LHSAP.smul_ov(RHSAP, Overflow); - else - (void)LHSAP.umul_ov(RHSAP, Overflow); - } else if (Opcode == BO_Div || Opcode == BO_Rem) { - if (Ty->hasSignedIntegerRepresentation() && !RHSCI->isZero()) - (void)LHSAP.sdiv_ov(RHSAP, Overflow); - else - return false; - } - return Overflow; + llvm::APInt Result; + return ::mayHaveIntegerOverflow( + LHSCI, RHSCI, Opcode, Ty->hasSignedIntegerRepresentation(), Result); } /// Check if the binop computes a division or a remainder. @@ -1925,7 +1940,8 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const Unary if (CGF.getLangOpts().isSignedOverflowDefined()) value = Builder.CreateGEP(value, numElts, "vla.inc"); else - value = Builder.CreateInBoundsGEP(value, numElts, "vla.inc"); + value = CGF.EmitCheckedInBoundsGEP(value, numElts, E->getExprLoc(), + "vla.inc"); // Arithmetic on function pointers (!) is just +-1. } else if (type->isFunctionType()) { @@ -1935,7 +1951,8 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const Unary if (CGF.getLangOpts().isSignedOverflowDefined()) value = Builder.CreateGEP(value, amt, "incdec.funcptr"); else - value = Builder.CreateInBoundsGEP(value, amt, "incdec.funcptr"); + value = CGF.EmitCheckedInBoundsGEP(value, amt, E->getExprLoc(), + "incdec.funcptr"); value = Builder.CreateBitCast(value, input->getType()); // For everything else, we can just do a simple increment. @@ -1944,7 +1961,8 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const Unary if (CGF.getLangOpts().isSignedOverflowDefined()) value = Builder.CreateGEP(value, amt, "incdec.ptr"); else - value = Builder.CreateInBoundsGEP(value, amt, "incdec.ptr"); + value = CGF.EmitCheckedInBoundsGEP(value, amt, E->getExprLoc(), + "incdec.ptr"); } // Vector increment/decrement. @@ -2025,7 +2043,8 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const Unary if (CGF.getLangOpts().isSignedOverflowDefined()) value = Builder.CreateGEP(value, sizeValue, "incdec.objptr"); else - value = Builder.CreateInBoundsGEP(value, sizeValue, "incdec.objptr"); + value = CGF.EmitCheckedInBoundsGEP(value, sizeValue, E->getExprLoc(), + "incdec.objptr"); value = Builder.CreateBitCast(value, input->getType()); } @@ -2692,7 +2711,8 @@ static Value *emitPointerArithmetic(CodeGenFunction &C pointer = CGF.Builder.CreateGEP(pointer, index, "add.ptr"); } else { index = CGF.Builder.CreateNSWMul(index, numElements, "vla.index"); - pointer = CGF.Builder.CreateInBoundsGEP(pointer, index, "add.ptr"); + pointer = CGF.EmitCheckedInBoundsGEP(pointer, index, op.E->getExprLoc(), + "add.ptr"); } return pointer; } @@ -2709,7 +2729,8 @@ static Value *emitPointerArithmetic(CodeGenFunction &C if (CGF.getLangOpts().isSignedOverflowDefined()) return CGF.Builder.CreateGEP(pointer, index, "add.ptr"); - return CGF.Builder.CreateInBoundsGEP(pointer, index, "add.ptr"); + return CGF.EmitCheckedInBoundsGEP(pointer, index, op.E->getExprLoc(), + "add.ptr"); } // Construct an fmuladd intrinsic to represent a fused mul-add of MulOp and @@ -3823,4 +3844,125 @@ LValue CodeGenFunction::EmitCompoundAssignmentLValue( } llvm_unreachable("Unhandled compound assignment operator"); +} + +Value *CodeGenFunction::EmitCheckedInBoundsGEP(Value *Ptr, + ArrayRef IdxList, + SourceLocation Loc, + const Twine &Name) { + Value *GEPVal = Builder.CreateInBoundsGEP(Ptr, IdxList, Name); + + // If the pointer overflow sanitizer isn't enabled, do nothing. + if (!SanOpts.has(SanitizerKind::PointerOverflow)) + return GEPVal; + + // If the GEP has already been reduced to a constant, leave it be. + if (isa(GEPVal)) + return GEPVal; + + // Only check for overflows in the default address space. + if (GEPVal->getType()->getPointerAddressSpace()) + return GEPVal; + + auto *GEP = cast(GEPVal); + assert(GEP->isInBounds() && "Expected inbounds GEP"); + + SanitizerScope SanScope(this); + auto &VMContext = getLLVMContext(); + const auto &DL = CGM.getDataLayout(); + auto *IntPtrTy = DL.getIntPtrType(GEP->getPointerOperandType()); + + // Grab references to the signed add/mul overflow intrinsics for intptr_t. + auto *Zero = llvm::ConstantInt::getNullValue(IntPtrTy); + auto *SAddIntrinsic = + CGM.getIntrinsic(llvm::Intrinsic::sadd_with_overflow, IntPtrTy); + auto *SMulIntrinsic = + CGM.getIntrinsic(llvm::Intrinsic::smul_with_overflow, IntPtrTy); + + // The total (signed) byte offset for the GEP. + llvm::Value *TotalOffset = nullptr; + // The offset overflow flag - true if the total offset overflows. + llvm::Value *OffsetOverflows = Builder.getFalse(); + + /// Return the result of the given binary operation. + auto eval = [&](BinaryOperator::Opcode Opcode, llvm::Value *LHS, + llvm::Value *RHS) -> llvm::Value * { + assert(Opcode == BO_Add || Opcode == BO_Mul && "Can't eval binop"); + + // If the operands are constants, return a constant result. + if (auto *LHSCI = dyn_cast(LHS)) { + if (auto *RHSCI = dyn_cast(RHS)) { + llvm::APInt N; + bool HasOverflow = mayHaveIntegerOverflow(LHSCI, RHSCI, Opcode, + /*Signed=*/true, N); + if (HasOverflow) + OffsetOverflows = Builder.getTrue(); + return llvm::ConstantInt::get(VMContext, N); + } + } + + // Otherwise, compute the result with checked arithmetic. + auto *ResultAndOverflow = Builder.CreateCall( + (Opcode == BO_Add) ? SAddIntrinsic : SMulIntrinsic, {LHS, RHS}); + OffsetOverflows = Builder.CreateOr( + OffsetOverflows, Builder.CreateExtractValue(ResultAndOverflow, 1)); + return Builder.CreateExtractValue(ResultAndOverflow, 0); + }; + + // Determine the total byte offset by looking at each GEP operand. + for (auto GTI = llvm::gep_type_begin(GEP), GTE = llvm::gep_type_end(GEP); + GTI != GTE; ++GTI) { + llvm::Value *LocalOffset; + auto *Index = GTI.getOperand(); + // Compute the local offset contributed by this indexing step: + if (auto *STy = GTI.getStructTypeOrNull()) { + // For struct indexing, the local offset is the byte position of the + // specified field. + unsigned FieldNo = cast(Index)->getZExtValue(); + LocalOffset = llvm::ConstantInt::get( + IntPtrTy, DL.getStructLayout(STy)->getElementOffset(FieldNo)); + } else { + // Otherwise this is array-like indexing. The local offset is the index + // multiplied by the element size. + auto *ElementSize = llvm::ConstantInt::get( + IntPtrTy, DL.getTypeAllocSize(GTI.getIndexedType())); + auto *IndexS = Builder.CreateIntCast(Index, IntPtrTy, /*isSigned=*/true); + LocalOffset = eval(BO_Mul, ElementSize, IndexS); + } + + // If this is the first offset, set it as the total offset. Otherwise, add + // the local offset into the running total. + if (!TotalOffset || TotalOffset == Zero) + TotalOffset = LocalOffset; + else + TotalOffset = eval(BO_Add, TotalOffset, LocalOffset); + } + + // Common case: if the total offset is zero, don't emit a check. + if (TotalOffset == Zero) + return GEPVal; + + // Now that we've computed the total offset, add it to the base pointer (with + // wrapping semantics). + auto *IntPtr = Builder.CreatePtrToInt(GEP->getPointerOperand(), IntPtrTy); + auto *ComputedGEP = Builder.CreateAdd(IntPtr, TotalOffset); + + // The GEP is valid if: + // 1) The total offset doesn't overflow, and + // 2) The sign of the difference between the computed address and the base + // pointer matches the sign of the total offset. + llvm::Value *PosOrZeroValid = Builder.CreateICmpUGE(ComputedGEP, IntPtr); + llvm::Value *NegValid = Builder.CreateICmpULT(ComputedGEP, IntPtr); + auto *PosOrZeroOffset = Builder.CreateICmpSGE(TotalOffset, Zero); + llvm::Value *ValidGEP = Builder.CreateAnd( + Builder.CreateNot(OffsetOverflows), + Builder.CreateSelect(PosOrZeroOffset, PosOrZeroValid, NegValid)); + + llvm::Constant *StaticArgs[] = {EmitCheckSourceLocation(Loc)}; + // Pass the computed GEP to the runtime to avoid emitting poisoned arguments. + llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP}; + EmitCheck(std::make_pair(ValidGEP, SanitizerKind::PointerOverflow), + SanitizerHandler::PointerOverflow, StaticArgs, DynamicArgs); + + return GEPVal; } Modified: vendor/clang/dist/lib/CodeGen/CGObjCRuntime.cpp ============================================================================== --- vendor/clang/dist/lib/CodeGen/CGObjCRuntime.cpp Thu Jun 1 20:58:42 2017 (r319462) +++ vendor/clang/dist/lib/CodeGen/CGObjCRuntime.cpp Thu Jun 1 20:58:49 2017 (r319463) @@ -90,7 +90,11 @@ LValue CGObjCRuntime::EmitValueForIvarAtOffset(CodeGen unsigned CVRQualifiers, llvm::Value *Offset) { // Compute (type*) ( (char *) BaseValue + Offset) - QualType IvarTy = Ivar->getType().withCVRQualifiers(CVRQualifiers); + QualType InterfaceTy{OID->getTypeForDecl(), 0}; + QualType ObjectPtrTy = + CGF.CGM.getContext().getObjCObjectPointerType(InterfaceTy); + QualType IvarTy = + Ivar->getUsageType(ObjectPtrTy).withCVRQualifiers(CVRQualifiers); llvm::Type *LTy = CGF.CGM.getTypes().ConvertTypeForMem(IvarTy); llvm::Value *V = CGF.Builder.CreateBitCast(BaseValue, CGF.Int8PtrTy); V = CGF.Builder.CreateInBoundsGEP(V, Offset, "add.ptr"); Modified: vendor/clang/dist/lib/CodeGen/CGVTables.cpp ============================================================================== --- vendor/clang/dist/lib/CodeGen/CGVTables.cpp Thu Jun 1 20:58:42 2017 (r319462) +++ vendor/clang/dist/lib/CodeGen/CGVTables.cpp Thu Jun 1 20:58:49 2017 (r319463) @@ -901,6 +901,8 @@ void CodeGenModule::EmitDeferredVTables() { for (const CXXRecordDecl *RD : DeferredVTables) if (shouldEmitVTableAtEndOfTranslationUnit(*this, RD)) VTables.GenerateClassData(RD); + else if (shouldOpportunisticallyEmitVTables()) + OpportunisticVTables.push_back(RD); assert(savedSize == DeferredVTables.size() && "deferred extra vtables during vtable emission?"); Modified: vendor/clang/dist/lib/CodeGen/CodeGenFunction.h ============================================================================== --- vendor/clang/dist/lib/CodeGen/CodeGenFunction.h Thu Jun 1 20:58:42 2017 (r319462) +++ vendor/clang/dist/lib/CodeGen/CodeGenFunction.h Thu Jun 1 20:58:49 2017 (r319463) @@ -120,6 +120,7 @@ enum TypeEvaluationKind { SANITIZER_CHECK(NonnullArg, nonnull_arg, 0) \ SANITIZER_CHECK(NonnullReturn, nonnull_return, 0) \ SANITIZER_CHECK(OutOfBounds, out_of_bounds, 0) \ + SANITIZER_CHECK(PointerOverflow, pointer_overflow, 0) \ SANITIZER_CHECK(ShiftOutOfBounds, shift_out_of_bounds, 0) \ SANITIZER_CHECK(SubOverflow, sub_overflow, 0) \ SANITIZER_CHECK(TypeMismatch, type_mismatch, 1) \ @@ -3550,6 +3551,13 @@ class CodeGenFunction : public CodeGenTypeCache { (pub /// Given an assignment `*LHS = RHS`, emit a test that checks if \p RHS is /// nonnull, if \p LHS is marked _Nonnull. void EmitNullabilityCheck(LValue LHS, llvm::Value *RHS, SourceLocation Loc); + + /// Same as IRBuilder::CreateInBoundsGEP, but additionally emits a check to + /// detect undefined behavior when the pointer overflow sanitizer is enabled. + llvm::Value *EmitCheckedInBoundsGEP(llvm::Value *Ptr, + ArrayRef IdxList, + SourceLocation Loc, + const Twine &Name = ""); /// \brief Emit a description of a type in a format suitable for passing to /// a runtime sanitizer handler. Modified: vendor/clang/dist/lib/CodeGen/CodeGenModule.cpp ============================================================================== --- vendor/clang/dist/lib/CodeGen/CodeGenModule.cpp Thu Jun 1 20:58:42 2017 (r319462) +++ vendor/clang/dist/lib/CodeGen/CodeGenModule.cpp Thu Jun 1 20:58:49 2017 (r319463) @@ -382,6 +382,7 @@ void InstrProfStats::reportDiagnostics(DiagnosticsEngi void CodeGenModule::Release() { EmitDeferred(); + EmitVTablesOpportunistically(); applyGlobalValReplacements(); applyReplacements(); checkAliases(); @@ -472,10 +473,10 @@ void CodeGenModule::Release() { // Width of wchar_t in bytes uint64_t WCharWidth = Context.getTypeSizeInChars(Context.getWideCharType()).getQuantity(); - assert(LangOpts.ShortWChar || - llvm::TargetLibraryInfoImpl::getTargetWCharSize(Target.getTriple()) == - Target.getWCharWidth() / 8 && - "LLVM wchar_t size out of sync"); + assert((LangOpts.ShortWChar || + llvm::TargetLibraryInfoImpl::getTargetWCharSize(Target.getTriple()) == + Target.getWCharWidth() / 8) && + "LLVM wchar_t size out of sync"); // We need to record the widths of enums and wchar_t, so that we can generate // the correct build attributes in the ARM backend. wchar_size is also used by @@ -1386,6 +1387,24 @@ void CodeGenModule::EmitDeferred() { } } +void CodeGenModule::EmitVTablesOpportunistically() { + // Try to emit external vtables as available_externally if they have emitted + // all inlined virtual functions. It runs after EmitDeferred() and therefore + // is not allowed to create new references to things that need to be emitted + // lazily. Note that it also uses fact that we eagerly emitting RTTI. + + assert((OpportunisticVTables.empty() || shouldOpportunisticallyEmitVTables()) + && "Only emit opportunistic vtables with optimizations"); + + for (const CXXRecordDecl *RD : OpportunisticVTables) { + assert(getVTables().isVTableExternal(RD) && + "This queue should only contain external vtables"); + if (getCXXABI().canSpeculativelyEmitVTable(RD)) + VTables.GenerateClassData(RD); + } + OpportunisticVTables.clear(); +} + void CodeGenModule::EmitGlobalAnnotations() { if (Annotations.empty()) return; @@ -1904,6 +1923,10 @@ bool CodeGenModule::shouldEmitFunction(GlobalDecl GD) // implementation. // This happens in glibc's btowc and in some configure checks. return !isTriviallyRecursive(F); +} + +bool CodeGenModule::shouldOpportunisticallyEmitVTables() { + return CodeGenOpts.OptimizationLevel > 0; } void CodeGenModule::EmitGlobalDefinition(GlobalDecl GD, llvm::GlobalValue *GV) { Modified: vendor/clang/dist/lib/CodeGen/CodeGenModule.h ============================================================================== --- vendor/clang/dist/lib/CodeGen/CodeGenModule.h Thu Jun 1 20:58:42 2017 (r319462) +++ vendor/clang/dist/lib/CodeGen/CodeGenModule.h Thu Jun 1 20:58:49 2017 (r319463) @@ -341,6 +341,9 @@ class CodeGenModule : public CodeGenTypeCache { (priva /// A queue of (optional) vtables to consider emitting. std::vector DeferredVTables; + /// A queue of (optional) vtables that may be emitted opportunistically. + std::vector OpportunisticVTables; + /// List of global values which are required to be present in the object file; /// bitcast to i8*. This is used for forcing visibility of symbols which may /// otherwise be optimized out. @@ -450,7 +453,7 @@ class CodeGenModule : public CodeGenTypeCache { (priva bool isTriviallyRecursive(const FunctionDecl *F); bool shouldEmitFunction(GlobalDecl GD); - + bool shouldOpportunisticallyEmitVTables(); /// Map used to be sure we don't emit the same CompoundLiteral twice. llvm::DenseMap EmittedCompoundLiterals; @@ -1277,6 +1280,12 @@ class CodeGenModule : public CodeGenTypeCache { (priva /// Emit any needed decls for which code generation was deferred. void EmitDeferred(); + + /// Try to emit external vtables as available_externally if they have emitted + /// all inlined virtual functions. It runs after EmitDeferred() and therefore + /// is not allowed to create new references to things that need to be emitted + /// lazily. + void EmitVTablesOpportunistically(); /// Call replaceAllUsesWith on all pairs in Replacements. void applyReplacements(); Modified: vendor/clang/dist/lib/CodeGen/ItaniumCXXABI.cpp ============================================================================== --- vendor/clang/dist/lib/CodeGen/ItaniumCXXABI.cpp Thu Jun 1 20:58:42 2017 (r319462) +++ vendor/clang/dist/lib/CodeGen/ItaniumCXXABI.cpp Thu Jun 1 20:58:49 2017 (r319463) @@ -366,20 +366,30 @@ class ItaniumCXXABI : public CodeGen::CGCXXABI { (publ void emitCXXStructor(const CXXMethodDecl *MD, StructorType Type) override; private: - bool hasAnyVirtualInlineFunction(const CXXRecordDecl *RD) const { - const auto &VtableLayout = - CGM.getItaniumVTableContext().getVTableLayout(RD); + bool hasAnyUnusedVirtualInlineFunction(const CXXRecordDecl *RD) const { + const auto &VtableLayout = + CGM.getItaniumVTableContext().getVTableLayout(RD); - for (const auto &VtableComponent : VtableLayout.vtable_components()) { *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***