diff --git a/docs/AttributeReference.rst b/docs/AttributeReference.rst index 26965e4cd737..d0e02fa72b33 100644 --- a/docs/AttributeReference.rst +++ b/docs/AttributeReference.rst @@ -36,23 +36,23 @@ used to process multiple arguments from a single invocation from a SIMD loop concurrently. The syntax of the `declare simd` construct is as follows: - .. code-block:: c + .. code-block:: none - #pragma omp declare simd [clause[[,] clause] ...] new-line - [#pragma omp declare simd [clause[[,] clause] ...] new-line] - [...] - function definition or declaration + #pragma omp declare simd [clause[[,] clause] ...] new-line + [#pragma omp declare simd [clause[[,] clause] ...] new-line] + [...] + function definition or declaration where clause is one of the following: - .. code-block:: c + .. code-block:: none - simdlen(length) - linear(argument-list[:constant-linear-step]) - aligned(argument-list[:alignment]) - uniform(argument-list) - inbranch - notinbranch + simdlen(length) + linear(argument-list[:constant-linear-step]) + aligned(argument-list[:alignment]) + uniform(argument-list) + inbranch + notinbranch #pragma omp declare target @@ -69,9 +69,9 @@ The syntax of the declare target directive is as follows: .. code-block:: c - #pragma omp declare target new-line - declarations-definition-seq - #pragma omp end declare target new-line + #pragma omp declare target new-line + declarations-definition-seq + #pragma omp end declare target new-line _Noreturn @@ -557,7 +557,7 @@ available in C. int isdigit(int c); int isdigit(int c) __attribute__((enable_if(c <= -1 || c > 255, "chosen when 'c' is out of range"))) __attribute__((unavailable("'c' must have the value of an unsigned char or EOF"))); - + void foo(char c) { isdigit(c); isdigit(10); @@ -610,7 +610,7 @@ overload out of a number of viable overloads using enable_if. void f() __attribute__((enable_if(true, ""))); // #1 void f() __attribute__((enable_if(true, ""))) __attribute__((enable_if(true, ""))); // #2 - + void g(int i, int j) __attribute__((enable_if(i, ""))); // #1 void g(int i, int j) __attribute__((enable_if(j, ""))) __attribute__((enable_if(true))); // #2 @@ -1170,7 +1170,7 @@ potentially-evaluated discarded-value expression that is not explicitly cast to .. code-block: c++ struct [[nodiscard]] error_info { /*...*/ }; error_info enable_missile_safety_mode(); - + void launch_missiles(); void test_missiles() { enable_missile_safety_mode(); // diagnoses @@ -1451,7 +1451,7 @@ default name. can only be placed before an @protocol or @interface declaration: .. code-block:: objc - + __attribute__((objc_runtime_name("MyLocalName"))) @interface Message @end diff --git a/docs/ClangCommandLineReference.rst b/docs/ClangCommandLineReference.rst index 782d225dce12..8a2da51bccbd 100644 --- a/docs/ClangCommandLineReference.rst +++ b/docs/ClangCommandLineReference.rst @@ -706,6 +706,10 @@ Print source range spans in numeric form .. option:: -fdiagnostics-show-category= +.. option:: -fexperimental-isel, -fno-experimental-isel + +Enables the experimental global instruction selector + .. option:: -fexperimental-new-pass-manager, -fno-experimental-new-pass-manager Enables an experimental new pass manager in LLVM. @@ -2414,6 +2418,10 @@ X86 .. option:: -mrdseed, -mno-rdseed +.. option:: -mretpoline, -mno-retpoline + +.. option:: -mretpoline-external-thunk, -mno-retpoline-external-thunk + .. option:: -mrtm, -mno-rtm .. option:: -msgx, -mno-sgx diff --git a/docs/DiagnosticsReference.rst b/docs/DiagnosticsReference.rst index e2b0bd7dd550..e38c58605f19 100644 --- a/docs/DiagnosticsReference.rst +++ b/docs/DiagnosticsReference.rst @@ -806,6 +806,17 @@ Also controls `-Wc++98-compat-bind-to-temporary-copy`_. +--------------------------------------------------------------------+-----------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ +-Wbinding-in-condition +---------------------- +This diagnostic is enabled by default. + +**Diagnostic text:** + ++--------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`ISO C++17 does not permit structured binding declaration in a condition`| ++--------------------------------------------------------------------------------------------------------------+ + + -Wbitfield-constant-conversion ------------------------------ This diagnostic is enabled by default. @@ -1402,6 +1413,10 @@ Some of the diagnostics controlled by this flag are enabled by default. **Diagnostic text:** ++--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`ISO C++ standards before C++17 do not allow new expression for type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to use list-initialization`| ++--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + +------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`constexpr if is a C++17 extension`| +------------------------------------------------------------------------+ @@ -1501,8 +1516,14 @@ Synonym for `-Wc++17-extensions`_. -Wc++2a-compat -------------- +Some of the diagnostics controlled by this flag are enabled by default. + **Diagnostic text:** ++------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`'<=>' is a single token in C++2a; add a space to avoid a change in behavior`| ++------------------------------------------------------------------------------------------------------------------+ + +-------------------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`'`:placeholder:`A`:diagtext:`' is a keyword in C++2a`| +-------------------------------------------------------------------------------------------+ @@ -1544,6 +1565,10 @@ Some of the diagnostics controlled by this flag are enabled by default. |:warning:`warning:` |nbsp| :diagtext:`explicit capture of 'this' with a capture default of '=' is incompatible with C++ standards before C++2a`| +-----------------------------------------------------------------------------------------------------------------------------------------------+ ++-----------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`'<=>' operator is incompatible with C++ standards before C++2a`| ++-----------------------------------------------------------------------------------------------------+ + -Wc++98-c++11-c++14-c++17-compat-pedantic ----------------------------------------- @@ -3540,6 +3565,21 @@ Some of the diagnostics controlled by this flag are enabled by default. +-------------------------------------------------------------------------------------------------+ +-Wexperimental-isel +------------------- +This diagnostic is enabled by default. + +**Diagnostic text:** + ++------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`-fexperimental-isel support for the '`:placeholder:`A`:diagtext:`' architecture is incomplete`| ++------------------------------------------------------------------------------------------------------------------------------------+ + ++----------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`-fexperimental-isel support is incomplete for this architecture at the current optimization level`| ++----------------------------------------------------------------------------------------------------------------------------------------+ + + -Wexplicit-initialize-call -------------------------- This diagnostic is enabled by default. @@ -3564,15 +3604,6 @@ This diagnostic is enabled by default. +-------------------------------------------------------------------------------------------------------------------------------------+ --Wextended-offsetof -------------------- -**Diagnostic text:** - -+--------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`using extended field designator is an extension`| -+--------------------------------------------------------------------------------------+ - - -Wextern-c-compat ----------------- This diagnostic is enabled by default. @@ -4565,96 +4596,34 @@ This diagnostic is enabled by default. | |+----------------------------------------------------------------------------------------------------------------+| | ||:diagtext:`variables and functions` || | |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`functions and global variables` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`functions, variables, and Objective-C interfaces` || -| |+----------------------------------------------------------------------------------------------------------------+| | ||:diagtext:`functions and methods` || | |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`parameters` || -| |+----------------------------------------------------------------------------------------------------------------+| | ||:diagtext:`functions, methods and blocks` || | |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`functions, methods, and classes` || -| |+----------------------------------------------------------------------------------------------------------------+| | ||:diagtext:`functions, methods, and parameters` || | |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`functions, methods, and global variables` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`classes` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`enums` || -| |+----------------------------------------------------------------------------------------------------------------+| | ||:diagtext:`variables` || | |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`methods` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`fields and global variables` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`structs` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`parameters and typedefs` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`variables and typedefs` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`thread-local variables` || -| |+----------------------------------------------------------------------------------------------------------------+| | ||:diagtext:`variables and fields` || | |+----------------------------------------------------------------------------------------------------------------+| | ||:diagtext:`variables, data members and tag types` || | |+----------------------------------------------------------------------------------------------------------------+| | ||:diagtext:`types and namespaces` || | |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`Objective-C interfaces` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`methods and properties` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`functions, methods, and properties` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`struct or union` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`struct, union or class` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`types` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`Objective-C instance methods` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`init methods of interface or class extension declarations` || -| |+----------------------------------------------------------------------------------------------------------------+| | ||:diagtext:`variables, functions and classes` || | |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`functions, variables, classes, and Objective-C interfaces` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`Objective-C protocols` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`variables with static or thread storage duration` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`functions, methods, properties, and global variables` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`structs, unions, and typedefs` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`structs and typedefs` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`interface or protocol declarations` || -| |+----------------------------------------------------------------------------------------------------------------+| | ||:diagtext:`kernel functions` || | |+----------------------------------------------------------------------------------------------------------------+| | ||:diagtext:`non-K&R-style functions` || | |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`variables, enums, fields and typedefs` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`functions, methods, enums, and classes` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`structs, classes, variables, functions, and inline namespaces` || -| |+----------------------------------------------------------------------------------------------------------------+| | ||:diagtext:`variables, functions, methods, types, enumerations, enumerators, labels, and non-static data members`|| | |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`classes and enumerations` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`named declarations` || -| |+----------------------------------------------------------------------------------------------------------------+| +------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------+ ++----------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`attribute only applies to` |nbsp| :placeholder:`B`| ++----------------------------------------------------------------------------------------------------------------+ + +--------------------------------------------------------------------------------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`attribute` |nbsp| :placeholder:`A` |nbsp| :diagtext:`ignored, because it cannot be applied to omitted return type`| +--------------------------------------------------------------------------------------------------------------------------------------------------------+ @@ -6333,6 +6302,17 @@ This diagnostic is enabled by default. +----------------------------------------------------------------------------------------------------------+ +-Wmicrosoft-inaccessible-base +----------------------------- +This diagnostic is enabled by default. + +**Diagnostic text:** + ++-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`accessing inaccessible direct base` |nbsp| :placeholder:`A` |nbsp| :diagtext:`of` |nbsp| :placeholder:`B` |nbsp| :diagtext:`is a Microsoft extension`| ++-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + + -Wmicrosoft-include ------------------- This diagnostic is enabled by default. @@ -8075,7 +8055,7 @@ This diagnostic is enabled by default. -Wpedantic ---------- -Also controls `-Wc++11-extra-semi`_, `-Wc++11-long-long`_, `-Wc++14-binary-literal`_, `-Wc11-extensions`_, `-Wcomplex-component-init`_, `-Wdeclaration-after-statement`_, `-Wdollar-in-identifier-extension`_, `-Wembedded-directive`_, `-Wempty-translation-unit`_, `-Wextended-offsetof`_, `-Wflexible-array-extensions`_, `-Wformat-pedantic`_, `-Wfour-char-constants`_, `-Wgnu-anonymous-struct`_, `-Wgnu-auto-type`_, `-Wgnu-binary-literal`_, `-Wgnu-case-range`_, `-Wgnu-complex-integer`_, `-Wgnu-compound-literal-initializer`_, `-Wgnu-conditional-omitted-operand`_, `-Wgnu-empty-initializer`_, `-Wgnu-empty-struct`_, `-Wgnu-flexible-array-initializer`_, `-Wgnu-flexible-array-union-member`_, `-Wgnu-folding-constant`_, `-Wgnu-imaginary-constant`_, `-Wgnu-include-next`_, `-Wgnu-label-as-value`_, `-Wgnu-redeclared-enum`_, `-Wgnu-statement-expression`_, `-Wgnu-union-cast`_, `-Wgnu-zero-line-directive`_, `-Wgnu-zero-variadic-macro-arguments`_, `-Wimport-preprocessor-directive-pedantic`_, `-Wkeyword-macro`_, `-Wlanguage-extension-token`_, `-Wlong-long`_, `-Wmicrosoft-charize`_, `-Wmicrosoft-comment-paste`_, `-Wmicrosoft-cpp-macro`_, `-Wmicrosoft-end-of-file`_, `-Wmicrosoft-enum-value`_, `-Wmicrosoft-fixed-enum`_, `-Wmicrosoft-flexible-array`_, `-Wmicrosoft-redeclare-static`_, `-Wnested-anon-types`_, `-Wnullability-extension`_, `-Woverlength-strings`_, `-Wretained-language-linkage`_, `-Wundefined-internal-type`_, `-Wvla-extension`_, `-Wzero-length-array`_. +Also controls `-Wc++11-extra-semi`_, `-Wc++11-long-long`_, `-Wc++14-binary-literal`_, `-Wc11-extensions`_, `-Wcomplex-component-init`_, `-Wdeclaration-after-statement`_, `-Wdollar-in-identifier-extension`_, `-Wembedded-directive`_, `-Wempty-translation-unit`_, `-Wflexible-array-extensions`_, `-Wformat-pedantic`_, `-Wfour-char-constants`_, `-Wgnu-anonymous-struct`_, `-Wgnu-auto-type`_, `-Wgnu-binary-literal`_, `-Wgnu-case-range`_, `-Wgnu-complex-integer`_, `-Wgnu-compound-literal-initializer`_, `-Wgnu-conditional-omitted-operand`_, `-Wgnu-empty-initializer`_, `-Wgnu-empty-struct`_, `-Wgnu-flexible-array-initializer`_, `-Wgnu-flexible-array-union-member`_, `-Wgnu-folding-constant`_, `-Wgnu-imaginary-constant`_, `-Wgnu-include-next`_, `-Wgnu-label-as-value`_, `-Wgnu-redeclared-enum`_, `-Wgnu-statement-expression`_, `-Wgnu-union-cast`_, `-Wgnu-zero-line-directive`_, `-Wgnu-zero-variadic-macro-arguments`_, `-Wimport-preprocessor-directive-pedantic`_, `-Wkeyword-macro`_, `-Wlanguage-extension-token`_, `-Wlong-long`_, `-Wmicrosoft-charize`_, `-Wmicrosoft-comment-paste`_, `-Wmicrosoft-cpp-macro`_, `-Wmicrosoft-end-of-file`_, `-Wmicrosoft-enum-value`_, `-Wmicrosoft-fixed-enum`_, `-Wmicrosoft-flexible-array`_, `-Wmicrosoft-redeclare-static`_, `-Wnested-anon-types`_, `-Wnullability-extension`_, `-Woverlength-strings`_, `-Wretained-language-linkage`_, `-Wundefined-internal-type`_, `-Wvla-extension`_, `-Wzero-length-array`_. **Diagnostic text:** @@ -8137,6 +8117,10 @@ Also controls `-Wc++11-extra-semi`_, `-Wc++11-long-long`_, `-Wc++14-binary-liter | |+---------------------------------------+| | +--------------------------------------------------------------------+-----------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ ++--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`ISO C++ standards before C++17 do not allow new expression for type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to use list-initialization`| ++--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + +--------------------------------------------------------------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`parameter` |nbsp| :placeholder:`A` |nbsp| :diagtext:`was not declared, defaulting to type 'int'`| +--------------------------------------------------------------------------------------------------------------------------------------+ @@ -8722,14 +8706,22 @@ This diagnostic is enabled by default. **Diagnostic text:** -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`top-level module '`:placeholder:`A`:diagtext:`' in private module map, expected a submodule of '`:placeholder:`B`:diagtext:`'`| -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+ ++----------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`expected canonical name for private module '`:placeholder:`A`:diagtext:`'`| ++----------------------------------------------------------------------------------------------------------------+ + ++----------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`private submodule '`:placeholder:`A`:diagtext:`' in private module map, expected top-level module`| ++----------------------------------------------------------------------------------------------------------------------------------------+ +----------------------------------------------------------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`module '`:placeholder:`A`:diagtext:`' already re-exported as '`:placeholder:`B`:diagtext:`'`| +----------------------------------------------------------------------------------------------------------------------------------+ ++---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`no submodule named` |nbsp| :placeholder:`A` |nbsp| :diagtext:`in module '`:placeholder:`B`:diagtext:`'; using top level '`:placeholder:`C`:diagtext:`'`| ++---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + -Wprofile-instr-missing ----------------------- @@ -10013,17 +10005,26 @@ Also controls `-Wtautological-constant-compare`_, `-Wtautological-overlap-compar ------------------------------- This diagnostic is enabled by default. -Also controls `-Wtautological-constant-out-of-range-compare`_, `-Wtautological-unsigned-enum-zero-compare`_, `-Wtautological-unsigned-zero-compare`_. +Also controls `-Wtautological-constant-out-of-range-compare`_. **Diagnostic text:** -+---------------------------------------------------------+------------------+--------------------------------+------------------+-------------------------------------+-------------------+ -|:warning:`warning:` |nbsp| :diagtext:`comparison` |nbsp| |+----------------+| |nbsp| :placeholder:`C` |nbsp| |+----------------+| |nbsp| :diagtext:`is always` |nbsp| |+-----------------+| -| ||:placeholder:`D`|| ||:placeholder:`B`|| ||:diagtext:`false`|| -| |+----------------+| |+----------------+| |+-----------------+| -| ||:placeholder:`B`|| ||:placeholder:`D`|| ||:diagtext:`true` || -| |+----------------+| |+----------------+| |+-----------------+| -+---------------------------------------------------------+------------------+--------------------------------+------------------+-------------------------------------+-------------------+ ++----------------------------------------------------------------------+------------------------------------------------+--------------------------------+----------------------------------------------------------+-----------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`result of comparison of` |nbsp| |+----------------------------------------------+| |nbsp| :diagtext:`with` |nbsp| |+--------------------------------------------------------+| |nbsp| :diagtext:`is always` |nbsp| :placeholder:`E`| +| ||+--------------------------------------------+|| ||+------------------------------------------------------+|| | +| |||:diagtext:`constant` |nbsp| :placeholder:`A`||| |||:diagtext:`expression of type` |nbsp| :placeholder:`C`||| | +| ||+--------------------------------------------+|| ||+------------------------------------------------------+|| | +| |+----------------------------------------------+| |+--------------------------------------------------------+| | +| ||:diagtext:`true` || ||:diagtext:`boolean expression` || | +| |+----------------------------------------------+| |+--------------------------------------------------------+| | +| ||:diagtext:`false` || | | | +| |+----------------------------------------------+| | | | ++----------------------------------------------------------------------+------------------------------------------------+--------------------------------+----------------------------------------------------------+-----------------------------------------------------+ + + +-Wtautological-constant-in-range-compare +---------------------------------------- +Controls `-Wtautological-type-limit-compare`_, `-Wtautological-unsigned-enum-zero-compare`_, `-Wtautological-unsigned-zero-compare`_. -Wtautological-constant-out-of-range-compare @@ -10032,17 +10033,17 @@ This diagnostic is enabled by default. **Diagnostic text:** -+------------------------------------------------------------+------------------------------------------------+--------------------------------+----------------------------------------------------------+-------------------------------------+-------------------+ -|:warning:`warning:` |nbsp| :diagtext:`comparison of` |nbsp| |+----------------------------------------------+| |nbsp| :diagtext:`with` |nbsp| |+--------------------------------------------------------+| |nbsp| :diagtext:`is always` |nbsp| |+-----------------+| -| ||+--------------------------------------------+|| ||+------------------------------------------------------+|| ||:diagtext:`false`|| -| |||:diagtext:`constant` |nbsp| :placeholder:`A`||| |||:diagtext:`expression of type` |nbsp| :placeholder:`C`||| |+-----------------+| -| ||+--------------------------------------------+|| ||+------------------------------------------------------+|| ||:diagtext:`true` || -| |+----------------------------------------------+| |+--------------------------------------------------------+| |+-----------------+| -| ||:diagtext:`true` || ||:diagtext:`boolean expression` || | | -| |+----------------------------------------------+| |+--------------------------------------------------------+| | | -| ||:diagtext:`false` || | | | | -| |+----------------------------------------------+| | | | | -+------------------------------------------------------------+------------------------------------------------+--------------------------------+----------------------------------------------------------+-------------------------------------+-------------------+ ++----------------------------------------------------------------------+------------------------------------------------+--------------------------------+----------------------------------------------------------+-----------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`result of comparison of` |nbsp| |+----------------------------------------------+| |nbsp| :diagtext:`with` |nbsp| |+--------------------------------------------------------+| |nbsp| :diagtext:`is always` |nbsp| :placeholder:`E`| +| ||+--------------------------------------------+|| ||+------------------------------------------------------+|| | +| |||:diagtext:`constant` |nbsp| :placeholder:`A`||| |||:diagtext:`expression of type` |nbsp| :placeholder:`C`||| | +| ||+--------------------------------------------+|| ||+------------------------------------------------------+|| | +| |+----------------------------------------------+| |+--------------------------------------------------------+| | +| ||:diagtext:`true` || ||:diagtext:`boolean expression` || | +| |+----------------------------------------------+| |+--------------------------------------------------------+| | +| ||:diagtext:`false` || | | | +| |+----------------------------------------------+| | | | ++----------------------------------------------------------------------+------------------------------------------------+--------------------------------+----------------------------------------------------------+-----------------------------------------------------+ -Wtautological-overlap-compare @@ -10083,6 +10084,19 @@ This diagnostic is enabled by default. +------------------------------------------------------------+------------------------+----------------------------------------------------------+-------------------------+-----------------------------------------------------+-------------------+ +-Wtautological-type-limit-compare +--------------------------------- +**Diagnostic text:** + ++-------------------------------------------------------------------+------------------+--------------------------------+------------------+-----------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`result of comparison` |nbsp| |+----------------+| |nbsp| :placeholder:`C` |nbsp| |+----------------+| |nbsp| :diagtext:`is always` |nbsp| :placeholder:`E`| +| ||:placeholder:`D`|| ||:placeholder:`B`|| | +| |+----------------+| |+----------------+| | +| ||:placeholder:`B`|| ||:placeholder:`D`|| | +| |+----------------+| |+----------------+| | ++-------------------------------------------------------------------+------------------+--------------------------------+------------------+-----------------------------------------------------+ + + -Wtautological-undefined-compare -------------------------------- This diagnostic is enabled by default. @@ -10108,32 +10122,28 @@ This diagnostic is enabled by default. -Wtautological-unsigned-enum-zero-compare ----------------------------------------- -This diagnostic is enabled by default. - **Diagnostic text:** -+------------------------------------------------------------+--------------------------------------+--------------------------------+--------------------------------------+-------------------------------------+-------------------+ -|:warning:`warning:` |nbsp| :diagtext:`comparison of` |nbsp| |+------------------------------------+| |nbsp| :placeholder:`C` |nbsp| |+------------------------------------+| |nbsp| :diagtext:`is always` |nbsp| |+-----------------+| -| ||:placeholder:`D` || ||:diagtext:`unsigned enum expression`|| ||:diagtext:`false`|| -| |+------------------------------------+| |+------------------------------------+| |+-----------------+| -| ||:diagtext:`unsigned enum expression`|| ||:placeholder:`D` || ||:diagtext:`true` || -| |+------------------------------------+| |+------------------------------------+| |+-----------------+| -+------------------------------------------------------------+--------------------------------------+--------------------------------+--------------------------------------+-------------------------------------+-------------------+ ++----------------------------------------------------------------------+--------------------------------------+--------------------------------+--------------------------------------+-----------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`result of comparison of` |nbsp| |+------------------------------------+| |nbsp| :placeholder:`C` |nbsp| |+------------------------------------+| |nbsp| :diagtext:`is always` |nbsp| :placeholder:`E`| +| ||:placeholder:`D` || ||:diagtext:`unsigned enum expression`|| | +| |+------------------------------------+| |+------------------------------------+| | +| ||:diagtext:`unsigned enum expression`|| ||:placeholder:`D` || | +| |+------------------------------------+| |+------------------------------------+| | ++----------------------------------------------------------------------+--------------------------------------+--------------------------------+--------------------------------------+-----------------------------------------------------+ -Wtautological-unsigned-zero-compare ------------------------------------ -This diagnostic is enabled by default. - **Diagnostic text:** -+------------------------------------------------------------+---------------------------------+--------------------------------+---------------------------------+-------------------------------------+-------------------+ -|:warning:`warning:` |nbsp| :diagtext:`comparison of` |nbsp| |+-------------------------------+| |nbsp| :placeholder:`C` |nbsp| |+-------------------------------+| |nbsp| :diagtext:`is always` |nbsp| |+-----------------+| -| ||:placeholder:`D` || ||:diagtext:`unsigned expression`|| ||:diagtext:`false`|| -| |+-------------------------------+| |+-------------------------------+| |+-----------------+| -| ||:diagtext:`unsigned expression`|| ||:placeholder:`D` || ||:diagtext:`true` || -| |+-------------------------------+| |+-------------------------------+| |+-----------------+| -+------------------------------------------------------------+---------------------------------+--------------------------------+---------------------------------+-------------------------------------+-------------------+ ++----------------------------------------------------------------------+---------------------------------+--------------------------------+---------------------------------+-----------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`result of comparison of` |nbsp| |+-------------------------------+| |nbsp| :placeholder:`C` |nbsp| |+-------------------------------+| |nbsp| :diagtext:`is always` |nbsp| :placeholder:`E`| +| ||:placeholder:`D` || ||:diagtext:`unsigned expression`|| | +| |+-------------------------------+| |+-------------------------------+| | +| ||:diagtext:`unsigned expression`|| ||:placeholder:`D` || | +| |+-------------------------------+| |+-------------------------------+| | ++----------------------------------------------------------------------+---------------------------------+--------------------------------+---------------------------------+-----------------------------------------------------+ -Wtentative-definition-incomplete-type @@ -10652,6 +10662,17 @@ This diagnostic is enabled by default. +---------------------------------------------------------------------------------------------+ +-Wunicode-homoglyph +------------------- +This diagnostic is enabled by default. + +**Diagnostic text:** + ++-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`treating Unicode character as identifier character rather than as '`:placeholder:`B`:diagtext:`' symbol`| ++-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + + -Wunicode-whitespace -------------------- This diagnostic is enabled by default. @@ -11134,19 +11155,17 @@ This diagnostic is enabled by default. **Diagnostic text:** -+---------------------------+-----------------------------------------+--------------------------------------------+ -|:warning:`warning:` |nbsp| |+---------------------------------------+| |nbsp| :diagtext:`comparison result unused`| -| ||+----------------+--------------------+|| | -| |||+--------------+|:diagtext:`equality`||| | -| |||| || ||| | -| |||+--------------+| ||| | -| ||||:diagtext:`in`|| ||| | -| |||+--------------+| ||| | -| ||+----------------+--------------------+|| | -| |+---------------------------------------+| | -| ||:diagtext:`relational` || | -| |+---------------------------------------+| | -+---------------------------+-----------------------------------------+--------------------------------------------+ ++---------------------------+------------------------+--------------------------------------------+ +|:warning:`warning:` |nbsp| |+----------------------+| |nbsp| :diagtext:`comparison result unused`| +| ||:diagtext:`equality` || | +| |+----------------------+| | +| ||:diagtext:`inequality`|| | +| |+----------------------+| | +| ||:diagtext:`relational`|| | +| |+----------------------+| | +| ||:diagtext:`three-way` || | +| |+----------------------+| | ++---------------------------+------------------------+--------------------------------------------+ -Wunused-const-variable diff --git a/docs/ReleaseNotes.rst b/docs/ReleaseNotes.rst index c5e037d0cd9d..efbf27a8872a 100644 --- a/docs/ReleaseNotes.rst +++ b/docs/ReleaseNotes.rst @@ -1,6 +1,6 @@ -======================================= -Clang 6.0.0 (In-Progress) Release Notes -======================================= +========================= +Clang 6.0.0 Release Notes +========================= .. contents:: :local: @@ -8,12 +8,6 @@ Clang 6.0.0 (In-Progress) Release Notes Written by the `LLVM Team `_ -.. warning:: - - These are in-progress notes for the upcoming Clang 6 release. - Release notes for previous releases can be found on - `the Download Page `_. - Introduction ============ @@ -30,11 +24,6 @@ For more information about Clang or LLVM, including information about the latest release, please see the `Clang Web Site `_ or the `LLVM Web Site `_. -Note that if you are reading this file from a Subversion checkout or the -main Clang web page, this document applies to the *next* release, not -the current one. To see the release notes for a specific release, please -see the `releases page `_. - What's New in Clang 6.0.0? ========================== @@ -43,13 +32,28 @@ here. Generic improvements to Clang as a whole or to its underlying infrastructure are described first, followed by language-specific sections with improvements to Clang's support for those languages. -Major New Features ------------------- +Non-comprehensive list of changes in this release +------------------------------------------------- + +- Bitrig OS was merged back into OpenBSD, so Bitrig support has been + removed from Clang/LLVM. + +- The default value of ``_MSC_VER`` was raised from 1800 to 1911, making it + compatible with the Visual Studio 2015 and 2017 C++ standard library headers. + Users should generally expect this to be regularly raised to match the most + recently released version of the Visual C++ compiler. + +- clang now defaults to ``.init_array`` if no gcc installation can be found. + If a gcc installation is found, it still prefers ``.ctors`` if the found + gcc is older than 4.7.0. + +- The new builtin preprocessor macros ``__is_target_arch``, + ``__is_target_vendor``, ``__is_target_os``, and ``__is_target_environment`` + can be used to to examine the individual components of the target triple. -- ... Improvements to Clang's diagnostics -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +----------------------------------- - ``-Wpragma-pack`` is a new warning that warns in the following cases: @@ -72,7 +76,7 @@ Improvements to Clang's diagnostics selector which could make the message send to ``id`` ambiguous. - ``-Wtautological-compare`` now warns when comparing an unsigned integer and 0 - regardless of whether the constant is signed or unsigned." + regardless of whether the constant is signed or unsigned. - ``-Wtautological-compare`` now warns about comparing a signed integer and 0 when the signed integer is coerced to an unsigned type for the comparison. @@ -95,55 +99,44 @@ Improvements to Clang's diagnostics - ``-Wzero-as-null-pointer-constant`` was adjusted not to warn on null pointer constants that originate from system macros, except ``NULL`` macro. -Non-comprehensive list of changes in this release -------------------------------------------------- - -- Bitrig OS was merged back into OpenBSD, so Bitrig support has been - removed from Clang/LLVM. - -- The default value of _MSC_VER was raised from 1800 to 1911, making it - compatible with the Visual Studio 2015 and 2017 C++ standard library headers. - Users should generally expect this to be regularly raised to match the most - recently released version of the Visual C++ compiler. +- ``-Wdelete-non-virtual-dtor`` can now fire in system headers, so that + ``std::unique_ptr<>`` deleting through a non-virtual dtor is now diagnosed. -- clang now defaults to ``.init_array`` if no gcc installation can be found. - If a gcc installation is found, it still prefers ``.ctors`` if the found - gcc is older than 4.7.0. +- ``-Wunreachable-code`` can now reason about ``__try``, ``__except`` and + ``__leave``. -- The new builtin preprocessor macros ``__is_target_arch``, - ``__is_target_vendor``, ``__is_target_os``, and ``__is_target_environment`` - can be used to to examine the individual components of the target triple. New Compiler Flags ------------------ -- --autocomplete was implemented to obtain a list of flags and its arguments. This is used for shell autocompletion. +- Clang now supports configuration files. These are collections of driver + options, which can be applied by specifying the configuration file, either + using command line option ``--config foo.cfg`` or encoding it into executable + name ``foo-clang``. Clang behaves as if the options from this file were inserted + before the options specified in command line. This feature is primary intended + to facilitate cross compilation. Details can be found in + `Clang Compiler User's Manual `_. - The ``-fdouble-square-bracket-attributes`` and corresponding ``-fno-double-square-bracket-attributes`` flags were added to enable or - disable [[]] attributes in any language mode. Currently, only a limited + disable ``[[]]`` attributes in any language mode. Currently, only a limited number of attributes are supported outside of C++ mode. See the Clang - attribute documentation for more information about which attributes are - supported for each syntax. - + `attribute documentation `_ for more information + about which attributes are supported for each syntax. + - Added the ``-std=c17``, ``-std=gnu17``, and ``-std=iso9899:2017`` language mode flags for compatibility with GCC. This enables support for the next version of the C standard, expected to be published by ISO in 2018. The only difference between the ``-std=c17`` and ``-std=c11`` language modes is the value of the ``__STDC_VERSION__`` macro, as C17 is a bug fix release. -Deprecated Compiler Flags -------------------------- - -The following options are deprecated and ignored. They will be removed in -future versions of Clang. +- Added the ``-fexperimental-isel`` and ``-fno-experimental-isel`` flags to + enable/disable the new GlobalISel instruction selection framework. This + feature is enabled by default for AArch64 at the ``-O0`` optimization level. + Support for other targets or optimization levels is currently incomplete. -- ... - -New Pragmas in Clang ------------------------ - -Clang now supports the ... +- New ``-nostdlib++`` flag to disable linking the C++ standard library. Similar + to using ``clang`` instead of ``clang++`` but doesn't disable ``-lm``. Attribute Changes in Clang @@ -154,25 +147,15 @@ Attribute Changes in Clang in the ``clang`` vendor namespace (``[[clang::name]]``). Attributes whose syntax is specified by some other standard (such as CUDA and OpenCL attributes) continue to follow their respective specification. - + - Added the ``__has_c_attribute()`` builtin preprocessor macro which allows users to dynamically detect whether a double square-bracket attribute is supported in C mode. This attribute syntax can be enabled with the ``-fdouble-square-bracket-attributes`` flag. - -- The presence of __attribute__((availability(...))) on a declaration no longer - implies default visibility for that declaration on macOS. -- Clang now supports configuration files. These are collections of driver - options, which can be applied by specifying the configuration file, either - using command line option `--config foo.cfg` or encoding it into executable - name `foo-clang`. Clang behaves as if the options from this file were inserted - before the options specified in command line. This feature is primary intended - to facilitate cross compilation. Details can be found in - `Clang Compiler User's Manual - `. +- The presence of ``__attribute__((availability(...)))`` on a declaration no + longer implies default visibility for that declaration on macOS. -- ... Windows Support --------------- @@ -180,17 +163,8 @@ Windows Support - Clang now has initial, preliminary support for targeting Windows on ARM64. -C Language Changes in Clang ---------------------------- - -- ... - -... - -C11 Feature Support -^^^^^^^^^^^^^^^^^^^ +- clang-cl now exposes the ``--version`` flag. -... C++ Language Changes in Clang ----------------------------- @@ -200,20 +174,38 @@ C++ Language Changes in Clang conforming GNU extensions. Projects incompatible with C++14 can add ``-std=gnu++98`` to their build settings to restore the previous behaviour. -C++1z Feature Support -^^^^^^^^^^^^^^^^^^^^^ +- Added support for some features from the C++ standard after C++17 + (provisionally known as C++2a but expected to be C++20). This support can be + enabled with the ``-std=c++2a`` flag. This enables: + + - Support for ``__VA_OPT__``, to allow variadic macros to easily provide + different expansions when they are invoked without variadic arguments. + + - Recognition of the ``<=>`` token (the C++2a three-way comparison operator). + + - Support for default member initializers for bit-fields. + + - Lambda capture of ``*this``. -... + - Pointer-to-member calls using ``const &``-qualified pointers on temporary objects. -Objective-C Language Changes in Clang -------------------------------------- + All of these features other than ``__VA_OPT__`` and ``<=>`` are made + available with a warning in earlier C++ language modes. -... +- A warning has been added for a ``<=`` token followed immediately by a ``>`` + character. Code containing such constructs will change meaning in C++2a due + to the addition of the ``<=>`` operator. + +- Clang implements the "destroying operator delete" feature described in C++ + committee paper `P0722R1 + `, + which is targeting inclusion in C++2a but has not yet been voted into the C++ + working draft. Support for this feature is enabled by the presence of the + standard library type ``std::destroying_delete_t``. OpenCL C Language Changes in Clang ---------------------------------- - - Added subgroup builtins to enqueue kernel support. - Added CL2.0 atomics as Clang builtins that now accept @@ -253,77 +245,72 @@ OpenCL C Language Changes in Clang - Miscellaneous improvements in vector diagnostics. - Added half float load and store builtins without enabling half as a legal type - (``__builtin_store_half for double``, ``__builtin_store_halff`` for double, - ``__builtin_load_half for double``, ``__builtin_load_halff`` for float). + (``__builtin_store_half`` for double, ``__builtin_store_halff`` for float, + ``__builtin_load_half`` for double, ``__builtin_load_halff`` for float). OpenMP Support in Clang ---------------------------------- -- Added options `-f[no]-openmp-simd` that support code emission only for OpenMP - SIMD-based directives, like `#pragma omp simd`, `#pragma omp parallel for simd` - etc. The code is emitted only for simd-based part of the combined directives +- Added options ``-f[no]-openmp-simd`` that support code emission only for OpenMP + SIMD-based directives, like ``#pragma omp simd``, ``#pragma omp parallel for simd`` + etc. The code is emitted only for SIMD-based part of the combined directives and clauses. - Added support for almost all target-based directives except for - `#pragma omp target teams distribute parallel for [simd]`. Although, please - note that `depend` clauses on target-based directives are not supported yet. + ``#pragma omp target teams distribute parallel for [simd]``. Although, please + note that ``depend`` clauses on target-based directives are not supported yet. Clang supports offloading to X86_64, AArch64 and PPC64[LE] devices. -- Added support for `reduction`-based clauses on `task`-based directives from +- Added support for ``reduction``-based clauses on ``task``-based directives from upcoming OpenMP 5.0. -- The LLVM OpenMP runtime `libomp` now supports the OpenMP Tools Interface (OMPT) +- The LLVM OpenMP runtime ``libomp`` now supports the OpenMP Tools Interface (OMPT) on x86, x86_64, AArch64, and PPC64 on Linux, Windows, and macOS. If you observe a measurable performance impact on one of your applications without a tool - attached, please rebuild the runtime library with `-DLIBOMP_OMPT_SUPPORT=OFF` and + attached, please rebuild the runtime library with ``-DLIBOMP_OMPT_SUPPORT=OFF`` and file a bug at `LLVM's Bugzilla `_ or send a message to the `OpenMP development list `_. -Internal API Changes --------------------- - -These are major API changes that have happened since the 4.0.0 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. - -- ... AST Matchers ------------ -The hasDeclaration matcher now works the same for Type and QualType and only +The ``hasDeclaration`` matcher now works the same for ``Type`` and ``QualType`` and only ever looks through one level of sugaring in a limited number of cases. There are two main patterns affected by this: -- qualType(hasDeclaration(recordDecl(...))): previously, we would look through - sugar like TypedefType to get at the underlying recordDecl; now, we need +- ``qualType(hasDeclaration(recordDecl(...)))``: previously, we would look through + sugar like ``TypedefType`` to get at the underlying ``recordDecl``; now, we need to explicitly remove the sugaring: - qualType(hasUnqualifiedDesugaredType(hasDeclaration(recordDecl(...)))) + ``qualType(hasUnqualifiedDesugaredType(hasDeclaration(recordDecl(...))))`` -- hasType(recordDecl(...)): hasType internally uses hasDeclaration; previously, - this matcher used to match for example TypedefTypes of the RecordType, but +- ``hasType(recordDecl(...))``: ``hasType`` internally uses ``hasDeclaration``; previously, + this matcher used to match for example ``TypedefTypes`` of the ``RecordType``, but after the change they don't; to fix, use: -:: - hasType(hasUnqualifiedDesugaredType( - recordType(hasDeclaration(recordDecl(...))))) + .. code-block:: c + + hasType(hasUnqualifiedDesugaredType( + recordType(hasDeclaration(recordDecl(...))))) -- templateSpecializationType(hasDeclaration(classTemplateDecl(...))): - previously, we would directly match the underlying ClassTemplateDecl; - now, we can explicitly match the ClassTemplateSpecializationDecl, but that - requires to explicitly get the ClassTemplateDecl: +- ``templateSpecializationType(hasDeclaration(classTemplateDecl(...)))``: + previously, we would directly match the underlying ``ClassTemplateDecl``; + now, we can explicitly match the ``ClassTemplateSpecializationDecl``, but that + requires to explicitly get the ``ClassTemplateDecl``: + + .. code-block:: c + + templateSpecializationType(hasDeclaration( + classTemplateSpecializationDecl( + hasSpecializedTemplate(classTemplateDecl(...))))) -:: - templateSpecializationType(hasDeclaration( - classTemplateSpecializationDecl( - hasSpecializedTemplate(classTemplateDecl(...))))) clang-format ------------ -* Option *IndentPPDirectives* added to indent preprocessor directives on +* Option ``IndentPPDirectives`` added to indent preprocessor directives on conditionals. +----------------------+----------------------+ @@ -338,10 +325,10 @@ clang-format | #endif | #endif | +----------------------+----------------------+ -* Option -verbose added to the command line. +* Option ``-verbose`` added to the command line. Shows the list of processed files. -* Option *IncludeBlocks* added to merge and regroup multiple ``#include`` blocks during sorting. +* Option ``IncludeBlocks`` added to merge and regroup multiple ``#include`` blocks during sorting. +-------------------------+-------------------------+-------------------------+ | Before (Preserve) | Merge | Regroup | @@ -354,19 +341,13 @@ clang-format | #include | | #include | +-------------------------+-------------------------+-------------------------+ -libclang --------- - -... - Static Analyzer --------------- -- Static Analyzer can now properly detect and diagnose unary pre-/post- +- The Static Analyzer can now properly detect and diagnose unary pre-/post- increment/decrement on an uninitialized value. -... Undefined Behavior Sanitizer (UBSan) ------------------------------------ @@ -376,25 +357,6 @@ Undefined Behavior Sanitizer (UBSan) issue logging and deduplication, and does not support ``-fsanitize=vptr`` checking. -Core Analysis Improvements -========================== - -- ... - -New Issues Found -================ - -- ... - -Python Binding Changes ----------------------- - -The following methods have been added: - -- ... - -Significant Known Problems -========================== Additional Information ====================== diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h index f93c9f0b9aaa..15de482a8619 100644 --- a/include/clang/AST/DeclBase.h +++ b/include/clang/AST/DeclBase.h @@ -836,6 +836,10 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) Decl { void setLexicalDeclContext(DeclContext *DC); + /// Determine whether this declaration is a templated entity (whether it is + // within the scope of a template parameter). + bool isTemplated() const; + /// isDefinedOutsideFunctionOrMethod - This predicate returns true if this /// scoped decl is defined outside the current function or method. This is /// roughly global variables and functions, but also handles enums (which diff --git a/include/clang/Basic/AttrDocs.td b/include/clang/Basic/AttrDocs.td index ecff329c4ccb..dc355832b875 100644 --- a/include/clang/Basic/AttrDocs.td +++ b/include/clang/Basic/AttrDocs.td @@ -353,7 +353,7 @@ available in C. int isdigit(int c); int isdigit(int c) __attribute__((enable_if(c <= -1 || c > 255, "chosen when 'c' is out of range"))) __attribute__((unavailable("'c' must have the value of an unsigned char or EOF"))); - + void foo(char c) { isdigit(c); isdigit(10); @@ -406,7 +406,7 @@ overload out of a number of viable overloads using enable_if. void f() __attribute__((enable_if(true, ""))); // #1 void f() __attribute__((enable_if(true, ""))) __attribute__((enable_if(true, ""))); // #2 - + void g(int i, int j) __attribute__((enable_if(i, ""))); // #1 void g(int i, int j) __attribute__((enable_if(j, ""))) __attribute__((enable_if(true))); // #2 @@ -918,11 +918,11 @@ default name. can only be placed before an @protocol or @interface declaration: .. code-block:: objc - + __attribute__((objc_runtime_name("MyLocalName"))) @interface Message @end - + }]; } @@ -1228,7 +1228,7 @@ potentially-evaluated discarded-value expression that is not explicitly cast to .. code-block: c++ struct [[nodiscard]] error_info { /*...*/ }; error_info enable_missile_safety_mode(); - + void launch_missiles(); void test_missiles() { enable_missile_safety_mode(); // diagnoses @@ -2641,23 +2641,23 @@ used to process multiple arguments from a single invocation from a SIMD loop concurrently. The syntax of the `declare simd` construct is as follows: - .. code-block:: c + .. code-block:: none - #pragma omp declare simd [clause[[,] clause] ...] new-line - [#pragma omp declare simd [clause[[,] clause] ...] new-line] - [...] - function definition or declaration + #pragma omp declare simd [clause[[,] clause] ...] new-line + [#pragma omp declare simd [clause[[,] clause] ...] new-line] + [...] + function definition or declaration where clause is one of the following: - .. code-block:: c + .. code-block:: none - simdlen(length) - linear(argument-list[:constant-linear-step]) - aligned(argument-list[:alignment]) - uniform(argument-list) - inbranch - notinbranch + simdlen(length) + linear(argument-list[:constant-linear-step]) + aligned(argument-list[:alignment]) + uniform(argument-list) + inbranch + notinbranch }]; } @@ -2673,9 +2673,9 @@ The syntax of the declare target directive is as follows: .. code-block:: c - #pragma omp declare target new-line - declarations-definition-seq - #pragma omp end declare target new-line + #pragma omp declare target new-line + declarations-definition-seq + #pragma omp end declare target new-line }]; } diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td index df296238493d..e0e84066337a 100644 --- a/include/clang/Driver/Options.td +++ b/include/clang/Driver/Options.td @@ -2583,6 +2583,10 @@ def mshstk : Flag<["-"], "mshstk">, Group; def mno_shstk : Flag<["-"], "mno-shstk">, Group; def mibt : Flag<["-"], "mibt">, Group; def mno_ibt : Flag<["-"], "mno-ibt">, Group; +def mretpoline : Flag<["-"], "mretpoline">, Group; +def mno_retpoline : Flag<["-"], "mno-retpoline">, Group; +def mretpoline_external_thunk : Flag<["-"], "mretpoline-external-thunk">, Group; +def mno_retpoline_external_thunk : Flag<["-"], "mno-retpoline-external-thunk">, Group; // These are legacy user-facing driver-level option spellings. They are always // aliases for options that are spelled using the more common Unix / GNU flag diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 3dc961d4f12b..c73ae9efe170 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -2145,7 +2145,7 @@ static bool unionHasUniqueObjectRepresentations(const ASTContext &Context, if (FieldSize != UnionSize) return false; } - return true; + return !RD->field_empty(); } static bool isStructEmpty(QualType Ty) { diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp index 2cdcdae9ab02..d427c79c44ab 100644 --- a/lib/AST/DeclBase.cpp +++ b/lib/AST/DeclBase.cpp @@ -236,10 +236,23 @@ TemplateDecl *Decl::getDescribedTemplate() const { return RD->getDescribedClassTemplate(); else if (auto *VD = dyn_cast(this)) return VD->getDescribedVarTemplate(); + else if (auto *AD = dyn_cast(this)) + return AD->getDescribedAliasTemplate(); return nullptr; } +bool Decl::isTemplated() const { + // A declaration is dependent if it is a template or a template pattern, or + // is within (lexcially for a friend, semantically otherwise) a dependent + // context. + // FIXME: Should local extern declarations be treated like friends? + if (auto *AsDC = dyn_cast(this)) + return AsDC->isDependentContext(); + auto *DC = getFriendObjectKind() ? getLexicalDeclContext() : getDeclContext(); + return DC->isDependentContext() || isTemplateDecl() || getDescribedTemplate(); +} + const DeclContext *Decl::getParentFunctionOrMethod() const { for (const DeclContext *DC = getDeclContext(); DC && !DC->isTranslationUnit() && !DC->isNamespace(); diff --git a/lib/AST/MicrosoftMangle.cpp b/lib/AST/MicrosoftMangle.cpp index 0c55c1a92287..b4e7a82eb000 100644 --- a/lib/AST/MicrosoftMangle.cpp +++ b/lib/AST/MicrosoftMangle.cpp @@ -950,11 +950,10 @@ void MicrosoftCXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND, } } +// ::= [] +// ::= [] void MicrosoftCXXNameMangler::mangleNestedName(const NamedDecl *ND) { - // ::= [] - // ::= [] const DeclContext *DC = getEffectiveDeclContext(ND); - while (!DC->isTranslationUnit()) { if (isa(ND) || isa(ND)) { unsigned Disc; @@ -2140,6 +2139,7 @@ void MicrosoftCXXNameMangler::mangleCallingConvention(CallingConv CC) { case CC_X86StdCall: Out << 'G'; break; case CC_X86FastCall: Out << 'I'; break; case CC_X86VectorCall: Out << 'Q'; break; + case CC_Swift: Out << 'S'; break; case CC_X86RegCall: Out << 'w'; break; } } diff --git a/lib/Basic/Targets/X86.cpp b/lib/Basic/Targets/X86.cpp index 0febb98d4684..cfa6c571d6ea 100644 --- a/lib/Basic/Targets/X86.cpp +++ b/lib/Basic/Targets/X86.cpp @@ -152,7 +152,8 @@ bool X86TargetInfo::initFeatureMap( setFeatureEnabledImpl(Features, "avx512bw", true); setFeatureEnabledImpl(Features, "avx512vl", true); setFeatureEnabledImpl(Features, "pku", true); - setFeatureEnabledImpl(Features, "clwb", true); + if (Kind != CK_Cannonlake) // CNL inherits all SKX features, except CLWB + setFeatureEnabledImpl(Features, "clwb", true); LLVM_FALLTHROUGH; case CK_SkylakeClient: setFeatureEnabledImpl(Features, "xsavec", true); @@ -763,6 +764,10 @@ bool X86TargetInfo::handleTargetFeatures(std::vector &Features, HasPREFETCHWT1 = true; } else if (Feature == "+clzero") { HasCLZERO = true; + } else if (Feature == "+retpoline") { + HasRetpoline = true; + } else if (Feature == "+retpoline-external-thunk") { + HasRetpolineExternalThunk = true; } X86SSEEnum Level = llvm::StringSwitch(Feature) @@ -1305,6 +1310,8 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const { .Case("prfchw", HasPRFCHW) .Case("rdrnd", HasRDRND) .Case("rdseed", HasRDSEED) + .Case("retpoline", HasRetpoline) + .Case("retpoline-external-thunk", HasRetpolineExternalThunk) .Case("rtm", HasRTM) .Case("sgx", HasSGX) .Case("sha", HasSHA) diff --git a/lib/Basic/Targets/X86.h b/lib/Basic/Targets/X86.h index cbd6a2d24fb5..590531c17854 100644 --- a/lib/Basic/Targets/X86.h +++ b/lib/Basic/Targets/X86.h @@ -96,6 +96,8 @@ class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo { bool HasCLWB = false; bool HasMOVBE = false; bool HasPREFETCHWT1 = false; + bool HasRetpoline = false; + bool HasRetpolineExternalThunk = false; /// \brief Enumeration of all of the X86 CPUs supported by Clang. /// diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index df33fc3e8200..2172486682cf 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -4000,18 +4000,13 @@ void CodeGenModule::EmitDeclContext(const DeclContext *DC) { /// EmitTopLevelDecl - Emit code for a single top level declaration. void CodeGenModule::EmitTopLevelDecl(Decl *D) { // Ignore dependent declarations. - if (D->getDeclContext() && D->getDeclContext()->isDependentContext()) + if (D->isTemplated()) return; switch (D->getKind()) { case Decl::CXXConversion: case Decl::CXXMethod: case Decl::Function: - // Skip function templates - if (cast(D)->getDescribedFunctionTemplate() || - cast(D)->isLateTemplateParsed()) - return; - EmitGlobal(cast(D)); // Always provide some coverage mapping // even for the functions that aren't emitted. @@ -4024,10 +4019,6 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) { case Decl::Var: case Decl::Decomposition: - // Skip variable templates - if (cast(D)->getDescribedVarTemplate()) - return; - LLVM_FALLTHROUGH; case Decl::VarTemplateSpecialization: EmitGlobal(cast(D)); if (auto *DD = dyn_cast(D)) @@ -4086,16 +4077,9 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) { DI->EmitUsingDirective(cast(*D)); return; case Decl::CXXConstructor: - // Skip function templates - if (cast(D)->getDescribedFunctionTemplate() || - cast(D)->isLateTemplateParsed()) - return; - getCXXABI().EmitCXXConstructors(cast(D)); break; case Decl::CXXDestructor: - if (cast(D)->isLateTemplateParsed()) - return; getCXXABI().EmitCXXDestructors(cast(D)); break; diff --git a/lib/CodeGen/ItaniumCXXABI.cpp b/lib/CodeGen/ItaniumCXXABI.cpp index c375b82ea936..a3c2766dbb49 100644 --- a/lib/CodeGen/ItaniumCXXABI.cpp +++ b/lib/CodeGen/ItaniumCXXABI.cpp @@ -2761,6 +2761,11 @@ static bool ShouldUseExternalRTTIDescriptor(CodeGenModule &CGM, // N.B. We must always emit the RTTI data ourselves if there exists a key // function. bool IsDLLImport = RD->hasAttr(); + + // Don't import the RTTI but emit it locally. + if (CGM.getTriple().isWindowsGNUEnvironment() && IsDLLImport) + return false; + if (CGM.getVTables().isVTableExternal(RD)) return IsDLLImport && !CGM.getTriple().isWindowsItaniumEnvironment() ? false diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp index 4b8006428f8f..abd633280b9d 100644 --- a/lib/CodeGen/TargetInfo.cpp +++ b/lib/CodeGen/TargetInfo.cpp @@ -3543,7 +3543,17 @@ ABIArgInfo X86_64ABIInfo::classifyRegCallStructType(QualType Ty, void X86_64ABIInfo::computeInfo(CGFunctionInfo &FI) const { - bool IsRegCall = FI.getCallingConvention() == llvm::CallingConv::X86_RegCall; + const unsigned CallingConv = FI.getCallingConvention(); + // It is possible to force Win64 calling convention on any x86_64 target by + // using __attribute__((ms_abi)). In such case to correctly emit Win64 + // compatible code delegate this call to WinX86_64ABIInfo::computeInfo. + if (CallingConv == llvm::CallingConv::Win64) { + WinX86_64ABIInfo Win64ABIInfo(CGT); + Win64ABIInfo.computeInfo(FI); + return; + } + + bool IsRegCall = CallingConv == llvm::CallingConv::X86_RegCall; // Keep track of the number of assigned registers. unsigned FreeIntRegs = IsRegCall ? 11 : 6; diff --git a/lib/Format/TokenAnnotator.cpp b/lib/Format/TokenAnnotator.cpp index 298c72b002f8..079b330f3a7d 100644 --- a/lib/Format/TokenAnnotator.cpp +++ b/lib/Format/TokenAnnotator.cpp @@ -1723,15 +1723,18 @@ void TokenAnnotator::setCommentLineLevels( } } - if (NextNonCommentLine && CommentLine) { - // If the comment is currently aligned with the line immediately following - // it, that's probably intentional and we should keep it. - bool AlignedWithNextLine = - NextNonCommentLine->First->NewlinesBefore <= 1 && - NextNonCommentLine->First->OriginalColumn == - (*I)->First->OriginalColumn; - if (AlignedWithNextLine) - (*I)->Level = NextNonCommentLine->Level; + // If the comment is currently aligned with the line immediately following + // it, that's probably intentional and we should keep it. + if (NextNonCommentLine && CommentLine && + NextNonCommentLine->First->NewlinesBefore <= 1 && + NextNonCommentLine->First->OriginalColumn == + (*I)->First->OriginalColumn) { + // Align comments for preprocessor lines with the # in column 0. + // Otherwise, align with the next line. + (*I)->Level = (NextNonCommentLine->Type == LT_PreprocessorDirective || + NextNonCommentLine->Type == LT_ImportStatement) + ? 0 + : NextNonCommentLine->Level; } else { NextNonCommentLine = (*I)->First->isNot(tok::r_brace) ? (*I) : nullptr; } diff --git a/lib/Format/UnwrappedLineParser.cpp b/lib/Format/UnwrappedLineParser.cpp index b8608dcac9c7..34d4ce28aad1 100644 --- a/lib/Format/UnwrappedLineParser.cpp +++ b/lib/Format/UnwrappedLineParser.cpp @@ -234,14 +234,17 @@ UnwrappedLineParser::UnwrappedLineParser(const FormatStyle &Style, CurrentLines(&Lines), Style(Style), Keywords(Keywords), CommentPragmasRegex(Style.CommentPragmas), Tokens(nullptr), Callback(Callback), AllTokens(Tokens), PPBranchLevel(-1), - IfNdefCondition(nullptr), FoundIncludeGuardStart(false), - IncludeGuardRejected(false), FirstStartColumn(FirstStartColumn) {} + IncludeGuard(Style.IndentPPDirectives == FormatStyle::PPDIS_None + ? IG_Rejected + : IG_Inited), + IncludeGuardToken(nullptr), FirstStartColumn(FirstStartColumn) {} void UnwrappedLineParser::reset() { PPBranchLevel = -1; - IfNdefCondition = nullptr; - FoundIncludeGuardStart = false; - IncludeGuardRejected = false; + IncludeGuard = Style.IndentPPDirectives == FormatStyle::PPDIS_None + ? IG_Rejected + : IG_Inited; + IncludeGuardToken = nullptr; Line.reset(new UnwrappedLine); CommentsBeforeNextToken.clear(); FormatTok = nullptr; @@ -264,6 +267,14 @@ void UnwrappedLineParser::parse() { readToken(); parseFile(); + + // If we found an include guard then all preprocessor directives (other than + // the guard) are over-indented by one. + if (IncludeGuard == IG_Found) + for (auto &Line : Lines) + if (Line.InPPDirective && Line.Level > 0) + --Line.Level; + // Create line with eof token. pushToken(FormatTok); addUnwrappedLine(); @@ -712,26 +723,27 @@ void UnwrappedLineParser::parsePPIf(bool IfDef) { // If there's a #ifndef on the first line, and the only lines before it are // comments, it could be an include guard. bool MaybeIncludeGuard = IfNDef; - if (!IncludeGuardRejected && !FoundIncludeGuardStart && MaybeIncludeGuard) { + if (IncludeGuard == IG_Inited && MaybeIncludeGuard) for (auto &Line : Lines) { if (!Line.Tokens.front().Tok->is(tok::comment)) { MaybeIncludeGuard = false; - IncludeGuardRejected = true; + IncludeGuard = IG_Rejected; break; } } - } --PPBranchLevel; parsePPUnknown(); ++PPBranchLevel; - if (!IncludeGuardRejected && !FoundIncludeGuardStart && MaybeIncludeGuard) - IfNdefCondition = IfCondition; + if (IncludeGuard == IG_Inited && MaybeIncludeGuard) { + IncludeGuard = IG_IfNdefed; + IncludeGuardToken = IfCondition; + } } void UnwrappedLineParser::parsePPElse() { // If a potential include guard has an #else, it's not an include guard. - if (FoundIncludeGuardStart && PPBranchLevel == 0) - FoundIncludeGuardStart = false; + if (IncludeGuard == IG_Defined && PPBranchLevel == 0) + IncludeGuard = IG_Rejected; conditionalCompilationAlternative(); if (PPBranchLevel > -1) --PPBranchLevel; @@ -745,34 +757,37 @@ void UnwrappedLineParser::parsePPEndIf() { conditionalCompilationEnd(); parsePPUnknown(); // If the #endif of a potential include guard is the last thing in the file, - // then we count it as a real include guard and subtract one from every - // preprocessor indent. + // then we found an include guard. unsigned TokenPosition = Tokens->getPosition(); FormatToken *PeekNext = AllTokens[TokenPosition]; - if (FoundIncludeGuardStart && PPBranchLevel == -1 && PeekNext->is(tok::eof) && + if (IncludeGuard == IG_Defined && PPBranchLevel == -1 && + PeekNext->is(tok::eof) && Style.IndentPPDirectives != FormatStyle::PPDIS_None) - for (auto &Line : Lines) - if (Line.InPPDirective && Line.Level > 0) - --Line.Level; + IncludeGuard = IG_Found; } void UnwrappedLineParser::parsePPDefine() { nextToken(); if (FormatTok->Tok.getKind() != tok::identifier) { + IncludeGuard = IG_Rejected; + IncludeGuardToken = nullptr; parsePPUnknown(); return; } - if (IfNdefCondition && IfNdefCondition->TokenText == FormatTok->TokenText) { - FoundIncludeGuardStart = true; + + if (IncludeGuard == IG_IfNdefed && + IncludeGuardToken->TokenText == FormatTok->TokenText) { + IncludeGuard = IG_Defined; + IncludeGuardToken = nullptr; for (auto &Line : Lines) { if (!Line.Tokens.front().Tok->isOneOf(tok::comment, tok::hash)) { - FoundIncludeGuardStart = false; + IncludeGuard = IG_Rejected; break; } } } - IfNdefCondition = nullptr; + nextToken(); if (FormatTok->Tok.getKind() == tok::l_paren && FormatTok->WhitespaceRange.getBegin() == @@ -799,7 +814,6 @@ void UnwrappedLineParser::parsePPUnknown() { if (Style.IndentPPDirectives == FormatStyle::PPDIS_AfterHash) Line->Level += PPBranchLevel + 1; addUnwrappedLine(); - IfNdefCondition = nullptr; } // Here we blacklist certain tokens that are not usually the first token in an diff --git a/lib/Format/UnwrappedLineParser.h b/lib/Format/UnwrappedLineParser.h index 1d8ccabbd0f8..cee03e9bce33 100644 --- a/lib/Format/UnwrappedLineParser.h +++ b/lib/Format/UnwrappedLineParser.h @@ -248,10 +248,23 @@ class UnwrappedLineParser { // sequence. std::stack PPChainBranchIndex; - // Contains the #ifndef condition for a potential include guard. - FormatToken *IfNdefCondition; - bool FoundIncludeGuardStart; - bool IncludeGuardRejected; + // Include guard search state. Used to fixup preprocessor indent levels + // so that include guards do not participate in indentation. + enum IncludeGuardState { + IG_Inited, // Search started, looking for #ifndef. + IG_IfNdefed, // #ifndef found, IncludeGuardToken points to condition. + IG_Defined, // Matching #define found, checking other requirements. + IG_Found, // All requirements met, need to fix indents. + IG_Rejected, // Search failed or never started. + }; + + // Current state of include guard search. + IncludeGuardState IncludeGuard; + + // Points to the #ifndef condition for a potential include guard. Null unless + // IncludeGuardState == IG_IfNdefed. + FormatToken *IncludeGuardToken; + // Contains the first start column where the source begins. This is zero for // normal source code and may be nonzero when formatting a code fragment that // does not start at the beginning of the file. diff --git a/lib/Headers/avx512bwintrin.h b/lib/Headers/avx512bwintrin.h index 3ff0e3aafdcc..064300a48798 100644 --- a/lib/Headers/avx512bwintrin.h +++ b/lib/Headers/avx512bwintrin.h @@ -1854,13 +1854,15 @@ _mm512_maskz_set1_epi8 (__mmask64 __M, char __A) static __inline__ __mmask64 __DEFAULT_FN_ATTRS _mm512_kunpackd (__mmask64 __A, __mmask64 __B) { - return (__mmask64) (( __A & 0xFFFFFFFF) | ( __B << 32)); + return (__mmask64) __builtin_ia32_kunpckdi ((__mmask64) __A, + (__mmask64) __B); } static __inline__ __mmask32 __DEFAULT_FN_ATTRS _mm512_kunpackw (__mmask32 __A, __mmask32 __B) { -return (__mmask32) (( __A & 0xFFFF) | ( __B << 16)); + return (__mmask32) __builtin_ia32_kunpcksi ((__mmask32) __A, + (__mmask32) __B); } static __inline__ __m512i __DEFAULT_FN_ATTRS diff --git a/lib/Headers/avx512fintrin.h b/lib/Headers/avx512fintrin.h index d34f0b1327ae..f5137428ba3f 100644 --- a/lib/Headers/avx512fintrin.h +++ b/lib/Headers/avx512fintrin.h @@ -8787,7 +8787,7 @@ _mm512_kortestz (__mmask16 __A, __mmask16 __B) static __inline__ __mmask16 __DEFAULT_FN_ATTRS _mm512_kunpackb (__mmask16 __A, __mmask16 __B) { - return (__mmask16) (( __A & 0xFF) | ( __B << 8)); + return (__mmask16) __builtin_ia32_kunpckhi ((__mmask16) __A, (__mmask16) __B); } static __inline__ __mmask16 __DEFAULT_FN_ATTRS diff --git a/lib/Lex/LiteralSupport.cpp b/lib/Lex/LiteralSupport.cpp index cbec5e6b6385..ec342ee3ae2a 100644 --- a/lib/Lex/LiteralSupport.cpp +++ b/lib/Lex/LiteralSupport.cpp @@ -738,15 +738,17 @@ void NumericLiteralParser::ParseDecimalOrOctalCommon(SourceLocation TokLoc){ s++; radix = 10; saw_exponent = true; - if (*s == '+' || *s == '-') s++; // sign + if (s != ThisTokEnd && (*s == '+' || *s == '-')) s++; // sign const char *first_non_digit = SkipDigits(s); if (containsDigits(s, first_non_digit)) { checkSeparator(TokLoc, s, CSK_BeforeDigits); s = first_non_digit; } else { - PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, Exponent-ThisTokBegin), - diag::err_exponent_has_no_digits); - hadError = true; + if (!hadError) { + PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, Exponent-ThisTokBegin), + diag::err_exponent_has_no_digits); + hadError = true; + } return; } } @@ -787,10 +789,12 @@ void NumericLiteralParser::checkSeparator(SourceLocation TokLoc, } else if (Pos == ThisTokEnd) return; - if (isDigitSeparator(*Pos)) + if (isDigitSeparator(*Pos)) { PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, Pos - ThisTokBegin), diag::err_digit_separator_not_between_digits) << IsAfterDigits; + hadError = true; + } } /// ParseNumberStartingWithZero - This method is called when the first character @@ -840,12 +844,14 @@ void NumericLiteralParser::ParseNumberStartingWithZero(SourceLocation TokLoc) { const char *Exponent = s; s++; saw_exponent = true; - if (*s == '+' || *s == '-') s++; // sign + if (s != ThisTokEnd && (*s == '+' || *s == '-')) s++; // sign const char *first_non_digit = SkipDigits(s); if (!containsDigits(s, first_non_digit)) { - PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, Exponent-ThisTokBegin), - diag::err_exponent_has_no_digits); - hadError = true; + if (!hadError) { + PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, Exponent-ThisTokBegin), + diag::err_exponent_has_no_digits); + hadError = true; + } return; } checkSeparator(TokLoc, s, CSK_BeforeDigits); diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index 803f87b3c568..57af6b86bf80 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -8972,6 +8972,16 @@ static void AnalyzeComparison(Sema &S, BinaryOperator *E) { LHS = LHS->IgnoreParenImpCasts(); RHS = RHS->IgnoreParenImpCasts(); + if (!S.getLangOpts().CPlusPlus) { + // Avoid warning about comparison of integers with different signs when + // RHS/LHS has a `typeof(E)` type whose sign is different from the sign of + // the type of `E`. + if (const auto *TET = dyn_cast(LHS->getType())) + LHS = TET->getUnderlyingExpr()->IgnoreParenImpCasts(); + if (const auto *TET = dyn_cast(RHS->getType())) + RHS = TET->getUnderlyingExpr()->IgnoreParenImpCasts(); + } + // Check to see if one of the (unmodified) operands is of different // signedness. Expr *signedOperand, *unsignedOperand; diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 743f4bb5e822..7ca48c34e516 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -12507,10 +12507,20 @@ void Sema::ActOnFinishDelayedAttribute(Scope *S, Decl *D, /// call, forming a call to an implicitly defined function (per C99 6.5.1p2). NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc, IdentifierInfo &II, Scope *S) { + // Find the scope in which the identifier is injected and the corresponding + // DeclContext. + // FIXME: C89 does not say what happens if there is no enclosing block scope. + // In that case, we inject the declaration into the translation unit scope + // instead. Scope *BlockScope = S; while (!BlockScope->isCompoundStmtScope() && BlockScope->getParent()) BlockScope = BlockScope->getParent(); + Scope *ContextScope = BlockScope; + while (!ContextScope->getEntity()) + ContextScope = ContextScope->getParent(); + ContextRAII SavedContext(*this, ContextScope->getEntity()); + // Before we produce a declaration for an implicitly defined // function, see whether there was a locally-scoped declaration of // this name as a function or variable. If so, use that diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 7e01b058ab2d..a6e43765e106 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -14926,7 +14926,8 @@ static void DoMarkVarDeclReferenced(Sema &SemaRef, SourceLocation Loc, if (RefersToEnclosingScope) { LambdaScopeInfo *const LSI = SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true); - if (LSI && !LSI->CallOperator->Encloses(Var->getDeclContext())) { + if (LSI && (!LSI->CallOperator || + !LSI->CallOperator->Encloses(Var->getDeclContext()))) { // If a variable could potentially be odr-used, defer marking it so // until we finish analyzing the full expression for any // lvalue-to-rvalue diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index 011051da58e5..df64a33954fa 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -352,6 +352,7 @@ class InitListChecker { bool FillWithNoInit = false); void FillInEmptyInitializations(const InitializedEntity &Entity, InitListExpr *ILE, bool &RequiresSecondPass, + InitListExpr *OuterILE, unsigned OuterIndex, bool FillWithNoInit = false); bool CheckFlexibleArrayInit(const InitializedEntity &Entity, Expr *InitExpr, FieldDecl *Field, @@ -517,12 +518,13 @@ void InitListChecker::FillInEmptyInitForBase( ILE->setInit(Init, BaseInit.getAs()); } else if (InitListExpr *InnerILE = dyn_cast(ILE->getInit(Init))) { - FillInEmptyInitializations(BaseEntity, InnerILE, - RequiresSecondPass, FillWithNoInit); + FillInEmptyInitializations(BaseEntity, InnerILE, RequiresSecondPass, + ILE, Init, FillWithNoInit); } else if (DesignatedInitUpdateExpr *InnerDIUE = dyn_cast(ILE->getInit(Init))) { FillInEmptyInitializations(BaseEntity, InnerDIUE->getUpdater(), - RequiresSecondPass, /*FillWithNoInit =*/true); + RequiresSecondPass, ILE, Init, + /*FillWithNoInit =*/true); } } @@ -605,24 +607,43 @@ void InitListChecker::FillInEmptyInitForField(unsigned Init, FieldDecl *Field, } else if (InitListExpr *InnerILE = dyn_cast(ILE->getInit(Init))) FillInEmptyInitializations(MemberEntity, InnerILE, - RequiresSecondPass, FillWithNoInit); + RequiresSecondPass, ILE, Init, FillWithNoInit); else if (DesignatedInitUpdateExpr *InnerDIUE = dyn_cast(ILE->getInit(Init))) FillInEmptyInitializations(MemberEntity, InnerDIUE->getUpdater(), - RequiresSecondPass, /*FillWithNoInit =*/ true); + RequiresSecondPass, ILE, Init, + /*FillWithNoInit =*/true); } /// Recursively replaces NULL values within the given initializer list /// with expressions that perform value-initialization of the -/// appropriate type. +/// appropriate type, and finish off the InitListExpr formation. void InitListChecker::FillInEmptyInitializations(const InitializedEntity &Entity, InitListExpr *ILE, bool &RequiresSecondPass, + InitListExpr *OuterILE, + unsigned OuterIndex, bool FillWithNoInit) { assert((ILE->getType() != SemaRef.Context.VoidTy) && "Should not have void type"); + // If this is a nested initializer list, we might have changed its contents + // (and therefore some of its properties, such as instantiation-dependence) + // while filling it in. Inform the outer initializer list so that its state + // can be updated to match. + // FIXME: We should fully build the inner initializers before constructing + // the outer InitListExpr instead of mutating AST nodes after they have + // been used as subexpressions of other nodes. + struct UpdateOuterILEWithUpdatedInit { + InitListExpr *Outer; + unsigned OuterIndex; + ~UpdateOuterILEWithUpdatedInit() { + if (Outer) + Outer->setInit(OuterIndex, Outer->getInit(OuterIndex)); + } + } UpdateOuterRAII = {OuterILE, OuterIndex}; + // A transparent ILE is not performing aggregate initialization and should // not be filled in. if (ILE->isTransparent()) @@ -769,11 +790,12 @@ InitListChecker::FillInEmptyInitializations(const InitializedEntity &Entity, } else if (InitListExpr *InnerILE = dyn_cast_or_null(InitExpr)) FillInEmptyInitializations(ElementEntity, InnerILE, RequiresSecondPass, - FillWithNoInit); + ILE, Init, FillWithNoInit); else if (DesignatedInitUpdateExpr *InnerDIUE = dyn_cast_or_null(InitExpr)) FillInEmptyInitializations(ElementEntity, InnerDIUE->getUpdater(), - RequiresSecondPass, /*FillWithNoInit =*/ true); + RequiresSecondPass, ILE, Init, + /*FillWithNoInit =*/true); } } @@ -795,10 +817,11 @@ InitListChecker::InitListChecker(Sema &S, const InitializedEntity &Entity, if (!hadError && !VerifyOnly) { bool RequiresSecondPass = false; - FillInEmptyInitializations(Entity, FullyStructuredList, RequiresSecondPass); + FillInEmptyInitializations(Entity, FullyStructuredList, RequiresSecondPass, + /*OuterILE=*/nullptr, /*OuterIndex=*/0); if (RequiresSecondPass && !hadError) FillInEmptyInitializations(Entity, FullyStructuredList, - RequiresSecondPass); + RequiresSecondPass, nullptr, 0); } } @@ -1162,10 +1185,12 @@ void InitListChecker::CheckSubElementType(const InitializedEntity &Entity, if (!hadError && !VerifyOnly) { bool RequiresSecondPass = false; FillInEmptyInitializations(Entity, InnerStructuredList, - RequiresSecondPass); + RequiresSecondPass, StructuredList, + StructuredIndex); if (RequiresSecondPass && !hadError) FillInEmptyInitializations(Entity, InnerStructuredList, - RequiresSecondPass); + RequiresSecondPass, StructuredList, + StructuredIndex); } ++StructuredIndex; ++Index; diff --git a/test/CodeGen/avx512bw-builtins.c b/test/CodeGen/avx512bw-builtins.c index 3160a6667c00..190387b2d97a 100644 --- a/test/CodeGen/avx512bw-builtins.c +++ b/test/CodeGen/avx512bw-builtins.c @@ -1626,26 +1626,16 @@ __m512i test_mm512_maskz_set1_epi8(__mmask64 __M, char __A) { return _mm512_maskz_set1_epi8(__M, __A); } -__mmask64 test_mm512_kunpackd(__m512i __A, __m512i __B, __m512i __C, __m512i __D, __m512i __E, __m512i __F) { +__mmask64 test_mm512_kunpackd(__mmask64 __A, __mmask64 __B) { // CHECK-LABEL: @test_mm512_kunpackd - // CHECK: bitcast <64 x i1> %{{.*}} to i64 - // CHECK: bitcast <64 x i1> %{{.*}} to i64 - // CHECK: and i64 %{{.*}}, 4294967295 - // CHECK: shl i64 %{{.*}}, 32 - // CHECK: or i64 %{{.*}}, %{{.*}} - // CHECK: bitcast i64 %{{.*}} to <64 x i1> - return _mm512_mask_cmpneq_epu8_mask(_mm512_kunpackd(_mm512_cmpneq_epu8_mask(__B, __A),_mm512_cmpneq_epu8_mask(__C, __D)), __E, __F); + // CHECK: @llvm.x86.avx512.kunpck.dq + return _mm512_kunpackd(__A, __B); } -__mmask32 test_mm512_kunpackw(__m512i __A, __m512i __B, __m512i __C, __m512i __D, __m512i __E, __m512i __F) { +__mmask32 test_mm512_kunpackw(__mmask32 __A, __mmask32 __B) { // CHECK-LABEL: @test_mm512_kunpackw - // CHECK: bitcast <32 x i1> %{{.*}} to i32 - // CHECK: bitcast <32 x i1> %{{.*}} to i32 - // CHECK: and i32 %{{.*}}, 65535 - // CHECK: shl i32 %{{.*}}, 16 - // CHECK: or i32 %{{.*}}, %{{.*}} - // CHECK: bitcast i32 %{{.*}} to <32 x i1> - return _mm512_mask_cmpneq_epu16_mask(_mm512_kunpackw(_mm512_cmpneq_epu16_mask(__B, __A),_mm512_cmpneq_epu16_mask(__C, __D)), __E, __F); + // CHECK: @llvm.x86.avx512.kunpck.wd + return _mm512_kunpackw(__A, __B); } __m512i test_mm512_mask_loadu_epi16(__m512i __W, __mmask32 __U, void const *__P) { diff --git a/test/CodeGen/avx512f-builtins.c b/test/CodeGen/avx512f-builtins.c index ce831d690ee7..2ba2faf1b697 100644 --- a/test/CodeGen/avx512f-builtins.c +++ b/test/CodeGen/avx512f-builtins.c @@ -6259,17 +6259,10 @@ int test_mm512_kortestz(__mmask16 __A, __mmask16 __B) { return _mm512_kortestz(__A, __B); } -__mmask16 test_mm512_kunpackb(__m512i __A, __m512i __B, __m512i __C, __m512i __D, __m512i __E, __m512i __F) { +__mmask16 test_mm512_kunpackb(__mmask16 __A, __mmask16 __B) { // CHECK-LABEL: @test_mm512_kunpackb - // CHECK: bitcast <16 x i1> %{{.*}} to i16 - // CHECK: bitcast <16 x i1> %{{.*}} to i16 - // CHECK: and i32 %{{.*}}, 255 - // CHECK: shl i32 %{{.*}}, 8 - // CHECK: or i32 %{{.*}}, %{{.*}} - // CHECK: bitcast i16 %{{.*}} to <16 x i1> - return _mm512_mask_cmpneq_epu32_mask(_mm512_kunpackb(_mm512_cmpneq_epu32_mask(__A, __B), - _mm512_cmpneq_epu32_mask(__C, __D)), - __E, __F); + // CHECK: @llvm.x86.avx512.kunpck.bw + return _mm512_kunpackb(__A, __B); } __mmask16 test_mm512_kxnor(__m512i __A, __m512i __B, __m512i __C, __m512i __D, __m512i __E, __m512i __F) { diff --git a/test/CodeGen/ms_abi.c b/test/CodeGen/ms_abi.c index 407087e40916..7486166c78d4 100644 --- a/test/CodeGen/ms_abi.c +++ b/test/CodeGen/ms_abi.c @@ -146,3 +146,16 @@ void __attribute__((sysv_abi)) f6(__builtin_ms_va_list ap) { // WIN64: %[[AP_VAL:.*]] = load i8*, i8** %[[AP]] // WIN64-NEXT: store i8* %[[AP_VAL]], i8** %[[AP2:.*]] } + +// This test checks if structs are passed according to Win64 calling convention +// when it's enforced by __attribute((ms_abi)). +struct i128 { + unsigned long long a; + unsigned long long b; +}; + +__attribute__((ms_abi)) struct i128 f7(struct i128 a) { + // WIN64: define void @f7(%struct.i128* noalias sret %agg.result, %struct.i128* %a) + // FREEBSD: define win64cc void @f7(%struct.i128* noalias sret %agg.result, %struct.i128* %a) + return a; +} diff --git a/test/CodeGenCXX/dllimport-missing-key.cpp b/test/CodeGenCXX/dllimport-missing-key.cpp new file mode 100644 index 000000000000..d8ef7aa7ea68 --- /dev/null +++ b/test/CodeGenCXX/dllimport-missing-key.cpp @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -triple i686-windows-gnu -emit-llvm -std=c++1y -O0 -o - %s -w | FileCheck --check-prefix=GNU %s + +class __declspec(dllimport) QObjectData { +public: + virtual ~QObjectData() = 0; + void *ptr; + + int method() const; +}; + +class LocalClass : public QObjectData { +}; + +void call() { + (new LocalClass())->method(); +} + +// GNU-DAG: @_ZTV11QObjectData = available_externally dllimport +// GNU-DAG: @_ZTS11QObjectData = linkonce_odr +// GNU-DAG: @_ZTI11QObjectData = linkonce_odr diff --git a/test/CodeGenCXX/dllimport-rtti.cpp b/test/CodeGenCXX/dllimport-rtti.cpp index 91e747ae1c15..dfb39a15eda5 100644 --- a/test/CodeGenCXX/dllimport-rtti.cpp +++ b/test/CodeGenCXX/dllimport-rtti.cpp @@ -12,7 +12,7 @@ struct __declspec(dllimport) S { // MSVC-DAG: @"\01??_R3S@@8" = linkonce_odr // GNU-DAG: @_ZTV1S = available_externally dllimport -// GNU-DAG: @_ZTI1S = external dllimport +// GNU-DAG: @_ZTI1S = linkonce_odr struct U : S { } u; diff --git a/test/CodeGenCXX/microsoft-abi-emit-dependent.cpp b/test/CodeGenCXX/microsoft-abi-emit-dependent.cpp new file mode 100644 index 000000000000..e74ebc879f5b --- /dev/null +++ b/test/CodeGenCXX/microsoft-abi-emit-dependent.cpp @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -emit-llvm-only -fmodules -triple x86_64-windows %s +// PR36181 +#pragma clang module build foo +module foo {} +#pragma clang module contents +template struct A { + friend void f(A) {} +}; +#pragma clang module endbuild +#pragma clang module import foo +void g() { f(A()); } diff --git a/test/CodeGenCXX/msabi-swiftcall-cc.cpp b/test/CodeGenCXX/msabi-swiftcall-cc.cpp new file mode 100644 index 000000000000..5a5453af8fa1 --- /dev/null +++ b/test/CodeGenCXX/msabi-swiftcall-cc.cpp @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -triple i686-unknown-windows-msvc -fdeclspec -emit-llvm %s -o - | FileCheck %s + +void __attribute__((__swiftcall__)) f() {} +// CHECK-DAG: @"\01?f@@YSXXZ" + +void (__attribute__((__swiftcall__)) *p)(); +// CHECK-DAG: @"\01?p@@3P6SXXZA" + +namespace { +void __attribute__((__swiftcall__)) __attribute__((__used__)) f() { } +// CHECK-DAG: "\01?f@?A@@YSXXZ" +} + +namespace n { +void __attribute__((__swiftcall__)) f() {} +// CHECK-DAG: "\01?f@n@@YSXXZ" +} + +struct __declspec(dllexport) S { + S(const S &) = delete; + S & operator=(const S &) = delete; + void __attribute__((__swiftcall__)) m() { } + // CHECK-DAG: "\01?m@S@@QASXXZ" +}; + +void f(void (__attribute__((__swiftcall__))())) {} +// CHECK-DAG: "\01?f@@YAXP6SXXZ@Z" + diff --git a/test/Driver/x86-target-features.c b/test/Driver/x86-target-features.c index 1289823d1dbe..36b15a7a350c 100644 --- a/test/Driver/x86-target-features.c +++ b/test/Driver/x86-target-features.c @@ -125,3 +125,12 @@ // VBMI2: "-target-feature" "+avx512vbmi2" // NO-VBMI2: "-target-feature" "-avx512vbmi2" +// RUN: %clang -target i386-linux-gnu -mretpoline %s -### -o %t.o 2>&1 | FileCheck -check-prefix=RETPOLINE %s +// RUN: %clang -target i386-linux-gnu -mno-retpoline %s -### -o %t.o 2>&1 | FileCheck -check-prefix=NO-RETPOLINE %s +// RETPOLINE: "-target-feature" "+retpoline" +// NO-RETPOLINE: "-target-feature" "-retpoline" + +// RUN: %clang -target i386-linux-gnu -mretpoline -mretpoline-external-thunk %s -### -o %t.o 2>&1 | FileCheck -check-prefix=RETPOLINE-EXTERNAL-THUNK %s +// RUN: %clang -target i386-linux-gnu -mretpoline -mno-retpoline-external-thunk %s -### -o %t.o 2>&1 | FileCheck -check-prefix=NO-RETPOLINE-EXTERNAL-THUNK %s +// RETPOLINE-EXTERNAL-THUNK: "-target-feature" "+retpoline-external-thunk" +// NO-RETPOLINE-EXTERNAL-THUNK: "-target-feature" "-retpoline-external-thunk" diff --git a/test/Lexer/cxx1y_digit_separators.cpp b/test/Lexer/cxx1y_digit_separators.cpp index 55366342eda0..67dcd7c510ed 100644 --- a/test/Lexer/cxx1y_digit_separators.cpp +++ b/test/Lexer/cxx1y_digit_separators.cpp @@ -51,6 +51,8 @@ namespace floating { float u = 0x.'p1f; // expected-error {{hexadecimal floating literal requires a significand}} float v = 0e'f; // expected-error {{exponent has no digits}} float w = 0x0p'f; // expected-error {{exponent has no digits}} + float x = 0'e+1; // expected-error {{digit separator cannot appear at end of digit sequence}} + float y = 0x0'p+1; // expected-error {{digit separator cannot appear at end of digit sequence}} } #line 123'456 diff --git a/test/Preprocessor/predefined-arch-macros.c b/test/Preprocessor/predefined-arch-macros.c index 6021f9c60e34..716d6f72ba61 100644 --- a/test/Preprocessor/predefined-arch-macros.c +++ b/test/Preprocessor/predefined-arch-macros.c @@ -972,7 +972,7 @@ // CHECK_CNL_M32: #define __BMI2__ 1 // CHECK_CNL_M32: #define __BMI__ 1 // CHECK_CNL_M32: #define __CLFLUSHOPT__ 1 -// CHECK_CNL_M32: #define __CLWB__ 1 +// CHECK_CNL_M32-NOT: #define __CLWB__ 1 // CHECK_CNL_M32: #define __F16C__ 1 // CHECK_CNL_M32: #define __FMA__ 1 // CHECK_CNL_M32: #define __LZCNT__ 1 @@ -1019,7 +1019,7 @@ // CHECK_CNL_M64: #define __BMI2__ 1 // CHECK_CNL_M64: #define __BMI__ 1 // CHECK_CNL_M64: #define __CLFLUSHOPT__ 1 -// CHECK_CNL_M64: #define __CLWB__ 1 +// CHECK_CNL_M64-NOT: #define __CLWB__ 1 // CHECK_CNL_M64: #define __F16C__ 1 // CHECK_CNL_M64: #define __FMA__ 1 // CHECK_CNL_M64: #define __LZCNT__ 1 diff --git a/test/Sema/bitfield.c b/test/Sema/bitfield.c index d625366e4e1f..13e9480a378b 100644 --- a/test/Sema/bitfield.c +++ b/test/Sema/bitfield.c @@ -82,3 +82,7 @@ typedef __typeof__(+(t5.n--)) Unsigned; // also act like compound-assignment. struct Test6 { : 0.0; // expected-error{{type name requires a specifier or qualifier}} }; + +struct PR36157 { + int n : 1 ? 1 : implicitly_declare_function(); // expected-warning {{invalid in C99}} +}; diff --git a/test/Sema/compare.c b/test/Sema/compare.c index 7cd8adab8921..b2b486f59f87 100644 --- a/test/Sema/compare.c +++ b/test/Sema/compare.c @@ -391,3 +391,16 @@ typedef char two_chars[2]; void test12(unsigned a) { if (0 && -1 > a) { } } + +// PR36008 + +enum PR36008EnumTest { + kPR36008Value = 0, +}; + +void pr36008(enum PR36008EnumTest lhs) { + __typeof__(lhs) x = lhs; + __typeof__(kPR36008Value) y = (kPR36008Value); + if (x == y) x = y; // no warning + if (y == x) y = x; // no warning +} diff --git a/test/Sema/cxx-as-c.c b/test/Sema/cxx-as-c.c new file mode 100644 index 000000000000..41d7350d1f15 --- /dev/null +++ b/test/Sema/cxx-as-c.c @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 %s -verify + +// PR36157 +struct Foo { + Foo(int n) : n_(n) {} // expected-error 1+{{}} expected-warning 1+{{}} +private: + int n; +}; +int main() { Foo f; } // expected-error 1+{{}} diff --git a/test/SemaCXX/init-expr-crash.cpp b/test/SemaCXX/init-expr-crash.cpp index 407da78e60b0..201ab03955cd 100644 --- a/test/SemaCXX/init-expr-crash.cpp +++ b/test/SemaCXX/init-expr-crash.cpp @@ -29,3 +29,11 @@ template struct B { return 0; } }; + +// This test checks for a crash that resulted from us miscomputing the +// dependence of a nested initializer list. +template struct X { + static constexpr int n = 4; + static constexpr int a[1][1] = {n}; +}; + diff --git a/test/SemaCXX/lambda-expressions.cpp b/test/SemaCXX/lambda-expressions.cpp index de77467b6d5a..4565345fc665 100644 --- a/test/SemaCXX/lambda-expressions.cpp +++ b/test/SemaCXX/lambda-expressions.cpp @@ -608,3 +608,18 @@ namespace ConversionOperatorDoesNotHaveDeducedReturnType { // This used to crash in return type deduction for the conversion opreator. struct A { int n; void f() { +[](decltype(n)) {}; } }; } + +namespace TypoCorrection { +template struct X {}; +// expected-note@-1 {{template parameter is declared here}} + +template +void Run(const int& points) { +// expected-note@-1 {{'points' declared here}} + auto outer_lambda = []() { + auto inner_lambda = [](const X&) {}; + // expected-error@-1 {{use of undeclared identifier 'Points'; did you mean 'points'?}} + // expected-error@-2 {{template argument for template type parameter must be a type}} + }; +} +} diff --git a/test/SemaCXX/type-traits.cpp b/test/SemaCXX/type-traits.cpp index b334e507554f..3c2f9c7f0fb6 100644 --- a/test/SemaCXX/type-traits.cpp +++ b/test/SemaCXX/type-traits.cpp @@ -2524,6 +2524,7 @@ static_assert(!has_unique_object_representations::value, "No refere static_assert(!has_unique_object_representations::value, "No references!"); static_assert(!has_unique_object_representations::value, "No references!"); static_assert(!has_unique_object_representations::value, "No empty types!"); +static_assert(!has_unique_object_representations::value, "No empty types!"); class Compressed : Empty { int x; diff --git a/test/SemaTemplate/instantiate-init.cpp b/test/SemaTemplate/instantiate-init.cpp index 244e94f6d605..51fa6955d0c0 100644 --- a/test/SemaTemplate/instantiate-init.cpp +++ b/test/SemaTemplate/instantiate-init.cpp @@ -142,3 +142,17 @@ namespace ReturnStmtIsInitialization { template X f() { return {}; } auto &&x = f(); } + +namespace InitListUpdate { + struct A { int n; }; + using AA = A[1]; + + // Check that an init list update doesn't "lose" the pack-ness of an expression. + template void f() { + g(AA{0, [0].n = N} ...); // expected-warning 3{{overrides prior init}} expected-note 3{{previous init}} + g(AA{N, [0].n = 0} ...); // expected-warning 3{{overrides prior init}} expected-note 3{{previous init}} + }; + + void g(AA, AA); + void h() { f<1, 2>(); } // expected-note {{instantiation of}} +} diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp index 2cae9dd0c547..593caf0fdc9a 100644 --- a/unittests/Format/FormatTest.cpp +++ b/unittests/Format/FormatTest.cpp @@ -2532,6 +2532,20 @@ TEST_F(FormatTest, IndentPreprocessorDirectives) { "#elif FOO\n" "#endif", Style); + // Non-identifier #define after potential include guard. + verifyFormat("#ifndef FOO\n" + "# define 1\n" + "#endif\n", + Style); + // #if closes past last non-preprocessor line. + verifyFormat("#ifndef FOO\n" + "#define FOO\n" + "#if 1\n" + "int i;\n" + "# define A 0\n" + "#endif\n" + "#endif\n", + Style); // FIXME: This doesn't handle the case where there's code between the // #ifndef and #define but all other conditions hold. This is because when // the #define line is parsed, UnwrappedLineParser::Lines doesn't hold the @@ -2580,21 +2594,85 @@ TEST_F(FormatTest, IndentPreprocessorDirectives) { "code();\n" "#endif", Style)); - // FIXME: The comment indent corrector in TokenAnnotator gets thrown off by - // preprocessor indentation. - EXPECT_EQ("#if 1\n" - " // comment\n" - "# define A 0\n" - "// comment\n" - "# define B 0\n" - "#endif", - format("#if 1\n" - "// comment\n" - "# define A 0\n" - " // comment\n" - "# define B 0\n" - "#endif", - Style)); + // Keep comments aligned with #, otherwise indent comments normally. These + // tests cannot use verifyFormat because messUp manipulates leading + // whitespace. + { + const char *Expected = "" + "void f() {\n" + "#if 1\n" + "// Preprocessor aligned.\n" + "# define A 0\n" + " // Code. Separated by blank line.\n" + "\n" + "# define B 0\n" + " // Code. Not aligned with #\n" + "# define C 0\n" + "#endif"; + const char *ToFormat = "" + "void f() {\n" + "#if 1\n" + "// Preprocessor aligned.\n" + "# define A 0\n" + "// Code. Separated by blank line.\n" + "\n" + "# define B 0\n" + " // Code. Not aligned with #\n" + "# define C 0\n" + "#endif"; + EXPECT_EQ(Expected, format(ToFormat, Style)); + EXPECT_EQ(Expected, format(Expected, Style)); + } + // Keep block quotes aligned. + { + const char *Expected = "" + "void f() {\n" + "#if 1\n" + "/* Preprocessor aligned. */\n" + "# define A 0\n" + " /* Code. Separated by blank line. */\n" + "\n" + "# define B 0\n" + " /* Code. Not aligned with # */\n" + "# define C 0\n" + "#endif"; + const char *ToFormat = "" + "void f() {\n" + "#if 1\n" + "/* Preprocessor aligned. */\n" + "# define A 0\n" + "/* Code. Separated by blank line. */\n" + "\n" + "# define B 0\n" + " /* Code. Not aligned with # */\n" + "# define C 0\n" + "#endif"; + EXPECT_EQ(Expected, format(ToFormat, Style)); + EXPECT_EQ(Expected, format(Expected, Style)); + } + // Keep comments aligned with un-indented directives. + { + const char *Expected = "" + "void f() {\n" + "// Preprocessor aligned.\n" + "#define A 0\n" + " // Code. Separated by blank line.\n" + "\n" + "#define B 0\n" + " // Code. Not aligned with #\n" + "#define C 0\n"; + const char *ToFormat = "" + "void f() {\n" + "// Preprocessor aligned.\n" + "#define A 0\n" + "// Code. Separated by blank line.\n" + "\n" + "#define B 0\n" + " // Code. Not aligned with #\n" + "#define C 0\n"; + EXPECT_EQ(Expected, format(ToFormat, Style)); + EXPECT_EQ(Expected, format(Expected, Style)); + } // Test with tabs. Style.UseTab = FormatStyle::UT_Always; Style.IndentWidth = 8;