diff options
Diffstat (limited to 'gnu/llvm/tools')
57 files changed, 706 insertions, 575 deletions
diff --git a/gnu/llvm/tools/clang/CMakeLists.txt b/gnu/llvm/tools/clang/CMakeLists.txt index c56707e7fb5..ff1ff210b56 100644 --- a/gnu/llvm/tools/clang/CMakeLists.txt +++ b/gnu/llvm/tools/clang/CMakeLists.txt @@ -42,7 +42,7 @@ if( CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR ) list(GET CONFIG_OUTPUT 3 INCLUDE_DIR) list(GET CONFIG_OUTPUT 4 LLVM_OBJ_ROOT) list(GET CONFIG_OUTPUT 5 MAIN_SRC_DIR) - list(GET CONFIG_OUTPUT 6 LLVM_CMAKE_PATH) + list(GET CONFIG_OUTPUT 6 LLVM_CONFIG_CMAKE_PATH) if(NOT MSVC_IDE) set(LLVM_ENABLE_ASSERTIONS ${ENABLE_ASSERTIONS} @@ -57,6 +57,10 @@ if( CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR ) set(LLVM_BINARY_DIR ${LLVM_OBJ_ROOT} CACHE PATH "Path to LLVM build tree") set(LLVM_MAIN_SRC_DIR ${MAIN_SRC_DIR} CACHE PATH "Path to LLVM source tree") + # Normalize LLVM_CMAKE_PATH. --cmakedir might contain backslashes. + # CMake assumes slashes as PATH. + file(TO_CMAKE_PATH ${LLVM_CONFIG_CMAKE_PATH} LLVM_CMAKE_PATH) + find_program(LLVM_TABLEGEN_EXE "llvm-tblgen" ${LLVM_TOOLS_BINARY_DIR} NO_DEFAULT_PATH) diff --git a/gnu/llvm/tools/clang/docs/AutomaticReferenceCounting.rst b/gnu/llvm/tools/clang/docs/AutomaticReferenceCounting.rst index aa2a28399d1..fbd1ba4c4d4 100644 --- a/gnu/llvm/tools/clang/docs/AutomaticReferenceCounting.rst +++ b/gnu/llvm/tools/clang/docs/AutomaticReferenceCounting.rst @@ -2258,16 +2258,13 @@ non-block type [*]_. Equivalent to the following code: .. code-block:: objc - id objc_storeStrong(id *object, id value) { - value = [value retain]; + void objc_storeStrong(id *object, id value) { id oldValue = *object; + value = [value retain]; *object = value; [oldValue release]; - return value; } -Always returns ``value``. - .. [*] This does not imply that a ``__strong`` object of block type is an invalid argument to this function. Rather it implies that an ``objc_retain`` and not an ``objc_retainBlock`` operation will be emitted if the argument is diff --git a/gnu/llvm/tools/clang/docs/LanguageExtensions.rst b/gnu/llvm/tools/clang/docs/LanguageExtensions.rst index 64e6ffb7f3e..885ad579ba7 100644 --- a/gnu/llvm/tools/clang/docs/LanguageExtensions.rst +++ b/gnu/llvm/tools/clang/docs/LanguageExtensions.rst @@ -1776,6 +1776,46 @@ numeric primitives such as frexp. See `LLVM canonicalize intrinsic <http://llvm.org/docs/LangRef.html#llvm-canonicalize-intrinsic>`_ for more information on the semantics. +String builtins +--------------- + +Clang provides constant expression evaluation support for builtins forms of +the following functions from the C standard library ``<strings.h>`` header: + +* ``memchr`` +* ``memcmp`` +* ``strchr`` +* ``strcmp`` +* ``strlen`` +* ``strncmp`` +* ``wcschr`` +* ``wcscmp`` +* ``wcslen`` +* ``wcsncmp`` +* ``wmemchr`` +* ``wmemcmp`` + +In each case, the builtin form has the name of the C library function prefixed +by ``__builtin_``. Example: + +.. code-block:: c + + void *p = __builtin_memchr("foobar", 'b', 5); + +In addition to the above, one further builtin is provided: + +.. code-block:: c + + char *__builtin_char_memchr(const char *haystack, int needle, size_t size); + +``__builtin_char_memchr(a, b, c)`` is identical to +``(char*)__builtin_memchr(a, b, c)`` except that its use is permitted within +constant expressions in C++11 onwards (where a cast from ``void*`` to ``char*`` +is disallowed in general). + +Support for constant expression evaluation for the above builtins be detected +with ``__has_feature(cxx_constexpr_string_builtins)``. + .. _langext-__c11_atomic: __c11_atomic builtins diff --git a/gnu/llvm/tools/clang/docs/ReleaseNotes.rst b/gnu/llvm/tools/clang/docs/ReleaseNotes.rst index 25ea577ba51..3278bcc0338 100644 --- a/gnu/llvm/tools/clang/docs/ReleaseNotes.rst +++ b/gnu/llvm/tools/clang/docs/ReleaseNotes.rst @@ -1,6 +1,6 @@ -======================================= -Clang 4.0.0 (In-Progress) Release Notes -======================================= +========================= +Clang 4.0.0 Release Notes +========================= .. contents:: :local: @@ -8,16 +8,10 @@ Clang 4.0.0 (In-Progress) Release Notes Written by the `LLVM Team <http://llvm.org/>`_ -.. warning:: - - These are in-progress notes for the upcoming Clang 4.0.0 release. You may - prefer the `Clang 3.9 Release Notes - <http://llvm.org/releases/3.9.0/tools/clang/docs/ReleaseNotes.html>`_. - Introduction ============ -This document contains the release notes for the Clang C/C++/Objective-C +This document contains the release notes for the Clang C/C++/Objective-C/OpenCL frontend, part of the LLVM Compiler Infrastructure, release 4.0.0. Here we describe the status of Clang in some detail, including major improvements from the previous release and new feature work. For the @@ -42,7 +36,8 @@ sections with improvements to Clang's support for those languages. Major New Features ------------------ -- The ``diagnose_if`` attribute has been added to clang. This attribute allows +- The `diagnose_if <AttributeReference.html#diagnose-if>`_ attribute has been + added to clang. This attribute allows clang to emit a warning or error if a function call meets one or more user-specified conditions. @@ -65,134 +60,123 @@ Major New Features } -- ... - Improvements to ThinLTO (-flto=thin) ------------------------------------ - Integration with profile data (PGO). When available, profile data enables more accurate function importing decisions, as well as cross-module indirect call promotion. - Significant build-time and binary-size improvements when compiling with debug - info (-g). - -Improvements to Clang's diagnostics -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -- ... + info (``-g``). New Compiler Flags ------------------ -The option -Og has been added to optimize the debugging experience. -For now, this option is exactly the same as -O1. However, in the future, -some other optimizations might be enabled or disabled. - -The option -MJ has been added to simplify adding JSON compilation -database output into existing build systems. - -The option .... - -New Pragmas in Clang ------------------------ - -Clang now supports the ... - - -Attribute Changes in Clang --------------------------- - -- ... - -Windows Support ---------------- - -Clang's support for building native Windows programs ... - +- The option ``-Og`` has been added to optimize the debugging experience. + For now, this option is exactly the same as ``-O1``. However, in the future, + some other optimizations might be enabled or disabled. -C Language Changes in Clang ---------------------------- +- The option ``-MJ`` has been added to simplify adding JSON compilation + database output into existing build systems. -- ... -... - -C11 Feature Support -^^^^^^^^^^^^^^^^^^^ - -... +OpenCL C Language Changes in Clang +---------------------------------- -C++ Language Changes in Clang ------------------------------ +**The following bugs in the OpenCL header have been fixed:** -... +* Added missing ``overloadable`` and ``convergent`` attributes. +* Removed some erroneous extra ``native_*`` functions. -C++1z Feature Support -^^^^^^^^^^^^^^^^^^^^^ +**The following bugs in the generation of metadata have been fixed:** -... +* Corrected the SPIR version depending on the OpenCL version. +* Source level address spaces are taken from the SPIR specification. +* Image types now contain no access qualifier. -Objective-C Language Changes in Clang -------------------------------------- +**The following bugs in the AMD target have been fixed:** -... +* Corrected the bitwidth of ``size_t`` and NULL pointer value with respect to + address spaces. +* Added ``cl_khr_subgroups``, ``cl_amd_media_ops`` and ``cl_amd_media_ops2`` + extensions. +* Added ``cl-denorms-are-zero`` support. +* Changed address spaces for image objects to be ``constant``. +* Added little-endian. -OpenCL C Language Changes in Clang ----------------------------------- +**The following bugs in OpenCL 2.0 have been fixed:** -... +* Fixed pipe builtin function return type, added extra argument to generated + IR intrinsics to propagate size and alignment information of the pipe packed + type. +* Improved pipe type to accommodate access qualifiers. +* Added correct address space to the ObjC block generation and ``enqueue_kernel`` + prototype. +* Improved handling of integer parameters of ``enqueue_kernel`` prototype. We + now allow ``size_t`` instead of ``int`` for specifying block parameter sizes. +* Allow using NULL (aka ``CLK_NULL_QUEUE``) with ``queue_t``. -OpenMP Support in Clang ----------------------------------- -... +**Improved the following diagnostics:** -Internal API Changes --------------------- +* Disallow address spaces other than ``global`` for kernel pointer parameters. +* Correct the use of half type argument and pointer assignment with + dereferencing. +* Disallow variadic arguments in functions and blocks. +* Allow partial initializer for array and struct. -These are major API changes that have happened since the 3.9 release of -Clang. If upgrading an external codebase that uses Clang as a library, -this section should help get you past the largest hurdles of upgrading. +**Some changes to OpenCL extensions have been made:** -- ... +* Added ``cl_khr_mipmap_image``. +* Added ``-cl-ext`` flag to allow overwriting supported extensions otherwise + set by the target compiled for (Example: ``-cl-ext=-all,+cl_khr_fp16``). +* New types and functions can now be flexibly added to extensions using the + following pragmas instead of modifying the Clang source code: -AST Matchers ------------- + .. code-block:: c -... + #pragma OPENCL EXTENSION the_new_extension_name : begin + // declare types and functions associated with the extension here + #pragma OPENCL EXTENSION the_new_extension_name : end -libclang --------- -... +**Miscellaneous changes:** -With the option --show-description, scan-build's list of defects will also -show the description of the defects. +* Fix ``__builtin_astype`` to cast between different address space objects. +* Allow using ``opencl_unroll_hint`` with earlier OpenCL versions than 2.0. +* Improved handling of floating point literal to default to single precision if + fp64 extension is not enabled. +* Refactor ``sampler_t`` implementation to simplify initializer representation + which is now handled as a compiler builtin function with an integer value + passed into it. +* Change fake address space map to use the SPIR convention. +* Added `the OpenCL manual <UsersManual.html#opencl-features>`_ to Clang + documentation. Static Analyzer --------------- -... - -Core Analysis Improvements -========================== - -- ... - -New Issues Found -================ - -- ... +With the option ``--show-description``, scan-build's list of defects will also +show the description of the defects. -Python Binding Changes ----------------------- +The analyzer now provides better support of code that uses gtest. -The following methods have been added: +Several new checks were added: -- ... +- The analyzer warns when virtual calls are made from constructors or + destructors. This check is off by default but can be enabled by passing the + following command to scan-build: ``-enable-checker optin.cplusplus.VirtualCall``. +- The analyzer checks for synthesized copy properties of mutable types in + Objective C, such as ``NSMutableArray``. Calling the setter for these properties + will store an immutable copy of the value. +- The analyzer checks for calls to ``dispatch_once()`` that use an Objective-C + instance variable as the predicate. Using an instance variable as a predicate + may result in the passed-in block being executed multiple times or not at all. + These calls should be rewritten either to use a lock or to store the predicate + in a global or static variable. +- The analyzer checks for unintended comparisons of ``NSNumber``, ``CFNumberRef``, and + other Cocoa number objects to scalar values. -Significant Known Problems -========================== Additional Information ====================== diff --git a/gnu/llvm/tools/clang/docs/UsersManual.rst b/gnu/llvm/tools/clang/docs/UsersManual.rst index 04023dd2060..6c8355776b7 100644 --- a/gnu/llvm/tools/clang/docs/UsersManual.rst +++ b/gnu/llvm/tools/clang/docs/UsersManual.rst @@ -2056,6 +2056,8 @@ can be given manually. In this case the kernel code should contain ``#include <opencl-c.h>`` just as a regular C include. +.. _opencl_cl_ext: + .. option:: -cl-ext Disables support of OpenCL extensions. All OpenCL targets provide a list @@ -2177,6 +2179,41 @@ To enable modules for OpenCL: $ clang -target spir-unknown-unknown -c -emit-llvm -Xclang -finclude-default-header -fmodules -fimplicit-module-maps -fmodules-cache-path=<path to the generated module> test.cl +OpenCL Extensions +----------------- + +All of the ``cl_khr_*`` extensions from `the official OpenCL specification +<https://www.khronos.org/registry/OpenCL/sdk/2.0/docs/man/xhtml/EXTENSION.html>`_ +up to and including version 2.0 are available and set per target depending on the +support available in the specific architecture. + +It is possible to alter the default extensions setting per target using +``-cl-ext`` flag. (See :ref:`flags description <opencl_cl_ext>` for more details). + +Vendor extensions can be added flexibly by declaring the list of types and +functions associated with each extensions enclosed within the following +compiler pragma directives: + + .. code-block:: c + + #pragma OPENCL EXTENSION the_new_extension_name : begin + // declare types and functions associated with the extension here + #pragma OPENCL EXTENSION the_new_extension_name : end + +For example, parsing the following code adds ``my_t`` type and ``my_func`` +function to the custom ``my_ext`` extension. + + .. code-block:: c + + #pragma OPENCL EXTENSION my_ext : begin + typedef struct{ + int a; + }my_t; + void my_func(my_t); + #pragma OPENCL EXTENSION my_ext : end + +Declaring the same types in different vendor extensions is disallowed. + OpenCL Metadata --------------- @@ -2215,7 +2252,7 @@ does not have any effect on the IR. For more details reffer to the specification <https://www.khronos.org/registry/cl/specs/opencl-2.0-openclc.pdf#49>`_ -opencl_hint_unroll +opencl_unroll_hint ^^^^^^^^^^^^^^^^^^ The implementation of this feature mirrors the unroll hint for C. diff --git a/gnu/llvm/tools/clang/docs/conf.py b/gnu/llvm/tools/clang/docs/conf.py index 4683ca567ec..9cf8d377295 100644 --- a/gnu/llvm/tools/clang/docs/conf.py +++ b/gnu/llvm/tools/clang/docs/conf.py @@ -49,9 +49,9 @@ copyright = u'2007-%d, The Clang Team' % date.today().year # built documents. # # The short X.Y version. -version = '4.0' +version = '4' # The full version, including alpha/beta/rc tags. -release = '4.0' +release = '4' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/gnu/llvm/tools/clang/include/clang/AST/Type.h b/gnu/llvm/tools/clang/include/clang/AST/Type.h index 744a408e579..a50e054f9b2 100644 --- a/gnu/llvm/tools/clang/include/clang/AST/Type.h +++ b/gnu/llvm/tools/clang/include/clang/AST/Type.h @@ -3827,13 +3827,13 @@ private: friend class ASTContext; // creates these - AttributedType(QualType canon, Kind attrKind, - QualType modified, QualType equivalent) - : Type(Attributed, canon, canon->isDependentType(), - canon->isInstantiationDependentType(), - canon->isVariablyModifiedType(), - canon->containsUnexpandedParameterPack()), - ModifiedType(modified), EquivalentType(equivalent) { + AttributedType(QualType canon, Kind attrKind, QualType modified, + QualType equivalent) + : Type(Attributed, canon, equivalent->isDependentType(), + equivalent->isInstantiationDependentType(), + equivalent->isVariablyModifiedType(), + equivalent->containsUnexpandedParameterPack()), + ModifiedType(modified), EquivalentType(equivalent) { AttributedTypeBits.AttrKind = attrKind; } diff --git a/gnu/llvm/tools/clang/include/clang/Basic/Builtins.def b/gnu/llvm/tools/clang/include/clang/Basic/Builtins.def index ec0a2796ec0..326a8fa6636 100644 --- a/gnu/llvm/tools/clang/include/clang/Basic/Builtins.def +++ b/gnu/llvm/tools/clang/include/clang/Basic/Builtins.def @@ -1339,6 +1339,7 @@ BUILTIN(__builtin_smulll_overflow, "bSLLiCSLLiCSLLi*", "n") BUILTIN(__builtin_addressof, "v*v&", "nct") BUILTIN(__builtin_operator_new, "v*z", "c") BUILTIN(__builtin_operator_delete, "vv*", "n") +BUILTIN(__builtin_char_memchr, "c*cC*iz", "n") // Safestack builtins BUILTIN(__builtin___get_unsafe_stack_start, "v*", "Fn") diff --git a/gnu/llvm/tools/clang/include/clang/Sema/Overload.h b/gnu/llvm/tools/clang/include/clang/Sema/Overload.h index 88fdc991f39..5220d987302 100644 --- a/gnu/llvm/tools/clang/include/clang/Sema/Overload.h +++ b/gnu/llvm/tools/clang/include/clang/Sema/Overload.h @@ -675,26 +675,6 @@ namespace clang { /// to be used while performing partial ordering of function templates. unsigned ExplicitCallArguments; - /// The number of diagnose_if attributes that this overload triggered. - /// If any of the triggered attributes are errors, this won't count - /// diagnose_if warnings. - unsigned NumTriggeredDiagnoseIfs = 0; - - /// Basically a TinyPtrVector<DiagnoseIfAttr *> that doesn't own the vector: - /// If NumTriggeredDiagnoseIfs is 0 or 1, this is a DiagnoseIfAttr *, - /// otherwise it's a pointer to an array of `NumTriggeredDiagnoseIfs` - /// DiagnoseIfAttr *s. - llvm::PointerUnion<DiagnoseIfAttr *, DiagnoseIfAttr **> DiagnoseIfInfo; - - /// Gets an ArrayRef for the data at DiagnoseIfInfo. Note that this may give - /// you a pointer into DiagnoseIfInfo. - ArrayRef<DiagnoseIfAttr *> getDiagnoseIfInfo() const { - auto *Ptr = NumTriggeredDiagnoseIfs <= 1 - ? DiagnoseIfInfo.getAddrOfPtr1() - : DiagnoseIfInfo.get<DiagnoseIfAttr **>(); - return {Ptr, NumTriggeredDiagnoseIfs}; - } - union { DeductionFailureInfo DeductionFailure; @@ -759,9 +739,8 @@ namespace clang { SmallVector<OverloadCandidate, 16> Candidates; llvm::SmallPtrSet<Decl *, 16> Functions; - // Allocator for ConversionSequenceLists and DiagnoseIfAttr* arrays. - // We store the first few of each of these inline to avoid allocation for - // small sets. + // Allocator for ConversionSequenceLists. We store the first few of these + // inline to avoid allocation for small sets. llvm::BumpPtrAllocator SlabAllocator; SourceLocation Loc; @@ -776,6 +755,8 @@ namespace clang { /// from the slab allocator. /// FIXME: It would probably be nice to have a SmallBumpPtrAllocator /// instead. + /// FIXME: Now that this only allocates ImplicitConversionSequences, do we + /// want to un-generalize this? template <typename T> T *slabAllocate(unsigned N) { // It's simpler if this doesn't need to consider alignment. @@ -809,11 +790,6 @@ namespace clang { SourceLocation getLocation() const { return Loc; } CandidateSetKind getKind() const { return Kind; } - /// Make a DiagnoseIfAttr* array in a block of memory that will live for - /// as long as this OverloadCandidateSet. Returns a pointer to the start - /// of that array. - DiagnoseIfAttr **addDiagnoseIfComplaints(ArrayRef<DiagnoseIfAttr *> CA); - /// \brief Determine when this overload candidate will be new to the /// overload set. bool isNewCandidate(Decl *F) { diff --git a/gnu/llvm/tools/clang/include/clang/Sema/Sema.h b/gnu/llvm/tools/clang/include/clang/Sema/Sema.h index c180a8ea3ee..63d078498fe 100644 --- a/gnu/llvm/tools/clang/include/clang/Sema/Sema.h +++ b/gnu/llvm/tools/clang/include/clang/Sema/Sema.h @@ -2532,14 +2532,14 @@ public: void AddMethodCandidate(DeclAccessPair FoundDecl, QualType ObjectType, Expr::Classification ObjectClassification, - Expr *ThisArg, ArrayRef<Expr *> Args, + ArrayRef<Expr *> Args, OverloadCandidateSet& CandidateSet, bool SuppressUserConversion = false); void AddMethodCandidate(CXXMethodDecl *Method, DeclAccessPair FoundDecl, CXXRecordDecl *ActingContext, QualType ObjectType, Expr::Classification ObjectClassification, - Expr *ThisArg, ArrayRef<Expr *> Args, + ArrayRef<Expr *> Args, OverloadCandidateSet& CandidateSet, bool SuppressUserConversions = false, bool PartialOverloading = false, @@ -2550,7 +2550,6 @@ public: TemplateArgumentListInfo *ExplicitTemplateArgs, QualType ObjectType, Expr::Classification ObjectClassification, - Expr *ThisArg, ArrayRef<Expr *> Args, OverloadCandidateSet& CandidateSet, bool SuppressUserConversions = false, @@ -2624,37 +2623,27 @@ public: EnableIfAttr *CheckEnableIf(FunctionDecl *Function, ArrayRef<Expr *> Args, bool MissingImplicitThis = false); - /// Check the diagnose_if attributes on the given function. Returns the - /// first succesful fatal attribute, or null if calling Function(Args) isn't - /// an error. + /// Emit diagnostics for the diagnose_if attributes on Function, ignoring any + /// non-ArgDependent DiagnoseIfAttrs. /// - /// This only considers ArgDependent DiagnoseIfAttrs. + /// Argument-dependent diagnose_if attributes should be checked each time a + /// function is used as a direct callee of a function call. /// - /// This will populate Nonfatal with all non-error DiagnoseIfAttrs that - /// succeed. If this function returns non-null, the contents of Nonfatal are - /// unspecified. - DiagnoseIfAttr * - checkArgDependentDiagnoseIf(FunctionDecl *Function, ArrayRef<Expr *> Args, - SmallVectorImpl<DiagnoseIfAttr *> &Nonfatal, - bool MissingImplicitThis = false, - Expr *ThisArg = nullptr); + /// Returns true if any errors were emitted. + bool diagnoseArgDependentDiagnoseIfAttrs(const FunctionDecl *Function, + const Expr *ThisArg, + ArrayRef<const Expr *> Args, + SourceLocation Loc); - /// Check the diagnose_if expressions on the given function. Returns the - /// first succesful fatal attribute, or null if using Function isn't - /// an error. + /// Emit diagnostics for the diagnose_if attributes on Function, ignoring any + /// ArgDependent DiagnoseIfAttrs. /// - /// This ignores all ArgDependent DiagnoseIfAttrs. + /// Argument-independent diagnose_if attributes should be checked on every use + /// of a function. /// - /// This will populate Nonfatal with all non-error DiagnoseIfAttrs that - /// succeed. If this function returns non-null, the contents of Nonfatal are - /// unspecified. - DiagnoseIfAttr * - checkArgIndependentDiagnoseIf(FunctionDecl *Function, - SmallVectorImpl<DiagnoseIfAttr *> &Nonfatal); - - /// Emits the diagnostic contained in the given DiagnoseIfAttr at Loc. Also - /// emits a note about the location of said attribute. - void emitDiagnoseIfDiagnostic(SourceLocation Loc, const DiagnoseIfAttr *DIA); + /// Returns true if any errors were emitted. + bool diagnoseArgIndependentDiagnoseIfAttrs(const FunctionDecl *Function, + SourceLocation Loc); /// Returns whether the given function's address can be taken or not, /// optionally emitting a diagnostic if the address can't be taken. @@ -9914,8 +9903,8 @@ private: SourceLocation Loc); void checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto, - ArrayRef<const Expr *> Args, bool IsMemberFunction, - SourceLocation Loc, SourceRange Range, + const Expr *ThisArg, ArrayRef<const Expr *> Args, + bool IsMemberFunction, SourceLocation Loc, SourceRange Range, VariadicCallType CallType); bool CheckObjCString(Expr *Arg); diff --git a/gnu/llvm/tools/clang/lib/AST/ASTContext.cpp b/gnu/llvm/tools/clang/lib/AST/ASTContext.cpp index d03c22af5b2..b531a66dbab 100644 --- a/gnu/llvm/tools/clang/lib/AST/ASTContext.cpp +++ b/gnu/llvm/tools/clang/lib/AST/ASTContext.cpp @@ -9025,7 +9025,8 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) { // Variables that have initialization with side-effects are required. if (VD->getInit() && VD->getInit()->HasSideEffects(*this) && - !VD->evaluateValue()) + // We can get a value-dependent initializer during error recovery. + (VD->getInit()->isValueDependent() || !VD->evaluateValue())) return true; // Likewise, variables with tuple-like bindings are required if their diff --git a/gnu/llvm/tools/clang/lib/AST/ExprConstant.cpp b/gnu/llvm/tools/clang/lib/AST/ExprConstant.cpp index a8512b29405..2c0fce91844 100644 --- a/gnu/llvm/tools/clang/lib/AST/ExprConstant.cpp +++ b/gnu/llvm/tools/clang/lib/AST/ExprConstant.cpp @@ -604,10 +604,12 @@ namespace { /// gets a chance to look at it. EM_PotentialConstantExpressionUnevaluated, - /// Evaluate as a constant expression. Continue evaluating if either: - /// - We find a MemberExpr with a base that can't be evaluated. - /// - We find a variable initialized with a call to a function that has - /// the alloc_size attribute on it. + /// Evaluate as a constant expression. In certain scenarios, if: + /// - we find a MemberExpr with a base that can't be evaluated, or + /// - we find a variable initialized with a call to a function that has + /// the alloc_size attribute on it + /// then we may consider evaluation to have succeeded. + /// /// In either case, the LValue returned shall have an invalid base; in the /// former, the base will be the invalid MemberExpr, in the latter, the /// base will be either the alloc_size CallExpr or a CastExpr wrapping @@ -890,10 +892,6 @@ namespace { return KeepGoing; } - bool allowInvalidBaseExpr() const { - return EvalMode == EM_OffsetFold; - } - class ArrayInitLoopIndex { EvalInfo &Info; uint64_t OuterIndex; @@ -1394,8 +1392,10 @@ static bool Evaluate(APValue &Result, EvalInfo &Info, const Expr *E); static bool EvaluateInPlace(APValue &Result, EvalInfo &Info, const LValue &This, const Expr *E, bool AllowNonLiteralTypes = false); -static bool EvaluateLValue(const Expr *E, LValue &Result, EvalInfo &Info); -static bool EvaluatePointer(const Expr *E, LValue &Result, EvalInfo &Info); +static bool EvaluateLValue(const Expr *E, LValue &Result, EvalInfo &Info, + bool InvalidBaseOK = false); +static bool EvaluatePointer(const Expr *E, LValue &Result, EvalInfo &Info, + bool InvalidBaseOK = false); static bool EvaluateMemberPointer(const Expr *E, MemberPtr &Result, EvalInfo &Info); static bool EvaluateTemporary(const Expr *E, LValue &Result, EvalInfo &Info); @@ -2362,7 +2362,14 @@ static unsigned getBaseIndex(const CXXRecordDecl *Derived, /// Extract the value of a character from a string literal. static APSInt extractStringLiteralCharacter(EvalInfo &Info, const Expr *Lit, uint64_t Index) { - // FIXME: Support ObjCEncodeExpr, MakeStringConstant + // FIXME: Support MakeStringConstant + if (const auto *ObjCEnc = dyn_cast<ObjCEncodeExpr>(Lit)) { + std::string Str; + Info.Ctx.getObjCEncodingForType(ObjCEnc->getEncodedType(), Str); + assert(Index <= Str.size() && "Index too large"); + return APSInt::getUnsigned(Str.c_str()[Index]); + } + if (auto PE = dyn_cast<PredefinedExpr>(Lit)) Lit = PE->getFunctionName(); const StringLiteral *S = cast<StringLiteral>(Lit); @@ -4796,6 +4803,7 @@ class LValueExprEvaluatorBase : public ExprEvaluatorBase<Derived> { protected: LValue &Result; + bool InvalidBaseOK; typedef LValueExprEvaluatorBase LValueExprEvaluatorBaseTy; typedef ExprEvaluatorBase<Derived> ExprEvaluatorBaseTy; @@ -4804,9 +4812,14 @@ protected: return true; } + bool evaluatePointer(const Expr *E, LValue &Result) { + return EvaluatePointer(E, Result, this->Info, InvalidBaseOK); + } + public: - LValueExprEvaluatorBase(EvalInfo &Info, LValue &Result) : - ExprEvaluatorBaseTy(Info), Result(Result) {} + LValueExprEvaluatorBase(EvalInfo &Info, LValue &Result, bool InvalidBaseOK) + : ExprEvaluatorBaseTy(Info), Result(Result), + InvalidBaseOK(InvalidBaseOK) {} bool Success(const APValue &V, const Expr *E) { Result.setFrom(this->Info.Ctx, V); @@ -4818,7 +4831,7 @@ public: QualType BaseTy; bool EvalOK; if (E->isArrow()) { - EvalOK = EvaluatePointer(E->getBase(), Result, this->Info); + EvalOK = evaluatePointer(E->getBase(), Result); BaseTy = E->getBase()->getType()->castAs<PointerType>()->getPointeeType(); } else if (E->getBase()->isRValue()) { assert(E->getBase()->getType()->isRecordType()); @@ -4829,7 +4842,7 @@ public: BaseTy = E->getBase()->getType(); } if (!EvalOK) { - if (!this->Info.allowInvalidBaseExpr()) + if (!InvalidBaseOK) return false; Result.setInvalid(E); return true; @@ -4923,8 +4936,8 @@ namespace { class LValueExprEvaluator : public LValueExprEvaluatorBase<LValueExprEvaluator> { public: - LValueExprEvaluator(EvalInfo &Info, LValue &Result) : - LValueExprEvaluatorBaseTy(Info, Result) {} + LValueExprEvaluator(EvalInfo &Info, LValue &Result, bool InvalidBaseOK) : + LValueExprEvaluatorBaseTy(Info, Result, InvalidBaseOK) {} bool VisitVarDecl(const Expr *E, const VarDecl *VD); bool VisitUnaryPreIncDec(const UnaryOperator *UO); @@ -4977,10 +4990,11 @@ public: /// * function designators in C, and /// * "extern void" objects /// * @selector() expressions in Objective-C -static bool EvaluateLValue(const Expr *E, LValue &Result, EvalInfo &Info) { +static bool EvaluateLValue(const Expr *E, LValue &Result, EvalInfo &Info, + bool InvalidBaseOK) { assert(E->isGLValue() || E->getType()->isFunctionType() || E->getType()->isVoidType() || isa<ObjCSelectorExpr>(E)); - return LValueExprEvaluator(Info, Result).Visit(E); + return LValueExprEvaluator(Info, Result, InvalidBaseOK).Visit(E); } bool LValueExprEvaluator::VisitDeclRefExpr(const DeclRefExpr *E) { @@ -5141,7 +5155,7 @@ bool LValueExprEvaluator::VisitArraySubscriptExpr(const ArraySubscriptExpr *E) { if (E->getBase()->getType()->isVectorType()) return Error(E); - if (!EvaluatePointer(E->getBase(), Result, Info)) + if (!evaluatePointer(E->getBase(), Result)) return false; APSInt Index; @@ -5153,7 +5167,7 @@ bool LValueExprEvaluator::VisitArraySubscriptExpr(const ArraySubscriptExpr *E) { } bool LValueExprEvaluator::VisitUnaryDeref(const UnaryOperator *E) { - return EvaluatePointer(E->getSubExpr(), Result, Info); + return evaluatePointer(E->getSubExpr(), Result); } bool LValueExprEvaluator::VisitUnaryReal(const UnaryOperator *E) { @@ -5301,7 +5315,7 @@ static bool getBytesReturnedByAllocSizeCall(const ASTContext &Ctx, /// and mark Result's Base as invalid. static bool evaluateLValueAsAllocSize(EvalInfo &Info, APValue::LValueBase Base, LValue &Result) { - if (!Info.allowInvalidBaseExpr() || Base.isNull()) + if (Base.isNull()) return false; // Because we do no form of static analysis, we only support const variables. @@ -5335,17 +5349,27 @@ namespace { class PointerExprEvaluator : public ExprEvaluatorBase<PointerExprEvaluator> { LValue &Result; + bool InvalidBaseOK; bool Success(const Expr *E) { Result.set(E); return true; } + bool evaluateLValue(const Expr *E, LValue &Result) { + return EvaluateLValue(E, Result, Info, InvalidBaseOK); + } + + bool evaluatePointer(const Expr *E, LValue &Result) { + return EvaluatePointer(E, Result, Info, InvalidBaseOK); + } + bool visitNonBuiltinCallExpr(const CallExpr *E); public: - PointerExprEvaluator(EvalInfo &info, LValue &Result) - : ExprEvaluatorBaseTy(info), Result(Result) {} + PointerExprEvaluator(EvalInfo &info, LValue &Result, bool InvalidBaseOK) + : ExprEvaluatorBaseTy(info), Result(Result), + InvalidBaseOK(InvalidBaseOK) {} bool Success(const APValue &V, const Expr *E) { Result.setFrom(Info.Ctx, V); @@ -5392,9 +5416,10 @@ public: }; } // end anonymous namespace -static bool EvaluatePointer(const Expr* E, LValue& Result, EvalInfo &Info) { +static bool EvaluatePointer(const Expr* E, LValue& Result, EvalInfo &Info, + bool InvalidBaseOK) { assert(E->isRValue() && E->getType()->hasPointerRepresentation()); - return PointerExprEvaluator(Info, Result).Visit(E); + return PointerExprEvaluator(Info, Result, InvalidBaseOK).Visit(E); } bool PointerExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { @@ -5407,7 +5432,7 @@ bool PointerExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { if (IExp->getType()->isPointerType()) std::swap(PExp, IExp); - bool EvalPtrOK = EvaluatePointer(PExp, Result, Info); + bool EvalPtrOK = evaluatePointer(PExp, Result); if (!EvalPtrOK && !Info.noteFailure()) return false; @@ -5425,7 +5450,7 @@ bool PointerExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { } bool PointerExprEvaluator::VisitUnaryAddrOf(const UnaryOperator *E) { - return EvaluateLValue(E->getSubExpr(), Result, Info); + return evaluateLValue(E->getSubExpr(), Result); } bool PointerExprEvaluator::VisitCastExpr(const CastExpr* E) { @@ -5459,7 +5484,7 @@ bool PointerExprEvaluator::VisitCastExpr(const CastExpr* E) { case CK_DerivedToBase: case CK_UncheckedDerivedToBase: - if (!EvaluatePointer(E->getSubExpr(), Result, Info)) + if (!evaluatePointer(E->getSubExpr(), Result)) return false; if (!Result.Base && Result.Offset.isZero()) return true; @@ -5506,7 +5531,7 @@ bool PointerExprEvaluator::VisitCastExpr(const CastExpr* E) { } case CK_ArrayToPointerDecay: if (SubExpr->isGLValue()) { - if (!EvaluateLValue(SubExpr, Result, Info)) + if (!evaluateLValue(SubExpr, Result)) return false; } else { Result.set(SubExpr, Info.CurrentCall->Index); @@ -5523,18 +5548,19 @@ bool PointerExprEvaluator::VisitCastExpr(const CastExpr* E) { return true; case CK_FunctionToPointerDecay: - return EvaluateLValue(SubExpr, Result, Info); + return evaluateLValue(SubExpr, Result); case CK_LValueToRValue: { LValue LVal; - if (!EvaluateLValue(E->getSubExpr(), LVal, Info)) + if (!evaluateLValue(E->getSubExpr(), LVal)) return false; APValue RVal; // Note, we use the subexpression's type in order to retain cv-qualifiers. if (!handleLValueToRValueConversion(Info, E, E->getSubExpr()->getType(), LVal, RVal)) - return evaluateLValueAsAllocSize(Info, LVal.Base, Result); + return InvalidBaseOK && + evaluateLValueAsAllocSize(Info, LVal.Base, Result); return Success(RVal, E); } } @@ -5579,7 +5605,7 @@ bool PointerExprEvaluator::visitNonBuiltinCallExpr(const CallExpr *E) { if (ExprEvaluatorBaseTy::VisitCallExpr(E)) return true; - if (!(Info.allowInvalidBaseExpr() && getAllocSizeAttr(E))) + if (!(InvalidBaseOK && getAllocSizeAttr(E))) return false; Result.setInvalid(E); @@ -5602,12 +5628,12 @@ bool PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, unsigned BuiltinOp) { switch (BuiltinOp) { case Builtin::BI__builtin_addressof: - return EvaluateLValue(E->getArg(0), Result, Info); + return evaluateLValue(E->getArg(0), Result); case Builtin::BI__builtin_assume_aligned: { // We need to be very careful here because: if the pointer does not have the // asserted alignment, then the behavior is undefined, and undefined // behavior is non-constant. - if (!EvaluatePointer(E->getArg(0), Result, Info)) + if (!evaluatePointer(E->getArg(0), Result)) return false; LValue OffsetResult(Result); @@ -5683,6 +5709,7 @@ bool PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, case Builtin::BI__builtin_strchr: case Builtin::BI__builtin_wcschr: case Builtin::BI__builtin_memchr: + case Builtin::BI__builtin_char_memchr: case Builtin::BI__builtin_wmemchr: { if (!Visit(E->getArg(0))) return false; @@ -5720,6 +5747,7 @@ bool PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, // Fall through. case Builtin::BImemchr: case Builtin::BI__builtin_memchr: + case Builtin::BI__builtin_char_memchr: // memchr compares by converting both sides to unsigned char. That's also // correct for strchr if we get this far (to cope with plain char being // unsigned in the strchr case). @@ -6246,7 +6274,7 @@ class TemporaryExprEvaluator : public LValueExprEvaluatorBase<TemporaryExprEvaluator> { public: TemporaryExprEvaluator(EvalInfo &Info, LValue &Result) : - LValueExprEvaluatorBaseTy(Info, Result) {} + LValueExprEvaluatorBaseTy(Info, Result, false) {} /// Visit an expression which constructs the value of this temporary. bool VisitConstructExpr(const Expr *E) { @@ -7349,7 +7377,8 @@ static bool tryEvaluateBuiltinObjectSize(const Expr *E, unsigned Type, if (!EvaluateAsRValue(Info, E, RVal)) return false; LVal.setFrom(Info.Ctx, RVal); - } else if (!EvaluatePointer(ignorePointerCastsAndParens(E), LVal, Info)) + } else if (!EvaluatePointer(ignorePointerCastsAndParens(E), LVal, Info, + /*InvalidBaseOK=*/true)) return false; } diff --git a/gnu/llvm/tools/clang/lib/Basic/Version.cpp b/gnu/llvm/tools/clang/lib/Basic/Version.cpp index ee60ca74924..97e75a9cd45 100644 --- a/gnu/llvm/tools/clang/lib/Basic/Version.cpp +++ b/gnu/llvm/tools/clang/lib/Basic/Version.cpp @@ -36,7 +36,7 @@ std::string getClangRepositoryPath() { // If the SVN_REPOSITORY is empty, try to use the SVN keyword. This helps us // pick up a tag in an SVN export, for example. - StringRef SVNRepository("$URL: https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_400/rc1/lib/Basic/Version.cpp $"); + StringRef SVNRepository("$URL: https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_400/final/lib/Basic/Version.cpp $"); if (URL.empty()) { URL = SVNRepository.slice(SVNRepository.find(':'), SVNRepository.find("/lib/Basic")); diff --git a/gnu/llvm/tools/clang/lib/CodeGen/CGBuiltin.cpp b/gnu/llvm/tools/clang/lib/CodeGen/CGBuiltin.cpp index 2ede1d46b3d..b3d02f1f51c 100644 --- a/gnu/llvm/tools/clang/lib/CodeGen/CGBuiltin.cpp +++ b/gnu/llvm/tools/clang/lib/CodeGen/CGBuiltin.cpp @@ -1189,6 +1189,10 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD, return RValue::get(Dest.getPointer()); } + case Builtin::BI__builtin_char_memchr: + BuiltinID = Builtin::BI__builtin_memchr; + break; + case Builtin::BI__builtin___memcpy_chk: { // fold __builtin_memcpy_chk(x, y, cst1, cst2) to memcpy iff cst1<=cst2. llvm::APSInt Size, DstSize; diff --git a/gnu/llvm/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/gnu/llvm/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp index db9de2ab6ad..40252171368 100644 --- a/gnu/llvm/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/gnu/llvm/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp @@ -4697,7 +4697,9 @@ void CGOpenMPRuntime::emitCancellationPointCall( // global_tid, kmp_int32 cncl_kind); if (auto *OMPRegionInfo = dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo)) { - if (OMPRegionInfo->hasCancel()) { + // For 'cancellation point taskgroup', the task region info may not have a + // cancel. This may instead happen in another adjacent task. + if (CancelRegion == OMPD_taskgroup || OMPRegionInfo->hasCancel()) { llvm::Value *Args[] = { emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc), CGF.Builder.getInt32(getCancellationKind(CancelRegion))}; @@ -4705,7 +4707,6 @@ void CGOpenMPRuntime::emitCancellationPointCall( auto *Result = CGF.EmitRuntimeCall( createRuntimeFunction(OMPRTL__kmpc_cancellationpoint), Args); // if (__kmpc_cancellationpoint()) { - // __kmpc_cancel_barrier(); // exit from construct; // } auto *ExitBB = CGF.createBasicBlock(".cancel.exit"); @@ -4713,8 +4714,6 @@ void CGOpenMPRuntime::emitCancellationPointCall( auto *Cmp = CGF.Builder.CreateIsNotNull(Result); CGF.Builder.CreateCondBr(Cmp, ExitBB, ContBB); CGF.EmitBlock(ExitBB); - // __kmpc_cancel_barrier(); - emitBarrierCall(CGF, Loc, OMPD_unknown, /*EmitChecks=*/false); // exit from construct; auto CancelDest = CGF.getOMPCancelDestination(OMPRegionInfo->getDirectiveKind()); @@ -4743,7 +4742,6 @@ void CGOpenMPRuntime::emitCancelCall(CodeGenFunction &CGF, SourceLocation Loc, auto *Result = CGF.EmitRuntimeCall( RT.createRuntimeFunction(OMPRTL__kmpc_cancel), Args); // if (__kmpc_cancel()) { - // __kmpc_cancel_barrier(); // exit from construct; // } auto *ExitBB = CGF.createBasicBlock(".cancel.exit"); @@ -4751,8 +4749,6 @@ void CGOpenMPRuntime::emitCancelCall(CodeGenFunction &CGF, SourceLocation Loc, auto *Cmp = CGF.Builder.CreateIsNotNull(Result); CGF.Builder.CreateCondBr(Cmp, ExitBB, ContBB); CGF.EmitBlock(ExitBB); - // __kmpc_cancel_barrier(); - RT.emitBarrierCall(CGF, Loc, OMPD_unknown, /*EmitChecks=*/false); // exit from construct; auto CancelDest = CGF.getOMPCancelDestination(OMPRegionInfo->getDirectiveKind()); diff --git a/gnu/llvm/tools/clang/lib/CodeGen/CodeGenFunction.cpp b/gnu/llvm/tools/clang/lib/CodeGen/CodeGenFunction.cpp index 137c69420dd..e142a21b1e7 100644 --- a/gnu/llvm/tools/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/gnu/llvm/tools/clang/lib/CodeGen/CodeGenFunction.cpp @@ -112,9 +112,8 @@ CodeGenFunction::~CodeGenFunction() { if (FirstBlockInfo) destroyBlockInfos(FirstBlockInfo); - if (getLangOpts().OpenMP) { + if (getLangOpts().OpenMP && CurFn) CGM.getOpenMPRuntime().functionFinished(*this); - } } CharUnits CodeGenFunction::getNaturalPointeeTypeAlignment(QualType T, diff --git a/gnu/llvm/tools/clang/lib/CodeGen/CodeGenModule.h b/gnu/llvm/tools/clang/lib/CodeGen/CodeGenModule.h index 1d72b4edeb1..36f6785fd1b 100644 --- a/gnu/llvm/tools/clang/lib/CodeGen/CodeGenModule.h +++ b/gnu/llvm/tools/clang/lib/CodeGen/CodeGenModule.h @@ -166,7 +166,7 @@ struct ObjCEntrypoints { /// void objc_release(id); llvm::Constant *objc_release; - /// id objc_storeStrong(id*, id); + /// void objc_storeStrong(id*, id); llvm::Constant *objc_storeStrong; /// id objc_storeWeak(id*, id); diff --git a/gnu/llvm/tools/clang/lib/CodeGen/CodeGenTypes.cpp b/gnu/llvm/tools/clang/lib/CodeGen/CodeGenTypes.cpp index b95b4fff573..adb40c8c0d4 100644 --- a/gnu/llvm/tools/clang/lib/CodeGen/CodeGenTypes.cpp +++ b/gnu/llvm/tools/clang/lib/CodeGen/CodeGenTypes.cpp @@ -737,7 +737,7 @@ CodeGenTypes::getCGRecordLayout(const RecordDecl *RD) { } bool CodeGenTypes::isPointerZeroInitializable(QualType T) { - assert (T->isAnyPointerType() && "Invalid type"); + assert((T->isAnyPointerType() || T->isBlockPointerType()) && "Invalid type"); return isZeroInitializable(T); } diff --git a/gnu/llvm/tools/clang/lib/Frontend/InitPreprocessor.cpp b/gnu/llvm/tools/clang/lib/Frontend/InitPreprocessor.cpp index 4502c92499a..17603ada11d 100644 --- a/gnu/llvm/tools/clang/lib/Frontend/InitPreprocessor.cpp +++ b/gnu/llvm/tools/clang/lib/Frontend/InitPreprocessor.cpp @@ -286,12 +286,12 @@ static void DefineFastIntType(unsigned TypeWidth, bool IsSigned, /// Get the value the ATOMIC_*_LOCK_FREE macro should have for a type with /// the specified properties. -static const char *getLockFreeValue(unsigned TypeWidth, unsigned InlineWidth) { +static const char *getLockFreeValue(unsigned TypeWidth, unsigned TypeAlign, + unsigned InlineWidth) { // Fully-aligned, power-of-2 sizes no larger than the inline // width will be inlined as lock-free operations. - // Note: we do not need to check alignment since _Atomic(T) is always - // appropriately-aligned in clang. - if ((TypeWidth & (TypeWidth - 1)) == 0 && TypeWidth <= InlineWidth) + if (TypeWidth == TypeAlign && (TypeWidth & (TypeWidth - 1)) == 0 && + TypeWidth <= InlineWidth) return "2"; // "always lock free" // We cannot be certain what operations the lib calls might be // able to implement as lock-free on future processors. @@ -881,6 +881,7 @@ static void InitializePredefinedMacros(const TargetInfo &TI, #define DEFINE_LOCK_FREE_MACRO(TYPE, Type) \ Builder.defineMacro("__GCC_ATOMIC_" #TYPE "_LOCK_FREE", \ getLockFreeValue(TI.get##Type##Width(), \ + TI.get##Type##Align(), \ InlineWidthBits)); DEFINE_LOCK_FREE_MACRO(BOOL, Bool); DEFINE_LOCK_FREE_MACRO(CHAR, Char); @@ -893,6 +894,7 @@ static void InitializePredefinedMacros(const TargetInfo &TI, DEFINE_LOCK_FREE_MACRO(LLONG, LongLong); Builder.defineMacro("__GCC_ATOMIC_POINTER_LOCK_FREE", getLockFreeValue(TI.getPointerWidth(0), + TI.getPointerAlign(0), InlineWidthBits)); #undef DEFINE_LOCK_FREE_MACRO } diff --git a/gnu/llvm/tools/clang/lib/Index/IndexDecl.cpp b/gnu/llvm/tools/clang/lib/Index/IndexDecl.cpp index 7d60aad3895..3b4f3f81399 100644 --- a/gnu/llvm/tools/clang/lib/Index/IndexDecl.cpp +++ b/gnu/llvm/tools/clang/lib/Index/IndexDecl.cpp @@ -92,7 +92,13 @@ public: Relations.emplace_back((unsigned)SymbolRole::RelationAccessorOf, AssociatedProp); - if (!IndexCtx.handleDecl(D, (unsigned)SymbolRole::Dynamic, Relations)) + // getLocation() returns beginning token of a method declaration, but for + // indexing purposes we want to point to the base name. + SourceLocation MethodLoc = D->getSelectorStartLoc(); + if (MethodLoc.isInvalid()) + MethodLoc = D->getLocation(); + + if (!IndexCtx.handleDecl(D, MethodLoc, (unsigned)SymbolRole::Dynamic, Relations)) return false; IndexCtx.indexTypeSourceInfo(D->getReturnTypeSourceInfo(), D); bool hasIBActionAndFirst = D->hasAttr<IBActionAttr>(); diff --git a/gnu/llvm/tools/clang/lib/Lex/PPMacroExpansion.cpp b/gnu/llvm/tools/clang/lib/Lex/PPMacroExpansion.cpp index aebebaac46a..de166c75e2c 100644 --- a/gnu/llvm/tools/clang/lib/Lex/PPMacroExpansion.cpp +++ b/gnu/llvm/tools/clang/lib/Lex/PPMacroExpansion.cpp @@ -1183,6 +1183,7 @@ static bool HasFeature(const Preprocessor &PP, StringRef Feature) { .Case("cxx_attributes", LangOpts.CPlusPlus11) .Case("cxx_auto_type", LangOpts.CPlusPlus11) .Case("cxx_constexpr", LangOpts.CPlusPlus11) + .Case("cxx_constexpr_string_builtins", LangOpts.CPlusPlus11) .Case("cxx_decltype", LangOpts.CPlusPlus11) .Case("cxx_decltype_incomplete_return_types", LangOpts.CPlusPlus11) .Case("cxx_default_function_template_args", LangOpts.CPlusPlus11) diff --git a/gnu/llvm/tools/clang/lib/Parse/ParseExpr.cpp b/gnu/llvm/tools/clang/lib/Parse/ParseExpr.cpp index ee06c76f602..852e2269393 100644 --- a/gnu/llvm/tools/clang/lib/Parse/ParseExpr.cpp +++ b/gnu/llvm/tools/clang/lib/Parse/ParseExpr.cpp @@ -2408,7 +2408,7 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr, // fold-expressions, we'll need to allow multiple ArgExprs here. if (ArgExprs.size() == 1 && isFoldOperator(Tok.getKind()) && NextToken().is(tok::ellipsis)) - return ParseFoldExpression(Result, T); + return ParseFoldExpression(ArgExprs[0], T); ExprType = SimpleExpr; Result = Actions.ActOnParenListExpr(OpenLoc, Tok.getLocation(), diff --git a/gnu/llvm/tools/clang/lib/Sema/SemaChecking.cpp b/gnu/llvm/tools/clang/lib/Sema/SemaChecking.cpp index 49208e20a49..3aedb2a8c9b 100644 --- a/gnu/llvm/tools/clang/lib/Sema/SemaChecking.cpp +++ b/gnu/llvm/tools/clang/lib/Sema/SemaChecking.cpp @@ -2426,11 +2426,12 @@ static void CheckNonNullArguments(Sema &S, } /// Handles the checks for format strings, non-POD arguments to vararg -/// functions, and NULL arguments passed to non-NULL parameters. +/// functions, NULL arguments passed to non-NULL parameters, and diagnose_if +/// attributes. void Sema::checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto, - ArrayRef<const Expr *> Args, bool IsMemberFunction, - SourceLocation Loc, SourceRange Range, - VariadicCallType CallType) { + const Expr *ThisArg, ArrayRef<const Expr *> Args, + bool IsMemberFunction, SourceLocation Loc, + SourceRange Range, VariadicCallType CallType) { // FIXME: We should check as much as we can in the template definition. if (CurContext->isDependentContext()) return; @@ -2477,6 +2478,9 @@ void Sema::checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto, CheckArgumentWithTypeTag(I, Args.data()); } } + + if (FD) + diagnoseArgDependentDiagnoseIfAttrs(FD, ThisArg, Args, Loc); } /// CheckConstructorCall - Check a constructor call for correctness and safety @@ -2487,8 +2491,8 @@ void Sema::CheckConstructorCall(FunctionDecl *FDecl, SourceLocation Loc) { VariadicCallType CallType = Proto->isVariadic() ? VariadicConstructor : VariadicDoesNotApply; - checkCall(FDecl, Proto, Args, /*IsMemberFunction=*/true, Loc, SourceRange(), - CallType); + checkCall(FDecl, Proto, /*ThisArg=*/nullptr, Args, /*IsMemberFunction=*/true, + Loc, SourceRange(), CallType); } /// CheckFunctionCall - Check a direct function call for various correctness @@ -2503,14 +2507,20 @@ bool Sema::CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall, TheCall->getCallee()); Expr** Args = TheCall->getArgs(); unsigned NumArgs = TheCall->getNumArgs(); + + Expr *ImplicitThis = nullptr; if (IsMemberOperatorCall) { // If this is a call to a member operator, hide the first argument // from checkCall. // FIXME: Our choice of AST representation here is less than ideal. + ImplicitThis = Args[0]; ++Args; --NumArgs; - } - checkCall(FDecl, Proto, llvm::makeArrayRef(Args, NumArgs), + } else if (IsMemberFunction) + ImplicitThis = + cast<CXXMemberCallExpr>(TheCall)->getImplicitObjectArgument(); + + checkCall(FDecl, Proto, ImplicitThis, llvm::makeArrayRef(Args, NumArgs), IsMemberFunction, TheCall->getRParenLoc(), TheCall->getCallee()->getSourceRange(), CallType); @@ -2546,8 +2556,8 @@ bool Sema::CheckObjCMethodCall(ObjCMethodDecl *Method, SourceLocation lbrac, VariadicCallType CallType = Method->isVariadic() ? VariadicMethod : VariadicDoesNotApply; - checkCall(Method, nullptr, Args, - /*IsMemberFunction=*/false, lbrac, Method->getSourceRange(), + checkCall(Method, nullptr, /*ThisArg=*/nullptr, Args, + /*IsMemberFunction=*/false, lbrac, Method->getSourceRange(), CallType); return false; @@ -2576,7 +2586,7 @@ bool Sema::CheckPointerCall(NamedDecl *NDecl, CallExpr *TheCall, CallType = VariadicFunction; } - checkCall(NDecl, Proto, + checkCall(NDecl, Proto, /*ThisArg=*/nullptr, llvm::makeArrayRef(TheCall->getArgs(), TheCall->getNumArgs()), /*IsMemberFunction=*/false, TheCall->getRParenLoc(), TheCall->getCallee()->getSourceRange(), CallType); @@ -2589,7 +2599,7 @@ bool Sema::CheckPointerCall(NamedDecl *NDecl, CallExpr *TheCall, bool Sema::CheckOtherCall(CallExpr *TheCall, const FunctionProtoType *Proto) { VariadicCallType CallType = getVariadicCallType(/*FDecl=*/nullptr, Proto, TheCall->getCallee()); - checkCall(/*FDecl=*/nullptr, Proto, + checkCall(/*FDecl=*/nullptr, Proto, /*ThisArg=*/nullptr, llvm::makeArrayRef(TheCall->getArgs(), TheCall->getNumArgs()), /*IsMemberFunction=*/false, TheCall->getRParenLoc(), TheCall->getCallee()->getSourceRange(), CallType); diff --git a/gnu/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp b/gnu/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp index a70e16cce18..f265f4c00f7 100644 --- a/gnu/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp +++ b/gnu/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp @@ -12383,9 +12383,9 @@ ExprResult Sema::BuildCXXDefaultInitExpr(SourceLocation Loc, FieldDecl *Field) { Diag(Loc, diag::err_in_class_initializer_not_yet_parsed) << OutermostClass << Field; Diag(Field->getLocEnd(), diag::note_in_class_initializer_not_yet_parsed); - - // Don't diagnose this again. - Field->setInvalidDecl(); + // Recover by marking the field invalid, unless we're in a SFINAE context. + if (!isSFINAEContext()) + Field->setInvalidDecl(); return ExprError(); } diff --git a/gnu/llvm/tools/clang/lib/Sema/SemaExpr.cpp b/gnu/llvm/tools/clang/lib/Sema/SemaExpr.cpp index d62e8fd68b6..0077d6c539c 100644 --- a/gnu/llvm/tools/clang/lib/Sema/SemaExpr.cpp +++ b/gnu/llvm/tools/clang/lib/Sema/SemaExpr.cpp @@ -342,7 +342,6 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc, } // See if this is a deleted function. - SmallVector<DiagnoseIfAttr *, 4> DiagnoseIfWarnings; if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { if (FD->isDeleted()) { auto *Ctor = dyn_cast<CXXConstructorDecl>(FD); @@ -365,11 +364,8 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc, if (getLangOpts().CUDA && !CheckCUDACall(Loc, FD)) return true; - if (const DiagnoseIfAttr *A = - checkArgIndependentDiagnoseIf(FD, DiagnoseIfWarnings)) { - emitDiagnoseIfDiagnostic(Loc, A); + if (diagnoseArgIndependentDiagnoseIfAttrs(FD, Loc)) return true; - } } // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions @@ -385,9 +381,6 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc, return true; } - for (const auto *W : DiagnoseIfWarnings) - emitDiagnoseIfDiagnostic(Loc, W); - DiagnoseAvailabilityOfDecl(*this, D, Loc, UnknownObjCClass, ObjCPropertyAccess); @@ -5189,16 +5182,6 @@ static void checkDirectCallValidity(Sema &S, const Expr *Fn, << Attr->getCond()->getSourceRange() << Attr->getMessage(); return; } - - SmallVector<DiagnoseIfAttr *, 4> Nonfatal; - if (const DiagnoseIfAttr *Attr = S.checkArgDependentDiagnoseIf( - Callee, ArgExprs, Nonfatal, /*MissingImplicitThis=*/true)) { - S.emitDiagnoseIfDiagnostic(Fn->getLocStart(), Attr); - return; - } - - for (const auto *W : Nonfatal) - S.emitDiagnoseIfDiagnostic(Fn->getLocStart(), W); } /// ActOnCallExpr - Handle a call to Fn with the specified array of arguments. @@ -11496,7 +11479,7 @@ ExprResult Sema::BuildBinOp(Scope *S, SourceLocation OpLoc, return checkPseudoObjectAssignment(S, OpLoc, Opc, LHSExpr, RHSExpr); // Don't resolve overloads if the other type is overloadable. - if (pty->getKind() == BuiltinType::Overload) { + if (getLangOpts().CPlusPlus && pty->getKind() == BuiltinType::Overload) { // We can't actually test that if we still have a placeholder, // though. Fortunately, none of the exceptions we see in that // code below are valid when the LHS is an overload set. Note @@ -11521,17 +11504,16 @@ ExprResult Sema::BuildBinOp(Scope *S, SourceLocation OpLoc, // An overload in the RHS can potentially be resolved by the type // being assigned to. if (Opc == BO_Assign && pty->getKind() == BuiltinType::Overload) { - if (LHSExpr->isTypeDependent() || RHSExpr->isTypeDependent()) - return BuildOverloadedBinOp(*this, S, OpLoc, Opc, LHSExpr, RHSExpr); - - if (LHSExpr->getType()->isOverloadableType()) + if (getLangOpts().CPlusPlus && + (LHSExpr->isTypeDependent() || RHSExpr->isTypeDependent() || + LHSExpr->getType()->isOverloadableType())) return BuildOverloadedBinOp(*this, S, OpLoc, Opc, LHSExpr, RHSExpr); return CreateBuiltinBinOp(OpLoc, Opc, LHSExpr, RHSExpr); } // Don't resolve overloads if the other type is overloadable. - if (pty->getKind() == BuiltinType::Overload && + if (getLangOpts().CPlusPlus && pty->getKind() == BuiltinType::Overload && LHSExpr->getType()->isOverloadableType()) return BuildOverloadedBinOp(*this, S, OpLoc, Opc, LHSExpr, RHSExpr); diff --git a/gnu/llvm/tools/clang/lib/Sema/SemaExprCXX.cpp b/gnu/llvm/tools/clang/lib/Sema/SemaExprCXX.cpp index b2fb33f5343..3afa95f7d1f 100644 --- a/gnu/llvm/tools/clang/lib/Sema/SemaExprCXX.cpp +++ b/gnu/llvm/tools/clang/lib/Sema/SemaExprCXX.cpp @@ -6712,6 +6712,11 @@ ExprResult Sema::BuildCXXMemberCallExpr(Expr *E, NamedDecl *FoundDecl, CXXMemberCallExpr *CE = new (Context) CXXMemberCallExpr(Context, ME, None, ResultType, VK, Exp.get()->getLocEnd()); + + if (CheckFunctionCall(Method, CE, + Method->getType()->castAs<FunctionProtoType>())) + return ExprError(); + return CE; } @@ -7185,14 +7190,6 @@ public: ExprResult TransformBlockExpr(BlockExpr *E) { return Owned(E); } - ExprResult TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E) { - return Owned(E); - } - - ExprResult TransformObjCIvarRefExpr(ObjCIvarRefExpr *E) { - return Owned(E); - } - ExprResult Transform(Expr *E) { ExprResult Res; while (true) { diff --git a/gnu/llvm/tools/clang/lib/Sema/SemaInit.cpp b/gnu/llvm/tools/clang/lib/Sema/SemaInit.cpp index 45eff5ee6b6..b053c83c3f6 100644 --- a/gnu/llvm/tools/clang/lib/Sema/SemaInit.cpp +++ b/gnu/llvm/tools/clang/lib/Sema/SemaInit.cpp @@ -1684,7 +1684,7 @@ void InitListChecker::CheckArrayType(const InitializedEntity &Entity, // If this is an incomplete array type, the actual type needs to // be calculated here. llvm::APSInt Zero(maxElements.getBitWidth(), maxElements.isUnsigned()); - if (maxElements == Zero) { + if (maxElements == Zero && !Entity.isVariableLengthArrayNew()) { // Sizing an array implicitly to zero is not allowed by ISO C, // but is supported by GNU. SemaRef.Diag(IList->getLocStart(), diff --git a/gnu/llvm/tools/clang/lib/Sema/SemaLookup.cpp b/gnu/llvm/tools/clang/lib/Sema/SemaLookup.cpp index 883e2ae264e..e2cb2c8169c 100644 --- a/gnu/llvm/tools/clang/lib/Sema/SemaLookup.cpp +++ b/gnu/llvm/tools/clang/lib/Sema/SemaLookup.cpp @@ -2831,6 +2831,9 @@ Sema::SpecialMemberOverloadResult *Sema::LookupSpecialMember(CXXRecordDecl *RD, assert((SM != CXXDefaultConstructor && SM != CXXDestructor) && "parameter-less special members can't have qualified arguments"); + // FIXME: Get the caller to pass in a location for the lookup. + SourceLocation LookupLoc = RD->getLocation(); + llvm::FoldingSetNodeID ID; ID.AddPointer(RD); ID.AddInteger(SM); @@ -2912,7 +2915,7 @@ Sema::SpecialMemberOverloadResult *Sema::LookupSpecialMember(CXXRecordDecl *RD, VK = VK_RValue; } - OpaqueValueExpr FakeArg(SourceLocation(), ArgType, VK); + OpaqueValueExpr FakeArg(LookupLoc, ArgType, VK); if (SM != CXXDefaultConstructor) { NumArgs = 1; @@ -2926,13 +2929,13 @@ Sema::SpecialMemberOverloadResult *Sema::LookupSpecialMember(CXXRecordDecl *RD, if (VolatileThis) ThisTy.addVolatile(); Expr::Classification Classification = - OpaqueValueExpr(SourceLocation(), ThisTy, + OpaqueValueExpr(LookupLoc, ThisTy, RValueThis ? VK_RValue : VK_LValue).Classify(Context); // Now we perform lookup on the name we computed earlier and do overload // resolution. Lookup is only performed directly into the class since there // will always be a (possibly implicit) declaration to shadow any others. - OverloadCandidateSet OCS(RD->getLocation(), OverloadCandidateSet::CSK_Normal); + OverloadCandidateSet OCS(LookupLoc, OverloadCandidateSet::CSK_Normal); DeclContext::lookup_result R = RD->lookup(Name); if (R.empty()) { @@ -2960,7 +2963,6 @@ Sema::SpecialMemberOverloadResult *Sema::LookupSpecialMember(CXXRecordDecl *RD, if (CXXMethodDecl *M = dyn_cast<CXXMethodDecl>(Cand->getUnderlyingDecl())) { if (SM == CXXCopyAssignment || SM == CXXMoveAssignment) AddMethodCandidate(M, Cand, RD, ThisTy, Classification, - /*ThisArg=*/nullptr, llvm::makeArrayRef(&Arg, NumArgs), OCS, true); else if (CtorInfo) AddOverloadCandidate(CtorInfo.Constructor, CtorInfo.FoundDecl, @@ -2973,7 +2975,7 @@ Sema::SpecialMemberOverloadResult *Sema::LookupSpecialMember(CXXRecordDecl *RD, if (SM == CXXCopyAssignment || SM == CXXMoveAssignment) AddMethodTemplateCandidate( Tmpl, Cand, RD, nullptr, ThisTy, Classification, - /*ThisArg=*/nullptr, llvm::makeArrayRef(&Arg, NumArgs), OCS, true); + llvm::makeArrayRef(&Arg, NumArgs), OCS, true); else if (CtorInfo) AddTemplateOverloadCandidate( CtorInfo.ConstructorTmpl, CtorInfo.FoundDecl, nullptr, @@ -2988,7 +2990,7 @@ Sema::SpecialMemberOverloadResult *Sema::LookupSpecialMember(CXXRecordDecl *RD, } OverloadCandidateSet::iterator Best; - switch (OCS.BestViableFunction(*this, SourceLocation(), Best)) { + switch (OCS.BestViableFunction(*this, LookupLoc, Best)) { case OR_Success: Result->setMethod(cast<CXXMethodDecl>(Best->Function)); Result->setKind(SpecialMemberOverloadResult::Success); diff --git a/gnu/llvm/tools/clang/lib/Sema/SemaOverload.cpp b/gnu/llvm/tools/clang/lib/Sema/SemaOverload.cpp index afdae4ed6d7..f976b76727f 100644 --- a/gnu/llvm/tools/clang/lib/Sema/SemaOverload.cpp +++ b/gnu/llvm/tools/clang/lib/Sema/SemaOverload.cpp @@ -839,20 +839,12 @@ void OverloadCandidateSet::destroyCandidates() { void OverloadCandidateSet::clear() { destroyCandidates(); - // DiagnoseIfAttrs are just pointers, so we don't need to destroy them. SlabAllocator.Reset(); NumInlineBytesUsed = 0; Candidates.clear(); Functions.clear(); } -DiagnoseIfAttr ** -OverloadCandidateSet::addDiagnoseIfComplaints(ArrayRef<DiagnoseIfAttr *> CA) { - auto *DIA = slabAllocate<DiagnoseIfAttr *>(CA.size()); - std::uninitialized_copy(CA.begin(), CA.end(), DIA); - return DIA; -} - namespace { class UnbridgedCastsSet { struct Entry { @@ -5831,28 +5823,6 @@ static bool IsAcceptableNonMemberOperatorCandidate(ASTContext &Context, return false; } -static void initDiagnoseIfComplaint(Sema &S, OverloadCandidateSet &CandidateSet, - OverloadCandidate &Candidate, - FunctionDecl *Function, - ArrayRef<Expr *> Args, - bool MissingImplicitThis = false, - Expr *ExplicitThis = nullptr) { - SmallVector<DiagnoseIfAttr *, 8> Results; - if (DiagnoseIfAttr *DIA = S.checkArgDependentDiagnoseIf( - Function, Args, Results, MissingImplicitThis, ExplicitThis)) { - Results.clear(); - Results.push_back(DIA); - } - - Candidate.NumTriggeredDiagnoseIfs = Results.size(); - if (Results.empty()) - Candidate.DiagnoseIfInfo = nullptr; - else if (Results.size() == 1) - Candidate.DiagnoseIfInfo = Results[0]; - else - Candidate.DiagnoseIfInfo = CandidateSet.addDiagnoseIfComplaints(Results); -} - /// AddOverloadCandidate - Adds the given function to the set of /// candidate functions, using the given function call arguments. If /// @p SuppressUserConversions, then don't allow user-defined @@ -5886,10 +5856,9 @@ Sema::AddOverloadCandidate(FunctionDecl *Function, // object argument (C++ [over.call.func]p3), and the acting context // is irrelevant. AddMethodCandidate(Method, FoundDecl, Method->getParent(), QualType(), - Expr::Classification::makeSimpleLValue(), - /*ThisArg=*/nullptr, Args, CandidateSet, - SuppressUserConversions, PartialOverloading, - EarlyConversions); + Expr::Classification::makeSimpleLValue(), Args, + CandidateSet, SuppressUserConversions, + PartialOverloading, EarlyConversions); return; } // We treat a constructor like a non-member function, since its object @@ -5944,6 +5913,28 @@ Sema::AddOverloadCandidate(FunctionDecl *Function, Candidate.FailureKind = ovl_fail_illegal_constructor; return; } + + // C++ [over.match.funcs]p8: (proposed DR resolution) + // A constructor inherited from class type C that has a first parameter + // of type "reference to P" (including such a constructor instantiated + // from a template) is excluded from the set of candidate functions when + // constructing an object of type cv D if the argument list has exactly + // one argument and D is reference-related to P and P is reference-related + // to C. + auto *Shadow = dyn_cast<ConstructorUsingShadowDecl>(FoundDecl.getDecl()); + if (Shadow && Args.size() == 1 && Constructor->getNumParams() >= 1 && + Constructor->getParamDecl(0)->getType()->isReferenceType()) { + QualType P = Constructor->getParamDecl(0)->getType()->getPointeeType(); + QualType C = Context.getRecordType(Constructor->getParent()); + QualType D = Context.getRecordType(Shadow->getParent()); + SourceLocation Loc = Args.front()->getExprLoc(); + if ((Context.hasSameUnqualifiedType(P, C) || IsDerivedFrom(Loc, P, C)) && + (Context.hasSameUnqualifiedType(D, P) || IsDerivedFrom(Loc, D, P))) { + Candidate.Viable = false; + Candidate.FailureKind = ovl_fail_inhctor_slice; + return; + } + } } unsigned NumParams = Proto->getNumParams(); @@ -6016,31 +6007,6 @@ Sema::AddOverloadCandidate(FunctionDecl *Function, } } - // C++ [over.best.ics]p4+: (proposed DR resolution) - // If the target is the first parameter of an inherited constructor when - // constructing an object of type C with an argument list that has exactly - // one expression, an implicit conversion sequence cannot be formed if C is - // reference-related to the type that the argument would have after the - // application of the user-defined conversion (if any) and before the final - // standard conversion sequence. - auto *Shadow = dyn_cast<ConstructorUsingShadowDecl>(FoundDecl.getDecl()); - if (Shadow && Args.size() == 1 && !isa<InitListExpr>(Args.front())) { - bool DerivedToBase, ObjCConversion, ObjCLifetimeConversion; - QualType ConvertedArgumentType = Args.front()->getType(); - if (Candidate.Conversions[0].isUserDefined()) - ConvertedArgumentType = - Candidate.Conversions[0].UserDefined.After.getFromType(); - if (CompareReferenceRelationship(Args.front()->getLocStart(), - Context.getRecordType(Shadow->getParent()), - ConvertedArgumentType, DerivedToBase, - ObjCConversion, - ObjCLifetimeConversion) >= Ref_Related) { - Candidate.Viable = false; - Candidate.FailureKind = ovl_fail_inhctor_slice; - return; - } - } - if (EnableIfAttr *FailedAttr = CheckEnableIf(Function, Args)) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_enable_if; @@ -6053,8 +6019,6 @@ Sema::AddOverloadCandidate(FunctionDecl *Function, Candidate.FailureKind = ovl_fail_ext_disabled; return; } - - initDiagnoseIfComplaint(*this, CandidateSet, Candidate, Function, Args); } ObjCMethodDecl * @@ -6263,85 +6227,73 @@ EnableIfAttr *Sema::CheckEnableIf(FunctionDecl *Function, ArrayRef<Expr *> Args, return nullptr; } -static bool gatherDiagnoseIfAttrs(FunctionDecl *Function, bool ArgDependent, - SmallVectorImpl<DiagnoseIfAttr *> &Errors, - SmallVectorImpl<DiagnoseIfAttr *> &Nonfatal) { - for (auto *DIA : Function->specific_attrs<DiagnoseIfAttr>()) - if (ArgDependent == DIA->getArgDependent()) { - if (DIA->isError()) - Errors.push_back(DIA); - else - Nonfatal.push_back(DIA); - } +template <typename CheckFn> +static bool diagnoseDiagnoseIfAttrsWith(Sema &S, const FunctionDecl *FD, + bool ArgDependent, SourceLocation Loc, + CheckFn &&IsSuccessful) { + SmallVector<const DiagnoseIfAttr *, 8> Attrs; + for (const auto *DIA : FD->specific_attrs<DiagnoseIfAttr>()) { + if (ArgDependent == DIA->getArgDependent()) + Attrs.push_back(DIA); + } - return !Errors.empty() || !Nonfatal.empty(); -} + // Common case: No diagnose_if attributes, so we can quit early. + if (Attrs.empty()) + return false; + + auto WarningBegin = std::stable_partition( + Attrs.begin(), Attrs.end(), + [](const DiagnoseIfAttr *DIA) { return DIA->isError(); }); -template <typename CheckFn> -static DiagnoseIfAttr * -checkDiagnoseIfAttrsWith(const SmallVectorImpl<DiagnoseIfAttr *> &Errors, - SmallVectorImpl<DiagnoseIfAttr *> &Nonfatal, - CheckFn &&IsSuccessful) { // Note that diagnose_if attributes are late-parsed, so they appear in the // correct order (unlike enable_if attributes). - auto ErrAttr = llvm::find_if(Errors, IsSuccessful); - if (ErrAttr != Errors.end()) - return *ErrAttr; - - llvm::erase_if(Nonfatal, [&](DiagnoseIfAttr *A) { return !IsSuccessful(A); }); - return nullptr; -} - -DiagnoseIfAttr * -Sema::checkArgDependentDiagnoseIf(FunctionDecl *Function, ArrayRef<Expr *> Args, - SmallVectorImpl<DiagnoseIfAttr *> &Nonfatal, - bool MissingImplicitThis, - Expr *ThisArg) { - SmallVector<DiagnoseIfAttr *, 4> Errors; - if (!gatherDiagnoseIfAttrs(Function, /*ArgDependent=*/true, Errors, Nonfatal)) - return nullptr; + auto ErrAttr = llvm::find_if(llvm::make_range(Attrs.begin(), WarningBegin), + IsSuccessful); + if (ErrAttr != WarningBegin) { + const DiagnoseIfAttr *DIA = *ErrAttr; + S.Diag(Loc, diag::err_diagnose_if_succeeded) << DIA->getMessage(); + S.Diag(DIA->getLocation(), diag::note_from_diagnose_if) + << DIA->getParent() << DIA->getCond()->getSourceRange(); + return true; + } - SFINAETrap Trap(*this); - SmallVector<Expr *, 16> ConvertedArgs; - Expr *ConvertedThis; - if (!convertArgsForAvailabilityChecks(*this, Function, ThisArg, Args, Trap, - MissingImplicitThis, ConvertedThis, - ConvertedArgs)) - return nullptr; + for (const auto *DIA : llvm::make_range(WarningBegin, Attrs.end())) + if (IsSuccessful(DIA)) { + S.Diag(Loc, diag::warn_diagnose_if_succeeded) << DIA->getMessage(); + S.Diag(DIA->getLocation(), diag::note_from_diagnose_if) + << DIA->getParent() << DIA->getCond()->getSourceRange(); + } - return checkDiagnoseIfAttrsWith(Errors, Nonfatal, [&](DiagnoseIfAttr *DIA) { - APValue Result; - // It's sane to use the same ConvertedArgs for any redecl of this function, - // since EvaluateWithSubstitution only cares about the position of each - // argument in the arg list, not the ParmVarDecl* it maps to. - if (!DIA->getCond()->EvaluateWithSubstitution( - Result, Context, DIA->getParent(), ConvertedArgs, ConvertedThis)) - return false; - return Result.isInt() && Result.getInt().getBoolValue(); - }); + return false; } -DiagnoseIfAttr *Sema::checkArgIndependentDiagnoseIf( - FunctionDecl *Function, SmallVectorImpl<DiagnoseIfAttr *> &Nonfatal) { - SmallVector<DiagnoseIfAttr *, 4> Errors; - if (!gatherDiagnoseIfAttrs(Function, /*ArgDependent=*/false, Errors, - Nonfatal)) - return nullptr; - - return checkDiagnoseIfAttrsWith(Errors, Nonfatal, [&](DiagnoseIfAttr *DIA) { - bool Result; - return DIA->getCond()->EvaluateAsBooleanCondition(Result, Context) && - Result; - }); +bool Sema::diagnoseArgDependentDiagnoseIfAttrs(const FunctionDecl *Function, + const Expr *ThisArg, + ArrayRef<const Expr *> Args, + SourceLocation Loc) { + return diagnoseDiagnoseIfAttrsWith( + *this, Function, /*ArgDependent=*/true, Loc, + [&](const DiagnoseIfAttr *DIA) { + APValue Result; + // It's sane to use the same Args for any redecl of this function, since + // EvaluateWithSubstitution only cares about the position of each + // argument in the arg list, not the ParmVarDecl* it maps to. + if (!DIA->getCond()->EvaluateWithSubstitution( + Result, Context, DIA->getParent(), Args, ThisArg)) + return false; + return Result.isInt() && Result.getInt().getBoolValue(); + }); } -void Sema::emitDiagnoseIfDiagnostic(SourceLocation Loc, - const DiagnoseIfAttr *DIA) { - auto Code = DIA->isError() ? diag::err_diagnose_if_succeeded - : diag::warn_diagnose_if_succeeded; - Diag(Loc, Code) << DIA->getMessage(); - Diag(DIA->getLocation(), diag::note_from_diagnose_if) - << DIA->getParent() << DIA->getCond()->getSourceRange(); +bool Sema::diagnoseArgIndependentDiagnoseIfAttrs(const FunctionDecl *Function, + SourceLocation Loc) { + return diagnoseDiagnoseIfAttrsWith( + *this, Function, /*ArgDependent=*/false, Loc, + [&](const DiagnoseIfAttr *DIA) { + bool Result; + return DIA->getCond()->EvaluateAsBooleanCondition(Result, Context) && + Result; + }); } /// \brief Add all of the function declarations in the given function set to @@ -6359,8 +6311,8 @@ void Sema::AddFunctionCandidates(const UnresolvedSetImpl &Fns, AddMethodCandidate(cast<CXXMethodDecl>(FD), F.getPair(), cast<CXXMethodDecl>(FD)->getParent(), Args[0]->getType(), Args[0]->Classify(Context), - Args[0], Args.slice(1), CandidateSet, - SuppressUserConversions, PartialOverloading); + Args.slice(1), CandidateSet, SuppressUserConversions, + PartialOverloading); else AddOverloadCandidate(FD, F.getPair(), Args, CandidateSet, SuppressUserConversions, PartialOverloading); @@ -6372,7 +6324,7 @@ void Sema::AddFunctionCandidates(const UnresolvedSetImpl &Fns, FunTmpl, F.getPair(), cast<CXXRecordDecl>(FunTmpl->getDeclContext()), ExplicitTemplateArgs, Args[0]->getType(), - Args[0]->Classify(Context), Args[0], Args.slice(1), CandidateSet, + Args[0]->Classify(Context), Args.slice(1), CandidateSet, SuppressUserConversions, PartialOverloading); else AddTemplateOverloadCandidate(FunTmpl, F.getPair(), @@ -6388,7 +6340,6 @@ void Sema::AddFunctionCandidates(const UnresolvedSetImpl &Fns, void Sema::AddMethodCandidate(DeclAccessPair FoundDecl, QualType ObjectType, Expr::Classification ObjectClassification, - Expr *ThisArg, ArrayRef<Expr *> Args, OverloadCandidateSet& CandidateSet, bool SuppressUserConversions) { @@ -6402,15 +6353,13 @@ void Sema::AddMethodCandidate(DeclAccessPair FoundDecl, assert(isa<CXXMethodDecl>(TD->getTemplatedDecl()) && "Expected a member function template"); AddMethodTemplateCandidate(TD, FoundDecl, ActingContext, - /*ExplicitArgs*/ nullptr, - ObjectType, ObjectClassification, - ThisArg, Args, CandidateSet, + /*ExplicitArgs*/ nullptr, ObjectType, + ObjectClassification, Args, CandidateSet, SuppressUserConversions); } else { AddMethodCandidate(cast<CXXMethodDecl>(Decl), FoundDecl, ActingContext, - ObjectType, ObjectClassification, - ThisArg, Args, - CandidateSet, SuppressUserConversions); + ObjectType, ObjectClassification, Args, CandidateSet, + SuppressUserConversions); } } @@ -6425,7 +6374,7 @@ void Sema::AddMethodCandidate(CXXMethodDecl *Method, DeclAccessPair FoundDecl, CXXRecordDecl *ActingContext, QualType ObjectType, Expr::Classification ObjectClassification, - Expr *ThisArg, ArrayRef<Expr *> Args, + ArrayRef<Expr *> Args, OverloadCandidateSet &CandidateSet, bool SuppressUserConversions, bool PartialOverloading, @@ -6547,9 +6496,6 @@ Sema::AddMethodCandidate(CXXMethodDecl *Method, DeclAccessPair FoundDecl, Candidate.DeductionFailure.Data = FailedAttr; return; } - - initDiagnoseIfComplaint(*this, CandidateSet, Candidate, Method, Args, - /*MissingImplicitThis=*/!ThisArg, ThisArg); } /// \brief Add a C++ member function template as a candidate to the candidate @@ -6562,7 +6508,6 @@ Sema::AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl, TemplateArgumentListInfo *ExplicitTemplateArgs, QualType ObjectType, Expr::Classification ObjectClassification, - Expr *ThisArg, ArrayRef<Expr *> Args, OverloadCandidateSet& CandidateSet, bool SuppressUserConversions, @@ -6616,9 +6561,9 @@ Sema::AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl, assert(isa<CXXMethodDecl>(Specialization) && "Specialization is not a member function?"); AddMethodCandidate(cast<CXXMethodDecl>(Specialization), FoundDecl, - ActingContext, ObjectType, ObjectClassification, - /*ThisArg=*/ThisArg, Args, CandidateSet, - SuppressUserConversions, PartialOverloading, Conversions); + ActingContext, ObjectType, ObjectClassification, Args, + CandidateSet, SuppressUserConversions, PartialOverloading, + Conversions); } /// \brief Add a C++ function template specialization as a candidate @@ -6945,8 +6890,6 @@ Sema::AddConversionCandidate(CXXConversionDecl *Conversion, Candidate.DeductionFailure.Data = FailedAttr; return; } - - initDiagnoseIfComplaint(*this, CandidateSet, Candidate, Conversion, None, false, From); } /// \brief Adds a conversion function template specialization @@ -7099,8 +7042,6 @@ void Sema::AddSurrogateCandidate(CXXConversionDecl *Conversion, Candidate.DeductionFailure.Data = FailedAttr; return; } - - initDiagnoseIfComplaint(*this, CandidateSet, Candidate, Conversion, None); } /// \brief Add overload candidates for overloaded operators that are @@ -7149,7 +7090,7 @@ void Sema::AddMemberOperatorCandidates(OverloadedOperatorKind Op, Oper != OperEnd; ++Oper) AddMethodCandidate(Oper.getPair(), Args[0]->getType(), - Args[0]->Classify(Context), Args[0], Args.slice(1), + Args[0]->Classify(Context), Args.slice(1), CandidateSet, /*SuppressUserConversions=*/false); } } @@ -9181,17 +9122,6 @@ void Sema::diagnoseEquivalentInternalLinkageDeclarations( } } -static bool isCandidateUnavailableDueToDiagnoseIf(const OverloadCandidate &OC) { - ArrayRef<DiagnoseIfAttr *> Info = OC.getDiagnoseIfInfo(); - if (!Info.empty() && Info[0]->isError()) - return true; - - assert(llvm::all_of(Info, - [](const DiagnoseIfAttr *A) { return !A->isError(); }) && - "DiagnoseIf info shouldn't have mixed warnings and errors."); - return false; -} - /// \brief Computes the best viable function (C++ 13.3.3) /// within an overload candidate set. /// @@ -9270,19 +9200,13 @@ OverloadCandidateSet::BestViableFunction(Sema &S, SourceLocation Loc, // Best is the best viable function. if (Best->Function && (Best->Function->isDeleted() || - S.isFunctionConsideredUnavailable(Best->Function) || - isCandidateUnavailableDueToDiagnoseIf(*Best))) + S.isFunctionConsideredUnavailable(Best->Function))) return OR_Deleted; if (!EquivalentCands.empty()) S.diagnoseEquivalentInternalLinkageDeclarations(Loc, Best->Function, EquivalentCands); - for (const auto *W : Best->getDiagnoseIfInfo()) { - assert(W->isWarning() && "Errors should've been caught earlier!"); - S.emitDiagnoseIfDiagnostic(Loc, W); - } - return OR_Success; } @@ -10165,14 +10089,6 @@ static void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand, MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); return; } - if (isCandidateUnavailableDueToDiagnoseIf(*Cand)) { - auto *A = Cand->DiagnoseIfInfo.get<DiagnoseIfAttr *>(); - assert(A->isError() && "Non-error diagnose_if disables a candidate?"); - S.Diag(Cand->Function->getLocation(), - diag::note_ovl_candidate_disabled_by_function_cond_attr) - << A->getCond()->getSourceRange() << A->getMessage(); - return; - } // We don't really have anything else to say about viable candidates. S.NoteOverloadCandidate(Cand->FoundDecl, Fn); @@ -10222,8 +10138,13 @@ static void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand, return DiagnoseOpenCLExtensionDisabled(S, Cand); case ovl_fail_inhctor_slice: + // It's generally not interesting to note copy/move constructors here. + if (cast<CXXConstructorDecl>(Fn)->isCopyOrMoveConstructor()) + return; S.Diag(Fn->getLocation(), - diag::note_ovl_candidate_inherited_constructor_slice); + diag::note_ovl_candidate_inherited_constructor_slice) + << (Fn->getPrimaryTemplate() ? 1 : 0) + << Fn->getParamDecl(0)->getType()->isRValueReferenceType(); MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); return; @@ -12111,6 +12032,10 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc, if (CheckCallReturnType(FnDecl->getReturnType(), OpLoc, TheCall, FnDecl)) return ExprError(); + if (CheckFunctionCall(FnDecl, TheCall, + FnDecl->getType()->castAs<FunctionProtoType>())) + return ExprError(); + return MaybeBindToTemporary(TheCall); } else { // We matched a built-in operator. Convert the arguments, then @@ -12341,16 +12266,20 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc, return ExprError(); ArrayRef<const Expr *> ArgsArray(Args, 2); + const Expr *ImplicitThis = nullptr; // Cut off the implicit 'this'. - if (isa<CXXMethodDecl>(FnDecl)) + if (isa<CXXMethodDecl>(FnDecl)) { + ImplicitThis = ArgsArray[0]; ArgsArray = ArgsArray.slice(1); + } // Check for a self move. if (Op == OO_Equal) DiagnoseSelfMove(Args[0], Args[1], OpLoc); - checkCall(FnDecl, nullptr, ArgsArray, isa<CXXMethodDecl>(FnDecl), OpLoc, - TheCall->getSourceRange(), VariadicDoesNotApply); + checkCall(FnDecl, nullptr, ImplicitThis, ArgsArray, + isa<CXXMethodDecl>(FnDecl), OpLoc, TheCall->getSourceRange(), + VariadicDoesNotApply); return MaybeBindToTemporary(TheCall); } else { @@ -12559,6 +12488,10 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc, if (CheckCallReturnType(FnDecl->getReturnType(), LLoc, TheCall, FnDecl)) return ExprError(); + if (CheckFunctionCall(Method, TheCall, + Method->getType()->castAs<FunctionProtoType>())) + return ExprError(); + return MaybeBindToTemporary(TheCall); } else { // We matched a built-in operator. Convert the arguments, then @@ -12725,16 +12658,6 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE, TemplateArgs = &TemplateArgsBuffer; } - // Poor-programmer's Lazy<Expr *>; isImplicitAccess requires stripping - // parens/casts, which would be nice to avoid potentially doing multiple - // times. - llvm::Optional<Expr *> UnresolvedBase; - auto GetUnresolvedBase = [&] { - if (!UnresolvedBase.hasValue()) - UnresolvedBase = - UnresExpr->isImplicitAccess() ? nullptr : UnresExpr->getBase(); - return *UnresolvedBase; - }; for (UnresolvedMemberExpr::decls_iterator I = UnresExpr->decls_begin(), E = UnresExpr->decls_end(); I != E; ++I) { @@ -12755,14 +12678,12 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE, continue; AddMethodCandidate(Method, I.getPair(), ActingDC, ObjectType, - ObjectClassification, - /*ThisArg=*/GetUnresolvedBase(), Args, CandidateSet, + ObjectClassification, Args, CandidateSet, /*SuppressUserConversions=*/false); } else { AddMethodTemplateCandidate( cast<FunctionTemplateDecl>(Func), I.getPair(), ActingDC, - TemplateArgs, ObjectType, ObjectClassification, - /*ThisArg=*/GetUnresolvedBase(), Args, CandidateSet, + TemplateArgs, ObjectType, ObjectClassification, Args, CandidateSet, /*SuppressUsedConversions=*/false); } } @@ -12880,16 +12801,6 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE, << Attr->getCond()->getSourceRange() << Attr->getMessage(); return ExprError(); } - - SmallVector<DiagnoseIfAttr *, 4> Nonfatal; - if (const DiagnoseIfAttr *Attr = checkArgDependentDiagnoseIf( - Method, Args, Nonfatal, false, MemE->getBase())) { - emitDiagnoseIfDiagnostic(MemE->getMemberLoc(), Attr); - return ExprError(); - } - - for (const auto *Attr : Nonfatal) - emitDiagnoseIfDiagnostic(MemE->getMemberLoc(), Attr); } if ((isa<CXXConstructorDecl>(CurContext) || @@ -12968,9 +12879,8 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj, for (LookupResult::iterator Oper = R.begin(), OperEnd = R.end(); Oper != OperEnd; ++Oper) { AddMethodCandidate(Oper.getPair(), Object.get()->getType(), - Object.get()->Classify(Context), - Object.get(), Args, CandidateSet, - /*SuppressUserConversions=*/ false); + Object.get()->Classify(Context), Args, CandidateSet, + /*SuppressUserConversions=*/false); } // C++ [over.call.object]p2: @@ -13245,8 +13155,7 @@ Sema::BuildOverloadedArrowExpr(Scope *S, Expr *Base, SourceLocation OpLoc, for (LookupResult::iterator Oper = R.begin(), OperEnd = R.end(); Oper != OperEnd; ++Oper) { AddMethodCandidate(Oper.getPair(), Base->getType(), Base->Classify(Context), - Base, None, CandidateSet, - /*SuppressUserConversions=*/false); + None, CandidateSet, /*SuppressUserConversions=*/false); } bool HadMultipleCandidates = (CandidateSet.size() > 1); @@ -13320,7 +13229,11 @@ Sema::BuildOverloadedArrowExpr(Scope *S, Expr *Base, SourceLocation OpLoc, Base, ResultTy, VK, OpLoc, false); if (CheckCallReturnType(Method->getReturnType(), OpLoc, TheCall, Method)) - return ExprError(); + return ExprError(); + + if (CheckFunctionCall(Method, TheCall, + Method->getType()->castAs<FunctionProtoType>())) + return ExprError(); return MaybeBindToTemporary(TheCall); } diff --git a/gnu/llvm/tools/clang/lib/Sema/SemaStmt.cpp b/gnu/llvm/tools/clang/lib/Sema/SemaStmt.cpp index a8832e9a1c5..390e1b52c8e 100644 --- a/gnu/llvm/tools/clang/lib/Sema/SemaStmt.cpp +++ b/gnu/llvm/tools/clang/lib/Sema/SemaStmt.cpp @@ -2743,15 +2743,17 @@ bool Sema::isCopyElisionCandidate(QualType ReturnType, const VarDecl *VD, // ...automatic... if (!VD->hasLocalStorage()) return false; + // Return false if VD is a __block variable. We don't want to implicitly move + // out of a __block variable during a return because we cannot assume the + // variable will no longer be used. + if (VD->hasAttr<BlocksAttr>()) return false; + if (AllowParamOrMoveConstructible) return true; // ...non-volatile... if (VD->getType().isVolatileQualified()) return false; - // __block variables can't be allocated in a way that permits NRVO. - if (VD->hasAttr<BlocksAttr>()) return false; - // Variables with higher required alignment than their type's ABI // alignment cannot use NRVO. if (!VD->getType()->isDependentType() && VD->hasAttr<AlignedAttr>() && diff --git a/gnu/llvm/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/gnu/llvm/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 48d8b94af15..200775756d3 100644 --- a/gnu/llvm/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/gnu/llvm/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -4996,8 +4996,12 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D, NamedDecl *Result = nullptr; // FIXME: If the name is a dependent name, this lookup won't necessarily // find it. Does that ever matter? - if (D->getDeclName()) { - DeclContext::lookup_result Found = ParentDC->lookup(D->getDeclName()); + if (auto Name = D->getDeclName()) { + DeclarationNameInfo NameInfo(Name, D->getLocation()); + Name = SubstDeclarationNameInfo(NameInfo, TemplateArgs).getName(); + if (!Name) + return nullptr; + DeclContext::lookup_result Found = ParentDC->lookup(Name); Result = findInstantiationOf(Context, D, Found.begin(), Found.end()); } else { // Since we don't have a name for the entity we're looking for, diff --git a/gnu/llvm/tools/clang/lib/Sema/SemaTemplateVariadic.cpp b/gnu/llvm/tools/clang/lib/Sema/SemaTemplateVariadic.cpp index 54556b505ee..725a3e42520 100644 --- a/gnu/llvm/tools/clang/lib/Sema/SemaTemplateVariadic.cpp +++ b/gnu/llvm/tools/clang/lib/Sema/SemaTemplateVariadic.cpp @@ -1014,6 +1014,11 @@ ExprResult Sema::ActOnCXXFoldExpr(SourceLocation LParenLoc, Expr *LHS, CheckFoldOperand(*this, LHS); CheckFoldOperand(*this, RHS); + auto DiscardOperands = [&] { + CorrectDelayedTyposInExpr(LHS); + CorrectDelayedTyposInExpr(RHS); + }; + // [expr.prim.fold]p3: // In a binary fold, op1 and op2 shall be the same fold-operator, and // either e1 shall contain an unexpanded parameter pack or e2 shall contain @@ -1021,6 +1026,7 @@ ExprResult Sema::ActOnCXXFoldExpr(SourceLocation LParenLoc, Expr *LHS, if (LHS && RHS && LHS->containsUnexpandedParameterPack() == RHS->containsUnexpandedParameterPack()) { + DiscardOperands(); return Diag(EllipsisLoc, LHS->containsUnexpandedParameterPack() ? diag::err_fold_expression_packs_both_sides @@ -1034,6 +1040,7 @@ ExprResult Sema::ActOnCXXFoldExpr(SourceLocation LParenLoc, Expr *LHS, if (!LHS || !RHS) { Expr *Pack = LHS ? LHS : RHS; assert(Pack && "fold expression with neither LHS nor RHS"); + DiscardOperands(); if (!Pack->containsUnexpandedParameterPack()) return Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs) << Pack->getSourceRange(); diff --git a/gnu/llvm/tools/clang/lib/Sema/SemaType.cpp b/gnu/llvm/tools/clang/lib/Sema/SemaType.cpp index 29b21426790..2cdf76caa7e 100644 --- a/gnu/llvm/tools/clang/lib/Sema/SemaType.cpp +++ b/gnu/llvm/tools/clang/lib/Sema/SemaType.cpp @@ -3154,7 +3154,7 @@ getCCForDeclaratorChunk(Sema &S, Declarator &D, if (Attr->getKind() == AttributeList::AT_OpenCLKernel) { llvm::Triple::ArchType arch = S.Context.getTargetInfo().getTriple().getArch(); if (arch == llvm::Triple::spir || arch == llvm::Triple::spir64 || - arch == llvm::Triple::amdgcn) { + arch == llvm::Triple::amdgcn || arch == llvm::Triple::r600) { CC = CC_OpenCLKernel; } break; diff --git a/gnu/llvm/tools/clang/lib/Sema/TreeTransform.h b/gnu/llvm/tools/clang/lib/Sema/TreeTransform.h index c2aa3fef67c..f8e65a119c3 100644 --- a/gnu/llvm/tools/clang/lib/Sema/TreeTransform.h +++ b/gnu/llvm/tools/clang/lib/Sema/TreeTransform.h @@ -2932,16 +2932,17 @@ public: ExprResult RebuildObjCIvarRefExpr(Expr *BaseArg, ObjCIvarDecl *Ivar, SourceLocation IvarLoc, bool IsArrow, bool IsFreeIvar) { - // FIXME: We lose track of the IsFreeIvar bit. CXXScopeSpec SS; DeclarationNameInfo NameInfo(Ivar->getDeclName(), IvarLoc); - return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(), - /*FIXME:*/IvarLoc, IsArrow, - SS, SourceLocation(), - /*FirstQualifierInScope=*/nullptr, - NameInfo, - /*TemplateArgs=*/nullptr, - /*S=*/nullptr); + ExprResult Result = getSema().BuildMemberReferenceExpr( + BaseArg, BaseArg->getType(), + /*FIXME:*/ IvarLoc, IsArrow, SS, SourceLocation(), + /*FirstQualifierInScope=*/nullptr, NameInfo, + /*TemplateArgs=*/nullptr, + /*S=*/nullptr); + if (IsFreeIvar && Result.isUsable()) + cast<ObjCIvarRefExpr>(Result.get())->setIsFreeIvar(IsFreeIvar); + return Result; } /// \brief Build a new Objective-C property reference expression. @@ -8818,12 +8819,18 @@ TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) { // base (and therefore couldn't do the check) and a // nested-name-qualifier (and therefore could do the lookup). NamedDecl *FirstQualifierInScope = nullptr; + DeclarationNameInfo MemberNameInfo = E->getMemberNameInfo(); + if (MemberNameInfo.getName()) { + MemberNameInfo = getDerived().TransformDeclarationNameInfo(MemberNameInfo); + if (!MemberNameInfo.getName()) + return ExprError(); + } return getDerived().RebuildMemberExpr(Base.get(), FakeOperatorLoc, E->isArrow(), QualifierLoc, TemplateKWLoc, - E->getMemberNameInfo(), + MemberNameInfo, Member, FoundDecl, (E->hasExplicitTemplateArgs() diff --git a/gnu/llvm/tools/clang/lib/Serialization/ASTReaderDecl.cpp b/gnu/llvm/tools/clang/lib/Serialization/ASTReaderDecl.cpp index c6919193391..707a9249dd9 100644 --- a/gnu/llvm/tools/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/gnu/llvm/tools/clang/lib/Serialization/ASTReaderDecl.cpp @@ -2513,8 +2513,8 @@ static bool isConsumerInterestedIn(ASTContext &Ctx, Decl *D, bool HasBody) { // An ImportDecl or VarDecl imported from a module will get emitted when // we import the relevant module. - if ((isa<ImportDecl>(D) || isa<VarDecl>(D)) && Ctx.DeclMustBeEmitted(D) && - D->getImportedOwningModule()) + if ((isa<ImportDecl>(D) || isa<VarDecl>(D)) && D->getImportedOwningModule() && + Ctx.DeclMustBeEmitted(D)) return false; if (isa<FileScopeAsmDecl>(D) || diff --git a/gnu/llvm/tools/clang/lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp b/gnu/llvm/tools/clang/lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp index 0e0f52af316..437378e53da 100644 --- a/gnu/llvm/tools/clang/lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp +++ b/gnu/llvm/tools/clang/lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp @@ -94,11 +94,18 @@ void MacOSXAPIChecker::CheckDispatchOnce(CheckerContext &C, const CallExpr *CE, bool SuggestStatic = false; os << "Call to '" << FName << "' uses"; if (const VarRegion *VR = dyn_cast<VarRegion>(RB)) { + const VarDecl *VD = VR->getDecl(); + // FIXME: These should have correct memory space and thus should be filtered + // out earlier. This branch only fires when we're looking from a block, + // which we analyze as a top-level declaration, onto a static local + // in a function that contains the block. + if (VD->isStaticLocal()) + return; // We filtered out globals earlier, so it must be a local variable // or a block variable which is under UnknownSpaceRegion. if (VR != R) os << " memory within"; - if (VR->getDecl()->hasAttr<BlocksAttr>()) + if (VD->hasAttr<BlocksAttr>()) os << " the block variable '"; else os << " the local variable '"; diff --git a/gnu/llvm/tools/clang/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp b/gnu/llvm/tools/clang/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp index 15e8ea31c4c..b47762b915c 100644 --- a/gnu/llvm/tools/clang/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp +++ b/gnu/llvm/tools/clang/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp @@ -179,7 +179,8 @@ void WalkAST::VisitCXXMemberCallExpr(CallExpr *CE) { } // Get the callee. - const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(CE->getDirectCallee()); + const CXXMethodDecl *MD = + dyn_cast_or_null<CXXMethodDecl>(CE->getDirectCallee()); if (MD && MD->isVirtual() && !callIsNonVirtual && !MD->hasAttr<FinalAttr>() && !MD->getParent()->hasAttr<FinalAttr>()) ReportVirtualCall(CE, MD->isPure()); diff --git a/gnu/llvm/tools/clang/lib/StaticAnalyzer/Core/MemRegion.cpp b/gnu/llvm/tools/clang/lib/StaticAnalyzer/Core/MemRegion.cpp index c4ba2ae199f..d6e8fe5b51b 100644 --- a/gnu/llvm/tools/clang/lib/StaticAnalyzer/Core/MemRegion.cpp +++ b/gnu/llvm/tools/clang/lib/StaticAnalyzer/Core/MemRegion.cpp @@ -816,9 +816,11 @@ const VarRegion* MemRegionManager::getVarRegion(const VarDecl *D, const StackFrameContext *STC = V.get<const StackFrameContext*>(); - if (!STC) + if (!STC) { + // FIXME: Assign a more sensible memory space to static locals + // we see from within blocks that we analyze as top-level declarations. sReg = getUnknownRegion(); - else { + } else { if (D->hasLocalStorage()) { sReg = isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D) ? static_cast<const MemRegion*>(getStackArgumentsRegion(STC)) diff --git a/gnu/llvm/tools/clang/lib/StaticAnalyzer/Core/RegionStore.cpp b/gnu/llvm/tools/clang/lib/StaticAnalyzer/Core/RegionStore.cpp index 15ca2c14f94..934cc5cd3ac 100644 --- a/gnu/llvm/tools/clang/lib/StaticAnalyzer/Core/RegionStore.cpp +++ b/gnu/llvm/tools/clang/lib/StaticAnalyzer/Core/RegionStore.cpp @@ -1849,6 +1849,8 @@ SVal RegionStoreManager::getBindingForVar(RegionBindingsConstRef B, // Function-scoped static variables are default-initialized to 0; if they // have an initializer, it would have been processed by now. + // FIXME: This is only true when we're starting analysis from main(). + // We're losing a lot of coverage here. if (isa<StaticGlobalSpaceRegion>(MS)) return svalBuilder.makeZeroVal(T); diff --git a/gnu/llvm/tools/clang/tools/libclang/CXIndexDataConsumer.cpp b/gnu/llvm/tools/clang/tools/libclang/CXIndexDataConsumer.cpp index 1981cabbbe4..cb8aebfd0c4 100644 --- a/gnu/llvm/tools/clang/tools/libclang/CXIndexDataConsumer.cpp +++ b/gnu/llvm/tools/clang/tools/libclang/CXIndexDataConsumer.cpp @@ -95,7 +95,7 @@ public: if (isa<ObjCImplDecl>(LexicalDC) && !D->isThisDeclarationADefinition()) DataConsumer.handleSynthesizedObjCMethod(D, DeclLoc, LexicalDC); else - DataConsumer.handleObjCMethod(D); + DataConsumer.handleObjCMethod(D, DeclLoc); return true; } @@ -801,7 +801,8 @@ bool CXIndexDataConsumer::handleObjCCategoryImpl(const ObjCCategoryImplDecl *D) return handleObjCContainer(D, CategoryLoc, getCursor(D), CatDInfo); } -bool CXIndexDataConsumer::handleObjCMethod(const ObjCMethodDecl *D) { +bool CXIndexDataConsumer::handleObjCMethod(const ObjCMethodDecl *D, + SourceLocation Loc) { bool isDef = D->isThisDeclarationADefinition(); bool isContainer = isDef; bool isSkipped = false; @@ -814,7 +815,7 @@ bool CXIndexDataConsumer::handleObjCMethod(const ObjCMethodDecl *D) { DeclInfo DInfo(!D->isCanonicalDecl(), isDef, isContainer); if (isSkipped) DInfo.flags |= CXIdxDeclFlag_Skipped; - return handleDecl(D, D->getLocation(), getCursor(D), DInfo); + return handleDecl(D, Loc, getCursor(D), DInfo); } bool CXIndexDataConsumer::handleSynthesizedObjCProperty( diff --git a/gnu/llvm/tools/clang/tools/libclang/CXIndexDataConsumer.h b/gnu/llvm/tools/clang/tools/libclang/CXIndexDataConsumer.h index 718a2a18b1b..16162cb83f7 100644 --- a/gnu/llvm/tools/clang/tools/libclang/CXIndexDataConsumer.h +++ b/gnu/llvm/tools/clang/tools/libclang/CXIndexDataConsumer.h @@ -418,7 +418,7 @@ public: bool handleObjCCategory(const ObjCCategoryDecl *D); bool handleObjCCategoryImpl(const ObjCCategoryImplDecl *D); - bool handleObjCMethod(const ObjCMethodDecl *D); + bool handleObjCMethod(const ObjCMethodDecl *D, SourceLocation Loc); bool handleSynthesizedObjCProperty(const ObjCPropertyImplDecl *D); bool handleSynthesizedObjCMethod(const ObjCMethodDecl *D, SourceLocation Loc, diff --git a/gnu/llvm/tools/lld/CMakeLists.txt b/gnu/llvm/tools/lld/CMakeLists.txt index 48ac5e038cd..be424efbbd8 100644 --- a/gnu/llvm/tools/lld/CMakeLists.txt +++ b/gnu/llvm/tools/lld/CMakeLists.txt @@ -42,6 +42,7 @@ if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) include_directories("${LLVM_BINARY_DIR}/include" ${LLVM_INCLUDE_DIRS}) link_directories(${LLVM_LIBRARY_DIRS}) + set(LLVM_LIBRARY_OUTPUT_INTDIR ${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/lib${LLVM_LIBDIR_SUFFIX}) set(LLVM_RUNTIME_OUTPUT_INTDIR ${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/bin) find_program(LLVM_TABLEGEN_EXE "llvm-tblgen" ${LLVM_TOOLS_BINARY_DIR} NO_DEFAULT_PATH) diff --git a/gnu/llvm/tools/lld/ELF/InputFiles.h b/gnu/llvm/tools/lld/ELF/InputFiles.h index 73dda7b566b..95888061d87 100644 --- a/gnu/llvm/tools/lld/ELF/InputFiles.h +++ b/gnu/llvm/tools/lld/ELF/InputFiles.h @@ -180,10 +180,6 @@ public: // R_MIPS_GPREL16 / R_MIPS_GPREL32 relocations. uint32_t MipsGp0 = 0; - // The number is the offset in the string table. It will be used as the - // st_name of the symbol. - std::vector<std::pair<const DefinedRegular<ELFT> *, unsigned>> KeptLocalSyms; - // Name of source file obtained from STT_FILE symbol value, // or empty string if there is no such symbol in object file // symbol table. diff --git a/gnu/llvm/tools/lld/ELF/InputSection.cpp b/gnu/llvm/tools/lld/ELF/InputSection.cpp index 35800424837..6b1e92891b9 100644 --- a/gnu/llvm/tools/lld/ELF/InputSection.cpp +++ b/gnu/llvm/tools/lld/ELF/InputSection.cpp @@ -246,7 +246,8 @@ void InputSection<ELFT>::copyRelocations(uint8_t *Buf, ArrayRef<RelTy> Rels) { if (Config->Rela) P->r_addend = getAddend<ELFT>(Rel); P->r_offset = RelocatedSection->getOffset(Rel.r_offset); - P->setSymbolAndType(Body.DynsymIndex, Type, Config->Mips64EL); + P->setSymbolAndType(In<ELFT>::SymTab->getSymbolIndex(&Body), Type, + Config->Mips64EL); } } diff --git a/gnu/llvm/tools/lld/ELF/LinkerScript.cpp b/gnu/llvm/tools/lld/ELF/LinkerScript.cpp index 887ca12537a..3cc235386b8 100644 --- a/gnu/llvm/tools/lld/ELF/LinkerScript.cpp +++ b/gnu/llvm/tools/lld/ELF/LinkerScript.cpp @@ -918,12 +918,7 @@ const OutputSectionBase *LinkerScript<ELFT>::getSymbolSection(StringRef S) { return CurOutSec ? CurOutSec : (*OutputSections)[0]; } - if (auto *DR = dyn_cast_or_null<DefinedRegular<ELFT>>(Sym)) - return DR->Section ? DR->Section->OutSec : nullptr; - if (auto *DS = dyn_cast_or_null<DefinedSynthetic>(Sym)) - return DS->Section; - - return nullptr; + return SymbolTableSection<ELFT>::getOutputSection(Sym); } // Returns indices of ELF headers containing specific section, identified diff --git a/gnu/llvm/tools/lld/ELF/SymbolTable.cpp b/gnu/llvm/tools/lld/ELF/SymbolTable.cpp index b3e91c9f32e..ce257933c26 100644 --- a/gnu/llvm/tools/lld/ELF/SymbolTable.cpp +++ b/gnu/llvm/tools/lld/ELF/SymbolTable.cpp @@ -140,7 +140,7 @@ template <class ELFT> DefinedRegular<ELFT> *SymbolTable<ELFT>::addIgnored(StringRef Name, uint8_t Visibility) { SymbolBody *S = find(Name); - if (!S || !S->isUndefined()) + if (!S || S->isInCurrentDSO()) return nullptr; return addAbsolute(Name, Visibility); } @@ -283,7 +283,7 @@ static int compareDefined(Symbol *S, bool WasInserted, uint8_t Binding) { if (WasInserted) return 1; SymbolBody *Body = S->body(); - if (Body->isLazy() || Body->isUndefined() || Body->isShared()) + if (Body->isLazy() || !Body->isInCurrentDSO()) return 1; if (Binding == STB_WEAK) return -1; @@ -464,6 +464,14 @@ template <class ELFT> SymbolBody *SymbolTable<ELFT>::find(StringRef Name) { } template <class ELFT> +SymbolBody *SymbolTable<ELFT>::findInCurrentDSO(StringRef Name) { + if (SymbolBody *S = find(Name)) + if (S->isInCurrentDSO()) + return S; + return nullptr; +} + +template <class ELFT> void SymbolTable<ELFT>::addLazyArchive(ArchiveFile *F, const object::Archive::Symbol Sym) { Symbol *S; diff --git a/gnu/llvm/tools/lld/ELF/SymbolTable.h b/gnu/llvm/tools/lld/ELF/SymbolTable.h index 1e5a335acc1..f39dbd1e2e1 100644 --- a/gnu/llvm/tools/lld/ELF/SymbolTable.h +++ b/gnu/llvm/tools/lld/ELF/SymbolTable.h @@ -82,6 +82,7 @@ public: void scanVersionScript(); SymbolBody *find(StringRef Name); + SymbolBody *findInCurrentDSO(StringRef Name); void trace(StringRef Name); void wrap(StringRef Name); diff --git a/gnu/llvm/tools/lld/ELF/Symbols.h b/gnu/llvm/tools/lld/ELF/Symbols.h index af85dc2b121..7acb89ad071 100644 --- a/gnu/llvm/tools/lld/ELF/Symbols.h +++ b/gnu/llvm/tools/lld/ELF/Symbols.h @@ -67,6 +67,7 @@ public: return SymbolKind == LazyArchiveKind || SymbolKind == LazyObjectKind; } bool isShared() const { return SymbolKind == SharedKind; } + bool isInCurrentDSO() const { return !isUndefined() && !isShared(); } bool isLocal() const { return IsLocal; } bool isPreemptible() const; StringRef getName() const { return Name; } diff --git a/gnu/llvm/tools/lld/ELF/SyntheticSections.h b/gnu/llvm/tools/lld/ELF/SyntheticSections.h index dfefb3821e7..df67e079ad0 100644 --- a/gnu/llvm/tools/lld/ELF/SyntheticSections.h +++ b/gnu/llvm/tools/lld/ELF/SyntheticSections.h @@ -366,23 +366,26 @@ public: void finalize() override; void writeTo(uint8_t *Buf) override; size_t getSize() const override { return getNumSymbols() * sizeof(Elf_Sym); } - void addSymbol(SymbolBody *Body); + void addGlobal(SymbolBody *Body); + void addLocal(SymbolBody *Body); StringTableSection<ELFT> &getStrTabSec() const { return StrTabSec; } - unsigned getNumSymbols() const { return NumLocals + Symbols.size() + 1; } + unsigned getNumSymbols() const { return Symbols.size() + 1; } + size_t getSymbolIndex(SymbolBody *Body); ArrayRef<SymbolTableEntry> getSymbols() const { return Symbols; } - unsigned NumLocals = 0; - StringTableSection<ELFT> &StrTabSec; + static const OutputSectionBase *getOutputSection(SymbolBody *Sym); private: void writeLocalSymbols(uint8_t *&Buf); void writeGlobalSymbols(uint8_t *Buf); - const OutputSectionBase *getOutputSection(SymbolBody *Sym); - // A vector of symbols and their string table offsets. std::vector<SymbolTableEntry> Symbols; + + StringTableSection<ELFT> &StrTabSec; + + unsigned NumLocals = 0; }; // Outputs GNU Hash section. For detailed explanation see: diff --git a/gnu/llvm/tools/lld/ELF/Writer.cpp b/gnu/llvm/tools/lld/ELF/Writer.cpp index bddc42e1acf..b004a4f0d7f 100644 --- a/gnu/llvm/tools/lld/ELF/Writer.cpp +++ b/gnu/llvm/tools/lld/ELF/Writer.cpp @@ -455,11 +455,7 @@ template <class ELFT> void Writer<ELFT>::copyLocalSymbols() { InputSectionBase<ELFT> *Sec = DR->Section; if (!shouldKeepInSymtab<ELFT>(Sec, B->getName(), *B)) continue; - ++In<ELFT>::SymTab->NumLocals; - if (Config->Relocatable) - B->DynsymIndex = In<ELFT>::SymTab->NumLocals; - F->KeptLocalSyms.push_back(std::make_pair( - DR, In<ELFT>::SymTab->StrTabSec.addString(B->getName()))); + In<ELFT>::SymTab->addLocal(B); } } } @@ -480,6 +476,16 @@ static int getPPC64SectionRank(StringRef SectionName) { .Default(1); } +// All sections with SHF_MIPS_GPREL flag should be grouped together +// because data in these sections is addressable with a gp relative address. +static int getMipsSectionRank(const OutputSectionBase *S) { + if ((S->Flags & SHF_MIPS_GPREL) == 0) + return 0; + if (S->getName() == ".got") + return 1; + return 2; +} + template <class ELFT> bool elf::isRelroSection(const OutputSectionBase *Sec) { if (!Config->ZRelro) return false; @@ -498,8 +504,6 @@ template <class ELFT> bool elf::isRelroSection(const OutputSectionBase *Sec) { return true; if (In<ELFT>::Got && Sec == In<ELFT>::Got->OutSec) return true; - if (In<ELFT>::MipsGot && Sec == In<ELFT>::MipsGot->OutSec) - return true; if (Sec == Out<ELFT>::BssRelRo) return true; StringRef S = Sec->getName(); @@ -599,6 +603,8 @@ static bool compareSectionsNonScript(const OutputSectionBase *A, if (Config->EMachine == EM_PPC64) return getPPC64SectionRank(A->getName()) < getPPC64SectionRank(B->getName()); + if (Config->EMachine == EM_MIPS) + return getMipsSectionRank(A) < getMipsSectionRank(B); return false; } @@ -641,7 +647,7 @@ static void addOptionalSynthetic(StringRef Name, OutputSectionBase *Sec, typename ELFT::uint Val, uint8_t StOther = STV_HIDDEN) { if (SymbolBody *S = Symtab<ELFT>::X->find(Name)) - if (S->isUndefined() || S->isShared()) + if (!S->isInCurrentDSO()) Symtab<ELFT>::X->addSynthetic(Name, Sec, Val, StOther); } @@ -661,7 +667,7 @@ static Symbol *addOptionalRegular(StringRef Name, InputSectionBase<ELFT> *IS, SymbolBody *S = Symtab<ELFT>::X->find(Name); if (!S) return nullptr; - if (!S->isUndefined() && !S->isShared()) + if (S->isInCurrentDSO()) return S->symbol(); return addRegular(Name, IS, Value); } @@ -1024,10 +1030,10 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() { if (!includeInSymtab<ELFT>(*Body)) continue; if (In<ELFT>::SymTab) - In<ELFT>::SymTab->addSymbol(Body); + In<ELFT>::SymTab->addGlobal(Body); if (In<ELFT>::DynSymTab && S->includeInDynsym()) { - In<ELFT>::DynSymTab->addSymbol(Body); + In<ELFT>::DynSymTab->addGlobal(Body); if (auto *SS = dyn_cast<SharedSymbol<ELFT>>(Body)) if (SS->file()->isNeeded()) In<ELFT>::VerNeed->addSymbol(SS); @@ -1466,7 +1472,7 @@ template <class ELFT> void Writer<ELFT>::setPhdrs() { // The glibc dynamic loader rounds the size down, so we need to round up // to protect the last page. This is a no-op on FreeBSD which always // rounds up. - P.p_memsz = alignTo(P.p_memsz, Config->MaxPageSize); + P.p_memsz = alignTo(P.p_memsz, Target->PageSize); } // The TLS pointer goes after PT_TLS. At least glibc will align it, diff --git a/gnu/llvm/tools/lld/cmake/modules/AddLLD.cmake b/gnu/llvm/tools/lld/cmake/modules/AddLLD.cmake index 906b2952a94..fd1d44199ca 100644 --- a/gnu/llvm/tools/lld/cmake/modules/AddLLD.cmake +++ b/gnu/llvm/tools/lld/cmake/modules/AddLLD.cmake @@ -1,6 +1,38 @@ macro(add_lld_library name) - llvm_add_library(${name} ${ARGN}) + cmake_parse_arguments(ARG + "SHARED" + "" + "" + ${ARGN}) + if(ARG_SHARED) + set(ARG_ENABLE_SHARED SHARED) + endif() + llvm_add_library(${name} ${ARG_ENABLE_SHARED} ${ARG_UNPARSED_ARGUMENTS}) set_target_properties(${name} PROPERTIES FOLDER "lld libraries") + + if (LLD_BUILD_TOOLS) + if(${name} IN_LIST LLVM_DISTRIBUTION_COMPONENTS OR + NOT LLVM_DISTRIBUTION_COMPONENTS) + set(export_to_lldtargets EXPORT lldTargets) + set_property(GLOBAL PROPERTY LLD_HAS_EXPORTS True) + endif() + + install(TARGETS ${name} + COMPONENT ${name} + ${export_to_lldtargets} + LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX} + ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX} + RUNTIME DESTINATION bin) + + if (${ARG_SHARED} AND NOT CMAKE_CONFIGURATION_TYPES) + add_custom_target(install-${name} + DEPENDS ${name} + COMMAND "${CMAKE_COMMAND}" + -DCMAKE_INSTALL_COMPONENT=${name} + -P "${CMAKE_BINARY_DIR}/cmake_install.cmake") + endif() + set_property(GLOBAL APPEND PROPERTY LLD_EXPORTS ${name}) + endif() endmacro(add_lld_library) macro(add_lld_executable name) diff --git a/gnu/llvm/tools/lld/docs/ReleaseNotes.rst b/gnu/llvm/tools/lld/docs/ReleaseNotes.rst index 8bd73db363d..07fc7dd04e7 100644 --- a/gnu/llvm/tools/lld/docs/ReleaseNotes.rst +++ b/gnu/llvm/tools/lld/docs/ReleaseNotes.rst @@ -5,31 +5,97 @@ LLD 4.0.0 Release Notes .. contents:: :local: -.. warning:: - These are in-progress notes for the upcoming LLVM 4.0.0 release. - Introduction ============ -This document contains the release notes for the LLD linker, release 4.0.0. +LLD is a linker which supports ELF (Unix), COFF (Windows) and Mach-O +(macOS). It is generally faster than the GNU BFD/gold linkers or the +MSVC linker. + +LLD is designed to be a drop-in replacement for the system linkers, so +that users don't need to change their build systems other than swapping +the linker command. + +This document contains the release notes for LLD 4.0.0. Here we describe the status of LLD, including major improvements from the previous release. All LLD releases may be downloaded from the `LLVM releases web site <http://llvm.org/releases/>`_. -Non-comprehensive list of changes in this release -================================================= + +What's New in LLD 4.0? +====================== ELF Improvements ---------------- -* Initial support for LTO. +LLD provides much better compatibility with the GNU linker than before. +Now it is able to link the entire FreeBSD base system including the kernel +out of the box. We are working closely with the FreeBSD project to +make it usable as the system linker in a future release of the operating +system. -COFF Improvements ------------------ +Multi-threading performance has been improved, and multi-threading +is now enabled by default. Combined with other optimizations, LLD 4.0 +is about 1.5 times faster than LLD 3.9 when linking large programs +in our test environment. + +Other notable changes are listed below: + +* Error messages contain more information than before. If debug info + is available, the linker prints out not only the object file name + but the source location of unresolved symbols. + +* Error messages are printed in red just like Clang by default. You + can disable it by passing ``-no-color-diagnostics``. + +* LLD's version string is now embedded in a .comment section in the + result output file. You can dump it with this command: ``objdump -j -s + .comment <file>``. + +* The ``-Map`` option is supported. With that, you can print out section + and symbol information to a specified file. This feature is useful + for analyzing link results. -* Item 1. +* The file format for the ``-reproduce`` option has changed from cpio to + tar. -MachO Improvements ------------------- +* When creating a copy relocation for a symbol, LLD now scans the + DSO's header to see if the symbol is in a read-only segment. If so, + space for the copy relocation is reserved in .bss.rel.ro instead of + .bss. This fixes a security issue that read-only data in a DSO + becomes writable if it is copied by a copy relocation. This issue + was disclosed originally on the + `binutils mailing list <https://sourceware.org/ml/libc-alpha/2016-12/msg00914.html>`_. + +* Compressed input sections are supported. + +* ``--oformat binary``, ``--section-start``, ``-Tbss``, ``-Tdata``, + ``-Ttext``, ``-b binary``, ``-build-id=uuid``, ``-no-rosegment``, + ``-nopie``, ``-nostdlib``, ``-omagic``, ``-retain-symbols-file``, + ``-sort-section``, ``-z max-page-size`` and ``-z wxneeded`` are + supported. + +* A lot of linker script directives have been added. + +* Default image base address for x86-64 has changed from 0x10000 to + 0x200000 to make it huge-page friendly. + +* ARM port now supports GNU ifunc, the ARM C++ exceptions ABI, TLS + relocations and static linking. Problems with ``dlopen()`` on systems + using eglibc fixed. + +* MIPS port now supports input files in new R6 revision of MIPS ABIs + or N32 ABI. Generated file now contains .MIPS.abiflags section and + complete set of ELF headers flags. + +* Relocations produced by the ``-mxgot`` compiler flag is supported + for MIPS. Now it is possible to generate "large" GOT that exceeds the 64K + limit. + +COFF Improvements +----------------- -* Item 1. +* Performance on Windows has been improved by parallelizing parts of the + linker and optimizing file system operations. As a result of these + improvements, LLD 4.0 has been measured to be about 2.5 times faster + than LLD 3.9 when linking a large Chromium DLL. diff --git a/gnu/llvm/tools/lld/docs/conf.py b/gnu/llvm/tools/lld/docs/conf.py index 6faed2fc980..8abd6f4facb 100644 --- a/gnu/llvm/tools/lld/docs/conf.py +++ b/gnu/llvm/tools/lld/docs/conf.py @@ -48,9 +48,9 @@ copyright = u'2011-%d, LLVM Project' % date.today().year # built documents. # # The short X.Y version. -version = '4.0' +version = '4' # The full version, including alpha/beta/rc tags. -release = '4.0' +release = '4' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/gnu/llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp b/gnu/llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp index 80a54bbf63d..1e2797ba333 100644 --- a/gnu/llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp +++ b/gnu/llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp @@ -14,9 +14,12 @@ using namespace llvm; -static void demangle(llvm::raw_ostream &OS, const char *Mangled) { +static void demangle(llvm::raw_ostream &OS, const std::string &Mangled) { int Status; - char *Demangled = itaniumDemangle(Mangled, nullptr, nullptr, &Status); + char *Demangled = nullptr; + if ((Mangled.size() >= 2 && Mangled.compare(0, 2, "_Z")) || + (Mangled.size() >= 4 && Mangled.compare(0, 4, "___Z"))) + Demangled = itaniumDemangle(Mangled.c_str(), nullptr, nullptr, &Status); OS << (Demangled ? Demangled : Mangled) << '\n'; free(Demangled); } @@ -24,7 +27,7 @@ static void demangle(llvm::raw_ostream &OS, const char *Mangled) { int main(int argc, char **argv) { if (argc == 1) for (std::string Mangled; std::getline(std::cin, Mangled);) - demangle(llvm::outs(), Mangled.c_str()); + demangle(llvm::outs(), Mangled); else for (int I = 1; I < argc; ++I) demangle(llvm::outs(), argv[I]); diff --git a/gnu/llvm/tools/llvm-objdump/ELFDump.cpp b/gnu/llvm/tools/llvm-objdump/ELFDump.cpp index aa6aa94ccd9..7f5fe5a9d3b 100644 --- a/gnu/llvm/tools/llvm-objdump/ELFDump.cpp +++ b/gnu/llvm/tools/llvm-objdump/ELFDump.cpp @@ -36,6 +36,9 @@ template <class ELFT> void printProgramHeaders(const ELFFile<ELFT> *o) { case ELF::PT_GNU_EH_FRAME: outs() << "EH_FRAME "; break; + case ELF::PT_GNU_RELRO: + outs() << " RELRO "; + break; case ELF::PT_GNU_STACK: outs() << " STACK "; break; @@ -45,6 +48,18 @@ template <class ELFT> void printProgramHeaders(const ELFFile<ELFT> *o) { case ELF::PT_LOAD: outs() << " LOAD "; break; + case ELF::PT_NOTE: + outs() << " NOTE "; + break; + case ELF::PT_OPENBSD_BOOTDATA: + outs() << " OPENBSD_BOOTDATA "; + break; + case ELF::PT_OPENBSD_RANDOMIZE: + outs() << " OPENBSD_RANDOMIZE "; + break; + case ELF::PT_OPENBSD_WXNEEDED: + outs() << " OPENBSD_WXNEEDED "; + break; case ELF::PT_PHDR: outs() << " PHDR "; break; diff --git a/gnu/llvm/tools/llvm-xray/xray-converter.cc b/gnu/llvm/tools/llvm-xray/xray-converter.cc index 31275e2902f..1bc9b15ae12 100644 --- a/gnu/llvm/tools/llvm-xray/xray-converter.cc +++ b/gnu/llvm/tools/llvm-xray/xray-converter.cc @@ -98,7 +98,7 @@ void TraceConverter::exportAsYAML(const Trace &Records, raw_ostream &OS) { : std::to_string(R.FuncId), R.TSC, R.TId}); } - Output Out(OS); + Output Out(OS, nullptr, 0); Out << Trace; } diff --git a/gnu/llvm/tools/llvm-xray/xray-extract.cc b/gnu/llvm/tools/llvm-xray/xray-extract.cc index 49ecd742113..ecd535114a6 100644 --- a/gnu/llvm/tools/llvm-xray/xray-extract.cc +++ b/gnu/llvm/tools/llvm-xray/xray-extract.cc @@ -270,7 +270,7 @@ void InstrumentationMapExtractor::exportAsYAML(raw_ostream &OS) { YAMLSleds.push_back({FunctionIds[Sled.Function], Sled.Address, Sled.Function, Sled.Kind, Sled.AlwaysInstrument}); } - Output Out(OS); + Output Out(OS, nullptr, 0); Out << YAMLSleds; } |