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...
Dimitry Andric
dim at FreeBSD.org
Thu Jun 1 20:58:54 UTC 2017
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<CXXDestructorDecl>(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<const DirectoryEntry *, const FileEntry *> 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<c>;
def _SLASH_d1reportAllClassLayout : CLFlag<"d1reportAllClassLayout">,
HelpText<"Dump record layout information">, Alias<fdump_record_layouts>;
+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<"<macro[=value]>">, Alias<D>;
def _SLASH_E : CLFlag<"E">, HelpText<"Preprocess to stdout">, Alias<E>;
@@ -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<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 TypeVisitor<ODRTypeVisit
AddNestedNameSpecifier(T->getQualifier());
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<TargetInfo::GCCRegAlias> 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<llvm::Instruction>(*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<llvm::AllocaInst>(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<llvm::Value*> 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<llvm::Value*> indices,
+ ArrayRef<llvm::Value *> 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<VectorType>()->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<ObjCObjectType>()){
// 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<llvm::ConstantInt>(LHS);
- const auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS);
+ auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS);
+ auto *RHSCI = dyn_cast<llvm::ConstantInt>(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<Value *> 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<llvm::Constant>(GEPVal))
+ return GEPVal;
+
+ // Only check for overflows in the default address space.
+ if (GEPVal->getType()->getPointerAddressSpace())
+ return GEPVal;
+
+ auto *GEP = cast<llvm::GEPOperator>(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<llvm::ConstantInt>(LHS)) {
+ if (auto *RHSCI = dyn_cast<llvm::ConstantInt>(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<llvm::ConstantInt>(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<llvm::Value *> 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<const CXXRecordDecl*> DeferredVTables;
+ /// A queue of (optional) vtables that may be emitted opportunistically.
+ std::vector<const CXXRecordDecl *> 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<const CompoundLiteralExpr *, llvm::GlobalVariable *>
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 ***
More information about the svn-src-vendor
mailing list