From 631f6b779f4d248755ad71398d0f296653dd62cf Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Wed, 17 Aug 2016 19:34:38 +0000 Subject: Vendor import of clang release_39 branch r278877: https://llvm.org/svn/llvm-project/cfe/branches/release_39@278877 --- docs/AttributeReference.rst | 2735 +++++++++++++++++++- docs/ReleaseNotes.rst | 86 +- docs/UsersManual.rst | 18 +- include/clang/AST/ExternalASTSource.h | 5 +- include/clang/AST/StmtGraphTraits.h | 2 + include/clang/Analysis/Analyses/Dominators.h | 1 + include/clang/Basic/BuiltinsX86.def | 8 + include/clang/Basic/DiagnosticASTKinds.td | 6 - include/clang/Basic/DiagnosticParseKinds.td | 11 +- include/clang/Sema/Sema.h | 3 +- include/clang/Serialization/ASTReader.h | 22 + .../Core/PathSensitive/ExplodedGraph.h | 2 + lib/AST/ASTDiagnostic.cpp | 6 + lib/AST/DeclCXX.cpp | 11 + lib/AST/ExprConstant.cpp | 18 +- lib/Analysis/CFG.cpp | 12 +- lib/Basic/Targets.cpp | 4 +- lib/CodeGen/CGBlocks.cpp | 12 +- lib/CodeGen/CGBuiltin.cpp | 5 +- lib/CodeGen/CGDebugInfo.cpp | 10 + lib/CodeGen/CGStmt.cpp | 22 +- lib/CodeGen/CoverageMappingGen.cpp | 11 + lib/Driver/ToolChains.cpp | 13 + lib/Driver/ToolChains.h | 3 +- lib/Driver/Tools.cpp | 29 +- lib/Headers/avx512fintrin.h | 1 - lib/Headers/avxintrin.h | 4 +- lib/Headers/cpuid.h | 8 +- lib/Headers/emmintrin.h | 9 +- lib/Headers/xmmintrin.h | 4 +- lib/Lex/Pragma.cpp | 4 +- lib/Parse/ParseExpr.cpp | 7 +- lib/Parse/ParseExprCXX.cpp | 65 +- lib/Sema/SemaChecking.cpp | 22 +- lib/Sema/SemaExprCXX.cpp | 38 +- lib/Sema/SemaLambda.cpp | 21 +- lib/Sema/SemaOverload.cpp | 6 +- lib/Sema/TreeTransform.h | 4 +- lib/Serialization/ASTReader.cpp | 2 + lib/Serialization/ASTReaderDecl.cpp | 13 +- lib/Serialization/ASTWriter.cpp | 18 +- test/CXX/special/class.copy/p11.0x.move.cpp | 12 + test/CodeGen/avx-builtins.c | 4 +- test/CodeGen/builtins-x86.c | 8 + test/CodeGen/forwarding-blocks-if.c | 36 - test/CodeGen/sse-builtins.c | 9 +- test/CodeGen/sse2-builtins.c | 10 +- test/CodeGen/target-data.c | 8 +- test/CodeGenCXX/debug-info-cxx1y.cpp | 26 +- test/CodeGenCXX/switch-case-folding-2.cpp | 9 + test/CodeGenOpenCL/cl20-device-side-enqueue.cl | 12 +- test/CodeGenOpenCL/to_addr_builtin.cl | 28 +- test/CoverageMapping/system_macro.c | 23 - test/CoverageMapping/system_macro.cpp | 26 + test/Driver/cl-options.c | 4 + test/Driver/cl-pch-errorhandling.cpp | 2 +- test/Driver/cl-pch-search.cpp | 2 +- test/Driver/cl-pch-showincludes.cpp | 10 +- test/Driver/cloudabi.c | 10 +- test/Driver/cloudabi.cpp | 12 +- test/Driver/frame-pointer-elim.c | 9 + test/Misc/diag-template-diffing.cpp | 30 + test/Modules/Inputs/PR28332/TextualInclude.h | 7 + test/Modules/Inputs/PR28332/a.h | 8 + test/Modules/Inputs/PR28332/b.h | 3 + test/Modules/Inputs/PR28332/c.h | 2 + test/Modules/Inputs/PR28332/module.modulemap | 3 + test/Modules/pr28332.cpp | 8 + test/PCH/Inputs/pragma-once.h | 5 + test/PCH/pragma-once.c | 13 + test/Parser/cxx1z-constexpr-lambdas.cpp | 31 - test/Sema/bitfield.c | 2 +- test/Sema/constant-conversion.c | 12 + test/Sema/enable_if.c | 21 + test/Sema/typo-correction.c | 15 + test/SemaCXX/cxx1z-constexpr-lambdas.cpp | 36 - test/SemaCXX/enable_if.cpp | 23 + test/SemaCXX/lambda-expressions.cpp | 30 +- test/SemaCXX/return-stack-addr-2.cpp | 61 +- test/SemaCXX/warn-thread-safety-analysis.cpp | 15 + test/SemaCXX/warn-unsequenced.cpp | 55 + www/cxx_dr_status.html | 20 +- www/make_cxx_dr_status | 4 +- 83 files changed, 3538 insertions(+), 407 deletions(-) delete mode 100644 test/CodeGen/forwarding-blocks-if.c delete mode 100644 test/CoverageMapping/system_macro.c create mode 100644 test/CoverageMapping/system_macro.cpp create mode 100644 test/Modules/Inputs/PR28332/TextualInclude.h create mode 100644 test/Modules/Inputs/PR28332/a.h create mode 100644 test/Modules/Inputs/PR28332/b.h create mode 100644 test/Modules/Inputs/PR28332/c.h create mode 100644 test/Modules/Inputs/PR28332/module.modulemap create mode 100644 test/Modules/pr28332.cpp create mode 100644 test/PCH/Inputs/pragma-once.h create mode 100644 test/PCH/pragma-once.c delete mode 100644 test/Parser/cxx1z-constexpr-lambdas.cpp delete mode 100644 test/SemaCXX/cxx1z-constexpr-lambdas.cpp diff --git a/docs/AttributeReference.rst b/docs/AttributeReference.rst index a763ddeaeb10..054d706fb28e 100644 --- a/docs/AttributeReference.rst +++ b/docs/AttributeReference.rst @@ -1,13 +1,2736 @@ .. ------------------------------------------------------------------- NOTE: This file is automatically generated by running clang-tblgen - -gen-attr-docs. Do not edit this file by hand!! The contents for - this file are automatically generated by a server-side process. - - Please do not commit this file. The file exists for local testing - purposes only. + -gen-attr-docs. Do not edit this file by hand!! ------------------------------------------------------------------- =================== Attributes in Clang -=================== \ No newline at end of file +=================== +.. contents:: + :local: + +Introduction +============ + +This page lists the attributes currently supported by Clang. + +Function Attributes +=================== + + +interrupt +--------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","","","", "" + +Clang supports the GNU style ``__attribute__((interrupt("TYPE")))`` attribute on +ARM targets. This attribute may be attached to a function definition and +instructs the backend to generate appropriate function entry/exit code so that +it can be used directly as an interrupt service routine. + +The parameter passed to the interrupt attribute is optional, but if +provided it must be a string literal with one of the following values: "IRQ", +"FIQ", "SWI", "ABORT", "UNDEF". + +The semantics are as follows: + +- If the function is AAPCS, Clang instructs the backend to realign the stack to + 8 bytes on entry. This is a general requirement of the AAPCS at public + interfaces, but may not hold when an exception is taken. Doing this allows + other AAPCS functions to be called. +- If the CPU is M-class this is all that needs to be done since the architecture + itself is designed in such a way that functions obeying the normal AAPCS ABI + constraints are valid exception handlers. +- If the CPU is not M-class, the prologue and epilogue are modified to save all + non-banked registers that are used, so that upon return the user-mode state + will not be corrupted. Note that to avoid unnecessary overhead, only + general-purpose (integer) registers are saved in this way. If VFP operations + are needed, that state must be saved manually. + + Specifically, interrupt kinds other than "FIQ" will save all core registers + except "lr" and "sp". "FIQ" interrupts will save r0-r7. +- If the CPU is not M-class, the return instruction is changed to one of the + canonical sequences permitted by the architecture for exception return. Where + possible the function itself will make the necessary "lr" adjustments so that + the "preferred return address" is selected. + + Unfortunately the compiler is unable to make this guarantee for an "UNDEF" + handler, where the offset from "lr" to the preferred return address depends on + the execution state of the code which generated the exception. In this case + a sequence equivalent to "movs pc, lr" will be used. + + +abi_tag (gnu::abi_tag) +---------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +The ``abi_tag`` attribute can be applied to a function, variable, class or +inline namespace declaration to modify the mangled name of the entity. It gives +the ability to distinguish between different versions of the same entity but +with different ABI versions supported. For example, a newer version of a class +could have a different set of data members and thus have a different size. Using +the ``abi_tag`` attribute, it is possible to have different mangled names for +a global variable of the class type. Therefor, the old code could keep using +the old manged name and the new code will use the new mangled name with tags. + + +acquire_capability (acquire_shared_capability, clang::acquire_capability, clang::acquire_shared_capability) +----------------------------------------------------------------------------------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +Marks a function as acquiring a capability. + + +interrupt +--------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","","","", "" + +Clang supports the GNU style ``__attribute__((interrupt))`` attribute on +x86/x86-64 targets.The compiler generates function entry and exit sequences +suitable for use in an interrupt handler when this attribute is present. +The 'IRET' instruction, instead of the 'RET' instruction, is used to return +from interrupt or exception handlers. All registers, except for the EFLAGS +register which is restored by the 'IRET' instruction, are preserved by the +compiler. + +Any interruptible-without-stack-switch code must be compiled with +-mno-red-zone since interrupt handlers can and will, because of the +hardware design, touch the red zone. + +1. interrupt handler must be declared with a mandatory pointer argument: + + .. code-block:: c + + struct interrupt_frame + { + uword_t ip; + uword_t cs; + uword_t flags; + uword_t sp; + uword_t ss; + }; + + __attribute__ ((interrupt)) + void f (struct interrupt_frame *frame) { + ... + } + +2. exception handler: + + The exception handler is very similar to the interrupt handler with + a different mandatory function signature: + + .. code-block:: c + + __attribute__ ((interrupt)) + void f (struct interrupt_frame *frame, uword_t error_code) { + ... + } + + and compiler pops 'ERROR_CODE' off stack before the 'IRET' instruction. + + The exception handler should only be used for exceptions which push an + error code and all other exceptions must use the interrupt handler. + The system will crash if the wrong handler is used. + + +assert_capability (assert_shared_capability, clang::assert_capability, clang::assert_shared_capability) +------------------------------------------------------------------------------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +Marks a function that dynamically tests whether a capability is held, and halts +the program if it is not held. + + +assume_aligned (gnu::assume_aligned) +------------------------------------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +Use ``__attribute__((assume_aligned([,]))`` on a function +declaration to specify that the return value of the function (which must be a +pointer type) has the specified offset, in bytes, from an address with the +specified alignment. The offset is taken to be zero if omitted. + +.. code-block:: c++ + + // The returned pointer value has 32-byte alignment. + void *a() __attribute__((assume_aligned (32))); + + // The returned pointer value is 4 bytes greater than an address having + // 32-byte alignment. + void *b() __attribute__((assume_aligned (32, 4))); + +Note that this attribute provides information to the compiler regarding a +condition that the code already ensures is true. It does not cause the compiler +to enforce the provided alignment assumption. + + +availability +------------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","","","", "" + +The ``availability`` attribute can be placed on declarations to describe the +lifecycle of that declaration relative to operating system versions. Consider +the function declaration for a hypothetical function ``f``: + +.. code-block:: c++ + + void f(void) __attribute__((availability(macos,introduced=10.4,deprecated=10.6,obsoleted=10.7))); + +The availability attribute states that ``f`` was introduced in Mac OS X 10.4, +deprecated in Mac OS X 10.6, and obsoleted in Mac OS X 10.7. This information +is used by Clang to determine when it is safe to use ``f``: for example, if +Clang is instructed to compile code for Mac OS X 10.5, a call to ``f()`` +succeeds. If Clang is instructed to compile code for Mac OS X 10.6, the call +succeeds but Clang emits a warning specifying that the function is deprecated. +Finally, if Clang is instructed to compile code for Mac OS X 10.7, the call +fails because ``f()`` is no longer available. + +The availability attribute is a comma-separated list starting with the +platform name and then including clauses specifying important milestones in the +declaration's lifetime (in any order) along with additional information. Those +clauses can be: + +introduced=\ *version* + The first version in which this declaration was introduced. + +deprecated=\ *version* + The first version in which this declaration was deprecated, meaning that + users should migrate away from this API. + +obsoleted=\ *version* + The first version in which this declaration was obsoleted, meaning that it + was removed completely and can no longer be used. + +unavailable + This declaration is never available on this platform. + +message=\ *string-literal* + Additional message text that Clang will provide when emitting a warning or + error about use of a deprecated or obsoleted declaration. Useful to direct + users to replacement APIs. + +replacement=\ *string-literal* + Additional message text that Clang will use to provide Fix-It when emitting + a warning about use of a deprecated declaration. The Fix-It will replace + the deprecated declaration with the new declaration specified. + +Multiple availability attributes can be placed on a declaration, which may +correspond to different platforms. Only the availability attribute with the +platform corresponding to the target platform will be used; any others will be +ignored. If no availability attribute specifies availability for the current +target platform, the availability attributes are ignored. Supported platforms +are: + +``ios`` + Apple's iOS operating system. The minimum deployment target is specified by + the ``-mios-version-min=*version*`` or ``-miphoneos-version-min=*version*`` + command-line arguments. + +``macos`` + Apple's Mac OS X operating system. The minimum deployment target is + specified by the ``-mmacosx-version-min=*version*`` command-line argument. + ``macosx`` is supported for backward-compatibility reasons, but it is + deprecated. + +``tvos`` + Apple's tvOS operating system. The minimum deployment target is specified by + the ``-mtvos-version-min=*version*`` command-line argument. + +``watchos`` + Apple's watchOS operating system. The minimum deployment target is specified by + the ``-mwatchos-version-min=*version*`` command-line argument. + +A declaration can typically be used even when deploying back to a platform +version prior to when the declaration was introduced. When this happens, the +declaration is `weakly linked +`_, +as if the ``weak_import`` attribute were added to the declaration. A +weakly-linked declaration may or may not be present a run-time, and a program +can determine whether the declaration is present by checking whether the +address of that declaration is non-NULL. + +The flag ``strict`` disallows using API when deploying back to a +platform version prior to when the declaration was introduced. An +attempt to use such API before its introduction causes a hard error. +Weakly-linking is almost always a better API choice, since it allows +users to query availability at runtime. + +If there are multiple declarations of the same entity, the availability +attributes must either match on a per-platform basis or later +declarations must not have availability attributes for that +platform. For example: + +.. code-block:: c + + void g(void) __attribute__((availability(macos,introduced=10.4))); + void g(void) __attribute__((availability(macos,introduced=10.4))); // okay, matches + void g(void) __attribute__((availability(ios,introduced=4.0))); // okay, adds a new platform + void g(void); // okay, inherits both macos and ios availability from above. + void g(void) __attribute__((availability(macos,introduced=10.5))); // error: mismatch + +When one method overrides another, the overriding method can be more widely available than the overridden method, e.g.,: + +.. code-block:: objc + + @interface A + - (id)method __attribute__((availability(macos,introduced=10.4))); + - (id)method2 __attribute__((availability(macos,introduced=10.4))); + @end + + @interface B : A + - (id)method __attribute__((availability(macos,introduced=10.3))); // okay: method moved into base class later + - (id)method __attribute__((availability(macos,introduced=10.5))); // error: this method was available via the base class in 10.4 + @end + + +_Noreturn +--------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "","","","X", "" + +A function declared as ``_Noreturn`` shall not return to its caller. The +compiler will generate a diagnostic for a function declared as ``_Noreturn`` +that appears to be capable of returning to its caller. + + +noreturn +-------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "","X","","", "" + +A function declared as ``[[noreturn]]`` shall not return to its caller. The +compiler will generate a diagnostic for a function declared as ``[[noreturn]]`` +that appears to be capable of returning to its caller. + + +carries_dependency +------------------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +The ``carries_dependency`` attribute specifies dependency propagation into and +out of functions. + +When specified on a function or Objective-C method, the ``carries_dependency`` +attribute means that the return value carries a dependency out of the function, +so that the implementation need not constrain ordering upon return from that +function. Implementations of the function and its caller may choose to preserve +dependencies instead of emitting memory ordering instructions such as fences. + +Note, this attribute does not change the meaning of the program, but may result +in generation of more efficient code. + + +deprecated (gnu::deprecated) +---------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","X","", "" + +The ``deprecated`` attribute can be applied to a function, a variable, or a +type. This is useful when identifying functions, variables, or types that are +expected to be removed in a future version of a program. + +Consider the function declaration for a hypothetical function ``f``: + +.. code-block:: c++ + + void f(void) __attribute__((deprecated("message", "replacement"))); + +When spelled as `__attribute__((deprecated))`, the deprecated attribute can have +two optional string arguments. The first one is the message to display when +emitting the warning; the second one enables the compiler to provide a Fix-It +to replace the deprecated name with a new name. Otherwise, when spelled as +`[[gnu::deprecated]] or [[deprecated]]`, the attribute can have one optional +string argument which is the message to display when emitting the warning. + + +disable_tail_calls (clang::disable_tail_calls) +---------------------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +The ``disable_tail_calls`` attribute instructs the backend to not perform tail call optimization inside the marked function. + +For example: + + .. code-block:: c + + int callee(int); + + int foo(int a) __attribute__((disable_tail_calls)) { + return callee(a); // This call is not tail-call optimized. + } + +Marking virtual functions as ``disable_tail_calls`` is legal. + + .. code-block:: c++ + + int callee(int); + + class Base { + public: + [[clang::disable_tail_calls]] virtual int foo1() { + return callee(); // This call is not tail-call optimized. + } + }; + + class Derived1 : public Base { + public: + int foo1() override { + return callee(); // This call is tail-call optimized. + } + }; + + +enable_if +--------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","","","", "" + +.. Note:: Some features of this attribute are experimental. The meaning of + multiple enable_if attributes on a single declaration is subject to change in + a future version of clang. Also, the ABI is not standardized and the name + mangling may change in future versions. To avoid that, use asm labels. + +The ``enable_if`` attribute can be placed on function declarations to control +which overload is selected based on the values of the function's arguments. +When combined with the ``overloadable`` attribute, this feature is also +available in C. + +.. code-block:: 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); + isdigit(-10); // results in a compile-time error. + } + +The enable_if attribute takes two arguments, the first is an expression written +in terms of the function parameters, the second is a string explaining why this +overload candidate could not be selected to be displayed in diagnostics. The +expression is part of the function signature for the purposes of determining +whether it is a redeclaration (following the rules used when determining +whether a C++ template specialization is ODR-equivalent), but is not part of +the type. + +The enable_if expression is evaluated as if it were the body of a +bool-returning constexpr function declared with the arguments of the function +it is being applied to, then called with the parameters at the call site. If the +result is false or could not be determined through constant expression +evaluation, then this overload will not be chosen and the provided string may +be used in a diagnostic if the compile fails as a result. + +Because the enable_if expression is an unevaluated context, there are no global +state changes, nor the ability to pass information from the enable_if +expression to the function body. For example, suppose we want calls to +strnlen(strbuf, maxlen) to resolve to strnlen_chk(strbuf, maxlen, size of +strbuf) only if the size of strbuf can be determined: + +.. code-block:: c++ + + __attribute__((always_inline)) + static inline size_t strnlen(const char *s, size_t maxlen) + __attribute__((overloadable)) + __attribute__((enable_if(__builtin_object_size(s, 0) != -1))), + "chosen when the buffer size is known but 'maxlen' is not"))) + { + return strnlen_chk(s, maxlen, __builtin_object_size(s, 0)); + } + +Multiple enable_if attributes may be applied to a single declaration. In this +case, the enable_if expressions are evaluated from left to right in the +following manner. First, the candidates whose enable_if expressions evaluate to +false or cannot be evaluated are discarded. If the remaining candidates do not +share ODR-equivalent enable_if expressions, the overload resolution is +ambiguous. Otherwise, enable_if overload resolution continues with the next +enable_if attribute on the candidates that have not been discarded and have +remaining enable_if attributes. In this way, we pick the most specific +overload out of a number of viable overloads using enable_if. + +.. code-block:: c++ + + 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 + +In this example, a call to f() is always resolved to #2, as the first enable_if +expression is ODR-equivalent for both declarations, but #1 does not have another +enable_if expression to continue evaluating, so the next round of evaluation has +only a single candidate. In a call to g(1, 1), the call is ambiguous even though +#2 has more enable_if attributes, because the first enable_if expressions are +not ODR-equivalent. + +Query for this feature with ``__has_attribute(enable_if)``. + +Note that functions with one or more ``enable_if`` attributes may not have +their address taken, unless all of the conditions specified by said +``enable_if`` are constants that evaluate to ``true``. For example: + +.. code-block:: c + + const int TrueConstant = 1; + const int FalseConstant = 0; + int f(int a) __attribute__((enable_if(a > 0, ""))); + int g(int a) __attribute__((enable_if(a == 0 || a != 0, ""))); + int h(int a) __attribute__((enable_if(1, ""))); + int i(int a) __attribute__((enable_if(TrueConstant, ""))); + int j(int a) __attribute__((enable_if(FalseConstant, ""))); + + void fn() { + int (*ptr)(int); + ptr = &f; // error: 'a > 0' is not always true + ptr = &g; // error: 'a == 0 || a != 0' is not a truthy constant + ptr = &h; // OK: 1 is a truthy constant + ptr = &i; // OK: 'TrueConstant' is a truthy constant + ptr = &j; // error: 'FalseConstant' is a constant, but not truthy + } + +Because ``enable_if`` evaluation happens during overload resolution, +``enable_if`` may give unintuitive results when used with templates, depending +on when overloads are resolved. In the example below, clang will emit a +diagnostic about no viable overloads for ``foo`` in ``bar``, but not in ``baz``: + +.. code-block:: c++ + + double foo(int i) __attribute__((enable_if(i > 0, ""))); + void *foo(int i) __attribute__((enable_if(i <= 0, ""))); + template + auto bar() { return foo(I); } + + template + auto baz() { return foo(T::number); } + + struct WithNumber { constexpr static int number = 1; }; + void callThem() { + bar(); + baz(); + } + +This is because, in ``bar``, ``foo`` is resolved prior to template +instantiation, so the value for ``I`` isn't known (thus, both ``enable_if`` +conditions for ``foo`` fail). However, in ``baz``, ``foo`` is resolved during +template instantiation, so the value for ``T::number`` is known. + + +flatten (gnu::flatten) +---------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +The ``flatten`` attribute causes calls within the attributed function to +be inlined unless it is impossible to do so, for example if the body of the +callee is unavailable or if the callee has the ``noinline`` attribute. + + +format (gnu::format) +-------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +Clang supports the ``format`` attribute, which indicates that the function +accepts a ``printf`` or ``scanf``-like format string and corresponding +arguments or a ``va_list`` that contains these arguments. + +Please see `GCC documentation about format attribute +`_ to find details +about attribute syntax. + +Clang implements two kinds of checks with this attribute. + +#. Clang checks that the function with the ``format`` attribute is called with + a format string that uses format specifiers that are allowed, and that + arguments match the format string. This is the ``-Wformat`` warning, it is + on by default. + +#. Clang checks that the format string argument is a literal string. This is + the ``-Wformat-nonliteral`` warning, it is off by default. + + Clang implements this mostly the same way as GCC, but there is a difference + for functions that accept a ``va_list`` argument (for example, ``vprintf``). + GCC does not emit ``-Wformat-nonliteral`` warning for calls to such + functions. Clang does not warn if the format string comes from a function + parameter, where the function is annotated with a compatible attribute, + otherwise it warns. For example: + + .. code-block:: c + + __attribute__((__format__ (__scanf__, 1, 3))) + void foo(const char* s, char *buf, ...) { + va_list ap; + va_start(ap, buf); + + vprintf(s, ap); // warning: format string is not a string literal + } + + In this case we warn because ``s`` contains a format string for a + ``scanf``-like function, but it is passed to a ``printf``-like function. + + If the attribute is removed, clang still warns, because the format string is + not a string literal. + + Another example: + + .. code-block:: c + + __attribute__((__format__ (__printf__, 1, 3))) + void foo(const char* s, char *buf, ...) { + va_list ap; + va_start(ap, buf); + + vprintf(s, ap); // warning + } + + In this case Clang does not warn because the format string ``s`` and + the corresponding arguments are annotated. If the arguments are + incorrect, the caller of ``foo`` will receive a warning. + + +ifunc (gnu::ifunc) +------------------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +``__attribute__((ifunc("resolver")))`` is used to mark that the address of a declaration should be resolved at runtime by calling a resolver function. + +The symbol name of the resolver function is given in quotes. A function with this name (after mangling) must be defined in the current translation unit; it may be ``static``. The resolver function should take no arguments and return a pointer. + +The ``ifunc`` attribute may only be used on a function declaration. A function declaration with an ``ifunc`` attribute is considered to be a definition of the declared entity. The entity must not have weak linkage; for example, in C++, it cannot be applied to a declaration if a definition at that location would be considered inline. + +Not all targets support this attribute. ELF targets support this attribute when using binutils v2.20.1 or higher and glibc v2.11.1 or higher. Non-ELF targets currently do not support this attribute. + + +internal_linkage (clang::internal_linkage) +------------------------------------------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +The ``internal_linkage`` attribute changes the linkage type of the declaration to internal. +This is similar to C-style ``static``, but can be used on classes and class methods. When applied to a class definition, +this attribute affects all methods and static data members of that class. +This can be used to contain the ABI of a C++ library by excluding unwanted class methods from the export tables. + + +interrupt +--------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","","","", "" + +Clang supports the GNU style ``__attribute__((interrupt("ARGUMENT")))`` attribute on +MIPS targets. This attribute may be attached to a function definition and instructs +the backend to generate appropriate function entry/exit code so that it can be used +directly as an interrupt service routine. + +By default, the compiler will produce a function prologue and epilogue suitable for +an interrupt service routine that handles an External Interrupt Controller (eic) +generated interrupt. This behaviour can be explicitly requested with the "eic" +argument. + +Otherwise, for use with vectored interrupt mode, the argument passed should be +of the form "vector=LEVEL" where LEVEL is one of the following values: +"sw0", "sw1", "hw0", "hw1", "hw2", "hw3", "hw4", "hw5". The compiler will +then set the interrupt mask to the corresponding level which will mask all +interrupts up to and including the argument. + +The semantics are as follows: + +- The prologue is modified so that the Exception Program Counter (EPC) and + Status coprocessor registers are saved to the stack. The interrupt mask is + set so that the function can only be interrupted by a higher priority + interrupt. The epilogue will restore the previous values of EPC and Status. + +- The prologue and epilogue are modified to save and restore all non-kernel + registers as necessary. + +- The FPU is disabled in the prologue, as the floating pointer registers are not + spilled to the stack. + +- The function return sequence is changed to use an exception return instruction. + +- The parameter sets the interrupt mask for the function corresponding to the + interrupt level specified. If no mask is specified the interrupt mask + defaults to "eic". + + +noalias +------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "","","X","", "" + +The ``noalias`` attribute indicates that the only memory accesses inside +function are loads and stores from objects pointed to by its pointer-typed +arguments, with arbitrary offsets. + + +noduplicate (clang::noduplicate) +-------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +The ``noduplicate`` attribute can be placed on function declarations to control +whether function calls to this function can be duplicated or not as a result of +optimizations. This is required for the implementation of functions with +certain special requirements, like the OpenCL "barrier" function, that might +need to be run concurrently by all the threads that are executing in lockstep +on the hardware. For example this attribute applied on the function +"nodupfunc" in the code below avoids that: + +.. code-block:: c + + void nodupfunc() __attribute__((noduplicate)); + // Setting it as a C++11 attribute is also valid + // void nodupfunc() [[clang::noduplicate]]; + void foo(); + void bar(); + + nodupfunc(); + if (a > n) { + foo(); + } else { + bar(); + } + +gets possibly modified by some optimizations into code similar to this: + +.. code-block:: c + + if (a > n) { + nodupfunc(); + foo(); + } else { + nodupfunc(); + bar(); + } + +where the call to "nodupfunc" is duplicated and sunk into the two branches +of the condition. + + +no_sanitize (clang::no_sanitize) +-------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +Use the ``no_sanitize`` attribute on a function declaration to specify +that a particular instrumentation or set of instrumentations should not be +applied to that function. The attribute takes a list of string literals, +which have the same meaning as values accepted by the ``-fno-sanitize=`` +flag. For example, ``__attribute__((no_sanitize("address", "thread")))`` +specifies that AddressSanitizer and ThreadSanitizer should not be applied +to the function. + +See :ref:`Controlling Code Generation ` for a +full list of supported sanitizer flags. + + +no_sanitize_address (no_address_safety_analysis, gnu::no_address_safety_analysis, gnu::no_sanitize_address) +----------------------------------------------------------------------------------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +.. _langext-address_sanitizer: + +Use ``__attribute__((no_sanitize_address))`` on a function declaration to +specify that address safety instrumentation (e.g. AddressSanitizer) should +not be applied to that function. + + +no_sanitize_thread +------------------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +.. _langext-thread_sanitizer: + +Use ``__attribute__((no_sanitize_thread))`` on a function declaration to +specify that checks for data races on plain (non-atomic) memory accesses should +not be inserted by ThreadSanitizer. The function is still instrumented by the +tool to avoid false positives and provide meaningful stack traces. + + +no_sanitize_memory +------------------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +.. _langext-memory_sanitizer: + +Use ``__attribute__((no_sanitize_memory))`` on a function declaration to +specify that checks for uninitialized memory should not be inserted +(e.g. by MemorySanitizer). The function may still be instrumented by the tool +to avoid false positives in other places. + + +no_split_stack (gnu::no_split_stack) +------------------------------------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +The ``no_split_stack`` attribute disables the emission of the split stack +preamble for a particular function. It has no effect if ``-fsplit-stack`` +is not specified. + + +not_tail_called (clang::not_tail_called) +---------------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +The ``not_tail_called`` attribute prevents tail-call optimization on statically bound calls. It has no effect on indirect calls. Virtual functions, objective-c methods, and functions marked as ``always_inline`` cannot be marked as ``not_tail_called``. + +For example, it prevents tail-call optimization in the following case: + + .. code-block:: c + + int __attribute__((not_tail_called)) foo1(int); + + int foo2(int a) { + return foo1(a); // No tail-call optimization on direct calls. + } + +However, it doesn't prevent tail-call optimization in this case: + + .. code-block:: c + + int __attribute__((not_tail_called)) foo1(int); + + int foo2(int a) { + int (*fn)(int) = &foo1; + + // not_tail_called has no effect on an indirect call even if the call can be + // resolved at compile time. + return (*fn)(a); + } + +Marking virtual functions as ``not_tail_called`` is an error: + + .. code-block:: c++ + + class Base { + public: + // not_tail_called on a virtual function is an error. + [[clang::not_tail_called]] virtual int foo1(); + + virtual int foo2(); + + // Non-virtual functions can be marked ``not_tail_called``. + [[clang::not_tail_called]] int foo3(); + }; + + class Derived1 : public Base { + public: + int foo1() override; + + // not_tail_called on a virtual function is an error. + [[clang::not_tail_called]] int foo2() override; + }; + + +#pragma omp declare simd +------------------------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "","","","", "X" + +The `declare simd` construct can be applied to a function to enable the creation +of one or more versions that can process multiple arguments using SIMD +instructions from a single invocation in a SIMD loop. The `declare simd` +directive is a declarative directive. There may be multiple `declare simd` +directives for a function. The use of a `declare simd` construct on a function +enables the creation of SIMD versions of the associated function that can be +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 + + #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 + + simdlen(length) + linear(argument-list[:constant-linear-step]) + aligned(argument-list[:alignment]) + uniform(argument-list) + inbranch + notinbranch + + +#pragma omp declare target +-------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "","","","", "X" + +The `declare target` directive specifies that variables and functions are mapped +to a device for OpenMP offload mechanism. + +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 + + +objc_boxable +------------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","","","", "" + +Structs and unions marked with the ``objc_boxable`` attribute can be used +with the Objective-C boxed expression syntax, ``@(...)``. + +**Usage**: ``__attribute__((objc_boxable))``. This attribute +can only be placed on a declaration of a trivially-copyable struct or union: + +.. code-block:: objc + + struct __attribute__((objc_boxable)) some_struct { + int i; + }; + union __attribute__((objc_boxable)) some_union { + int i; + float f; + }; + typedef struct __attribute__((objc_boxable)) _some_struct some_struct; + + // ... + + some_struct ss; + NSValue *boxed = @(ss); + + +objc_method_family +------------------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","","","", "" + +Many methods in Objective-C have conventional meanings determined by their +selectors. It is sometimes useful to be able to mark a method as having a +particular conventional meaning despite not having the right selector, or as +not having the conventional meaning that its selector would suggest. For these +use cases, we provide an attribute to specifically describe the "method family" +that a method belongs to. + +**Usage**: ``__attribute__((objc_method_family(X)))``, where ``X`` is one of +``none``, ``alloc``, ``copy``, ``init``, ``mutableCopy``, or ``new``. This +attribute can only be placed at the end of a method declaration: + +.. code-block:: objc + + - (NSString *)initMyStringValue __attribute__((objc_method_family(none))); + +Users who do not wish to change the conventional meaning of a method, and who +merely want to document its non-standard retain and release semantics, should +use the retaining behavior attributes (``ns_returns_retained``, +``ns_returns_not_retained``, etc). + +Query for this feature with ``__has_attribute(objc_method_family)``. + + +objc_requires_super +------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","","","", "" + +Some Objective-C classes allow a subclass to override a particular method in a +parent class but expect that the overriding method also calls the overridden +method in the parent class. For these cases, we provide an attribute to +designate that a method requires a "call to ``super``" in the overriding +method in the subclass. + +**Usage**: ``__attribute__((objc_requires_super))``. This attribute can only +be placed at the end of a method declaration: + +.. code-block:: objc + + - (void)foo __attribute__((objc_requires_super)); + +This attribute can only be applied the method declarations within a class, and +not a protocol. Currently this attribute does not enforce any placement of +where the call occurs in the overriding method (such as in the case of +``-dealloc`` where the call must appear at the end). It checks only that it +exists. + +Note that on both OS X and iOS that the Foundation framework provides a +convenience macro ``NS_REQUIRES_SUPER`` that provides syntactic sugar for this +attribute: + +.. code-block:: objc + + - (void)foo NS_REQUIRES_SUPER; + +This macro is conditionally defined depending on the compiler's support for +this attribute. If the compiler does not support the attribute the macro +expands to nothing. + +Operationally, when a method has this annotation the compiler will warn if the +implementation of an override in a subclass does not call super. For example: + +.. code-block:: objc + + warning: method possibly missing a [super AnnotMeth] call + - (void) AnnotMeth{}; + ^ + + +objc_runtime_name +----------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","","","", "" + +By default, the Objective-C interface or protocol identifier is used +in the metadata name for that object. The `objc_runtime_name` +attribute allows annotated interfaces or protocols to use the +specified string argument in the object's metadata name instead of the +default name. + +**Usage**: ``__attribute__((objc_runtime_name("MyLocalName")))``. This attribute +can only be placed before an @protocol or @interface declaration: + +.. code-block:: objc + + __attribute__((objc_runtime_name("MyLocalName"))) + @interface Message + @end + + +objc_runtime_visible +-------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","","","", "" + +This attribute specifies that the Objective-C class to which it applies is visible to the Objective-C runtime but not to the linker. Classes annotated with this attribute cannot be subclassed and cannot have categories defined for them. + + +optnone (clang::optnone) +------------------------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +The ``optnone`` attribute suppresses essentially all optimizations +on a function or method, regardless of the optimization level applied to +the compilation unit as a whole. This is particularly useful when you +need to debug a particular function, but it is infeasible to build the +entire application without optimization. Avoiding optimization on the +specified function can improve the quality of the debugging information +for that function. + +This attribute is incompatible with the ``always_inline`` and ``minsize`` +attributes. + + +overloadable +------------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","","","", "" + +Clang provides support for C++ function overloading in C. Function overloading +in C is introduced using the ``overloadable`` attribute. For example, one +might provide several overloaded versions of a ``tgsin`` function that invokes +the appropriate standard function computing the sine of a value with ``float``, +``double``, or ``long double`` precision: + +.. code-block:: c + + #include + float __attribute__((overloadable)) tgsin(float x) { return sinf(x); } + double __attribute__((overloadable)) tgsin(double x) { return sin(x); } + long double __attribute__((overloadable)) tgsin(long double x) { return sinl(x); } + +Given these declarations, one can call ``tgsin`` with a ``float`` value to +receive a ``float`` result, with a ``double`` to receive a ``double`` result, +etc. Function overloading in C follows the rules of C++ function overloading +to pick the best overload given the call arguments, with a few C-specific +semantics: + +* Conversion from ``float`` or ``double`` to ``long double`` is ranked as a + floating-point promotion (per C99) rather than as a floating-point conversion + (as in C++). + +* A conversion from a pointer of type ``T*`` to a pointer of type ``U*`` is + considered a pointer conversion (with conversion rank) if ``T`` and ``U`` are + compatible types. + +* A conversion from type ``T`` to a value of type ``U`` is permitted if ``T`` + and ``U`` are compatible types. This conversion is given "conversion" rank. + +The declaration of ``overloadable`` functions is restricted to function +declarations and definitions. Most importantly, if any function with a given +name is given the ``overloadable`` attribute, then all function declarations +and definitions with that name (and in that scope) must have the +``overloadable`` attribute. This rule even applies to redeclarations of +functions whose original declaration had the ``overloadable`` attribute, e.g., + +.. code-block:: c + + int f(int) __attribute__((overloadable)); + float f(float); // error: declaration of "f" must have the "overloadable" attribute + + int g(int) __attribute__((overloadable)); + int g(int) { } // error: redeclaration of "g" must also have the "overloadable" attribute + +Functions marked ``overloadable`` must have prototypes. Therefore, the +following code is ill-formed: + +.. code-block:: c + + int h() __attribute__((overloadable)); // error: h does not have a prototype + +However, ``overloadable`` functions are allowed to use a ellipsis even if there +are no named parameters (as is permitted in C++). This feature is particularly +useful when combined with the ``unavailable`` attribute: + +.. code-block:: c++ + + void honeypot(...) __attribute__((overloadable, unavailable)); // calling me is an error + +Functions declared with the ``overloadable`` attribute have their names mangled +according to the same rules as C++ function names. For example, the three +``tgsin`` functions in our motivating example get the mangled names +``_Z5tgsinf``, ``_Z5tgsind``, and ``_Z5tgsine``, respectively. There are two +caveats to this use of name mangling: + +* Future versions of Clang may change the name mangling of functions overloaded + in C, so you should not depend on an specific mangling. To be completely + safe, we strongly urge the use of ``static inline`` with ``overloadable`` + functions. + +* The ``overloadable`` attribute has almost no meaning when used in C++, + because names will already be mangled and functions are already overloadable. + However, when an ``overloadable`` function occurs within an ``extern "C"`` + linkage specification, it's name *will* be mangled in the same way as it + would in C. + +Query for this feature with ``__has_extension(attribute_overloadable)``. + + +release_capability (release_shared_capability, clang::release_capability, clang::release_shared_capability) +----------------------------------------------------------------------------------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +Marks a function as releasing a capability. + + +kernel +------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","","","", "" + +``__attribute__((kernel))`` is used to mark a ``kernel`` function in +RenderScript. + +In RenderScript, ``kernel`` functions are used to express data-parallel +computations. The RenderScript runtime efficiently parallelizes ``kernel`` +functions to run on computational resources such as multi-core CPUs and GPUs. +See the RenderScript_ documentation for more information. + +.. _RenderScript: https://developer.android.com/guide/topics/renderscript/compute.html + + +target (gnu::target) +-------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +Clang supports the GNU style ``__attribute__((target("OPTIONS")))`` attribute. +This attribute may be attached to a function definition and instructs +the backend to use different code generation options than were passed on the +command line. + +The current set of options correspond to the existing "subtarget features" for +the target with or without a "-mno-" in front corresponding to the absence +of the feature, as well as ``arch="CPU"`` which will change the default "CPU" +for the function. + +Example "subtarget features" from the x86 backend include: "mmx", "sse", "sse4.2", +"avx", "xop" and largely correspond to the machine specific options handled by +the front end. + + +try_acquire_capability (try_acquire_shared_capability, clang::try_acquire_capability, clang::try_acquire_shared_capability) +--------------------------------------------------------------------------------------------------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +Marks a function that attempts to acquire a capability. This function may fail to +actually acquire the capability; they accept a Boolean value determining +whether acquiring the capability means success (true), or failing to acquire +the capability means success (false). + + +nodiscard, warn_unused_result, clang::warn_unused_result, gnu::warn_unused_result +--------------------------------------------------------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +Clang supports the ability to diagnose when the results of a function call +expression are discarded under suspicious circumstances. A diagnostic is +generated when a function or its return type is marked with ``[[nodiscard]]`` +(or ``__attribute__((warn_unused_result))``) and the function call appears as a +potentially-evaluated discarded-value expression that is not explicitly cast to +`void`. + +.. code-block: c++ + struct [[nodiscard]] error_info { /*...*/ }; + error_info enable_missile_safety_mode(); + + void launch_missiles(); + void test_missiles() { + enable_missile_safety_mode(); // diagnoses + launch_missiles(); + } + error_info &foo(); + void f() { foo(); } // Does not diagnose, error_info is a reference. + + +xray_always_instrument (clang::xray_always_instrument), xray_never_instrument (clang::xray_never_instrument) +------------------------------------------------------------------------------------------------------------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +``__attribute__((xray_always_instrument))`` or ``[[clang::xray_always_instrument]]`` is used to mark member functions (in C++), methods (in Objective C), and free functions (in C, C++, and Objective C) to be instrumented with XRay. This will cause the function to always have space at the beginning and exit points to allow for runtime patching. + +Conversely, ``__attribute__((xray_never_instrument))`` or ``[[clang::xray_never_instrument]]`` will inhibit the insertion of these instrumentation points. + +If a function has neither of these attributes, they become subject to the XRay heuristics used to determine whether a function should be instrumented or otherwise. + + +Variable Attributes +=================== + + +dllexport (gnu::dllexport) +-------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","X","", "" + +The ``__declspec(dllexport)`` attribute declares a variable, function, or +Objective-C interface to be exported from the module. It is available under the +``-fdeclspec`` flag for compatibility with various compilers. The primary use +is for COFF object files which explicitly specify what interfaces are available +for external use. See the dllexport_ documentation on MSDN for more +information. + +.. _dllexport: https://msdn.microsoft.com/en-us/library/3y1sfaz2.aspx + + +dllimport (gnu::dllimport) +-------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","X","", "" + +The ``__declspec(dllimport)`` attribute declares a variable, function, or +Objective-C interface to be imported from an external module. It is available +under the ``-fdeclspec`` flag for compatibility with various compilers. The +primary use is for COFF object files which explicitly specify what interfaces +are imported from external modules. See the dllimport_ documentation on MSDN +for more information. + +.. _dllimport: https://msdn.microsoft.com/en-us/library/3y1sfaz2.aspx + + +init_seg +-------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "","","","", "X" + +The attribute applied by ``pragma init_seg()`` controls the section into +which global initialization function pointers are emitted. It is only +available with ``-fms-extensions``. Typically, this function pointer is +emitted into ``.CRT$XCU`` on Windows. The user can change the order of +initialization by using a different section name with the same +``.CRT$XC`` prefix and a suffix that sorts lexicographically before or +after the standard ``.CRT$XCU`` sections. See the init_seg_ +documentation on MSDN for more information. + +.. _init_seg: http://msdn.microsoft.com/en-us/library/7977wcck(v=vs.110).aspx + + +nodebug (gnu::nodebug) +---------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +The ``nodebug`` attribute allows you to suppress debugging information for a +function or method, or for a variable that is not a parameter or a non-static +data member. + + +nosvm +----- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","","","", "" + +OpenCL 2.0 supports the optional ``__attribute__((nosvm))`` qualifier for +pointer variable. It informs the compiler that the pointer does not refer +to a shared virtual memory region. See OpenCL v2.0 s6.7.2 for details. + +Since it is not widely used and has been removed from OpenCL 2.1, it is ignored +by Clang. + + +pass_object_size +---------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","","","", "" + +.. Note:: The mangling of functions with parameters that are annotated with + ``pass_object_size`` is subject to change. You can get around this by + using ``__asm__("foo")`` to explicitly name your functions, thus preserving + your ABI; also, non-overloadable C functions with ``pass_object_size`` are + not mangled. + +The ``pass_object_size(Type)`` attribute can be placed on function parameters to +instruct clang to call ``__builtin_object_size(param, Type)`` at each callsite +of said function, and implicitly pass the result of this call in as an invisible +argument of type ``size_t`` directly after the parameter annotated with +``pass_object_size``. Clang will also replace any calls to +``__builtin_object_size(param, Type)`` in the function by said implicit +parameter. + +Example usage: + +.. code-block:: c + + int bzero1(char *const p __attribute__((pass_object_size(0)))) + __attribute__((noinline)) { + int i = 0; + for (/**/; i < (int)__builtin_object_size(p, 0); ++i) { + p[i] = 0; + } + return i; + } + + int main() { + char chars[100]; + int n = bzero1(&chars[0]); + assert(n == sizeof(chars)); + return 0; + } + +If successfully evaluating ``__builtin_object_size(param, Type)`` at the +callsite is not possible, then the "failed" value is passed in. So, using the +definition of ``bzero1`` from above, the following code would exit cleanly: + +.. code-block:: c + + int main2(int argc, char *argv[]) { + int n = bzero1(argv); + assert(n == -1); + return 0; + } + +``pass_object_size`` plays a part in overload resolution. If two overload +candidates are otherwise equally good, then the overload with one or more +parameters with ``pass_object_size`` is preferred. This implies that the choice +between two identical overloads both with ``pass_object_size`` on one or more +parameters will always be ambiguous; for this reason, having two such overloads +is illegal. For example: + +.. code-block:: c++ + + #define PS(N) __attribute__((pass_object_size(N))) + // OK + void Foo(char *a, char *b); // Overload A + // OK -- overload A has no parameters with pass_object_size. + void Foo(char *a PS(0), char *b PS(0)); // Overload B + // Error -- Same signature (sans pass_object_size) as overload B, and both + // overloads have one or more parameters with the pass_object_size attribute. + void Foo(void *a PS(0), void *b); + + // OK + void Bar(void *a PS(0)); // Overload C + // OK + void Bar(char *c PS(1)); // Overload D + + void main() { + char known[10], *unknown; + Foo(unknown, unknown); // Calls overload B + Foo(known, unknown); // Calls overload B + Foo(unknown, known); // Calls overload B + Foo(known, known); // Calls overload B + + Bar(known); // Calls overload D + Bar(unknown); // Calls overload D + } + +Currently, ``pass_object_size`` is a bit restricted in terms of its usage: + +* Only one use of ``pass_object_size`` is allowed per parameter. + +* It is an error to take the address of a function with ``pass_object_size`` on + any of its parameters. If you wish to do this, you can create an overload + without ``pass_object_size`` on any parameters. + +* It is an error to apply the ``pass_object_size`` attribute to parameters that + are not pointers. Additionally, any parameter that ``pass_object_size`` is + applied to must be marked ``const`` at its function's definition. + + +section (gnu::section, __declspec(allocate)) +-------------------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","X","", "" + +The ``section`` attribute allows you to specify a specific section a +global variable or function should be in after translation. + + +swiftcall (gnu::swiftcall) +-------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +The ``swiftcall`` attribute indicates that a function should be called +using the Swift calling convention for a function or function pointer. + +The lowering for the Swift calling convention, as described by the Swift +ABI documentation, occurs in multiple phases. The first, "high-level" +phase breaks down the formal parameters and results into innately direct +and indirect components, adds implicit paraameters for the generic +signature, and assigns the context and error ABI treatments to parameters +where applicable. The second phase breaks down the direct parameters +and results from the first phase and assigns them to registers or the +stack. The ``swiftcall`` convention only handles this second phase of +lowering; the C function type must accurately reflect the results +of the first phase, as follows: + +- Results classified as indirect by high-level lowering should be + represented as parameters with the ``swift_indirect_result`` attribute. + +- Results classified as direct by high-level lowering should be represented + as follows: + + - First, remove any empty direct results. + + - If there are no direct results, the C result type should be ``void``. + + - If there is one direct result, the C result type should be a type with + the exact layout of that result type. + + - If there are a multiple direct results, the C result type should be + a struct type with the exact layout of a tuple of those results. + +- Parameters classified as indirect by high-level lowering should be + represented as parameters of pointer type. + +- Parameters classified as direct by high-level lowering should be + omitted if they are empty types; otherwise, they should be represented + as a parameter type with a layout exactly matching the layout of the + Swift parameter type. + +- The context parameter, if present, should be represented as a trailing + parameter with the ``swift_context`` attribute. + +- The error result parameter, if present, should be represented as a + trailing parameter (always following a context parameter) with the + ``swift_error_result`` attribute. + +``swiftcall`` does not support variadic arguments or unprototyped functions. + +The parameter ABI treatment attributes are aspects of the function type. +A function type which which applies an ABI treatment attribute to a +parameter is a different type from an otherwise-identical function type +that does not. A single parameter may not have multiple ABI treatment +attributes. + +Support for this feature is target-dependent, although it should be +supported on every target that Swift supports. Query for this support +with ``__has_attribute(swiftcall)``. This implies support for the +``swift_context``, ``swift_error_result``, and ``swift_indirect_result`` +attributes. + + +swift_context (gnu::swift_context) +---------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +The ``swift_context`` attribute marks a parameter of a ``swiftcall`` +function as having the special context-parameter ABI treatment. + +This treatment generally passes the context value in a special register +which is normally callee-preserved. + +A ``swift_context`` parameter must either be the last parameter or must be +followed by a ``swift_error_result`` parameter (which itself must always be +the last parameter). + +A context parameter must have pointer or reference type. + + +swift_error_result (gnu::swift_error_result) +-------------------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +The ``swift_error_result`` attribute marks a parameter of a ``swiftcall`` +function as having the special error-result ABI treatment. + +This treatment generally passes the underlying error value in and out of +the function through a special register which is normally callee-preserved. +This is modeled in C by pretending that the register is addressable memory: + +- The caller appears to pass the address of a variable of pointer type. + The current value of this variable is copied into the register before + the call; if the call returns normally, the value is copied back into the + variable. + +- The callee appears to receive the address of a variable. This address + is actually a hidden location in its own stack, initialized with the + value of the register upon entry. When the function returns normally, + the value in that hidden location is written back to the register. + +A ``swift_error_result`` parameter must be the last parameter, and it must be +preceded by a ``swift_context`` parameter. + +A ``swift_error_result`` parameter must have type ``T**`` or ``T*&`` for some +type T. Note that no qualifiers are permitted on the intermediate level. + +It is undefined behavior if the caller does not pass a pointer or +reference to a valid object. + +The standard convention is that the error value itself (that is, the +value stored in the apparent argument) will be null upon function entry, +but this is not enforced by the ABI. + + +swift_indirect_result (gnu::swift_indirect_result) +-------------------------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +The ``swift_indirect_result`` attribute marks a parameter of a ``swiftcall`` +function as having the special indirect-result ABI treatmenet. + +This treatment gives the parameter the target's normal indirect-result +ABI treatment, which may involve passing it differently from an ordinary +parameter. However, only the first indirect result will receive this +treatment. Furthermore, low-level lowering may decide that a direct result +must be returned indirectly; if so, this will take priority over the +``swift_indirect_result`` parameters. + +A ``swift_indirect_result`` parameter must either be the first parameter or +follow another ``swift_indirect_result`` parameter. + +A ``swift_indirect_result`` parameter must have type ``T*`` or ``T&`` for +some object type ``T``. If ``T`` is a complete type at the point of +definition of a function, it is undefined behavior if the argument +value does not point to storage of adequate size and alignment for a +value of type ``T``. + +Making indirect results explicit in the signature allows C functions to +directly construct objects into them without relying on language +optimizations like C++'s named return value optimization (NRVO). + + +tls_model (gnu::tls_model) +-------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +The ``tls_model`` attribute allows you to specify which thread-local storage +model to use. It accepts the following strings: + +* global-dynamic +* local-dynamic +* initial-exec +* local-exec + +TLS models are mutually exclusive. + + +thread +------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "","","X","", "" + +The ``__declspec(thread)`` attribute declares a variable with thread local +storage. It is available under the ``-fms-extensions`` flag for MSVC +compatibility. See the documentation for `__declspec(thread)`_ on MSDN. + +.. _`__declspec(thread)`: http://msdn.microsoft.com/en-us/library/9w1sdazb.aspx + +In Clang, ``__declspec(thread)`` is generally equivalent in functionality to the +GNU ``__thread`` keyword. The variable must not have a destructor and must have +a constant initializer, if any. The attribute only applies to variables +declared with static storage duration, such as globals, class static data +members, and static locals. + + +maybe_unused, unused, gnu::unused +--------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +When passing the ``-Wunused`` flag to Clang, entities that are unused by the +program may be diagnosed. The ``[[maybe_unused]]`` (or +``__attribute__((unused))``) attribute can be used to silence such diagnostics +when the entity cannot be removed. For instance, a local variable may exist +solely for use in an ``assert()`` statement, which makes the local variable +unused when ``NDEBUG`` is defined. + +The attribute may be applied to the declaration of a class, a typedef, a +variable, a function or method, a function parameter, an enumeration, an +enumerator, a non-static data member, or a label. + +.. code-block: c++ + #include + + [[maybe_unused]] void f([[maybe_unused]] bool thing1, + [[maybe_unused]] bool thing2) { + [[maybe_unused]] bool b = thing1 && thing2; + assert(b); + } + + +Type Attributes +=============== + + +align_value +----------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","","","", "" + +The align_value attribute can be added to the typedef of a pointer type or the +declaration of a variable of pointer or reference type. It specifies that the +pointer will point to, or the reference will bind to, only objects with at +least the provided alignment. This alignment value must be some positive power +of 2. + + .. code-block:: c + + typedef double * aligned_double_ptr __attribute__((align_value(64))); + void foo(double & x __attribute__((align_value(128)), + aligned_double_ptr y) { ... } + +If the pointer value does not have the specified alignment at runtime, the +behavior of the program is undefined. + + +empty_bases +----------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "","","X","", "" + +The empty_bases attribute permits the compiler to utilize the +empty-base-optimization more frequently. +This attribute only applies to struct, class, and union types. +It is only supported when using the Microsoft C++ ABI. + + +flag_enum +--------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","","","", "" + +This attribute can be added to an enumerator to signal to the compiler that it +is intended to be used as a flag type. This will cause the compiler to assume +that the range of the type includes all of the values that you can get by +manipulating bits of the enumerator when issuing warnings. + + +lto_visibility_public (clang::lto_visibility_public) +---------------------------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "","X","","", "" + +See :doc:`LTOVisibility`. + + +layout_version +-------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "","","X","", "" + +The layout_version attribute requests that the compiler utilize the class +layout rules of a particular compiler version. +This attribute only applies to struct, class, and union types. +It is only supported when using the Microsoft C++ ABI. + + +__single_inhertiance, __multiple_inheritance, __virtual_inheritance +------------------------------------------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "","","","X", "" + +This collection of keywords is enabled under ``-fms-extensions`` and controls +the pointer-to-member representation used on ``*-*-win32`` targets. + +The ``*-*-win32`` targets utilize a pointer-to-member representation which +varies in size and alignment depending on the definition of the underlying +class. + +However, this is problematic when a forward declaration is only available and +no definition has been made yet. In such cases, Clang is forced to utilize the +most general representation that is available to it. + +These keywords make it possible to use a pointer-to-member representation other +than the most general one regardless of whether or not the definition will ever +be present in the current translation unit. + +This family of keywords belong between the ``class-key`` and ``class-name``: + +.. code-block:: c++ + + struct __single_inheritance S; + int S::*i; + struct S {}; + +This keyword can be applied to class templates but only has an effect when used +on full specializations: + +.. code-block:: c++ + + template struct __single_inheritance A; // warning: inheritance model ignored on primary template + template struct __multiple_inheritance A; // warning: inheritance model ignored on partial specialization + template <> struct __single_inheritance A; + +Note that choosing an inheritance model less general than strictly necessary is +an error: + +.. code-block:: c++ + + struct __multiple_inheritance S; // error: inheritance model does not match definition + int S::*i; + struct S {}; + + +novtable +-------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "","","X","", "" + +This attribute can be added to a class declaration or definition to signal to +the compiler that constructors and destructors will not reference the virtual +function table. It is only supported when using the Microsoft C++ ABI. + + +Statement Attributes +==================== + + +fallthrough, clang::fallthrough +------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "","X","","", "" + +The ``fallthrough`` (or ``clang::fallthrough``) attribute is used +to annotate intentional fall-through +between switch labels. It can only be applied to a null statement placed at a +point of execution between any statement and the next switch label. It is +common to mark these places with a specific comment, but this attribute is +meant to replace comments with a more strict annotation, which can be checked +by the compiler. This attribute doesn't change semantics of the code and can +be used wherever an intended fall-through occurs. It is designed to mimic +control-flow statements like ``break;``, so it can be placed in most places +where ``break;`` can, but only if there are no statements on the execution path +between it and the next switch label. + +By default, Clang does not warn on unannotated fallthrough from one ``switch`` +case to another. Diagnostics on fallthrough without a corresponding annotation +can be enabled with the ``-Wimplicit-fallthrough`` argument. + +Here is an example: + +.. code-block:: c++ + + // compile with -Wimplicit-fallthrough + switch (n) { + case 22: + case 33: // no warning: no statements between case labels + f(); + case 44: // warning: unannotated fall-through + g(); + [[clang::fallthrough]]; + case 55: // no warning + if (x) { + h(); + break; + } + else { + i(); + [[clang::fallthrough]]; + } + case 66: // no warning + p(); + [[clang::fallthrough]]; // warning: fallthrough annotation does not + // directly precede case label + q(); + case 77: // warning: unannotated fall-through + r(); + } + + +#pragma clang loop +------------------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "","","","", "X" + +The ``#pragma clang loop`` directive allows loop optimization hints to be +specified for the subsequent loop. The directive allows vectorization, +interleaving, and unrolling to be enabled or disabled. Vector width as well +as interleave and unrolling count can be manually specified. See +`language extensions +`_ +for details. + + +#pragma unroll, #pragma nounroll +-------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "","","","", "X" + +Loop unrolling optimization hints can be specified with ``#pragma unroll`` and +``#pragma nounroll``. The pragma is placed immediately before a for, while, +do-while, or c++11 range-based for loop. + +Specifying ``#pragma unroll`` without a parameter directs the loop unroller to +attempt to fully unroll the loop if the trip count is known at compile time and +attempt to partially unroll the loop if the trip count is not known at compile +time: + +.. code-block:: c++ + + #pragma unroll + for (...) { + ... + } + +Specifying the optional parameter, ``#pragma unroll _value_``, directs the +unroller to unroll the loop ``_value_`` times. The parameter may optionally be +enclosed in parentheses: + +.. code-block:: c++ + + #pragma unroll 16 + for (...) { + ... + } + + #pragma unroll(16) + for (...) { + ... + } + +Specifying ``#pragma nounroll`` indicates that the loop should not be unrolled: + +.. code-block:: c++ + + #pragma nounroll + for (...) { + ... + } + +``#pragma unroll`` and ``#pragma unroll _value_`` have identical semantics to +``#pragma clang loop unroll(full)`` and +``#pragma clang loop unroll_count(_value_)`` respectively. ``#pragma nounroll`` +is equivalent to ``#pragma clang loop unroll(disable)``. See +`language extensions +`_ +for further details including limitations of the unroll hints. + + +__read_only, __write_only, __read_write (read_only, write_only, read_write) +--------------------------------------------------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "","","","X", "" + +The access qualifiers must be used with image object arguments or pipe arguments +to declare if they are being read or written by a kernel or function. + +The read_only/__read_only, write_only/__write_only and read_write/__read_write +names are reserved for use as access qualifiers and shall not be used otherwise. + +.. code-block:: c + + kernel void + foo (read_only image2d_t imageA, + write_only image2d_t imageB) { + ... + } + +In the above example imageA is a read-only 2D image object, and imageB is a +write-only 2D image object. + +The read_write (or __read_write) qualifier can not be used with pipe. + +More details can be found in the OpenCL C language Spec v2.0, Section 6.6. + + +__attribute__((opencl_unroll_hint)) +----------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","","","", "" + +The opencl_unroll_hint attribute qualifier can be used to specify that a loop +(for, while and do loops) can be unrolled. This attribute qualifier can be +used to specify full unrolling or partial unrolling by a specified amount. +This is a compiler hint and the compiler may ignore this directive. See +`OpenCL v2.0 `_ +s6.11.5 for details. + + +AMD GPU Register Attributes +=========================== +Clang supports attributes for controlling register usage on AMD GPU +targets. These attributes may be attached to a kernel function +definition and is an optimization hint to the backend for the maximum +number of registers to use. This is useful in cases where register +limited occupancy is known to be an important factor for the +performance for the kernel. + +The semantics are as follows: + +- The backend will attempt to limit the number of used registers to + the specified value, but the exact number used is not + guaranteed. The number used may be rounded up to satisfy the + allocation requirements or ABI constraints of the subtarget. For + example, on Southern Islands VGPRs may only be allocated in + increments of 4, so requesting a limit of 39 VGPRs will really + attempt to use up to 40. Requesting more registers than the + subtarget supports will truncate to the maximum allowed. The backend + may also use fewer registers than requested whenever possible. + +- 0 implies the default no limit on register usage. + +- Ignored on older VLIW subtargets which did not have separate scalar + and vector registers, R600 through Northern Islands. + +amdgpu_num_sgpr +--------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","","","", "" + +Clang supports the +``__attribute__((amdgpu_num_sgpr()))`` attribute on AMD +Southern Islands GPUs and later for controlling the number of scalar +registers. A typical value would be between 8 and 104 in increments of +8. + +Due to common instruction constraints, an additional 2-4 SGPRs are +typically required for internal use depending on features used. This +value is a hint for the total number of SGPRs to use, and not the +number of user SGPRs, so no special consideration needs to be given +for these. + + +amdgpu_num_vgpr +--------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","","","", "" + +Clang supports the +``__attribute__((amdgpu_num_vgpr()))`` attribute on AMD +Southern Islands GPUs and later for controlling the number of vector +registers. A typical value would be between 4 and 256 in increments +of 4. + + +Calling Conventions +=================== +Clang supports several different calling conventions, depending on the target +platform and architecture. The calling convention used for a function determines +how parameters are passed, how results are returned to the caller, and other +low-level details of calling a function. + +fastcall (gnu::fastcall, __fastcall, _fastcall) +----------------------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","X", "" + +On 32-bit x86 targets, this attribute changes the calling convention of a +function to use ECX and EDX as register parameters and clear parameters off of +the stack on return. This convention does not support variadic calls or +unprototyped functions in C, and has no effect on x86_64 targets. This calling +convention is supported primarily for compatibility with existing code. Users +seeking register parameters should use the ``regparm`` attribute, which does +not require callee-cleanup. See the documentation for `__fastcall`_ on MSDN. + +.. _`__fastcall`: http://msdn.microsoft.com/en-us/library/6xa169sk.aspx + + +ms_abi (gnu::ms_abi) +-------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +On non-Windows x86_64 targets, this attribute changes the calling convention of +a function to match the default convention used on Windows x86_64. This +attribute has no effect on Windows targets or non-x86_64 targets. + + +pcs (gnu::pcs) +-------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +On ARM targets, this attribute can be used to select calling conventions +similar to ``stdcall`` on x86. Valid parameter values are "aapcs" and +"aapcs-vfp". + + +preserve_all +------------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","","","", "" + +On X86-64 and AArch64 targets, this attribute changes the calling convention of +a function. The ``preserve_all`` calling convention attempts to make the code +in the caller even less intrusive than the ``preserve_most`` calling convention. +This calling convention also behaves identical to the ``C`` calling convention +on how arguments and return values are passed, but it uses a different set of +caller/callee-saved registers. This removes the burden of saving and +recovering a large register set before and after the call in the caller. If +the arguments are passed in callee-saved registers, then they will be +preserved by the callee across the call. This doesn't apply for values +returned in callee-saved registers. + +- On X86-64 the callee preserves all general purpose registers, except for + R11. R11 can be used as a scratch register. Furthermore it also preserves + all floating-point registers (XMMs/YMMs). + +The idea behind this convention is to support calls to runtime functions +that don't need to call out to any other functions. + +This calling convention, like the ``preserve_most`` calling convention, will be +used by a future version of the Objective-C runtime and should be considered +experimental at this time. + + +preserve_most +------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","","","", "" + +On X86-64 and AArch64 targets, this attribute changes the calling convention of +a function. The ``preserve_most`` calling convention attempts to make the code +in the caller as unintrusive as possible. This convention behaves identically +to the ``C`` calling convention on how arguments and return values are passed, +but it uses a different set of caller/callee-saved registers. This alleviates +the burden of saving and recovering a large register set before and after the +call in the caller. If the arguments are passed in callee-saved registers, +then they will be preserved by the callee across the call. This doesn't +apply for values returned in callee-saved registers. + +- On X86-64 the callee preserves all general purpose registers, except for + R11. R11 can be used as a scratch register. Floating-point registers + (XMMs/YMMs) are not preserved and need to be saved by the caller. + +The idea behind this convention is to support calls to runtime functions +that have a hot path and a cold path. The hot path is usually a small piece +of code that doesn't use many registers. The cold path might need to call out to +another function and therefore only needs to preserve the caller-saved +registers, which haven't already been saved by the caller. The +`preserve_most` calling convention is very similar to the ``cold`` calling +convention in terms of caller/callee-saved registers, but they are used for +different types of function calls. ``coldcc`` is for function calls that are +rarely executed, whereas `preserve_most` function calls are intended to be +on the hot path and definitely executed a lot. Furthermore ``preserve_most`` +doesn't prevent the inliner from inlining the function call. + +This calling convention will be used by a future version of the Objective-C +runtime and should therefore still be considered experimental at this time. +Although this convention was created to optimize certain runtime calls to +the Objective-C runtime, it is not limited to this runtime and might be used +by other runtimes in the future too. The current implementation only +supports X86-64 and AArch64, but the intention is to support more architectures +in the future. + + +regparm (gnu::regparm) +---------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +On 32-bit x86 targets, the regparm attribute causes the compiler to pass +the first three integer parameters in EAX, EDX, and ECX instead of on the +stack. This attribute has no effect on variadic functions, and all parameters +are passed via the stack as normal. + + +stdcall (gnu::stdcall, __stdcall, _stdcall) +------------------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","X", "" + +On 32-bit x86 targets, this attribute changes the calling convention of a +function to clear parameters off of the stack on return. This convention does +not support variadic calls or unprototyped functions in C, and has no effect on +x86_64 targets. This calling convention is used widely by the Windows API and +COM applications. See the documentation for `__stdcall`_ on MSDN. + +.. _`__stdcall`: http://msdn.microsoft.com/en-us/library/zxk0tw93.aspx + + +thiscall (gnu::thiscall, __thiscall, _thiscall) +----------------------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","X", "" + +On 32-bit x86 targets, this attribute changes the calling convention of a +function to use ECX for the first parameter (typically the implicit ``this`` +parameter of C++ methods) and clear parameters off of the stack on return. This +convention does not support variadic calls or unprototyped functions in C, and +has no effect on x86_64 targets. See the documentation for `__thiscall`_ on +MSDN. + +.. _`__thiscall`: http://msdn.microsoft.com/en-us/library/ek8tkfbw.aspx + + +vectorcall (__vectorcall, _vectorcall) +-------------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","","","X", "" + +On 32-bit x86 *and* x86_64 targets, this attribute changes the calling +convention of a function to pass vector parameters in SSE registers. + +On 32-bit x86 targets, this calling convention is similar to ``__fastcall``. +The first two integer parameters are passed in ECX and EDX. Subsequent integer +parameters are passed in memory, and callee clears the stack. On x86_64 +targets, the callee does *not* clear the stack, and integer parameters are +passed in RCX, RDX, R8, and R9 as is done for the default Windows x64 calling +convention. + +On both 32-bit x86 and x86_64 targets, vector and floating point arguments are +passed in XMM0-XMM5. Homogenous vector aggregates of up to four elements are +passed in sequential SSE registers if enough are available. If AVX is enabled, +256 bit vectors are passed in YMM0-YMM5. Any vector or aggregate type that +cannot be passed in registers for any reason is passed by reference, which +allows the caller to align the parameter memory. + +See the documentation for `__vectorcall`_ on MSDN for more details. + +.. _`__vectorcall`: http://msdn.microsoft.com/en-us/library/dn375768.aspx + + +Consumed Annotation Checking +============================ +Clang supports additional attributes for checking basic resource management +properties, specifically for unique objects that have a single owning reference. +The following attributes are currently supported, although **the implementation +for these annotations is currently in development and are subject to change.** + +callable_when +------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","","","", "" + +Use ``__attribute__((callable_when(...)))`` to indicate what states a method +may be called in. Valid states are unconsumed, consumed, or unknown. Each +argument to this attribute must be a quoted string. E.g.: + +``__attribute__((callable_when("unconsumed", "unknown")))`` + + +consumable +---------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","","","", "" + +Each ``class`` that uses any of the typestate annotations must first be marked +using the ``consumable`` attribute. Failure to do so will result in a warning. + +This attribute accepts a single parameter that must be one of the following: +``unknown``, ``consumed``, or ``unconsumed``. + + +param_typestate +--------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","","","", "" + +This attribute specifies expectations about function parameters. Calls to an +function with annotated parameters will issue a warning if the corresponding +argument isn't in the expected state. The attribute is also used to set the +initial state of the parameter when analyzing the function's body. + + +return_typestate +---------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","","","", "" + +The ``return_typestate`` attribute can be applied to functions or parameters. +When applied to a function the attribute specifies the state of the returned +value. The function's body is checked to ensure that it always returns a value +in the specified state. On the caller side, values returned by the annotated +function are initialized to the given state. + +When applied to a function parameter it modifies the state of an argument after +a call to the function returns. The function's body is checked to ensure that +the parameter is in the expected state before returning. + + +set_typestate +------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","","","", "" + +Annotate methods that transition an object into a new state with +``__attribute__((set_typestate(new_state)))``. The new state must be +unconsumed, consumed, or unknown. + + +test_typestate +-------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","","","", "" + +Use ``__attribute__((test_typestate(tested_state)))`` to indicate that a method +returns true if the object is in the specified state.. + + +Type Safety Checking +==================== +Clang supports additional attributes to enable checking type safety properties +that can't be enforced by the C type system. Use cases include: + +* MPI library implementations, where these attributes enable checking that + the buffer type matches the passed ``MPI_Datatype``; +* for HDF5 library there is a similar use case to MPI; +* checking types of variadic functions' arguments for functions like + ``fcntl()`` and ``ioctl()``. + +You can detect support for these attributes with ``__has_attribute()``. For +example: + +.. code-block:: c++ + + #if defined(__has_attribute) + # if __has_attribute(argument_with_type_tag) && \ + __has_attribute(pointer_with_type_tag) && \ + __has_attribute(type_tag_for_datatype) + # define ATTR_MPI_PWT(buffer_idx, type_idx) __attribute__((pointer_with_type_tag(mpi,buffer_idx,type_idx))) + /* ... other macros ... */ + # endif + #endif + + #if !defined(ATTR_MPI_PWT) + # define ATTR_MPI_PWT(buffer_idx, type_idx) + #endif + + int MPI_Send(void *buf, int count, MPI_Datatype datatype /*, other args omitted */) + ATTR_MPI_PWT(1,3); + +argument_with_type_tag +---------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","","","", "" + +Use ``__attribute__((argument_with_type_tag(arg_kind, arg_idx, +type_tag_idx)))`` on a function declaration to specify that the function +accepts a type tag that determines the type of some other argument. +``arg_kind`` is an identifier that should be used when annotating all +applicable type tags. + +This attribute is primarily useful for checking arguments of variadic functions +(``pointer_with_type_tag`` can be used in most non-variadic cases). + +For example: + +.. code-block:: c++ + + int fcntl(int fd, int cmd, ...) + __attribute__(( argument_with_type_tag(fcntl,3,2) )); + + +pointer_with_type_tag +--------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","","","", "" + +Use ``__attribute__((pointer_with_type_tag(ptr_kind, ptr_idx, type_tag_idx)))`` +on a function declaration to specify that the function accepts a type tag that +determines the pointee type of some other pointer argument. + +For example: + +.. code-block:: c++ + + int MPI_Send(void *buf, int count, MPI_Datatype datatype /*, other args omitted */) + __attribute__(( pointer_with_type_tag(mpi,1,3) )); + + +type_tag_for_datatype +--------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","","","", "" + +Clang supports annotating type tags of two forms. + +* **Type tag that is an expression containing a reference to some declared + identifier.** Use ``__attribute__((type_tag_for_datatype(kind, type)))`` on a + declaration with that identifier: + + .. code-block:: c++ + + extern struct mpi_datatype mpi_datatype_int + __attribute__(( type_tag_for_datatype(mpi,int) )); + #define MPI_INT ((MPI_Datatype) &mpi_datatype_int) + +* **Type tag that is an integral literal.** Introduce a ``static const`` + variable with a corresponding initializer value and attach + ``__attribute__((type_tag_for_datatype(kind, type)))`` on that declaration, + for example: + + .. code-block:: c++ + + #define MPI_INT ((MPI_Datatype) 42) + static const MPI_Datatype mpi_datatype_int + __attribute__(( type_tag_for_datatype(mpi,int) )) = 42 + +The attribute also accepts an optional third argument that determines how the +expression is compared to the type tag. There are two supported flags: + +* ``layout_compatible`` will cause types to be compared according to + layout-compatibility rules (C++11 [class.mem] p 17, 18). This is + implemented to support annotating types like ``MPI_DOUBLE_INT``. + + For example: + + .. code-block:: c++ + + /* In mpi.h */ + struct internal_mpi_double_int { double d; int i; }; + extern struct mpi_datatype mpi_datatype_double_int + __attribute__(( type_tag_for_datatype(mpi, struct internal_mpi_double_int, layout_compatible) )); + + #define MPI_DOUBLE_INT ((MPI_Datatype) &mpi_datatype_double_int) + + /* In user code */ + struct my_pair { double a; int b; }; + struct my_pair *buffer; + MPI_Send(buffer, 1, MPI_DOUBLE_INT /*, ... */); // no warning + + struct my_int_pair { int a; int b; } + struct my_int_pair *buffer2; + MPI_Send(buffer2, 1, MPI_DOUBLE_INT /*, ... */); // warning: actual buffer element + // type 'struct my_int_pair' + // doesn't match specified MPI_Datatype + +* ``must_be_null`` specifies that the expression should be a null pointer + constant, for example: + + .. code-block:: c++ + + /* In mpi.h */ + extern struct mpi_datatype mpi_datatype_null + __attribute__(( type_tag_for_datatype(mpi, void, must_be_null) )); + + #define MPI_DATATYPE_NULL ((MPI_Datatype) &mpi_datatype_null) + + /* In user code */ + MPI_Send(buffer, 1, MPI_DATATYPE_NULL /*, ... */); // warning: MPI_DATATYPE_NULL + // was specified but buffer + // is not a null pointer + + +OpenCL Address Spaces +===================== +The address space qualifier may be used to specify the region of memory that is +used to allocate the object. OpenCL supports the following address spaces: +__generic(generic), __global(global), __local(local), __private(private), +__constant(constant). + + .. code-block:: c + + __constant int c = ...; + + __generic int* foo(global int* g) { + __local int* l; + private int p; + ... + return l; + } + +More details can be found in the OpenCL C language Spec v2.0, Section 6.5. + +constant (__constant) +--------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "","","","X", "" + +The constant address space attribute signals that an object is located in +a constant (non-modifiable) memory region. It is available to all work items. +Any type can be annotated with the constant address space attribute. Objects +with the constant address space qualifier can be declared in any scope and must +have an initializer. + + +generic (__generic) +------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "","","","X", "" + +The generic address space attribute is only available with OpenCL v2.0 and later. +It can be used with pointer types. Variables in global and local scope and +function parameters in non-kernel functions can have the generic address space +type attribute. It is intended to be a placeholder for any other address space +except for '__constant' in OpenCL code which can be used with multiple address +spaces. + + +global (__global) +----------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "","","","X", "" + +The global address space attribute specifies that an object is allocated in +global memory, which is accessible by all work items. The content stored in this +memory area persists between kernel executions. Pointer types to the global +address space are allowed as function parameters or local variables. Starting +with OpenCL v2.0, the global address space can be used with global (program +scope) variables and static local variable as well. + + +local (__local) +--------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "","","","X", "" + +The local address space specifies that an object is allocated in the local (work +group) memory area, which is accessible to all work items in the same work +group. The content stored in this memory region is not accessible after +the kernel execution ends. In a kernel function scope, any variable can be in +the local address space. In other scopes, only pointer types to the local address +space are allowed. Local address space variables cannot have an initializer. + + +private (__private) +------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "","","","X", "" + +The private address space specifies that an object is allocated in the private +(work item) memory. Other work items cannot access the same memory area and its +content is destroyed after work item execution ends. Local variables can be +declared in the private address space. Function arguments are always in the +private address space. Kernel function arguments of a pointer or an array type +cannot point to the private address space. + + +Nullability Attributes +====================== +Whether a particular pointer may be "null" is an important concern when working with pointers in the C family of languages. The various nullability attributes indicate whether a particular pointer can be null or not, which makes APIs more expressive and can help static analysis tools identify bugs involving null pointers. Clang supports several kinds of nullability attributes: the ``nonnull`` and ``returns_nonnull`` attributes indicate which function or method parameters and result types can never be null, while nullability type qualifiers indicate which pointer types can be null (``_Nullable``) or cannot be null (``_Nonnull``). + +The nullability (type) qualifiers express whether a value of a given pointer type can be null (the ``_Nullable`` qualifier), doesn't have a defined meaning for null (the ``_Nonnull`` qualifier), or for which the purpose of null is unclear (the ``_Null_unspecified`` qualifier). Because nullability qualifiers are expressed within the type system, they are more general than the ``nonnull`` and ``returns_nonnull`` attributes, allowing one to express (for example) a nullable pointer to an array of nonnull pointers. Nullability qualifiers are written to the right of the pointer to which they apply. For example: + + .. code-block:: c + + // No meaningful result when 'ptr' is null (here, it happens to be undefined behavior). + int fetch(int * _Nonnull ptr) { return *ptr; } + + // 'ptr' may be null. + int fetch_or_zero(int * _Nullable ptr) { + return ptr ? *ptr : 0; + } + + // A nullable pointer to non-null pointers to const characters. + const char *join_strings(const char * _Nonnull * _Nullable strings, unsigned n); + +In Objective-C, there is an alternate spelling for the nullability qualifiers that can be used in Objective-C methods and properties using context-sensitive, non-underscored keywords. For example: + + .. code-block:: objective-c + + @interface NSView : NSResponder + - (nullable NSView *)ancestorSharedWithView:(nonnull NSView *)aView; + @property (assign, nullable) NSView *superview; + @property (readonly, nonnull) NSArray *subviews; + @end + +nonnull (gnu::nonnull) +---------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +The ``nonnull`` attribute indicates that some function parameters must not be null, and can be used in several different ways. It's original usage (`from GCC `_) is as a function (or Objective-C method) attribute that specifies which parameters of the function are nonnull in a comma-separated list. For example: + + .. code-block:: c + + extern void * my_memcpy (void *dest, const void *src, size_t len) + __attribute__((nonnull (1, 2))); + +Here, the ``nonnull`` attribute indicates that parameters 1 and 2 +cannot have a null value. Omitting the parenthesized list of parameter indices means that all parameters of pointer type cannot be null: + + .. code-block:: c + + extern void * my_memcpy (void *dest, const void *src, size_t len) + __attribute__((nonnull)); + +Clang also allows the ``nonnull`` attribute to be placed directly on a function (or Objective-C method) parameter, eliminating the need to specify the parameter index ahead of type. For example: + + .. code-block:: c + + extern void * my_memcpy (void *dest __attribute__((nonnull)), + const void *src __attribute__((nonnull)), size_t len); + +Note that the ``nonnull`` attribute indicates that passing null to a non-null parameter is undefined behavior, which the optimizer may take advantage of to, e.g., remove null checks. The ``_Nonnull`` type qualifier indicates that a pointer cannot be null in a more general manner (because it is part of the type system) and does not imply undefined behavior, making it more widely applicable. + + +returns_nonnull (gnu::returns_nonnull) +-------------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +The ``returns_nonnull`` attribute indicates that a particular function (or Objective-C method) always returns a non-null pointer. For example, a particular system ``malloc`` might be defined to terminate a process when memory is not available rather than returning a null pointer: + + .. code-block:: c + + extern void * malloc (size_t size) __attribute__((returns_nonnull)); + +The ``returns_nonnull`` attribute implies that returning a null pointer is undefined behavior, which the optimizer may take advantage of. The ``_Nonnull`` type qualifier indicates that a pointer cannot be null in a more general manner (because it is part of the type system) and does not imply undefined behavior, making it more widely applicable + + +_Nonnull +-------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "","","","X", "" + +The ``_Nonnull`` nullability qualifier indicates that null is not a meaningful value for a value of the ``_Nonnull`` pointer type. For example, given a declaration such as: + + .. code-block:: c + + int fetch(int * _Nonnull ptr); + +a caller of ``fetch`` should not provide a null value, and the compiler will produce a warning if it sees a literal null value passed to ``fetch``. Note that, unlike the declaration attribute ``nonnull``, the presence of ``_Nonnull`` does not imply that passing null is undefined behavior: ``fetch`` is free to consider null undefined behavior or (perhaps for backward-compatibility reasons) defensively handle null. + + +_Null_unspecified +----------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "","","","X", "" + +The ``_Null_unspecified`` nullability qualifier indicates that neither the ``_Nonnull`` nor ``_Nullable`` qualifiers make sense for a particular pointer type. It is used primarily to indicate that the role of null with specific pointers in a nullability-annotated header is unclear, e.g., due to overly-complex implementations or historical factors with a long-lived API. + + +_Nullable +--------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "","","","X", "" + +The ``_Nullable`` nullability qualifier indicates that a value of the ``_Nullable`` pointer type can be null. For example, given: + + .. code-block:: c + + int fetch_or_zero(int * _Nullable ptr); + +a caller of ``fetch_or_zero`` can provide null. + + diff --git a/docs/ReleaseNotes.rst b/docs/ReleaseNotes.rst index badb2737dae3..dcffbfd825df 100644 --- a/docs/ReleaseNotes.rst +++ b/docs/ReleaseNotes.rst @@ -47,7 +47,7 @@ sections with improvements to Clang's support for those languages. Major New Features ------------------ -- Clang will no longer passes --build-id by default to the linker. In modern +- Clang will no longer pass --build-id by default to the linker. In modern linkers that is a relatively expensive option. It can be passed explicitly with -Wl,--build-id. To have clang always pass it, build clang with -DENABLE_LINKER_BUILD_ID. @@ -62,7 +62,13 @@ Clang's diagnostics are constantly being improved to catch more issues, explain them more clearly, and provide more accurate source information about them. The improvements since the 3.8 release include: -- ... +- -Wcomma is a new warning to show most uses of the builtin comma operator. +- -Wfloat-conversion has two new sub-warnings to give finer grain control for + floating point to integer conversion warnings. + - -Wfloat-overflow-convserion detects when a constant floating point value + is converted to an integer type and will overflow the target type. + - -Wfloat-zero-conversion detects when a non-zero floating point value is + converted to a zero integer value. New Compiler Flags ------------------ @@ -92,6 +98,18 @@ Clang's support for building native Windows programs ... TLS is enabled for Cygwin defaults to -femulated-tls. +Proper support, including correct mangling and overloading, added for +MS-specific "__unaligned" type qualifier. + +clang-cl now has limited support for the precompiled header flags /Yc, /Yu, and +/Fp. If the precompiled header is passed on the compile command with /FI, then +the precompiled header flags are honored. But if the precompiled header is +included by an `#include ` in each source file instead of by a +`/FIstdafx.h` flag, these flag continue to be ignored. + +clang-cl has a new flag, `/imsvc `, for adding a directory to the system +include search path (where warnings are disabled default) without having to +set `%INCLUDE`. C Language Changes in Clang --------------------------- @@ -177,7 +195,52 @@ Objective-C Language Changes in Clang OpenCL C Language Changes in Clang ---------------------------------- -... +Clang now has support for all OpenCL 2.0 features. In particular, the following +features have been completed since the previous release: + +- Pipe builtin functions (s6.13.16.2-4). +- Address space conversion functions ``to_{global/local/private}``. +- ``nosvm`` attribute support. +- Improved diagnostic and generation of Clang Blocks used in OpenCL kernel code. +- ``opencl_unroll_hint`` pragma. + +Several miscellaneous improvements have been made: + +- Supported extensions are now part of the target representation to give correct + diagnostics for unsupported target features during compilation. For example, + when compiling for a target that does not support the double precision + floating point extension, Clang will give an error when encountering the + ``cl_khr_fp64`` pragma. Several missing extensions were added covering up to + and including OpenCL 2.0. +- Clang now comes with the OpenCL standard headers declaring builtin types and + functions up to and including OpenCL 2.0 in ``lib/Headers/opencl-c.h``. By + default, Clang will not include this header. It can be included either using + the regular ``-I`` directive or (if the default one + from installation is to be used) using the ``-finclude-default-header`` + frontend flag. + + Example: + + .. code-block:: none + + echo "bool is_wg_uniform(int i){return get_enqueued_local_size(i)==get_local_size(i);}" > test.cl + clang -cc1 -finclude-default-header -cl-std=CL2.0 test.cl + + All builtin function declarations from OpenCL 2.0 will be automatically + visible in test.cl. +- Image types have been improved with better diagnostics for access qualifiers. + Images with one access qualifier type cannot be used in declarations for + another type. Also qualifiers are now propagated from the frontend down to + libraries and backends. +- Diagnostic improvements for OpenCL types, address spaces and vectors. +- Half type literal support has been added. For example, ``1.0h`` represents a + floating point literal in half precision, i.e., the value ``0xH3C00``. +- The Clang driver now accepts OpenCL compiler options ``-cl-*`` (following the + OpenCL Spec v1.1-1.2 s5.8). For example, the ``-cl-std=CL1.2`` option from the + spec enables compilation for OpenCL 1.2, or ``-cl-mad-enable`` will enable + fusing multiply-and-add operations. +- Clang now uses function metadata instead of module metadata to propagate + information related to OpenCL kernels e.g. kernel argument information. OpenMP Support in Clang ---------------------------------- @@ -224,7 +287,22 @@ libclang Static Analyzer --------------- -... +The analyzer now checks for incorrect usage of MPI APIs in C and C++. This +check can be enabled by passing the following command to scan-build: +``-enable-checker optin.mpi.MPI-Checker.`` + +The analyzer now checks for improper instance cleanup up in Objective-C +``-dealloc`` methods under manual retain/release. + +On Windows, checks for memory leaks, double frees, and use-after-free problems +are now enabled by default. + +The analyzer now includes scan-build-py, an experimental reimplementation of +scan-build in Python that also creates compilation databases. + +The scan-build tool now supports a ``--force-analyze-debug-code`` flag that +forces projects to analyze in debug mode. This flag leaves in assertions and so +typically results in fewer false positives. Core Analysis Improvements ========================== diff --git a/docs/UsersManual.rst b/docs/UsersManual.rst index 8e591518d54d..2ebcbdf60317 100644 --- a/docs/UsersManual.rst +++ b/docs/UsersManual.rst @@ -2082,16 +2082,26 @@ Execute ``clang-cl /?`` to see a list of supported options: /fp:fast /fp:precise /fp:strict + /Fp Set pch filename (with /Yc and /Yu) /GA Assume thread-local variables are defined in the executable + /Gd Set __cdecl as a default calling convention /GF- Disable string pooling /GR- Disable emission of RTTI data /GR Enable emission of RTTI data + /Gr Set __fastcall as a default calling convention + /GS- Disable buffer security check + /GS Enable buffer security check /Gs Set stack probe size + /Gv Set __vectorcall as a default calling convention /Gw- Don't put each data item in its own section /Gw Put each data item in its own section + /GX- Enable exception handling + /GX Enable exception handling /Gy- Don't put each function in its own section /Gy Put each function in its own section + /Gz Set __stdcall as a default calling convention /help Display available options + /imsvc Add directory to system include search path, as if part of %INCLUDE% /I Add directory to include search path /J Make char type unsigned /LDd Create debug DLL @@ -2101,7 +2111,6 @@ Execute ``clang-cl /?`` to see a list of supported options: /MD Use DLL run-time /MTd Use static debug run-time /MT Use static run-time - /Ob0 Disable inlining /Od Disable optimization /Oi- Disable use of builtin functions /Oi Enable use of builtin functions @@ -2113,6 +2122,7 @@ Execute ``clang-cl /?`` to see a list of supported options: /Qvec- Disable the loop vectorization passes /Qvec Enable the loop vectorization passes /showIncludes Print info about included files to stderr + /std: Language standard to compile for /TC Treat all source files as C /Tc Specify a C source file /TP Treat all source files as C++ @@ -2135,6 +2145,9 @@ Execute ``clang-cl /?`` to see a list of supported options: /WX- Do not treat warnings as errors /WX Treat warnings as errors /w Disable all warnings + /Y- Disable precompiled headers, overrides /Yc and /Yu + /Yc Generate a pch file for all code up to and including + /Yu Load a pch file and use it instead of all code up to and including /Z7 Enable CodeView debug information in object files /Zc:sizedDealloc- Disable C++14 sized global deallocation functions /Zc:sizedDealloc Enable C++14 sized global deallocation functions @@ -2143,6 +2156,7 @@ Execute ``clang-cl /?`` to see a list of supported options: /Zc:threadSafeInit Enable thread-safe initialization of static variables /Zc:trigraphs- Disable trigraphs (default) /Zc:trigraphs Enable trigraphs + /Zd Emit debug line number tables only /Zi Alias for /Z7. Does not produce PDBs. /Zl Don't mention any default libraries in the object file /Zp Set the default maximum struct packing alignment to 1 @@ -2179,6 +2193,8 @@ Execute ``clang-cl /?`` to see a list of supported options: -fsanitize= Turn on runtime checks for various forms of undefined or suspicious behavior. See user manual for available checks -gcodeview Generate CodeView debug information + -gline-tables-only Emit debug line number tables only + -miamcu Use Intel MCU ABI -mllvm Additional arguments to forward to LLVM's option processing -Qunused-arguments Don't emit warning for unused driver arguments -R Enable the specified remark diff --git a/include/clang/AST/ExternalASTSource.h b/include/clang/AST/ExternalASTSource.h index 81cf631c7a4a..2e99f395f495 100644 --- a/include/clang/AST/ExternalASTSource.h +++ b/include/clang/AST/ExternalASTSource.h @@ -503,8 +503,9 @@ public: /// We define this as a wrapping iterator around an int. The /// iterator_adaptor_base class forwards the iterator methods to basic integer /// arithmetic. - class iterator : public llvm::iterator_adaptor_base< - iterator, int, std::random_access_iterator_tag, T, int> { + class iterator + : public llvm::iterator_adaptor_base< + iterator, int, std::random_access_iterator_tag, T, int, T *, T &> { LazyVector *Self; iterator(LazyVector *Self, int Position) diff --git a/include/clang/AST/StmtGraphTraits.h b/include/clang/AST/StmtGraphTraits.h index ab636a5ddc48..dac4495c6a0f 100644 --- a/include/clang/AST/StmtGraphTraits.h +++ b/include/clang/AST/StmtGraphTraits.h @@ -26,6 +26,7 @@ namespace llvm { template <> struct GraphTraits { typedef clang::Stmt NodeType; + typedef clang::Stmt * NodeRef; typedef clang::Stmt::child_iterator ChildIteratorType; typedef llvm::df_iterator nodes_iterator; @@ -53,6 +54,7 @@ template <> struct GraphTraits { template <> struct GraphTraits { typedef const clang::Stmt NodeType; + typedef const clang::Stmt * NodeRef; typedef clang::Stmt::const_child_iterator ChildIteratorType; typedef llvm::df_iterator nodes_iterator; diff --git a/include/clang/Analysis/Analyses/Dominators.h b/include/clang/Analysis/Analyses/Dominators.h index 4524aebe4e8b..c64a3ca2551d 100644 --- a/include/clang/Analysis/Analyses/Dominators.h +++ b/include/clang/Analysis/Analyses/Dominators.h @@ -168,6 +168,7 @@ private: namespace llvm { template <> struct GraphTraits< ::clang::DomTreeNode* > { typedef ::clang::DomTreeNode NodeType; + typedef ::clang::DomTreeNode *NodeRef; typedef NodeType::iterator ChildIteratorType; static NodeType *getEntryNode(NodeType *N) { diff --git a/include/clang/Basic/BuiltinsX86.def b/include/clang/Basic/BuiltinsX86.def index ff97693c313e..0accba4abab1 100644 --- a/include/clang/Basic/BuiltinsX86.def +++ b/include/clang/Basic/BuiltinsX86.def @@ -303,7 +303,9 @@ TARGET_BUILTIN(__builtin_ia32_pabsd128, "V4iV4i", "", "ssse3") TARGET_BUILTIN(__builtin_ia32_ldmxcsr, "vUi", "", "sse") TARGET_BUILTIN(__builtin_ia32_stmxcsr, "Ui", "", "sse") TARGET_BUILTIN(__builtin_ia32_cvtss2si, "iV4f", "", "sse") +TARGET_BUILTIN(__builtin_ia32_cvttss2si, "iV4f", "", "sse") TARGET_BUILTIN(__builtin_ia32_cvtss2si64, "LLiV4f", "", "sse") +TARGET_BUILTIN(__builtin_ia32_cvttss2si64, "LLiV4f", "", "sse") TARGET_BUILTIN(__builtin_ia32_storehps, "vV2i*V4f", "", "sse") TARGET_BUILTIN(__builtin_ia32_storelps, "vV2i*V4f", "", "sse") TARGET_BUILTIN(__builtin_ia32_movmskps, "iV4f", "", "sse") @@ -328,8 +330,12 @@ TARGET_BUILTIN(__builtin_ia32_cvtpd2dq, "V2LLiV2d", "", "sse2") TARGET_BUILTIN(__builtin_ia32_cvtpd2ps, "V4fV2d", "", "sse2") TARGET_BUILTIN(__builtin_ia32_cvttpd2dq, "V4iV2d", "", "sse2") TARGET_BUILTIN(__builtin_ia32_cvtsd2si, "iV2d", "", "sse2") +TARGET_BUILTIN(__builtin_ia32_cvttsd2si, "iV2d", "", "sse2") TARGET_BUILTIN(__builtin_ia32_cvtsd2si64, "LLiV2d", "", "sse2") +TARGET_BUILTIN(__builtin_ia32_cvttsd2si64, "LLiV2d", "", "sse2") +TARGET_BUILTIN(__builtin_ia32_cvtsd2ss, "V4fV4fV2d", "", "sse2") TARGET_BUILTIN(__builtin_ia32_cvtps2dq, "V4iV4f", "", "sse2") +TARGET_BUILTIN(__builtin_ia32_cvttps2dq, "V4iV4f", "", "sse2") TARGET_BUILTIN(__builtin_ia32_clflush, "vvC*", "", "sse2") TARGET_BUILTIN(__builtin_ia32_lfence, "v", "", "sse2") TARGET_BUILTIN(__builtin_ia32_mfence, "v", "", "sse2") @@ -455,7 +461,9 @@ TARGET_BUILTIN(__builtin_ia32_cmpss, "V4fV4fV4fIc", "", "avx") TARGET_BUILTIN(__builtin_ia32_cvtdq2ps256, "V8fV8i", "", "avx") TARGET_BUILTIN(__builtin_ia32_cvtpd2ps256, "V4fV4d", "", "avx") TARGET_BUILTIN(__builtin_ia32_cvtps2dq256, "V8iV8f", "", "avx") +TARGET_BUILTIN(__builtin_ia32_cvttpd2dq256, "V4iV4d", "", "avx") TARGET_BUILTIN(__builtin_ia32_cvtpd2dq256, "V4iV4d", "", "avx") +TARGET_BUILTIN(__builtin_ia32_cvttps2dq256, "V8iV8f", "", "avx") TARGET_BUILTIN(__builtin_ia32_vperm2f128_pd256, "V4dV4dV4dIc", "", "avx") TARGET_BUILTIN(__builtin_ia32_vperm2f128_ps256, "V8fV8fV8fIc", "", "avx") TARGET_BUILTIN(__builtin_ia32_vperm2f128_si256, "V8iV8iV8iIc", "", "avx") diff --git a/include/clang/Basic/DiagnosticASTKinds.td b/include/clang/Basic/DiagnosticASTKinds.td index 03ed8aa74597..039888ba6631 100644 --- a/include/clang/Basic/DiagnosticASTKinds.td +++ b/include/clang/Basic/DiagnosticASTKinds.td @@ -158,12 +158,6 @@ def warn_integer_constant_overflow : Warning< "overflow in expression; result is %0 with type %1">, InGroup>; -// This is a temporary diagnostic, and shall be removed once our -// implementation is complete, and like the preceding constexpr notes belongs -// in Sema. -def note_unimplemented_constexpr_lambda_feature_ast : Note< - "unimplemented constexpr lambda feature: %0 (coming soon!)">; - // inline asm related. let CategoryName = "Inline Assembly Issue" in { def err_asm_invalid_escape : Error< diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td index e5c64681e48f..45044e626770 100644 --- a/include/clang/Basic/DiagnosticParseKinds.td +++ b/include/clang/Basic/DiagnosticParseKinds.td @@ -780,20 +780,11 @@ def warn_cxx98_compat_lambda : Warning< InGroup, DefaultIgnore; def err_lambda_missing_parens : Error< "lambda requires '()' before %select{'mutable'|return type|" - "attribute specifier|'constexpr'}0">; -def err_lambda_decl_specifier_repeated : Error< - "%select{'mutable'|'constexpr'}0 cannot appear multiple times in a lambda declarator">; + "attribute specifier}0">; // C++1z lambda expressions def err_expected_star_this_capture : Error< "expected 'this' following '*' in lambda capture list">; -// C++1z constexpr lambda expressions -def warn_cxx14_compat_constexpr_on_lambda : Warning< - "constexpr on lambda expressions is incompatible with C++ standards before C++1z">, - InGroup, DefaultIgnore; -def ext_constexpr_on_lambda_cxx1z : ExtWarn< - "'constexpr' on lambda expressions is a C++1z extension">, InGroup; - // Availability attribute def err_expected_version : Error< "expected a version of the form 'major[.minor[.subminor]]'">; diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 25aa805dac4b..10a8a5ac538a 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -5111,8 +5111,7 @@ public: SourceRange IntroducerRange, TypeSourceInfo *MethodType, SourceLocation EndLoc, - ArrayRef Params, - bool IsConstexprSpecified); + ArrayRef Params); /// \brief Endow the lambda scope info with the relevant properties. void buildLambdaScope(sema::LambdaScopeInfo *LSI, diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h index 1b40494fd43c..18e23870a765 100644 --- a/include/clang/Serialization/ASTReader.h +++ b/include/clang/Serialization/ASTReader.h @@ -843,6 +843,9 @@ private: /// \brief Whether we have tried loading the global module index yet. bool TriedLoadingGlobalIndex; + ///\brief Whether we are currently processing update records. + bool ProcessingUpdateRecords; + typedef llvm::DenseMap SwitchCaseMapTy; /// \brief Mapping from switch-case IDs in the chain to switch-case statements /// @@ -1042,6 +1045,23 @@ private: ~ReadingKindTracker() { Reader.ReadingKind = PrevKind; } }; + /// \brief RAII object to mark the start of processing updates. + class ProcessingUpdatesRAIIObj { + ASTReader &Reader; + bool PrevState; + + ProcessingUpdatesRAIIObj(const ProcessingUpdatesRAIIObj &) = delete; + void operator=(const ProcessingUpdatesRAIIObj &) = delete; + + public: + ProcessingUpdatesRAIIObj(ASTReader &reader) + : Reader(reader), PrevState(Reader.ProcessingUpdateRecords) { + Reader.ProcessingUpdateRecords = true; + } + + ~ProcessingUpdatesRAIIObj() { Reader.ProcessingUpdateRecords = PrevState; } + }; + /// \brief Suggested contents of the predefines buffer, after this /// PCH file has been processed. /// @@ -2130,6 +2150,8 @@ public: /// \brief Loads comments ranges. void ReadComments() override; + + bool isProcessingUpdateRecords() { return ProcessingUpdateRecords; } }; /// \brief Helper class that saves the current stream position and diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h index bacb42dd176f..549db1a6a1e8 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h @@ -452,6 +452,7 @@ public: namespace llvm { template<> struct GraphTraits { typedef clang::ento::ExplodedNode NodeType; + typedef clang::ento::ExplodedNode *NodeRef; typedef NodeType::succ_iterator ChildIteratorType; typedef llvm::df_iterator nodes_iterator; @@ -478,6 +479,7 @@ namespace llvm { template<> struct GraphTraits { typedef const clang::ento::ExplodedNode NodeType; + typedef const clang::ento::ExplodedNode *NodeRef; typedef NodeType::const_succ_iterator ChildIteratorType; typedef llvm::df_iterator nodes_iterator; diff --git a/lib/AST/ASTDiagnostic.cpp b/lib/AST/ASTDiagnostic.cpp index 22de8bc0dd05..0f5a8b5ae892 100644 --- a/lib/AST/ASTDiagnostic.cpp +++ b/lib/AST/ASTDiagnostic.cpp @@ -917,6 +917,8 @@ class TemplateDiff { /// template argument. InternalIterator(const TemplateSpecializationType *TST) : TST(TST), Index(0), CurrentTA(nullptr), EndTA(nullptr) { + if (!TST) return; + if (isEnd()) return; // Set to first template argument. If not a parameter pack, done. @@ -937,11 +939,13 @@ class TemplateDiff { /// isEnd - Returns true if the iterator is one past the end. bool isEnd() const { + assert(TST && "InternalIterator is invalid with a null TST."); return Index >= TST->getNumArgs(); } /// &operator++ - Increment the iterator to the next template argument. InternalIterator &operator++() { + assert(TST && "InternalIterator is invalid with a null TST."); if (isEnd()) { return *this; } @@ -977,6 +981,7 @@ class TemplateDiff { /// operator* - Returns the appropriate TemplateArgument. reference operator*() const { + assert(TST && "InternalIterator is invalid with a null TST."); assert(!isEnd() && "Index exceeds number of arguments."); if (CurrentTA == EndTA) return TST->getArg(Index); @@ -986,6 +991,7 @@ class TemplateDiff { /// operator-> - Allow access to the underlying TemplateArgument. pointer operator->() const { + assert(TST && "InternalIterator is invalid with a null TST."); return &operator*(); } }; diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp index d069bfdc3dc2..81f94148d6ed 100644 --- a/lib/AST/DeclCXX.cpp +++ b/lib/AST/DeclCXX.cpp @@ -807,6 +807,17 @@ void CXXRecordDecl::addedMember(Decl *D) { data().DefaultedDestructorIsDeleted = true; } + // For an anonymous union member, our overload resolution will perform + // overload resolution for its members. + if (Field->isAnonymousStructOrUnion()) { + data().NeedOverloadResolutionForMoveConstructor |= + FieldRec->data().NeedOverloadResolutionForMoveConstructor; + data().NeedOverloadResolutionForMoveAssignment |= + FieldRec->data().NeedOverloadResolutionForMoveAssignment; + data().NeedOverloadResolutionForDestructor |= + FieldRec->data().NeedOverloadResolutionForDestructor; + } + // C++0x [class.ctor]p5: // A default constructor is trivial [...] if: // -- for all the non-static data members of its class that are of diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index a25a6c7e5135..df944e8f25f2 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -36,7 +36,6 @@ #include "clang/AST/APValue.h" #include "clang/AST/ASTContext.h" #include "clang/AST/ASTDiagnostic.h" -#include "clang/AST/ASTLambda.h" #include "clang/AST/CharUnits.h" #include "clang/AST/Expr.h" #include "clang/AST/RecordLayout.h" @@ -2126,22 +2125,7 @@ static bool evaluateVarDeclInit(EvalInfo &Info, const Expr *E, // If this is a local variable, dig out its value. if (Frame) { Result = Frame->getTemporary(VD); - if (!Result) { - // Assume variables referenced within a lambda's call operator that were - // not declared within the call operator are captures and during checking - // of a potential constant expression, assume they are unknown constant - // expressions. - assert(isLambdaCallOperator(Frame->Callee) && - (VD->getDeclContext() != Frame->Callee || VD->isInitCapture()) && - "missing value for local variable"); - if (Info.checkingPotentialConstantExpression()) - return false; - // FIXME: implement capture evaluation during constant expr evaluation. - Info.FFDiag(E->getLocStart(), - diag::note_unimplemented_constexpr_lambda_feature_ast) - << "captures not currently allowed"; - return false; - } + assert(Result && "missing value for local variable"); return true; } diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp index d7a9bdb3d82c..a67f0910e15a 100644 --- a/lib/Analysis/CFG.cpp +++ b/lib/Analysis/CFG.cpp @@ -3902,7 +3902,17 @@ CFGImplicitDtor::getDestructorDecl(ASTContext &astContext) const { case CFGElement::AutomaticObjectDtor: { const VarDecl *var = castAs().getVarDecl(); QualType ty = var->getType(); - ty = ty.getNonReferenceType(); + + // FIXME: See CFGBuilder::addLocalScopeForVarDecl. + // + // Lifetime-extending constructs are handled here. This works for a single + // temporary in an initializer expression. + if (ty->isReferenceType()) { + if (const Expr *Init = var->getInit()) { + ty = getReferenceInitTemporaryType(astContext, Init); + } + } + while (const ArrayType *arrayType = astContext.getAsArrayType(ty)) { ty = arrayType->getElementType(); } diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp index c3ca8c8af5d5..7ec06bb17e3f 100644 --- a/lib/Basic/Targets.cpp +++ b/lib/Basic/Targets.cpp @@ -7094,9 +7094,9 @@ class MipsTargetInfo : public TargetInfo { if (ABI == "o32") Layout = "m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64"; else if (ABI == "n32") - Layout = "m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32:64-S128"; + Layout = "m:e-p:32:32-i8:8:32-i16:16:32-i64:64-n32:64-S128"; else if (ABI == "n64") - Layout = "m:m-i8:8:32-i16:16:32-i64:64-n32:64-S128"; + Layout = "m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128"; else llvm_unreachable("Invalid ABI"); diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp index 5a41f361d9ac..e3658ab9b762 100644 --- a/lib/CodeGen/CGBlocks.cpp +++ b/lib/CodeGen/CGBlocks.cpp @@ -125,10 +125,15 @@ static llvm::Constant *buildBlockDescriptor(CodeGenModule &CGM, llvm::Constant *init = llvm::ConstantStruct::getAnon(elements); + unsigned AddrSpace = 0; + if (C.getLangOpts().OpenCL) + AddrSpace = C.getTargetAddressSpace(LangAS::opencl_constant); llvm::GlobalVariable *global = new llvm::GlobalVariable(CGM.getModule(), init->getType(), true, llvm::GlobalValue::InternalLinkage, - init, "__block_descriptor_tmp"); + init, "__block_descriptor_tmp", nullptr, + llvm::GlobalValue::NotThreadLocal, + AddrSpace); return llvm::ConstantExpr::getBitCast(global, CGM.getBlockDescriptorType()); } @@ -927,7 +932,10 @@ llvm::Type *CodeGenModule::getBlockDescriptorType() { UnsignedLongTy, UnsignedLongTy, nullptr); // Now form a pointer to that. - BlockDescriptorType = llvm::PointerType::getUnqual(BlockDescriptorType); + unsigned AddrSpace = 0; + if (getLangOpts().OpenCL) + AddrSpace = getContext().getTargetAddressSpace(LangAS::opencl_constant); + BlockDescriptorType = llvm::PointerType::get(BlockDescriptorType, AddrSpace); return BlockDescriptorType; } diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp index c74e53ea84e0..a5fc53113bdc 100644 --- a/lib/CodeGen/CGBuiltin.cpp +++ b/lib/CodeGen/CGBuiltin.cpp @@ -2209,8 +2209,9 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD, NewArg = Builder.CreateAddrSpaceCast(Arg0, NewArgT); else NewArg = Builder.CreateBitOrPointerCast(Arg0, NewArgT); - auto NewCall = Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, - E->getDirectCallee()->getName()), {NewArg}); + auto NewName = std::string("__") + E->getDirectCallee()->getName().str(); + auto NewCall = + Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, NewName), {NewArg}); return RValue::get(Builder.CreateBitOrPointerCast(NewCall, ConvertType(E->getType()))); } diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp index 5e9d73f082fc..0607a5157a6f 100644 --- a/lib/CodeGen/CGDebugInfo.cpp +++ b/lib/CodeGen/CGDebugInfo.cpp @@ -3637,6 +3637,16 @@ void CGDebugInfo::EmitUsingDecl(const UsingDecl &UD) { // Emitting one decl is sufficient - debuggers can detect that this is an // overloaded name & provide lookup for all the overloads. const UsingShadowDecl &USD = **UD.shadow_begin(); + + // FIXME: Skip functions with undeduced auto return type for now since we + // don't currently have the plumbing for separate declarations & definitions + // of free functions and mismatched types (auto in the declaration, concrete + // return type in the definition) + if (const auto *FD = dyn_cast(USD.getUnderlyingDecl())) + if (const auto *AT = + FD->getType()->getAs()->getContainedAutoType()) + if (AT->getDeducedType().isNull()) + return; if (llvm::DINode *Target = getDeclarationOrDefinition(USD.getUnderlyingDecl())) DBuilder.createImportedDeclaration( diff --git a/lib/CodeGen/CGStmt.cpp b/lib/CodeGen/CGStmt.cpp index 13c02f218135..77879021f9af 100644 --- a/lib/CodeGen/CGStmt.cpp +++ b/lib/CodeGen/CGStmt.cpp @@ -620,14 +620,7 @@ void CodeGenFunction::EmitIfStmt(const IfStmt &S) { RunCleanupsScope ThenScope(*this); EmitStmt(S.getThen()); } - { - auto CurBlock = Builder.GetInsertBlock(); - EmitBranch(ContBlock); - // Eliminate any empty blocks that may have been created by nested - // control flow statements in the 'then' clause. - if (CurBlock) - SimplifyForwardingBlocks(CurBlock); - } + EmitBranch(ContBlock); // Emit the 'else' code if present. if (const Stmt *Else = S.getElse()) { @@ -643,12 +636,7 @@ void CodeGenFunction::EmitIfStmt(const IfStmt &S) { { // There is no need to emit line number for an unconditional branch. auto NL = ApplyDebugLocation::CreateEmpty(*this); - auto CurBlock = Builder.GetInsertBlock(); EmitBranch(ContBlock); - // Eliminate any empty blocks that may have been created by nested - // control flow statements emitted in the 'else' clause. - if (CurBlock) - SimplifyForwardingBlocks(CurBlock); } } @@ -1261,6 +1249,14 @@ void CodeGenFunction::EmitCaseStmt(const CaseStmt &S) { } void CodeGenFunction::EmitDefaultStmt(const DefaultStmt &S) { + // If there is no enclosing switch instance that we're aware of, then this + // default statement can be elided. This situation only happens when we've + // constant-folded the switch. + if (!SwitchInsn) { + EmitStmt(S.getSubStmt()); + return; + } + llvm::BasicBlock *DefaultBlock = SwitchInsn->getDefaultDest(); assert(DefaultBlock->empty() && "EmitDefaultStmt: Default block already defined?"); diff --git a/lib/CodeGen/CoverageMappingGen.cpp b/lib/CodeGen/CoverageMappingGen.cpp index b4dd1a930325..b011a0f319e3 100644 --- a/lib/CodeGen/CoverageMappingGen.cpp +++ b/lib/CodeGen/CoverageMappingGen.cpp @@ -351,6 +351,9 @@ struct EmptyCoverageMappingBuilder : public CoverageMappingBuilder { gatherFileIDs(FileIDMapping); emitSourceRegions(); + if (MappingRegions.empty()) + return; + CoverageMappingWriter Writer(FileIDMapping, None, MappingRegions); Writer.write(OS); } @@ -604,6 +607,9 @@ struct CounterCoverageMappingBuilder emitExpansionRegions(); gatherSkippedRegions(); + if (MappingRegions.empty()) + return; + CoverageMappingWriter Writer(VirtualFileMapping, Builder.getExpressions(), MappingRegions); Writer.write(OS); @@ -620,6 +626,11 @@ struct CounterCoverageMappingBuilder void VisitDecl(const Decl *D) { Stmt *Body = D->getBody(); + + // Do not propagate region counts into system headers. + if (Body && SM.isInSystemHeader(SM.getSpellingLoc(getStart(Body)))) + return; + propagateCounts(getRegionCounter(Body), Body); } diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp index 4ecbf2bac3c3..9bb7a59adc1c 100644 --- a/lib/Driver/ToolChains.cpp +++ b/lib/Driver/ToolChains.cpp @@ -3281,6 +3281,19 @@ Tool *CloudABI::buildLinker() const { return new tools::cloudabi::Linker(*this); } +bool CloudABI::isPIEDefault() const { + // Only enable PIE on architectures that support PC-relative + // addressing. PC-relative addressing is required, as the process + // startup code must be able to relocate itself. + switch (getTriple().getArch()) { + case llvm::Triple::aarch64: + case llvm::Triple::x86_64: + return true; + default: + return false; + } +} + SanitizerMask CloudABI::getSupportedSanitizers() const { SanitizerMask Res = ToolChain::getSupportedSanitizers(); Res |= SanitizerKind::SafeStack; diff --git a/lib/Driver/ToolChains.h b/lib/Driver/ToolChains.h index 4e5c3f7f96a6..369712fa934b 100644 --- a/lib/Driver/ToolChains.h +++ b/lib/Driver/ToolChains.h @@ -634,8 +634,7 @@ public: void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const override; - bool isPIEDefault() const override { return true; } - + bool isPIEDefault() const override; SanitizerMask getSupportedSanitizers() const override; SanitizerMask getDefaultSanitizers() const override; diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index af70017edb05..31d436018450 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -3258,7 +3258,7 @@ static bool shouldUseFramePointerForTarget(const ArgList &Args, break; } - if (Triple.isOSLinux()) { + if (Triple.isOSLinux() || Triple.getOS() == llvm::Triple::CloudABI) { switch (Triple.getArch()) { // Don't use a frame pointer on linux if optimizing for certain targets. case llvm::Triple::mips64: @@ -4568,8 +4568,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, options::OPT_gdwarf_4, options::OPT_gdwarf_5)) DwarfVersion = DwarfVersionNum(A->getSpelling()); - // Forward -gcodeview. - // 'EmitCodeView might have been set by CL-compatibility argument parsing. + // Forward -gcodeview. EmitCodeView might have been set by CL-compatibility + // argument parsing. if (Args.hasArg(options::OPT_gcodeview) || EmitCodeView) { // DwarfVersion remains at 0 if no explicit choice was made. CmdArgs.push_back("-gcodeview"); @@ -5020,9 +5020,13 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_show_template_tree); Args.AddLastArg(CmdArgs, options::OPT_fno_elide_type); - // Forward flags for OpenMP + // Forward flags for OpenMP. We don't do this if the current action is an + // device offloading action. + // + // TODO: Allow OpenMP offload actions when they become available. if (Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ, - options::OPT_fno_openmp, false)) { + options::OPT_fno_openmp, false) && + JA.isDeviceOffloading(Action::OFK_None)) { switch (getOpenMPRuntime(getToolChain(), Args)) { case OMPRT_OMP: case OMPRT_IOMP5: @@ -6354,9 +6358,10 @@ void Clang::AddClangCLArgs(const ArgList &Args, types::ID InputType, CmdArgs.push_back(Args.MakeArgString(Twine(LangOptions::SSPStrong))); } - // Emit CodeView if -Z7 or -Zd are present. + // Emit CodeView if -Z7, -Zd, or -gline-tables-only are present. if (Arg *DebugInfoArg = - Args.getLastArg(options::OPT__SLASH_Z7, options::OPT__SLASH_Zd)) { + Args.getLastArg(options::OPT__SLASH_Z7, options::OPT__SLASH_Zd, + options::OPT_gline_tables_only)) { *EmitCodeView = true; if (DebugInfoArg->getOption().matches(options::OPT__SLASH_Z7)) *DebugInfoKind = codegenoptions::LimitedDebugInfo; @@ -7453,11 +7458,13 @@ void cloudabi::Linker::ConstructJob(Compilation &C, const JobAction &JA, // CloudABI only supports static linkage. CmdArgs.push_back("-Bstatic"); - - // CloudABI uses Position Independent Executables exclusively. - CmdArgs.push_back("-pie"); CmdArgs.push_back("--no-dynamic-linker"); - CmdArgs.push_back("-zrelro"); + + // Provide PIE linker flags in case PIE is default for the architecture. + if (ToolChain.isPIEDefault()) { + CmdArgs.push_back("-pie"); + CmdArgs.push_back("-zrelro"); + } CmdArgs.push_back("--eh-frame-hdr"); CmdArgs.push_back("--gc-sections"); diff --git a/lib/Headers/avx512fintrin.h b/lib/Headers/avx512fintrin.h index badc43650bab..0bf6582345d4 100644 --- a/lib/Headers/avx512fintrin.h +++ b/lib/Headers/avx512fintrin.h @@ -7484,7 +7484,6 @@ _mm512_mask_cvtsepi64_storeu_epi8 (void * __P, __mmask8 __M, __m512i __A) static __inline__ __m256i __DEFAULT_FN_ATTRS _mm512_cvtsepi64_epi32 (__m512i __A) { - __v8si __O; return (__m256i) __builtin_ia32_pmovsqd512_mask ((__v8di) __A, (__v8si) _mm256_undefined_si256 (), (__mmask8) -1); diff --git a/lib/Headers/avxintrin.h b/lib/Headers/avxintrin.h index 86bfdfb80c79..32e8546817b3 100644 --- a/lib/Headers/avxintrin.h +++ b/lib/Headers/avxintrin.h @@ -2117,7 +2117,7 @@ _mm256_cvtps_pd(__m128 __a) static __inline __m128i __DEFAULT_FN_ATTRS _mm256_cvttpd_epi32(__m256d __a) { - return (__m128i)__builtin_convertvector((__v4df) __a, __v4si); + return (__m128i)__builtin_ia32_cvttpd2dq256((__v4df) __a); } static __inline __m128i __DEFAULT_FN_ATTRS @@ -2129,7 +2129,7 @@ _mm256_cvtpd_epi32(__m256d __a) static __inline __m256i __DEFAULT_FN_ATTRS _mm256_cvttps_epi32(__m256 __a) { - return (__m256i)__builtin_convertvector((__v8sf) __a, __v8si); + return (__m256i)__builtin_ia32_cvttps2dq256((__v8sf) __a); } static __inline double __DEFAULT_FN_ATTRS diff --git a/lib/Headers/cpuid.h b/lib/Headers/cpuid.h index 5da02e0e5152..400dcfacd552 100644 --- a/lib/Headers/cpuid.h +++ b/lib/Headers/cpuid.h @@ -82,6 +82,7 @@ /* Features in %ecx for level 1 */ #define bit_SSE3 0x00000001 #define bit_PCLMULQDQ 0x00000002 +#define bit_PCLMUL bit_PCLMULQDQ /* for gcc compat */ #define bit_DTES64 0x00000004 #define bit_MONITOR 0x00000008 #define bit_DSCPL 0x00000010 @@ -98,15 +99,19 @@ #define bit_PCID 0x00020000 #define bit_DCA 0x00040000 #define bit_SSE41 0x00080000 +#define bit_SSE4_1 bit_SSE41 /* for gcc compat */ #define bit_SSE42 0x00100000 +#define bit_SSE4_2 bit_SSE42 /* for gcc compat */ #define bit_x2APIC 0x00200000 #define bit_MOVBE 0x00400000 #define bit_POPCNT 0x00800000 #define bit_TSCDeadline 0x01000000 #define bit_AESNI 0x02000000 +#define bit_AES bit_AESNI /* for gcc compat */ #define bit_XSAVE 0x04000000 #define bit_OSXSAVE 0x08000000 #define bit_AVX 0x10000000 +#define bit_F16C 0x20000000 #define bit_RDRND 0x40000000 /* Features in %edx for level 1 */ @@ -119,6 +124,7 @@ #define bit_PAE 0x00000040 #define bit_MCE 0x00000080 #define bit_CX8 0x00000100 +#define bit_CMPXCHG8B bit_CX8 /* for gcc compat */ #define bit_APIC 0x00000200 #define bit_SEP 0x00000800 #define bit_MTRR 0x00001000 @@ -133,7 +139,7 @@ #define bit_ACPI 0x00400000 #define bit_MMX 0x00800000 #define bit_FXSR 0x01000000 -#define bit_FXSAVE bit_FXSR /* for gcc compat */ +#define bit_FXSAVE bit_FXSR /* for gcc compat */ #define bit_SSE 0x02000000 #define bit_SSE2 0x04000000 #define bit_SS 0x08000000 diff --git a/lib/Headers/emmintrin.h b/lib/Headers/emmintrin.h index c78d059f442b..70d6d726110a 100644 --- a/lib/Headers/emmintrin.h +++ b/lib/Headers/emmintrin.h @@ -417,8 +417,7 @@ _mm_cvtsd_si32(__m128d __a) static __inline__ __m128 __DEFAULT_FN_ATTRS _mm_cvtsd_ss(__m128 __a, __m128d __b) { - __a[0] = __b[0]; - return __a; + return (__m128)__builtin_ia32_cvtsd2ss((__v4sf)__a, (__v2df)__b); } static __inline__ __m128d __DEFAULT_FN_ATTRS @@ -444,7 +443,7 @@ _mm_cvttpd_epi32(__m128d __a) static __inline__ int __DEFAULT_FN_ATTRS _mm_cvttsd_si32(__m128d __a) { - return __a[0]; + return __builtin_ia32_cvttsd2si((__v2df)__a); } static __inline__ __m64 __DEFAULT_FN_ATTRS @@ -1707,7 +1706,7 @@ _mm_cvtsd_si64(__m128d __a) static __inline__ long long __DEFAULT_FN_ATTRS _mm_cvttsd_si64(__m128d __a) { - return __a[0]; + return __builtin_ia32_cvttsd2si64((__v2df)__a); } #endif @@ -1755,7 +1754,7 @@ _mm_cvtps_epi32(__m128 __a) static __inline__ __m128i __DEFAULT_FN_ATTRS _mm_cvttps_epi32(__m128 __a) { - return (__m128i)__builtin_convertvector((__v4sf)__a, __v4si); + return (__m128i)__builtin_ia32_cvttps2dq((__v4sf)__a); } /// \brief Returns a vector of [4 x i32] where the lowest element is the input diff --git a/lib/Headers/xmmintrin.h b/lib/Headers/xmmintrin.h index 3110e8babf94..99cddb0fac82 100644 --- a/lib/Headers/xmmintrin.h +++ b/lib/Headers/xmmintrin.h @@ -1350,7 +1350,7 @@ _mm_cvt_ps2pi(__m128 __a) static __inline__ int __DEFAULT_FN_ATTRS _mm_cvttss_si32(__m128 __a) { - return __a[0]; + return __builtin_ia32_cvttss2si((__v4sf)__a); } /// \brief Converts a float value contained in the lower 32 bits of a vector of @@ -1386,7 +1386,7 @@ _mm_cvtt_ss2si(__m128 __a) static __inline__ long long __DEFAULT_FN_ATTRS _mm_cvttss_si64(__m128 __a) { - return __a[0]; + return __builtin_ia32_cvttss2si64((__v4sf)__a); } /// \brief Converts two low-order float values in a 128-bit vector of diff --git a/lib/Lex/Pragma.cpp b/lib/Lex/Pragma.cpp index 1819f4f06bc5..3bdd31b26ff8 100644 --- a/lib/Lex/Pragma.cpp +++ b/lib/Lex/Pragma.cpp @@ -354,7 +354,9 @@ void Preprocessor::HandleMicrosoft__pragma(Token &Tok) { /// HandlePragmaOnce - Handle \#pragma once. OnceTok is the 'once'. /// void Preprocessor::HandlePragmaOnce(Token &OnceTok) { - if (isInPrimaryFile()) { + // Don't honor the 'once' when handling the primary source file, unless + // this is a prefix to a TU, which indicates we're generating a PCH file. + if (isInPrimaryFile() && TUKind != TU_Prefix) { Diag(OnceTok, diag::pp_pragma_once_in_main_file); return; } diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp index 47d1326b7989..3e87a73aafe8 100644 --- a/lib/Parse/ParseExpr.cpp +++ b/lib/Parse/ParseExpr.cpp @@ -447,14 +447,15 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) { LHS = Actions.ActOnBinOp(getCurScope(), OpToken.getLocation(), OpToken.getKind(), LHS.get(), RHS.get()); - // In this case, ActOnBinOp performed the CorrectDelayedTyposInExpr check. - if (!getLangOpts().CPlusPlus) - continue; } else { LHS = Actions.ActOnConditionalOp(OpToken.getLocation(), ColonLoc, LHS.get(), TernaryMiddle.get(), RHS.get()); } + // In this case, ActOnBinOp or ActOnConditionalOp performed the + // CorrectDelayedTyposInExpr check. + if (!getLangOpts().CPlusPlus) + continue; } // Ensure potential typos aren't left undiagnosed. if (LHS.isInvalid()) { diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp index b09d7dbc12fc..85c1301fc967 100644 --- a/lib/Parse/ParseExprCXX.cpp +++ b/lib/Parse/ParseExprCXX.cpp @@ -1053,58 +1053,6 @@ bool Parser::TryParseLambdaIntroducer(LambdaIntroducer &Intro) { return false; } -static void -tryConsumeMutableOrConstexprToken(Parser &P, SourceLocation &MutableLoc, - SourceLocation &ConstexprLoc, - SourceLocation &DeclEndLoc) { - assert(MutableLoc.isInvalid()); - assert(ConstexprLoc.isInvalid()); - // Consume constexpr-opt mutable-opt in any sequence, and set the DeclEndLoc - // to the final of those locations. Emit an error if we have multiple - // copies of those keywords and recover. - - while (true) { - switch (P.getCurToken().getKind()) { - case tok::kw_mutable: { - if (MutableLoc.isValid()) { - P.Diag(P.getCurToken().getLocation(), - diag::err_lambda_decl_specifier_repeated) - << 0 << FixItHint::CreateRemoval(P.getCurToken().getLocation()); - } - MutableLoc = P.ConsumeToken(); - DeclEndLoc = MutableLoc; - break /*switch*/; - } - case tok::kw_constexpr: - if (ConstexprLoc.isValid()) { - P.Diag(P.getCurToken().getLocation(), - diag::err_lambda_decl_specifier_repeated) - << 1 << FixItHint::CreateRemoval(P.getCurToken().getLocation()); - } - ConstexprLoc = P.ConsumeToken(); - DeclEndLoc = ConstexprLoc; - break /*switch*/; - default: - return; - } - } -} - -static void -addConstexprToLambdaDeclSpecifier(Parser &P, SourceLocation ConstexprLoc, - DeclSpec &DS) { - if (ConstexprLoc.isValid()) { - P.Diag(ConstexprLoc, !P.getLangOpts().CPlusPlus1z - ? diag::ext_constexpr_on_lambda_cxx1z - : diag::warn_cxx14_compat_constexpr_on_lambda); - const char *PrevSpec = nullptr; - unsigned DiagID = 0; - DS.SetConstexprSpec(ConstexprLoc, PrevSpec, DiagID); - assert(PrevSpec == nullptr && DiagID == 0 && - "Constexpr cannot have been set previously!"); - } -} - /// ParseLambdaExpressionAfterIntroducer - Parse the rest of a lambda /// expression. ExprResult Parser::ParseLambdaExpressionAfterIntroducer( @@ -1163,13 +1111,10 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer( // compatible with MSVC. MaybeParseMicrosoftDeclSpecs(Attr, &DeclEndLoc); - // Parse mutable-opt and/or constexpr-opt, and update the DeclEndLoc. + // Parse 'mutable'[opt]. SourceLocation MutableLoc; - SourceLocation ConstexprLoc; - tryConsumeMutableOrConstexprToken(*this, MutableLoc, ConstexprLoc, - DeclEndLoc); - - addConstexprToLambdaDeclSpecifier(*this, ConstexprLoc, DS); + if (TryConsumeToken(tok::kw_mutable, MutableLoc)) + DeclEndLoc = MutableLoc; // Parse exception-specification[opt]. ExceptionSpecificationType ESpecType = EST_None; @@ -1227,8 +1172,7 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer( LParenLoc, FunLocalRangeEnd, D, TrailingReturnType), Attr, DeclEndLoc); - } else if (Tok.isOneOf(tok::kw_mutable, tok::arrow, tok::kw___attribute, - tok::kw_constexpr) || + } else if (Tok.isOneOf(tok::kw_mutable, tok::arrow, tok::kw___attribute) || (Tok.is(tok::l_square) && NextToken().is(tok::l_square))) { // It's common to forget that one needs '()' before 'mutable', an attribute // specifier, or the result type. Deal with this. @@ -1238,7 +1182,6 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer( case tok::arrow: TokKind = 1; break; case tok::kw___attribute: case tok::l_square: TokKind = 2; break; - case tok::kw_constexpr: TokKind = 3; break; default: llvm_unreachable("Unknown token kind"); } diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index 0c25e01787c1..b8e7ede2716c 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -6523,6 +6523,12 @@ CheckReturnStackAddr(Sema &S, Expr *RetValExp, QualType lhsType, if (!stackE) return; // Nothing suspicious was found. + // Parameters are initalized in the calling scope, so taking the address + // of a parameter reference doesn't need a warning. + for (auto *DRE : refVars) + if (isa(DRE->getDecl())) + return; + SourceLocation diagLoc; SourceRange diagRange; if (refVars.empty()) { @@ -6546,6 +6552,13 @@ CheckReturnStackAddr(Sema &S, Expr *RetValExp, QualType lhsType, } else if (isa(stackE)) { // address of label. S.Diag(diagLoc, diag::warn_ret_addr_label) << diagRange; } else { // local temporary. + // If there is an LValue->RValue conversion, then the value of the + // reference type is used, not the reference. + if (auto *ICE = dyn_cast(RetValExp)) { + if (ICE->getCastKind() == CK_LValueToRValue) { + return; + } + } S.Diag(diagLoc, diag::warn_ret_local_temp_addr_ref) << lhsType->isReferenceType() << diagRange; } @@ -7776,6 +7789,12 @@ bool AnalyzeBitFieldAssignment(Sema &S, FieldDecl *Bitfield, Expr *Init, unsigned OriginalWidth = Value.getBitWidth(); unsigned FieldWidth = Bitfield->getBitWidthValue(S.Context); + if (Value.isSigned() && Value.isNegative()) + if (UnaryOperator *UO = dyn_cast(OriginalInit)) + if (UO->getOpcode() == UO_Minus) + if (isa(UO->getSubExpr())) + OriginalWidth = Value.getMinSignedBits(); + if (OriginalWidth <= FieldWidth) return false; @@ -9372,7 +9391,8 @@ void Sema::CheckUnsequencedOperations(Expr *E) { void Sema::CheckCompletedExpr(Expr *E, SourceLocation CheckLoc, bool IsConstexpr) { CheckImplicitConversions(E, CheckLoc); - CheckUnsequencedOperations(E); + if (!E->isInstantiationDependent()) + CheckUnsequencedOperations(E); if (!IsConstexpr && !E->isValueDependent()) CheckForIntOverflow(E); } diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 2cd00f8218a6..b7a968e09d4d 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -961,32 +961,26 @@ static QualType adjustCVQualifiersForCXXThisWithinLambda( QualType Sema::getCurrentThisType() { DeclContext *DC = getFunctionLevelDeclContext(); QualType ThisTy = CXXThisTypeOverride; + if (CXXMethodDecl *method = dyn_cast(DC)) { if (method && method->isInstance()) ThisTy = method->getThisType(Context); } - if (ThisTy.isNull()) { - if (isGenericLambdaCallOperatorSpecialization(CurContext) && - CurContext->getParent()->getParent()->isRecord()) { - // This is a generic lambda call operator that is being instantiated - // within a default initializer - so use the enclosing class as 'this'. - // There is no enclosing member function to retrieve the 'this' pointer - // from. - - // FIXME: This looks wrong. If we're in a lambda within a lambda within a - // default member initializer, we need to recurse up more parents to find - // the right context. Looks like we should be walking up to the parent of - // the closure type, checking whether that is itself a lambda, and if so, - // recursing, until we reach a class or a function that isn't a lambda - // call operator. And we should accumulate the constness of *this on the - // way. - - QualType ClassTy = Context.getTypeDeclType( - cast(CurContext->getParent()->getParent())); - // There are no cv-qualifiers for 'this' within default initializers, - // per [expr.prim.general]p4. - ThisTy = Context.getPointerType(ClassTy); - } + + if (ThisTy.isNull() && isLambdaCallOperator(CurContext) && + !ActiveTemplateInstantiations.empty()) { + + assert(isa(DC) && + "Trying to get 'this' type from static method?"); + + // This is a lambda call operator that is being instantiated as a default + // initializer. DC must point to the enclosing class type, so we can recover + // the 'this' type from it. + + QualType ClassTy = Context.getTypeDeclType(cast(DC)); + // There are no cv-qualifiers for 'this' within default initializers, + // per [expr.prim.general]p4. + ThisTy = Context.getPointerType(ClassTy); } // If we are within a lambda's call operator, the cv-qualifiers of 'this' diff --git a/lib/Sema/SemaLambda.cpp b/lib/Sema/SemaLambda.cpp index 1b8410d7f4b9..8a2bf929dfc0 100644 --- a/lib/Sema/SemaLambda.cpp +++ b/lib/Sema/SemaLambda.cpp @@ -355,8 +355,7 @@ CXXMethodDecl *Sema::startLambdaDefinition(CXXRecordDecl *Class, SourceRange IntroducerRange, TypeSourceInfo *MethodTypeInfo, SourceLocation EndLoc, - ArrayRef Params, - const bool IsConstexprSpecified) { + ArrayRef Params) { QualType MethodType = MethodTypeInfo->getType(); TemplateParameterList *TemplateParams = getGenericLambdaTemplateParameterList(getCurLambda(), *this); @@ -393,7 +392,7 @@ CXXMethodDecl *Sema::startLambdaDefinition(CXXRecordDecl *Class, MethodType, MethodTypeInfo, SC_None, /*isInline=*/true, - IsConstexprSpecified, + /*isConstExpr=*/false, EndLoc); Method->setAccess(AS_public); @@ -878,9 +877,8 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro, CXXRecordDecl *Class = createLambdaClosureType(Intro.Range, MethodTyInfo, KnownDependent, Intro.Default); - CXXMethodDecl *Method = - startLambdaDefinition(Class, Intro.Range, MethodTyInfo, EndLoc, Params, - ParamInfo.getDeclSpec().isConstexprSpecified()); + CXXMethodDecl *Method = startLambdaDefinition(Class, Intro.Range, + MethodTyInfo, EndLoc, Params); if (ExplicitParams) CheckCXXDefaultArguments(Method); @@ -1599,17 +1597,6 @@ ExprResult Sema::BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc, CaptureInits, ArrayIndexVars, ArrayIndexStarts, EndLoc, ContainsUnexpandedParameterPack); - // If the lambda expression's call operator is not explicitly marked constexpr - // and we are not in a dependent context, analyze the call operator to infer - // its constexpr-ness, supressing diagnostics while doing so. - if (getLangOpts().CPlusPlus1z && !CallOperator->isInvalidDecl() && - !CallOperator->isConstexpr() && - !Class->getDeclContext()->isDependentContext()) { - TentativeAnalysisScope DiagnosticScopeGuard(*this); - CallOperator->setConstexpr( - CheckConstexprFunctionDecl(CallOperator) && - CheckConstexprFunctionBody(CallOperator, CallOperator->getBody())); - } if (!CurContext->isDependentContext()) { switch (ExprEvalContexts.back().Context) { diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index b025a397edca..40d6e910f1fb 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -5975,8 +5975,12 @@ EnableIfAttr *Sema::CheckEnableIf(FunctionDecl *Function, ArrayRef Args, SmallVector ConvertedArgs; bool InitializationFailed = false; + // Ignore any variadic parameters. Converting them is pointless, since the + // user can't refer to them in the enable_if condition. + unsigned ArgSizeNoVarargs = std::min(Function->param_size(), Args.size()); + // Convert the arguments. - for (unsigned I = 0, E = Args.size(); I != E; ++I) { + for (unsigned I = 0; I != ArgSizeNoVarargs; ++I) { ExprResult R; if (I == 0 && !MissingImplicitThis && isa(Function) && !cast(Function)->isStatic() && diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 36859f61d387..7224eef848de 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -10222,9 +10222,7 @@ TreeTransform::TransformLambdaExpr(LambdaExpr *E) { CXXMethodDecl *NewCallOperator = getSema().startLambdaDefinition( Class, E->getIntroducerRange(), NewCallOpTSI, E->getCallOperator()->getLocEnd(), - NewCallOpTSI->getTypeLoc().castAs().getParams(), - E->getCallOperator()->isConstexpr()); - + NewCallOpTSI->getTypeLoc().castAs().getParams()); LSI->CallOperator = NewCallOperator; getDerived().transformAttrs(E->getCallOperator(), NewCallOperator); diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index b35bd7bd329b..9d1554a826aa 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -8637,6 +8637,7 @@ void ASTReader::FinishedDeserializing() { auto Updates = std::move(PendingExceptionSpecUpdates); PendingExceptionSpecUpdates.clear(); for (auto Update : Updates) { + ProcessingUpdatesRAIIObj ProcessingUpdates(*this); auto *FPT = Update.second->getType()->castAs(); auto ESI = FPT->getExtProtoInfo().ExceptionSpec; if (auto *Listener = Context.getASTMutationListener()) @@ -8707,6 +8708,7 @@ ASTReader::ASTReader( AllowConfigurationMismatch(AllowConfigurationMismatch), ValidateSystemInputs(ValidateSystemInputs), UseGlobalIndex(UseGlobalIndex), TriedLoadingGlobalIndex(false), + ProcessingUpdateRecords(false), CurrSwitchCaseStmts(&SwitchCaseStmts), NumSLocEntriesRead(0), TotalNumSLocEntries(0), NumStatementsRead(0), TotalNumStatements(0), NumMacrosRead(0), TotalNumMacros(0), NumIdentifierLookups(0), diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp index 4fd7aeb83ac1..d38a701c04b5 100644 --- a/lib/Serialization/ASTReaderDecl.cpp +++ b/lib/Serialization/ASTReaderDecl.cpp @@ -3484,6 +3484,7 @@ void ASTReader::loadDeclUpdateRecords(serialization::DeclID ID, Decl *D) { // The declaration may have been modified by files later in the chain. // If this is the case, read the record containing the updates from each file // and pass it to ASTDeclReader to make the modifications. + ProcessingUpdatesRAIIObj ProcessingUpdates(*this); DeclUpdateOffsetsMap::iterator UpdI = DeclUpdateOffsets.find(ID); if (UpdI != DeclUpdateOffsets.end()) { auto UpdateOffsets = std::move(UpdI->second); @@ -3902,11 +3903,8 @@ void ASTDeclReader::UpdateDecl(Decl *D, ModuleFile &ModuleFile, } case UPD_DECL_MARKED_USED: { - // FIXME: This doesn't send the right notifications if there are - // ASTMutationListeners other than an ASTWriter. - // Maintain AST consistency: any later redeclarations are used too. - D->setIsUsed(); + D->markUsed(Reader.Context); break; } @@ -3930,11 +3928,8 @@ void ASTDeclReader::UpdateDecl(Decl *D, ModuleFile &ModuleFile, Exported = TD->getDefinition(); Module *Owner = SubmoduleID ? Reader.getSubmodule(SubmoduleID) : nullptr; if (Reader.getContext().getLangOpts().ModulesLocalVisibility) { - // FIXME: This doesn't send the right notifications if there are - // ASTMutationListeners other than an ASTWriter. - Reader.getContext().mergeDefinitionIntoModule( - cast(Exported), Owner, - /*NotifyListeners*/ false); + Reader.getContext().mergeDefinitionIntoModule(cast(Exported), + Owner); Reader.PendingMergedDefinitionsToDeduplicate.insert( cast(Exported)); } else if (Owner && Owner->NameVisibility != Module::AllVisible) { diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp index bb6a8ae8f628..7589b0c5dd52 100644 --- a/lib/Serialization/ASTWriter.cpp +++ b/lib/Serialization/ASTWriter.cpp @@ -5637,6 +5637,7 @@ void ASTWriter::ModuleRead(serialization::SubmoduleID ID, Module *Mod) { } void ASTWriter::CompletedTagDefinition(const TagDecl *D) { + if (Chain && Chain->isProcessingUpdateRecords()) return; assert(D->isCompleteDefinition()); assert(!WritingAST && "Already writing the AST!"); if (auto *RD = dyn_cast(D)) { @@ -5663,7 +5664,8 @@ static bool isImportedDeclContext(ASTReader *Chain, const Decl *D) { } void ASTWriter::AddedVisibleDecl(const DeclContext *DC, const Decl *D) { - assert(DC->isLookupContext() && + if (Chain && Chain->isProcessingUpdateRecords()) return; + assert(DC->isLookupContext() && "Should not add lookup results to non-lookup contexts!"); // TU is handled elsewhere. @@ -5697,6 +5699,7 @@ void ASTWriter::AddedVisibleDecl(const DeclContext *DC, const Decl *D) { } void ASTWriter::AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D) { + if (Chain && Chain->isProcessingUpdateRecords()) return; assert(D->isImplicit()); // We're only interested in cases where a local declaration is added to an @@ -5714,6 +5717,7 @@ void ASTWriter::AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D) { } void ASTWriter::ResolvedExceptionSpec(const FunctionDecl *FD) { + if (Chain && Chain->isProcessingUpdateRecords()) return; assert(!DoneWritingDeclsAndTypes && "Already done writing updates!"); if (!Chain) return; Chain->forEachImportedKeyDecl(FD, [&](const Decl *D) { @@ -5728,6 +5732,7 @@ void ASTWriter::ResolvedExceptionSpec(const FunctionDecl *FD) { } void ASTWriter::DeducedReturnType(const FunctionDecl *FD, QualType ReturnType) { + if (Chain && Chain->isProcessingUpdateRecords()) return; assert(!WritingAST && "Already writing the AST!"); if (!Chain) return; Chain->forEachImportedKeyDecl(FD, [&](const Decl *D) { @@ -5738,6 +5743,7 @@ void ASTWriter::DeducedReturnType(const FunctionDecl *FD, QualType ReturnType) { void ASTWriter::ResolvedOperatorDelete(const CXXDestructorDecl *DD, const FunctionDecl *Delete) { + if (Chain && Chain->isProcessingUpdateRecords()) return; assert(!WritingAST && "Already writing the AST!"); assert(Delete && "Not given an operator delete"); if (!Chain) return; @@ -5747,6 +5753,7 @@ void ASTWriter::ResolvedOperatorDelete(const CXXDestructorDecl *DD, } void ASTWriter::CompletedImplicitDefinition(const FunctionDecl *D) { + if (Chain && Chain->isProcessingUpdateRecords()) return; assert(!WritingAST && "Already writing the AST!"); if (!D->isFromASTFile()) return; // Declaration not imported from PCH. @@ -5756,6 +5763,7 @@ void ASTWriter::CompletedImplicitDefinition(const FunctionDecl *D) { } void ASTWriter::FunctionDefinitionInstantiated(const FunctionDecl *D) { + if (Chain && Chain->isProcessingUpdateRecords()) return; assert(!WritingAST && "Already writing the AST!"); if (!D->isFromASTFile()) return; @@ -5764,6 +5772,7 @@ void ASTWriter::FunctionDefinitionInstantiated(const FunctionDecl *D) { } void ASTWriter::StaticDataMemberInstantiated(const VarDecl *D) { + if (Chain && Chain->isProcessingUpdateRecords()) return; assert(!WritingAST && "Already writing the AST!"); if (!D->isFromASTFile()) return; @@ -5776,6 +5785,7 @@ void ASTWriter::StaticDataMemberInstantiated(const VarDecl *D) { } void ASTWriter::DefaultArgumentInstantiated(const ParmVarDecl *D) { + if (Chain && Chain->isProcessingUpdateRecords()) return; assert(!WritingAST && "Already writing the AST!"); if (!D->isFromASTFile()) return; @@ -5786,6 +5796,7 @@ void ASTWriter::DefaultArgumentInstantiated(const ParmVarDecl *D) { void ASTWriter::AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD, const ObjCInterfaceDecl *IFD) { + if (Chain && Chain->isProcessingUpdateRecords()) return; assert(!WritingAST && "Already writing the AST!"); if (!IFD->isFromASTFile()) return; // Declaration not imported from PCH. @@ -5796,6 +5807,7 @@ void ASTWriter::AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD, } void ASTWriter::DeclarationMarkedUsed(const Decl *D) { + if (Chain && Chain->isProcessingUpdateRecords()) return; assert(!WritingAST && "Already writing the AST!"); // If there is *any* declaration of the entity that's not from an AST file, @@ -5809,6 +5821,7 @@ void ASTWriter::DeclarationMarkedUsed(const Decl *D) { } void ASTWriter::DeclarationMarkedOpenMPThreadPrivate(const Decl *D) { + if (Chain && Chain->isProcessingUpdateRecords()) return; assert(!WritingAST && "Already writing the AST!"); if (!D->isFromASTFile()) return; @@ -5818,6 +5831,7 @@ void ASTWriter::DeclarationMarkedOpenMPThreadPrivate(const Decl *D) { void ASTWriter::DeclarationMarkedOpenMPDeclareTarget(const Decl *D, const Attr *Attr) { + if (Chain && Chain->isProcessingUpdateRecords()) return; assert(!WritingAST && "Already writing the AST!"); if (!D->isFromASTFile()) return; @@ -5827,6 +5841,7 @@ void ASTWriter::DeclarationMarkedOpenMPDeclareTarget(const Decl *D, } void ASTWriter::RedefinedHiddenDefinition(const NamedDecl *D, Module *M) { + if (Chain && Chain->isProcessingUpdateRecords()) return; assert(!WritingAST && "Already writing the AST!"); assert(D->isHidden() && "expected a hidden declaration"); DeclUpdates[D].push_back(DeclUpdate(UPD_DECL_EXPORTED, M)); @@ -5834,6 +5849,7 @@ void ASTWriter::RedefinedHiddenDefinition(const NamedDecl *D, Module *M) { void ASTWriter::AddedAttributeToRecord(const Attr *Attr, const RecordDecl *Record) { + if (Chain && Chain->isProcessingUpdateRecords()) return; assert(!WritingAST && "Already writing the AST!"); if (!Record->isFromASTFile()) return; diff --git a/test/CXX/special/class.copy/p11.0x.move.cpp b/test/CXX/special/class.copy/p11.0x.move.cpp index 514817d2b71c..ab4259548e74 100644 --- a/test/CXX/special/class.copy/p11.0x.move.cpp +++ b/test/CXX/special/class.copy/p11.0x.move.cpp @@ -4,6 +4,9 @@ struct Trivial {}; struct NonTrivial { NonTrivial(NonTrivial&&); // expected-note{{copy constructor is implicitly deleted}} }; +struct DeletedCopy { + DeletedCopy(const DeletedCopy&) = delete; +}; // A defaulted move constructor for a class X is defined as deleted if X has: @@ -22,6 +25,15 @@ struct DeletedNTVariant2 { }; DeletedNTVariant2::DeletedNTVariant2(DeletedNTVariant2&&) = default; // expected-error{{would delete}} +// Note, move constructor is not a candidate because it is deleted. +template struct DeletedNTVariant3 { // expected-note 2{{default}} expected-note 2{{copy}} + union { + T NT; + }; +}; +extern DeletedNTVariant3 dntv3a(0); // expected-error {{no matching}} +extern DeletedNTVariant3 dntv3a(0); // expected-error {{no matching}} + // -- a non-static data member of class type M (or array thereof) that cannot be // copied because overload resolution results in an ambiguity or a function // that is deleted or inaccessible diff --git a/test/CodeGen/avx-builtins.c b/test/CodeGen/avx-builtins.c index bf3e8cc5db60..650e4d280ecb 100644 --- a/test/CodeGen/avx-builtins.c +++ b/test/CodeGen/avx-builtins.c @@ -286,13 +286,13 @@ __m256d test_mm256_cvtps_pd(__m128 A) { __m128i test_mm256_cvttpd_epi32(__m256d A) { // CHECK-LABEL: test_mm256_cvttpd_epi32 - // CHECK: fptosi <4 x double> %{{.*}} to <4 x i32> + // CHECK: call <4 x i32> @llvm.x86.avx.cvtt.pd2dq.256(<4 x double> %{{.*}}) return _mm256_cvttpd_epi32(A); } __m256i test_mm256_cvttps_epi32(__m256 A) { // CHECK-LABEL: test_mm256_cvttps_epi32 - // CHECK: fptosi <8 x float> %{{.*}} to <8 x i32> + // CHECK: call <8 x i32> @llvm.x86.avx.cvtt.ps2dq.256(<8 x float> %{{.*}}) return _mm256_cvttps_epi32(A); } diff --git a/test/CodeGen/builtins-x86.c b/test/CodeGen/builtins-x86.c index 55e473fa4e4a..8fa24e668f74 100644 --- a/test/CodeGen/builtins-x86.c +++ b/test/CodeGen/builtins-x86.c @@ -287,12 +287,14 @@ void f0() { tmp_V4f = __builtin_ia32_cvtpi2ps(tmp_V4f, tmp_V2i); tmp_V2i = __builtin_ia32_cvtps2pi(tmp_V4f); tmp_i = __builtin_ia32_cvtss2si(tmp_V4f); + tmp_i = __builtin_ia32_cvttss2si(tmp_V4f); tmp_i = __builtin_ia32_rdtsc(); tmp_i = __builtin_ia32_rdtscp(&tmp_Ui); tmp_LLi = __builtin_ia32_rdpmc(tmp_i); #ifdef USE_64 tmp_LLi = __builtin_ia32_cvtss2si64(tmp_V4f); + tmp_LLi = __builtin_ia32_cvttss2si64(tmp_V4f); #endif tmp_V2i = __builtin_ia32_cvttps2pi(tmp_V4f); (void) __builtin_ia32_maskmovq(tmp_V8c, tmp_V8c, tmp_cp); @@ -328,10 +330,14 @@ void f0() { tmp_V2i = __builtin_ia32_cvttpd2pi(tmp_V2d); tmp_V2d = __builtin_ia32_cvtpi2pd(tmp_V2i); tmp_i = __builtin_ia32_cvtsd2si(tmp_V2d); + tmp_i = __builtin_ia32_cvttsd2si(tmp_V2d); + tmp_V4f = __builtin_ia32_cvtsd2ss(tmp_V4f, tmp_V2d); #ifdef USE_64 tmp_LLi = __builtin_ia32_cvtsd2si64(tmp_V2d); + tmp_LLi = __builtin_ia32_cvttsd2si64(tmp_V2d); #endif tmp_V4i = __builtin_ia32_cvtps2dq(tmp_V4f); + tmp_V4i = __builtin_ia32_cvttps2dq(tmp_V4f); (void) __builtin_ia32_clflush(tmp_vCp); (void) __builtin_ia32_lfence(); (void) __builtin_ia32_mfence(); @@ -410,7 +416,9 @@ void f0() { tmp_V8f = __builtin_ia32_cvtdq2ps256(tmp_V8i); tmp_V4f = __builtin_ia32_cvtpd2ps256(tmp_V4d); tmp_V8i = __builtin_ia32_cvtps2dq256(tmp_V8f); + tmp_V4i = __builtin_ia32_cvttpd2dq256(tmp_V4d); tmp_V4i = __builtin_ia32_cvtpd2dq256(tmp_V4d); + tmp_V8i = __builtin_ia32_cvttps2dq256(tmp_V8f); tmp_V4d = __builtin_ia32_vperm2f128_pd256(tmp_V4d, tmp_V4d, 0x7); tmp_V8f = __builtin_ia32_vperm2f128_ps256(tmp_V8f, tmp_V8f, 0x7); tmp_V8i = __builtin_ia32_vperm2f128_si256(tmp_V8i, tmp_V8i, 0x7); diff --git a/test/CodeGen/forwarding-blocks-if.c b/test/CodeGen/forwarding-blocks-if.c deleted file mode 100644 index 51711bf0ef46..000000000000 --- a/test/CodeGen/forwarding-blocks-if.c +++ /dev/null @@ -1,36 +0,0 @@ -// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s -// Check that no empty blocks are generated for nested ifs. - -extern void func(); - -int f0(int val) { - if (val == 0) { - func(); - } else if (val == 1) { - func(); - } - return 0; -} - -// CHECK-LABEL: define {{.*}}i32 @f0 -// CHECK: call void {{.*}} @func -// CHECK: call void {{.*}} @func -// CHECK: br label %[[RETBLOCK1:[^ ]*]] -// CHECK: [[RETBLOCK1]]: -// CHECK-NOT: br label -// CHECK: ret i32 - -int f1(int val, int g) { - if (val == 0) - if (g == 1) { - func(); - } - return 0; -} - -// CHECK-LABEL: define {{.*}}i32 @f1 -// CHECK: call void {{.*}} @func -// CHECK: br label %[[RETBLOCK2:[^ ]*]] -// CHECK: [[RETBLOCK2]]: -// CHECK-NOT: br label -// CHECK: ret i32 diff --git a/test/CodeGen/sse-builtins.c b/test/CodeGen/sse-builtins.c index a6c5c1a0a166..6f313b825c9a 100644 --- a/test/CodeGen/sse-builtins.c +++ b/test/CodeGen/sse-builtins.c @@ -295,22 +295,19 @@ long long test_mm_cvtss_si64(__m128 A) { int test_mm_cvtt_ss2si(__m128 A) { // CHECK-LABEL: test_mm_cvtt_ss2si - // CHECK: extractelement <4 x float> %{{.*}}, i32 0 - // CHECK: fptosi float %{{.*}} to i32 + // CHECK: call i32 @llvm.x86.sse.cvttss2si(<4 x float> %{{.*}}) return _mm_cvtt_ss2si(A); } int test_mm_cvttss_si32(__m128 A) { // CHECK-LABEL: test_mm_cvttss_si32 - // CHECK: extractelement <4 x float> %{{.*}}, i32 0 - // CHECK: fptosi float %{{.*}} to i32 + // CHECK: call i32 @llvm.x86.sse.cvttss2si(<4 x float> %{{.*}}) return _mm_cvttss_si32(A); } long long test_mm_cvttss_si64(__m128 A) { // CHECK-LABEL: test_mm_cvttss_si64 - // CHECK: extractelement <4 x float> %{{.*}}, i32 0 - // CHECK: fptosi float %{{.*}} to i64 + // CHECK: call i64 @llvm.x86.sse.cvttss2si64(<4 x float> %{{.*}}) return _mm_cvttss_si64(A); } diff --git a/test/CodeGen/sse2-builtins.c b/test/CodeGen/sse2-builtins.c index b340d1a27553..ee9dca7d4451 100644 --- a/test/CodeGen/sse2-builtins.c +++ b/test/CodeGen/sse2-builtins.c @@ -507,7 +507,7 @@ long long test_mm_cvtsd_si64(__m128d A) { __m128 test_mm_cvtsd_ss(__m128 A, __m128d B) { // CHECK-LABEL: test_mm_cvtsd_ss - // CHECK: fptrunc double %{{.*}} to float + // CHECK: call <4 x float> @llvm.x86.sse2.cvtsd2ss(<4 x float> %{{.*}}, <2 x double> %{{.*}}) return _mm_cvtsd_ss(A, B); } @@ -569,21 +569,19 @@ __m128i test_mm_cvttpd_epi32(__m128d A) { __m128i test_mm_cvttps_epi32(__m128 A) { // CHECK-LABEL: test_mm_cvttps_epi32 - // CHECK: fptosi <4 x float> %{{.*}} to <4 x i32> + // CHECK: call <4 x i32> @llvm.x86.sse2.cvttps2dq(<4 x float> %{{.*}}) return _mm_cvttps_epi32(A); } int test_mm_cvttsd_si32(__m128d A) { // CHECK-LABEL: test_mm_cvttsd_si32 - // CHECK: extractelement <2 x double> %{{.*}}, i32 0 - // CHECK: fptosi double %{{.*}} to i32 + // CHECK: call i32 @llvm.x86.sse2.cvttsd2si(<2 x double> %{{.*}}) return _mm_cvttsd_si32(A); } long long test_mm_cvttsd_si64(__m128d A) { // CHECK-LABEL: test_mm_cvttsd_si64 - // CHECK: extractelement <2 x double> %{{.*}}, i32 0 - // CHECK: fptosi double %{{.*}} to i64 + // CHECK: call i64 @llvm.x86.sse2.cvttsd2si64(<2 x double> %{{.*}}) return _mm_cvttsd_si64(A); } diff --git a/test/CodeGen/target-data.c b/test/CodeGen/target-data.c index 49406a30e5d9..c12ad2c1c977 100644 --- a/test/CodeGen/target-data.c +++ b/test/CodeGen/target-data.c @@ -40,19 +40,19 @@ // RUN: %clang_cc1 -triple mips64el-linux-gnu -o - -emit-llvm %s | \ // RUN: FileCheck %s -check-prefix=MIPS-64EL -// MIPS-64EL: target datalayout = "e-m:m-i8:8:32-i16:16:32-i64:64-n32:64-S128" +// MIPS-64EL: target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128" // RUN: %clang_cc1 -triple mips64el-linux-gnu -o - -emit-llvm -target-abi n32 \ // RUN: %s | FileCheck %s -check-prefix=MIPS-64EL-N32 -// MIPS-64EL-N32: target datalayout = "e-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32:64-S128" +// MIPS-64EL-N32: target datalayout = "e-m:e-p:32:32-i8:8:32-i16:16:32-i64:64-n32:64-S128" // RUN: %clang_cc1 -triple mips64-linux-gnu -o - -emit-llvm %s | \ // RUN: FileCheck %s -check-prefix=MIPS-64EB -// MIPS-64EB: target datalayout = "E-m:m-i8:8:32-i16:16:32-i64:64-n32:64-S128" +// MIPS-64EB: target datalayout = "E-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128" // RUN: %clang_cc1 -triple mips64-linux-gnu -o - -emit-llvm %s -target-abi n32 \ // RUN: | FileCheck %s -check-prefix=MIPS-64EB-N32 -// MIPS-64EB-N32: target datalayout = "E-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32:64-S128" +// MIPS-64EB-N32: target datalayout = "E-m:e-p:32:32-i8:8:32-i16:16:32-i64:64-n32:64-S128" // RUN: %clang_cc1 -triple powerpc64-lv2 -o - -emit-llvm %s | \ // RUN: FileCheck %s -check-prefix=PS3 diff --git a/test/CodeGenCXX/debug-info-cxx1y.cpp b/test/CodeGenCXX/debug-info-cxx1y.cpp index faf29d3ed11b..36b3e09180c6 100644 --- a/test/CodeGenCXX/debug-info-cxx1y.cpp +++ b/test/CodeGenCXX/debug-info-cxx1y.cpp @@ -1,16 +1,25 @@ // RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm-only -std=c++14 -emit-llvm -debug-info-kind=limited %s -o - | FileCheck %s +// CHECK: imports: [[IMPS:![0-9]*]] // CHECK: [[EMPTY:![0-9]*]] = !{} + // CHECK: [[FOO:![0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "foo", // CHECK-SAME: elements: [[EMPTY]] -// FIXME: The context of this definition should be the CU/file scope, not the class. -// CHECK: !DISubprogram(name: "func", {{.*}} scope: [[FOO]] + +// CHECK: [[IMPS]] = !{[[IMP:![0-9]*]]} +// CHECK: [[IMP]] = !DIImportedEntity( +// CHECK-SAME: entity: [[F3:![0-9]*]] +// CHECK: [[F3]] = distinct !DISubprogram(name: "f3" // CHECK-SAME: type: [[SUBROUTINE_TYPE:![0-9]*]] -// CHECK-SAME: isDefinition: true -// CHECK-SAME: declaration: [[FUNC_DECL:![0-9]*]] // CHECK: [[SUBROUTINE_TYPE]] = !DISubroutineType(types: [[TYPE_LIST:![0-9]*]]) // CHECK: [[TYPE_LIST]] = !{[[INT:![0-9]*]]} // CHECK: [[INT]] = !DIBasicType(name: "int" + +// FIXME: The context of this definition should be the CU/file scope, not the class. +// CHECK: !DISubprogram(name: "func", {{.*}} scope: [[FOO]] +// CHECK-SAME: type: [[SUBROUTINE_TYPE]] +// CHECK-SAME: isDefinition: true +// CHECK-SAME: declaration: [[FUNC_DECL:![0-9]*]] // CHECK: [[FUNC_DECL]] = !DISubprogram(name: "func", // CHECK-SAME: scope: [[FOO]] // CHECK-SAME: type: [[SUBROUTINE_TYPE]] @@ -25,3 +34,12 @@ foo f; auto foo::func() { return 1; } + +namespace ns { +auto f2(); +auto f3() { + return 0; +} +} +using ns::f2; +using ns::f3; diff --git a/test/CodeGenCXX/switch-case-folding-2.cpp b/test/CodeGenCXX/switch-case-folding-2.cpp index b0bbf3282ac3..558ca3c87d9b 100644 --- a/test/CodeGenCXX/switch-case-folding-2.cpp +++ b/test/CodeGenCXX/switch-case-folding-2.cpp @@ -18,4 +18,13 @@ int main(void) { return test(5); } +void other_test() { + switch(0) { + case 0: + do { + default:; + } while(0); + } +} + // CHECK: call i32 (i8*, ...) @_Z6printfPKcz diff --git a/test/CodeGenOpenCL/cl20-device-side-enqueue.cl b/test/CodeGenOpenCL/cl20-device-side-enqueue.cl index 08b24bdc5bec..783ce0254a1a 100644 --- a/test/CodeGenOpenCL/cl20-device-side-enqueue.cl +++ b/test/CodeGenOpenCL/cl20-device-side-enqueue.cl @@ -21,7 +21,7 @@ kernel void device_side_enqueue(global int *a, global int *b, int i) { // CHECK: [[DEF_Q:%[0-9]+]] = load %opencl.queue_t*, %opencl.queue_t** %default_queue // CHECK: [[FLAGS:%[0-9]+]] = load i32, i32* %flags // CHECK: [[NDR:%[0-9]+]] = load %opencl.ndrange_t*, %opencl.ndrange_t** %ndrange - // CHECK: [[BL:%[0-9]+]] = bitcast <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32{{.*}}, i32{{.*}}, i32{{.*}} }>* %block to void ()* + // CHECK: [[BL:%[0-9]+]] = bitcast <{ i8*, i32, i32, i8*, %struct.__block_descriptor addrspace(3)*, i32{{.*}}, i32{{.*}}, i32{{.*}} }>* %block to void ()* // CHECK: [[BL_I8:%[0-9]+]] = bitcast void ()* [[BL]] to i8* // CHECK: call i32 @__enqueue_kernel_basic(%opencl.queue_t* [[DEF_Q]], i32 [[FLAGS]], %opencl.ndrange_t* [[NDR]], i8* [[BL_I8]]) enqueue_kernel(default_queue, flags, ndrange, @@ -32,7 +32,7 @@ kernel void device_side_enqueue(global int *a, global int *b, int i) { // CHECK: [[DEF_Q:%[0-9]+]] = load %opencl.queue_t*, %opencl.queue_t** %default_queue // CHECK: [[FLAGS:%[0-9]+]] = load i32, i32* %flags // CHECK: [[NDR:%[0-9]+]] = load %opencl.ndrange_t*, %opencl.ndrange_t** %ndrange - // CHECK: [[BL:%[0-9]+]] = bitcast <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32{{.*}}, i32{{.*}}, i32{{.*}} }>* %block3 to void ()* + // CHECK: [[BL:%[0-9]+]] = bitcast <{ i8*, i32, i32, i8*, %struct.__block_descriptor addrspace(3)*, i32{{.*}}, i32{{.*}}, i32{{.*}} }>* %block3 to void ()* // CHECK: [[BL_I8:%[0-9]+]] = bitcast void ()* [[BL]] to i8* // CHECK: call i32 @__enqueue_kernel_basic_events(%opencl.queue_t* [[DEF_Q]], i32 [[FLAGS]], %opencl.ndrange_t* [[NDR]], i32 2, %opencl.clk_event_t** %event_wait_list, %opencl.clk_event_t** %clk_event, i8* [[BL_I8]]) enqueue_kernel(default_queue, flags, ndrange, 2, &event_wait_list, &clk_event, @@ -43,7 +43,7 @@ kernel void device_side_enqueue(global int *a, global int *b, int i) { // CHECK: [[DEF_Q:%[0-9]+]] = load %opencl.queue_t*, %opencl.queue_t** %default_queue // CHECK: [[FLAGS:%[0-9]+]] = load i32, i32* %flags // CHECK: [[NDR:%[0-9]+]] = load %opencl.ndrange_t*, %opencl.ndrange_t** %ndrange - // CHECK: call i32 (%opencl.queue_t*, i32, %opencl.ndrange_t*, i8*, i32, ...) @__enqueue_kernel_vaargs(%opencl.queue_t* [[DEF_Q]], i32 [[FLAGS]], %opencl.ndrange_t* [[NDR]], i8* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor* }* @__block_literal_global{{(.[0-9]+)?}} to i8*), i32 1, i32 256) + // CHECK: call i32 (%opencl.queue_t*, i32, %opencl.ndrange_t*, i8*, i32, ...) @__enqueue_kernel_vaargs(%opencl.queue_t* [[DEF_Q]], i32 [[FLAGS]], %opencl.ndrange_t* [[NDR]], i8* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor addrspace(3)* }* @__block_literal_global{{(.[0-9]+)?}} to i8*), i32 1, i32 256) enqueue_kernel(default_queue, flags, ndrange, ^(local void *p) { return; @@ -54,7 +54,7 @@ kernel void device_side_enqueue(global int *a, global int *b, int i) { // CHECK: [[FLAGS:%[0-9]+]] = load i32, i32* %flags // CHECK: [[NDR:%[0-9]+]] = load %opencl.ndrange_t*, %opencl.ndrange_t** %ndrange // CHECK: [[SIZE:%[0-9]+]] = zext i8 {{%[0-9]+}} to i32 - // CHECK: call i32 (%opencl.queue_t*, i32, %opencl.ndrange_t*, i8*, i32, ...) @__enqueue_kernel_vaargs(%opencl.queue_t* [[DEF_Q]], i32 [[FLAGS]], %opencl.ndrange_t* [[NDR]], i8* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor* }* @__block_literal_global{{(.[0-9]+)?}} to i8*), i32 1, i32 [[SIZE]]) + // CHECK: call i32 (%opencl.queue_t*, i32, %opencl.ndrange_t*, i8*, i32, ...) @__enqueue_kernel_vaargs(%opencl.queue_t* [[DEF_Q]], i32 [[FLAGS]], %opencl.ndrange_t* [[NDR]], i8* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor addrspace(3)* }* @__block_literal_global{{(.[0-9]+)?}} to i8*), i32 1, i32 [[SIZE]]) enqueue_kernel(default_queue, flags, ndrange, ^(local void *p) { return; @@ -65,7 +65,7 @@ kernel void device_side_enqueue(global int *a, global int *b, int i) { // CHECK: [[FLAGS:%[0-9]+]] = load i32, i32* %flags // CHECK: [[NDR:%[0-9]+]] = load %opencl.ndrange_t*, %opencl.ndrange_t** %ndrange // CHECK: [[AD:%arraydecay[0-9]*]] = getelementptr inbounds [1 x %opencl.clk_event_t*], [1 x %opencl.clk_event_t*]* %event_wait_list2, i32 0, i32 0 - // CHECK: call i32 (%opencl.queue_t*, i32, %opencl.ndrange_t*, i32, %opencl.clk_event_t**, %opencl.clk_event_t**, i8*, i32, ...) @__enqueue_kernel_events_vaargs(%opencl.queue_t* [[DEF_Q]], i32 [[FLAGS]], %opencl.ndrange_t* [[NDR]], i32 2, %opencl.clk_event_t** [[AD]], %opencl.clk_event_t** %clk_event, i8* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor* }* @__block_literal_global{{(.[0-9]+)?}} to i8*), i32 1, i32 256) + // CHECK: call i32 (%opencl.queue_t*, i32, %opencl.ndrange_t*, i32, %opencl.clk_event_t**, %opencl.clk_event_t**, i8*, i32, ...) @__enqueue_kernel_events_vaargs(%opencl.queue_t* [[DEF_Q]], i32 [[FLAGS]], %opencl.ndrange_t* [[NDR]], i32 2, %opencl.clk_event_t** [[AD]], %opencl.clk_event_t** %clk_event, i8* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor addrspace(3)* }* @__block_literal_global{{(.[0-9]+)?}} to i8*), i32 1, i32 256) enqueue_kernel(default_queue, flags, ndrange, 2, event_wait_list2, &clk_event, ^(local void *p) { return; @@ -77,7 +77,7 @@ kernel void device_side_enqueue(global int *a, global int *b, int i) { // CHECK: [[NDR:%[0-9]+]] = load %opencl.ndrange_t*, %opencl.ndrange_t** %ndrange // CHECK: [[AD:%arraydecay[0-9]*]] = getelementptr inbounds [1 x %opencl.clk_event_t*], [1 x %opencl.clk_event_t*]* %event_wait_list2, i32 0, i32 0 // CHECK: [[SIZE:%[0-9]+]] = zext i8 {{%[0-9]+}} to i32 - // CHECK: call i32 (%opencl.queue_t*, i32, %opencl.ndrange_t*, i32, %opencl.clk_event_t**, %opencl.clk_event_t**, i8*, i32, ...) @__enqueue_kernel_events_vaargs(%opencl.queue_t* [[DEF_Q]], i32 [[FLAGS]], %opencl.ndrange_t* [[NDR]], i32 2, %opencl.clk_event_t** [[AD]], %opencl.clk_event_t** %clk_event, i8* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor* }* @__block_literal_global{{(.[0-9]+)?}} to i8*), i32 1, i32 [[SIZE]]) + // CHECK: call i32 (%opencl.queue_t*, i32, %opencl.ndrange_t*, i32, %opencl.clk_event_t**, %opencl.clk_event_t**, i8*, i32, ...) @__enqueue_kernel_events_vaargs(%opencl.queue_t* [[DEF_Q]], i32 [[FLAGS]], %opencl.ndrange_t* [[NDR]], i32 2, %opencl.clk_event_t** [[AD]], %opencl.clk_event_t** %clk_event, i8* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor addrspace(3)* }* @__block_literal_global{{(.[0-9]+)?}} to i8*), i32 1, i32 [[SIZE]]) enqueue_kernel(default_queue, flags, ndrange, 2, event_wait_list2, &clk_event, ^(local void *p) { return; diff --git a/test/CodeGenOpenCL/to_addr_builtin.cl b/test/CodeGenOpenCL/to_addr_builtin.cl index 67475d565e3a..72c09da488d5 100644 --- a/test/CodeGenOpenCL/to_addr_builtin.cl +++ b/test/CodeGenOpenCL/to_addr_builtin.cl @@ -14,74 +14,74 @@ void test(void) { generic int *gen; //CHECK: %[[ARG:.*]] = addrspacecast i32 addrspace(1)* %{{.*}} to i8 addrspace(4)* - //CHECK: %[[RET:.*]] = call i8 addrspace(1)* @to_global(i8 addrspace(4)* %[[ARG]]) + //CHECK: %[[RET:.*]] = call i8 addrspace(1)* @__to_global(i8 addrspace(4)* %[[ARG]]) //CHECK: %{{.*}} = bitcast i8 addrspace(1)* %[[RET]] to i32 addrspace(1)* glob = to_global(glob); //CHECK: %[[ARG:.*]] = addrspacecast i32 addrspace(3)* %{{.*}} to i8 addrspace(4)* - //CHECK: %[[RET:.*]] = call i8 addrspace(1)* @to_global(i8 addrspace(4)* %[[ARG]]) + //CHECK: %[[RET:.*]] = call i8 addrspace(1)* @__to_global(i8 addrspace(4)* %[[ARG]]) //CHECK: %{{.*}} = bitcast i8 addrspace(1)* %[[RET]] to i32 addrspace(1)* glob = to_global(loc); //CHECK: %[[ARG:.*]] = addrspacecast i32* %{{.*}} to i8 addrspace(4)* - //CHECK: %[[RET:.*]] = call i8 addrspace(1)* @to_global(i8 addrspace(4)* %[[ARG]]) + //CHECK: %[[RET:.*]] = call i8 addrspace(1)* @__to_global(i8 addrspace(4)* %[[ARG]]) //CHECK: %{{.*}} = bitcast i8 addrspace(1)* %[[RET]] to i32 addrspace(1)* glob = to_global(priv); //CHECK: %[[ARG:.*]] = bitcast i32 addrspace(4)* %{{.*}} to i8 addrspace(4)* - //CHECK: %[[RET:.*]] = call i8 addrspace(1)* @to_global(i8 addrspace(4)* %[[ARG]]) + //CHECK: %[[RET:.*]] = call i8 addrspace(1)* @__to_global(i8 addrspace(4)* %[[ARG]]) //CHECK: %{{.*}} = bitcast i8 addrspace(1)* %[[RET]] to i32 addrspace(1)* glob = to_global(gen); //CHECK: %[[ARG:.*]] = addrspacecast i32 addrspace(1)* %{{.*}} to i8 addrspace(4)* - //CHECK: %[[RET:.*]] = call i8 addrspace(3)* @to_local(i8 addrspace(4)* %[[ARG]]) + //CHECK: %[[RET:.*]] = call i8 addrspace(3)* @__to_local(i8 addrspace(4)* %[[ARG]]) //CHECK: %{{.*}} = bitcast i8 addrspace(3)* %[[RET]] to i32 addrspace(3)* loc = to_local(glob); //CHECK: %[[ARG:.*]] = addrspacecast i32 addrspace(3)* %{{.*}} to i8 addrspace(4)* - //CHECK: %[[RET:.*]] = call i8 addrspace(3)* @to_local(i8 addrspace(4)* %[[ARG]]) + //CHECK: %[[RET:.*]] = call i8 addrspace(3)* @__to_local(i8 addrspace(4)* %[[ARG]]) //CHECK: %{{.*}} = bitcast i8 addrspace(3)* %[[RET]] to i32 addrspace(3)* loc = to_local(loc); //CHECK: %[[ARG:.*]] = addrspacecast i32* %{{.*}} to i8 addrspace(4)* - //CHECK: %[[RET:.*]] = call i8 addrspace(3)* @to_local(i8 addrspace(4)* %[[ARG]]) + //CHECK: %[[RET:.*]] = call i8 addrspace(3)* @__to_local(i8 addrspace(4)* %[[ARG]]) //CHECK: %{{.*}} = bitcast i8 addrspace(3)* %[[RET]] to i32 addrspace(3)* loc = to_local(priv); //CHECK: %[[ARG:.*]] = bitcast i32 addrspace(4)* %{{.*}} to i8 addrspace(4)* - //CHECK: %[[RET:.*]] = call i8 addrspace(3)* @to_local(i8 addrspace(4)* %[[ARG]]) + //CHECK: %[[RET:.*]] = call i8 addrspace(3)* @__to_local(i8 addrspace(4)* %[[ARG]]) //CHECK: %{{.*}} = bitcast i8 addrspace(3)* %[[RET]] to i32 addrspace(3)* loc = to_local(gen); //CHECK: %[[ARG:.*]] = addrspacecast i32 addrspace(1)* %{{.*}} to i8 addrspace(4)* - //CHECK: %[[RET:.*]] = call i8* @to_private(i8 addrspace(4)* %[[ARG]]) + //CHECK: %[[RET:.*]] = call i8* @__to_private(i8 addrspace(4)* %[[ARG]]) //CHECK: %{{.*}} = bitcast i8* %[[RET]] to i32* priv = to_private(glob); //CHECK: %[[ARG:.*]] = addrspacecast i32 addrspace(3)* %{{.*}} to i8 addrspace(4)* - //CHECK: %[[RET:.*]] = call i8* @to_private(i8 addrspace(4)* %[[ARG]]) + //CHECK: %[[RET:.*]] = call i8* @__to_private(i8 addrspace(4)* %[[ARG]]) //CHECK: %{{.*}} = bitcast i8* %[[RET]] to i32* priv = to_private(loc); //CHECK: %[[ARG:.*]] = addrspacecast i32* %{{.*}} to i8 addrspace(4)* - //CHECK: %[[RET:.*]] = call i8* @to_private(i8 addrspace(4)* %[[ARG]]) + //CHECK: %[[RET:.*]] = call i8* @__to_private(i8 addrspace(4)* %[[ARG]]) //CHECK: %{{.*}} = bitcast i8* %[[RET]] to i32* priv = to_private(priv); //CHECK: %[[ARG:.*]] = bitcast i32 addrspace(4)* %{{.*}} to i8 addrspace(4)* - //CHECK: %[[RET:.*]] = call i8* @to_private(i8 addrspace(4)* %[[ARG]]) + //CHECK: %[[RET:.*]] = call i8* @__to_private(i8 addrspace(4)* %[[ARG]]) //CHECK: %{{.*}} = bitcast i8* %[[RET]] to i32* priv = to_private(gen); //CHECK: %[[ARG:.*]] = addrspacecast %[[A]]* %{{.*}} to i8 addrspace(4)* - //CHECK: %[[RET:.*]] = call i8 addrspace(1)* @to_global(i8 addrspace(4)* %[[ARG]]) + //CHECK: %[[RET:.*]] = call i8 addrspace(1)* @__to_global(i8 addrspace(4)* %[[ARG]]) //CHECK: %{{.*}} = bitcast i8 addrspace(1)* %[[RET]] to %[[A]] addrspace(1)* PA pA; GA gA = to_global(pA); //CHECK-NOT: addrspacecast //CHECK-NOT: bitcast - //CHECK: call i8 addrspace(1)* @to_global(i8 addrspace(4)* %{{.*}}) + //CHECK: call i8 addrspace(1)* @__to_global(i8 addrspace(4)* %{{.*}}) //CHECK-NOT: addrspacecast //CHECK-NOT: bitcast generic void *gen_v; diff --git a/test/CoverageMapping/system_macro.c b/test/CoverageMapping/system_macro.c deleted file mode 100644 index bddc822b0d90..000000000000 --- a/test/CoverageMapping/system_macro.c +++ /dev/null @@ -1,23 +0,0 @@ -// RUN: %clang_cc1 -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -emit-llvm-only -main-file-name system_macro.c -o - %s | FileCheck %s - -#ifdef IS_SYSHEADER - -#pragma clang system_header -#define Func(x) if (x) {} -#define SomeType int - -#else - -#define IS_SYSHEADER -#include __FILE__ - -// CHECK-LABEL: doSomething: -void doSomething(int x) { // CHECK: File 0, [[@LINE]]:25 -> {{[0-9:]+}} = #0 - Func(x); - return; - SomeType *f; // CHECK: File 0, [[@LINE]]:11 -> {{[0-9:]+}} = 0 -} - -int main() {} - -#endif diff --git a/test/CoverageMapping/system_macro.cpp b/test/CoverageMapping/system_macro.cpp new file mode 100644 index 000000000000..ce0da17ce06c --- /dev/null +++ b/test/CoverageMapping/system_macro.cpp @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -std=c++11 -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -emit-llvm-only -main-file-name system_macro.cpp -o - %s | FileCheck %s + +#ifdef IS_SYSHEADER + +#pragma clang system_header +#define Func(x) if (x) {} +#define SomeType int + +#else + +#define IS_SYSHEADER +#include __FILE__ + +// CHECK-LABEL: doSomething +void doSomething(int x) { // CHECK: File 0, [[@LINE]]:25 -> {{[0-9:]+}} = #0 + Func(x); + return; + SomeType *f; // CHECK: File 0, [[@LINE]]:11 -> {{[0-9:]+}} = 0 +} + +// CHECK-LABEL: main +int main() { // CHECK: File 0, [[@LINE]]:12 -> [[@LINE+2]]:2 = #0 + Func([] { return true; }()); +} + +#endif diff --git a/test/Driver/cl-options.c b/test/Driver/cl-options.c index 223d37e5f440..4d9416b1f87c 100644 --- a/test/Driver/cl-options.c +++ b/test/Driver/cl-options.c @@ -424,6 +424,10 @@ // Z7GMLT: "-gcodeview" // Z7GMLT: "-debug-info-kind=line-tables-only" +// RUN: %clang_cl -gline-tables-only /c -### -- %s 2>&1 | FileCheck -check-prefix=ZGMLT %s +// ZGMLT: "-gcodeview" +// ZGMLT: "-debug-info-kind=line-tables-only" + // RUN: %clang_cl /c -### -- %s 2>&1 | FileCheck -check-prefix=BreproDefault %s // BreproDefault: "-mincremental-linker-compatible" diff --git a/test/Driver/cl-pch-errorhandling.cpp b/test/Driver/cl-pch-errorhandling.cpp index 879c8cf8e7da..33071beb5b8f 100644 --- a/test/Driver/cl-pch-errorhandling.cpp +++ b/test/Driver/cl-pch-errorhandling.cpp @@ -6,7 +6,7 @@ // code generation, which makes this test require an x86 backend. // REQUIRES: x86-registered-target -// RUN: not %clang_cl -Werror /Yc%S/Inputs/pchfile.h /FI%S/Inputs/pchfile.h /Fp%t.pch /c -DERR_HEADER -- %s 2>&1 \ +// RUN: not %clang_cl -Werror --target=x86_64 /Yc%S/Inputs/pchfile.h /FI%S/Inputs/pchfile.h /Fp%t.pch /c -DERR_HEADER -- %s 2>&1 \ // RUN: | FileCheck %s // CHECK: nope1 diff --git a/test/Driver/cl-pch-search.cpp b/test/Driver/cl-pch-search.cpp index 118cf19efbd5..ca62668ef13b 100644 --- a/test/Driver/cl-pch-search.cpp +++ b/test/Driver/cl-pch-search.cpp @@ -3,4 +3,4 @@ // REQUIRES: x86-registered-target // Check that pchfile.h next to to pchfile.cc is found correctly. -// RUN: %clang_cl -Werror /Ycpchfile.h /FIpchfile.h /c /Fo%t.obj /Fp%t.pch -- %S/Inputs/pchfile.cpp +// RUN: %clang_cl -Werror --target=x86_64 /Ycpchfile.h /FIpchfile.h /c /Fo%t.obj /Fp%t.pch -- %S/Inputs/pchfile.cpp diff --git a/test/Driver/cl-pch-showincludes.cpp b/test/Driver/cl-pch-showincludes.cpp index 8115e6b5d380..7e0e1097361d 100644 --- a/test/Driver/cl-pch-showincludes.cpp +++ b/test/Driver/cl-pch-showincludes.cpp @@ -8,14 +8,14 @@ // When building the pch, header1.h (included by header2.h), header2.h (the pch // input itself) and header3.h (included directly, above) should be printed. -// RUN: %clang_cl -Werror /showIncludes /I%S/Inputs /Ycheader2.h /FIheader2.h /Fp%t.pch /c /Fo%t -- %s \ +// RUN: %clang_cl -Werror --target=x86_64 /showIncludes /I%S/Inputs /Ycheader2.h /FIheader2.h /Fp%t.pch /c /Fo%t -- %s \ // RUN: | FileCheck --strict-whitespace -check-prefix=CHECK-YC %s // CHECK-YC: Note: including file: {{[^ ]*header2.h}} // CHECK-YC: Note: including file: {{[^ ]*header1.h}} // CHECK-YC: Note: including file: {{[^ ]*header3.h}} // When using the pch, only the direct include is printed. -// RUN: %clang_cl -Werror /showIncludes /I%S/Inputs /Yuheader2.h /FIheader2.h /Fp%t.pch /c /Fo%t -- %s \ +// RUN: %clang_cl -Werror --target=x86_64 /showIncludes /I%S/Inputs /Yuheader2.h /FIheader2.h /Fp%t.pch /c /Fo%t -- %s \ // RUN: | FileCheck --strict-whitespace -check-prefix=CHECK-YU %s // CHECK-YU-NOT: Note: including file: {{.*pch}} // CHECK-YU-NOT: Note: including file: {{.*header1.h}} @@ -23,7 +23,7 @@ // CHECK-YU: Note: including file: {{[^ ]*header3.h}} // When not using pch at all, all the /FI files are printed. -// RUN: %clang_cl -Werror /showIncludes /I%S/Inputs /FIheader2.h /c /Fo%t -- %s \ +// RUN: %clang_cl -Werror --target=x86_64 /showIncludes /I%S/Inputs /FIheader2.h /c /Fo%t -- %s \ // RUN: | FileCheck --strict-whitespace -check-prefix=CHECK-FI %s // CHECK-FI: Note: including file: {{[^ ]*header2.h}} // CHECK-FI: Note: including file: {{[^ ]*header1.h}} @@ -32,7 +32,7 @@ // Also check that /FI arguments before the /Yc / /Yu flags are printed right. // /FI flags before the /Yc arg should be printed, /FI flags after it shouldn't. -// RUN: %clang_cl -Werror /showIncludes /I%S/Inputs /Ycheader2.h /FIheader0.h /FIheader2.h /FIheader4.h /Fp%t.pch /c /Fo%t -- %s \ +// RUN: %clang_cl -Werror --target=x86_64 /showIncludes /I%S/Inputs /Ycheader2.h /FIheader0.h /FIheader2.h /FIheader4.h /Fp%t.pch /c /Fo%t -- %s \ // RUN: | FileCheck --strict-whitespace -check-prefix=CHECK-YCFI %s // CHECK-YCFI: Note: including file: {{[^ ]*header0.h}} // CHECK-YCFI: Note: including file: {{[^ ]*header2.h}} @@ -40,7 +40,7 @@ // CHECK-YCFI: Note: including file: {{[^ ]*header4.h}} // CHECK-YCFI: Note: including file: {{[^ ]*header3.h}} -// RUN: %clang_cl -Werror /showIncludes /I%S/Inputs /Yuheader2.h /FIheader0.h /FIheader2.h /FIheader4.h /Fp%t.pch /c /Fo%t -- %s \ +// RUN: %clang_cl -Werror --target=x86_64 /showIncludes /I%S/Inputs /Yuheader2.h /FIheader0.h /FIheader2.h /FIheader4.h /Fp%t.pch /c /Fo%t -- %s \ // RUN: | FileCheck --strict-whitespace -check-prefix=CHECK-YUFI %s // CHECK-YUFI-NOT: Note: including file: {{.*pch}} // CHECK-YUFI-NOT: Note: including file: {{.*header0.h}} diff --git a/test/Driver/cloudabi.c b/test/Driver/cloudabi.c index 7a72f6189515..053092a53d41 100644 --- a/test/Driver/cloudabi.c +++ b/test/Driver/cloudabi.c @@ -1,8 +1,14 @@ // RUN: %clang %s -### -target x86_64-unknown-cloudabi 2>&1 | FileCheck %s -check-prefix=SAFESTACK // SAFESTACK: "-cc1" "-triple" "x86_64-unknown-cloudabi" {{.*}} "-ffunction-sections" "-fdata-sections" {{.*}} "-fsanitize=safe-stack" -// SAFESTACK: "-Bstatic" "-pie" "--no-dynamic-linker" "-zrelro" "--eh-frame-hdr" "--gc-sections" "-o" "a.out" "crt0.o" "crtbegin.o" "{{.*}}" "{{.*}}" "-lc" "-lcompiler_rt" "crtend.o" +// SAFESTACK: "-Bstatic" "--no-dynamic-linker" "-pie" "-zrelro" "--eh-frame-hdr" "--gc-sections" "-o" "a.out" "crt0.o" "crtbegin.o" "{{.*}}" "{{.*}}" "-lc" "-lcompiler_rt" "crtend.o" // RUN: %clang %s -### -target x86_64-unknown-cloudabi -fno-sanitize=safe-stack 2>&1 | FileCheck %s -check-prefix=NOSAFESTACK // NOSAFESTACK: "-cc1" "-triple" "x86_64-unknown-cloudabi" {{.*}} "-ffunction-sections" "-fdata-sections" // NOSAFESTACK-NOT: "-fsanitize=safe-stack" -// NOSAFESTACK: "-Bstatic" "-pie" "--no-dynamic-linker" "-zrelro" "--eh-frame-hdr" "--gc-sections" "-o" "a.out" "crt0.o" "crtbegin.o" "{{.*}}" "{{.*}}" "-lc" "-lcompiler_rt" "crtend.o" +// NOSAFESTACK: "-Bstatic" "--no-dynamic-linker" "-pie" "-zrelro" "--eh-frame-hdr" "--gc-sections" "-o" "a.out" "crt0.o" "crtbegin.o" "{{.*}}" "{{.*}}" "-lc" "-lcompiler_rt" "crtend.o" + +// PIE shouldn't be enabled on i686. Just on architectures that provide +// PC-relative addressing. +// RUN: %clang %s -### -target i686-unknown-cloudabi 2>&1 | FileCheck %s -check-prefix=NOPIE +// NOPIE: "-cc1" "-triple" "i686-unknown-cloudabi" {{.*}} "-ffunction-sections" "-fdata-sections" {{.*}} "-fsanitize=safe-stack" +// NOPIE: "-Bstatic" "--no-dynamic-linker" "--eh-frame-hdr" "--gc-sections" "-o" "a.out" "crt0.o" "crtbegin.o" "{{.*}}" "{{.*}}" "-lc" "-lcompiler_rt" "crtend.o" diff --git a/test/Driver/cloudabi.cpp b/test/Driver/cloudabi.cpp index dd52ac36acc8..f9e9ba5cb427 100644 --- a/test/Driver/cloudabi.cpp +++ b/test/Driver/cloudabi.cpp @@ -1,8 +1,14 @@ // RUN: %clangxx %s -### -target x86_64-unknown-cloudabi 2>&1 | FileCheck %s -check-prefix=SAFESTACK // SAFESTACK: "-cc1" "-triple" "x86_64-unknown-cloudabi" {{.*}} "-ffunction-sections" "-fdata-sections" {{.*}} "-fsanitize=safe-stack" -// SAFESTACK: "-Bstatic" "-pie" "--no-dynamic-linker" "-zrelro" "--eh-frame-hdr" "--gc-sections" "-o" "a.out" "crt0.o" "crtbegin.o" "{{.*}}" "{{.*}}" "-lc++" "-lc++abi" "-lunwind" "-lc" "-lcompiler_rt" "crtend.o" +// SAFESTACK: "-Bstatic" "--no-dynamic-linker" "-pie" "-zrelro" "--eh-frame-hdr" "--gc-sections" "-o" "a.out" "crt0.o" "crtbegin.o" "{{.*}}" "{{.*}}" "-lc++" "-lc++abi" "-lunwind" "-lc" "-lcompiler_rt" "crtend.o" -// RUN: %clangxx %s -### -target x86_64-unknown-cloudabi -fno-sanitize=safe-stack 2>&1 | FileCheck %s -check-prefix=NOSAFESTACk +// RUN: %clangxx %s -### -target x86_64-unknown-cloudabi -fno-sanitize=safe-stack 2>&1 | FileCheck %s -check-prefix=NOSAFESTACK // NOSAFESTACK: "-cc1" "-triple" "x86_64-unknown-cloudabi" {{.*}} "-ffunction-sections" "-fdata-sections" // NOSAFESTACK-NOT: "-fsanitize=safe-stack" -// NOSAFESTACk: "-Bstatic" "-pie" "--no-dynamic-linker" "-zrelro" "--eh-frame-hdr" "--gc-sections" "-o" "a.out" "crt0.o" "crtbegin.o" "{{.*}}" "{{.*}}" "-lc++" "-lc++abi" "-lunwind" "-lc" "-lcompiler_rt" "crtend.o" +// NOSAFESTACK: "-Bstatic" "--no-dynamic-linker" "-pie" "-zrelro" "--eh-frame-hdr" "--gc-sections" "-o" "a.out" "crt0.o" "crtbegin.o" "{{.*}}" "{{.*}}" "-lc++" "-lc++abi" "-lunwind" "-lc" "-lcompiler_rt" "crtend.o" + +// PIE shouldn't be enabled on i686. Just on architectures that provide +// PC-relative addressing. +// RUN: %clangxx %s -### -target i686-unknown-cloudabi 2>&1 | FileCheck %s -check-prefix=NOPIE +// NOPIE: "-cc1" "-triple" "i686-unknown-cloudabi" {{.*}} "-ffunction-sections" "-fdata-sections" {{.*}} "-fsanitize=safe-stack" +// NOPIE: "-Bstatic" "--no-dynamic-linker" "--eh-frame-hdr" "--gc-sections" "-o" "a.out" "crt0.o" "crtbegin.o" "{{.*}}" "{{.*}}" "-lc++" "-lc++abi" "-lunwind" "-lc" "-lcompiler_rt" "crtend.o" diff --git a/test/Driver/frame-pointer-elim.c b/test/Driver/frame-pointer-elim.c index 5355cbe3a364..139c0ccb952a 100644 --- a/test/Driver/frame-pointer-elim.c +++ b/test/Driver/frame-pointer-elim.c @@ -8,6 +8,15 @@ // RUN: FileCheck --check-prefix=LINUX %s // LINUX-NOT: "-momit-leaf-frame-pointer" +// CloudABI follows the same rules as Linux. +// RUN: %clang -### -target x86_64-unknown-cloudabi -S -O1 %s 2>&1 | \ +// RUN: FileCheck --check-prefix=CLOUDABI-OPT %s +// CLOUDABI-OPT: "-momit-leaf-frame-pointer" + +// RUN: %clang -### -target x86_64-unknown-cloudabi -S %s 2>&1 | \ +// RUN: FileCheck --check-prefix=CLOUDABI %s +// CLOUDABI-NOT: "-momit-leaf-frame-pointer" + // Darwin disables omitting the leaf frame pointer even under optimization // unless the command lines are given. // RUN: %clang -### -target i386-apple-darwin -S %s 2>&1 | \ diff --git a/test/Misc/diag-template-diffing.cpp b/test/Misc/diag-template-diffing.cpp index 90bcf6b2d17e..a4f29cc8c7f0 100644 --- a/test/Misc/diag-template-diffing.cpp +++ b/test/Misc/diag-template-diffing.cpp @@ -1455,7 +1455,37 @@ void run() { } // CHECK-ELIDE-NOTREE: error: no matching function for call to 'D' // CHECK-ELIDE-NOTREE: note: candidate function [with x = TypeAlias::X::X1] not viable: no known conversion from 'VectorType' to 'const VectorType<(TypeAlias::X)0>' for 1st argument +} + +namespace TypeAlias2 { +template +class A {}; + +template +using A_reg = A; +void take_reg(A_reg); + +template +using A_ptr = A *; +void take_ptr(A_ptr); + +template +using A_ref = const A &; +void take_ref(A_ref); +void run(A_reg reg, A_ptr ptr, A_ref ref) { + take_reg(reg); +// CHECK-ELIDE-NOTREE: error: no matching function for call to 'take_reg' +// CHECK-ELIDE-NOTREE: note: candidate function not viable: no known conversion from 'A_reg' to 'A_reg' for 1st argument + + take_ptr(ptr); +// CHECK-ELIDE-NOTREE: error: no matching function for call to 'take_ptr' +// CHECK-ELIDE-NOTREE: note: candidate function not viable: no known conversion from 'A_ptr' to 'A_ptr' for 1st argument + + take_ref(ref); +// CHECK-ELIDE-NOTREE: error: no matching function for call to 'take_ref' +// CHECK-ELIDE-NOTREE: note: candidate function not viable: no known conversion from 'const A' to 'const A' for 1st argument +} } // CHECK-ELIDE-NOTREE: {{[0-9]*}} errors generated. diff --git a/test/Modules/Inputs/PR28332/TextualInclude.h b/test/Modules/Inputs/PR28332/TextualInclude.h new file mode 100644 index 000000000000..e4d2580230fe --- /dev/null +++ b/test/Modules/Inputs/PR28332/TextualInclude.h @@ -0,0 +1,7 @@ +#ifndef LLVM_ADT_SMALLVECTORIMPL_H +#define LLVM_ADT_SMALLVECTORIMPL_H +class SmallVectorImpl { +public: + ~SmallVectorImpl(); +}; +#endif \ No newline at end of file diff --git a/test/Modules/Inputs/PR28332/a.h b/test/Modules/Inputs/PR28332/a.h new file mode 100644 index 000000000000..1dc96c80fcd6 --- /dev/null +++ b/test/Modules/Inputs/PR28332/a.h @@ -0,0 +1,8 @@ +#include "b.h" + +class A { + SmallVector LegalIntWidths; + A() {} +}; + +#include "c.h" diff --git a/test/Modules/Inputs/PR28332/b.h b/test/Modules/Inputs/PR28332/b.h new file mode 100644 index 000000000000..e1e07e892079 --- /dev/null +++ b/test/Modules/Inputs/PR28332/b.h @@ -0,0 +1,3 @@ +#include "TextualInclude.h" +template class SmallVector : SmallVectorImpl {}; + diff --git a/test/Modules/Inputs/PR28332/c.h b/test/Modules/Inputs/PR28332/c.h new file mode 100644 index 000000000000..e18bdaccca6c --- /dev/null +++ b/test/Modules/Inputs/PR28332/c.h @@ -0,0 +1,2 @@ +#include "TextualInclude.h" + diff --git a/test/Modules/Inputs/PR28332/module.modulemap b/test/Modules/Inputs/PR28332/module.modulemap new file mode 100644 index 000000000000..8c3f4ecab4e5 --- /dev/null +++ b/test/Modules/Inputs/PR28332/module.modulemap @@ -0,0 +1,3 @@ +module "c.h" { header "c.h" export * } +module "b.h" { header "b.h" export * } +module "a.h" { header "a.h" } diff --git a/test/Modules/pr28332.cpp b/test/Modules/pr28332.cpp new file mode 100644 index 000000000000..596dd246008e --- /dev/null +++ b/test/Modules/pr28332.cpp @@ -0,0 +1,8 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -std=c++11 -I%S/Inputs/PR28332 -verify %s +// RUN: %clang_cc1 -std=c++11 -fmodules -fmodule-map-file=%S/Inputs/PR28332/module.modulemap -fmodules-cache-path=%t -I%S/Inputs/PR28332 -verify %s + +#include "a.h" + +// expected-no-diagnostics + diff --git a/test/PCH/Inputs/pragma-once.h b/test/PCH/Inputs/pragma-once.h new file mode 100644 index 000000000000..831cf553c764 --- /dev/null +++ b/test/PCH/Inputs/pragma-once.h @@ -0,0 +1,5 @@ +#pragma once + +/* For use with the pragma-once.c test */ + +int x = 3; diff --git a/test/PCH/pragma-once.c b/test/PCH/pragma-once.c new file mode 100644 index 000000000000..15e8503c1158 --- /dev/null +++ b/test/PCH/pragma-once.c @@ -0,0 +1,13 @@ +// Test this without pch. +// RUN: %clang_cc1 -include %S/Inputs/pragma-once.h -fsyntax-only -verify %s + +// Test with pch. +// RUN: %clang_cc1 -emit-pch -o %t %S/Inputs/pragma-once.h +// RUN: %clang_cc1 -include-pch %t -fsyntax-only -verify %s + +// expected-no-diagnostics + +// Including "pragma-once.h" twice, to verify the 'once' aspect is honored. +#include "Inputs/pragma-once.h" +#include "Inputs/pragma-once.h" +int foo(void) { return 0; } diff --git a/test/Parser/cxx1z-constexpr-lambdas.cpp b/test/Parser/cxx1z-constexpr-lambdas.cpp deleted file mode 100644 index ea000e361ccb..000000000000 --- a/test/Parser/cxx1z-constexpr-lambdas.cpp +++ /dev/null @@ -1,31 +0,0 @@ -// RUN: %clang_cc1 -std=c++1z %s -verify -// RUN: %clang_cc1 -std=c++14 %s -verify -// RUN: %clang_cc1 -std=c++11 %s -verify - - -auto XL0 = [] constexpr { }; //expected-error{{requires '()'}} expected-error{{expected body}} -auto XL1 = [] () mutable - mutable //expected-error{{cannot appear multiple times}} - mutable { }; //expected-error{{cannot appear multiple times}} - -#if __cplusplus > 201402L -auto XL2 = [] () constexpr mutable constexpr { }; //expected-error{{cannot appear multiple times}} -auto L = []() mutable constexpr { }; -auto L2 = []() constexpr { }; -auto L4 = []() constexpr mutable { }; -auto XL16 = [] () constexpr - mutable - constexpr //expected-error{{cannot appear multiple times}} - mutable //expected-error{{cannot appear multiple times}} - mutable //expected-error{{cannot appear multiple times}} - constexpr //expected-error{{cannot appear multiple times}} - constexpr //expected-error{{cannot appear multiple times}} - { }; - -#else -auto L = []() mutable constexpr {return 0; }; //expected-warning{{is a C++1z extension}} -auto L2 = []() constexpr { return 0;};//expected-warning{{is a C++1z extension}} -auto L4 = []() constexpr mutable { return 0; }; //expected-warning{{is a C++1z extension}} -#endif - - diff --git a/test/Sema/bitfield.c b/test/Sema/bitfield.c index 810dc798eaa5..d625366e4e1f 100644 --- a/test/Sema/bitfield.c +++ b/test/Sema/bitfield.c @@ -64,7 +64,7 @@ typedef signed Signed; struct Test5 { unsigned n : 2; } t5; // Bitfield is unsigned -struct Test5 sometest5 = {-1}; // expected-warning {{implicit truncation from 'int' to bitfield changes value from -1 to 3}} +struct Test5 sometest5 = {-1}; typedef __typeof__(+t5.n) Signed; // ... but promotes to signed. typedef __typeof__(t5.n + 0) Signed; // Arithmetic promotes. diff --git a/test/Sema/constant-conversion.c b/test/Sema/constant-conversion.c index b717f9325336..203e7373897c 100644 --- a/test/Sema/constant-conversion.c +++ b/test/Sema/constant-conversion.c @@ -113,3 +113,15 @@ void test9() { char array_init[] = { 255, 127, 128, 129, 0 }; } + +void test10() { + struct S { + unsigned a : 4; + } s; + s.a = -1; + s.a = 15; + s.a = -8; + + s.a = -9; // expected-warning{{implicit truncation from 'int' to bitfield changes value from -9 to 7}} + s.a = 16; // expected-warning{{implicit truncation from 'int' to bitfield changes value from 16 to 0}} +} diff --git a/test/Sema/enable_if.c b/test/Sema/enable_if.c index 1cc14659021d..a11f53eb4930 100644 --- a/test/Sema/enable_if.c +++ b/test/Sema/enable_if.c @@ -149,4 +149,25 @@ void PR27122_ext() { regular_enable_if(1, 2); // expected-error{{too many arguments}} regular_enable_if(); // expected-error{{too few arguments}} } + +// We had a bug where we'd crash upon trying to evaluate varargs. +void variadic_enable_if(int a, ...) __attribute__((enable_if(a, ""))); // expected-note 6 {{disabled}} +void variadic_test() { + variadic_enable_if(1); + variadic_enable_if(1, 2); + variadic_enable_if(1, "c", 3); + + variadic_enable_if(0); // expected-error{{no matching}} + variadic_enable_if(0, 2); // expected-error{{no matching}} + variadic_enable_if(0, "c", 3); // expected-error{{no matching}} + + int m; + variadic_enable_if(1); + variadic_enable_if(1, m); + variadic_enable_if(1, m, "c"); + + variadic_enable_if(0); // expected-error{{no matching}} + variadic_enable_if(0, m); // expected-error{{no matching}} + variadic_enable_if(0, m, 3); // expected-error{{no matching}} +} #endif diff --git a/test/Sema/typo-correction.c b/test/Sema/typo-correction.c index a1107a25ee54..59f022dfe528 100644 --- a/test/Sema/typo-correction.c +++ b/test/Sema/typo-correction.c @@ -65,3 +65,18 @@ int fn_with_rs(int r) { r = TYPO + r * TYPO; } // expected-error 2 {{use of unde void fn_with_unknown(int a, int b) { fn_with_unknown(unknown, unknown | unknown); // expected-error 3 {{use of undeclared identifier}} } + +// Two typos in a parenthesized expression or argument list with a conditional +// expression caused a crash in C mode. +// +// r272587 fixed a similar bug for binary operations. The same fix was needed for +// conditional expressions. + +int g(int x, int y) { + return x + y; +} + +int h() { + g(x, 5 ? z : 0); // expected-error 2 {{use of undeclared identifier}} + (x, 5 ? z : 0); // expected-error 2 {{use of undeclared identifier}} +} diff --git a/test/SemaCXX/cxx1z-constexpr-lambdas.cpp b/test/SemaCXX/cxx1z-constexpr-lambdas.cpp deleted file mode 100644 index 8e7657fb6e8d..000000000000 --- a/test/SemaCXX/cxx1z-constexpr-lambdas.cpp +++ /dev/null @@ -1,36 +0,0 @@ -// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks %s -// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fdelayed-template-parsing %s -// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fms-extensions %s -// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fdelayed-template-parsing -fms-extensions %s - -namespace test_constexpr_checking { - -namespace ns1 { - struct NonLit { ~NonLit(); }; //expected-note{{not literal}} - auto L = [](NonLit NL) constexpr { }; //expected-error{{not a literal type}} -} // end ns1 - -namespace ns2 { - auto L = [](int I) constexpr { asm("non-constexpr"); }; //expected-error{{not allowed in constexpr function}} -} // end ns1 - -} // end ns test_constexpr_checking - -namespace test_constexpr_call { - -namespace ns1 { - auto L = [](int I) { return I; }; - static_assert(L(3) == 3); -} // end ns1 -namespace ns2 { - auto L = [](auto a) { return a; }; - static_assert(L(3) == 3); - static_assert(L(3.14) == 3.14); -} -namespace ns3 { - auto L = [](auto a) { asm("non-constexpr"); return a; }; //expected-note{{declared here}} - constexpr int I = //expected-error{{must be initialized by a constant expression}} - L(3); //expected-note{{non-constexpr function}} -} - -} // end ns test_constexpr_call \ No newline at end of file diff --git a/test/SemaCXX/enable_if.cpp b/test/SemaCXX/enable_if.cpp index 7ec07aa8b0ca..81308136c480 100644 --- a/test/SemaCXX/enable_if.cpp +++ b/test/SemaCXX/enable_if.cpp @@ -417,3 +417,26 @@ template constexpr int callTemplated() { return templated(); } constexpr int B = callTemplated<0>(); // expected-error{{initialized by a constant expression}} expected-error@-2{{no matching function for call to 'templated'}} expected-note{{in instantiation of function template}} expected-note@-9{{candidate disabled}} static_assert(callTemplated<1>() == 1, ""); } + +namespace variadic { +void foo(int a, int b = 0, ...) __attribute__((enable_if(a && b, ""))); // expected-note 6{{disabled}} + +void testFoo() { + foo(1, 1); + foo(1, 1, 2); + foo(1, 1, 2, 3); + + foo(1, 0); // expected-error{{no matching}} + foo(1, 0, 2); // expected-error{{no matching}} + foo(1, 0, 2, 3); // expected-error{{no matching}} + + int m; + foo(1, 1); + foo(1, 1, m); + foo(1, 1, m, 3); + + foo(1, 0); // expected-error{{no matching}} + foo(1, 0, m); // expected-error{{no matching}} + foo(1, 0, m, 3); // expected-error{{no matching}} +} +} diff --git a/test/SemaCXX/lambda-expressions.cpp b/test/SemaCXX/lambda-expressions.cpp index 17808cef363a..5fffe4111783 100644 --- a/test/SemaCXX/lambda-expressions.cpp +++ b/test/SemaCXX/lambda-expressions.cpp @@ -1,5 +1,4 @@ -// RUN: %clang_cc1 -std=c++11 -Wno-unused-value -fsyntax-only -verify -fblocks %s -// RUN: %clang_cc1 -std=c++1y -Wno-unused-value -fsyntax-only -verify -fblocks %s +// RUN: %clang_cc1 -std=c++14 -Wno-unused-value -fsyntax-only -verify -fblocks %s namespace std { class type_info; }; @@ -499,3 +498,30 @@ void foo() { }; } } + +namespace PR27994 { +struct A { template A(T); }; + +template +struct B { + int x; + A a = [&] { int y = x; }; + A b = [&] { [&] { [&] { int y = x; }; }; }; + A d = [&](auto param) { int y = x; }; + A e = [&](auto param) { [&] { [&](auto param2) { int y = x; }; }; }; +}; + +B b; + +template struct C { + struct D { + int x; + A f = [&] { int y = x; }; + }; +}; + +int func() { + C a; + decltype(a)::D b; +} +} diff --git a/test/SemaCXX/return-stack-addr-2.cpp b/test/SemaCXX/return-stack-addr-2.cpp index ad27567fcd64..47b45957e94b 100644 --- a/test/SemaCXX/return-stack-addr-2.cpp +++ b/test/SemaCXX/return-stack-addr-2.cpp @@ -1,5 +1,4 @@ // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -std=c++11 %s -// expected-no-diagnostics namespace PR26599 { template @@ -20,3 +19,63 @@ void *&pointer() { } } +namespace LocalTemporary { + +template +class QMap { +public: + T value(const T &t = T()) const { + return t; + } +}; + +struct A {}; + +void test() { + QMap map; + map.value(); +} + +typedef int* ptr; +ptr int1(const ptr &p = ptr()) { + return (p); +} + +ptr int2(const ptr &p = nullptr) { + return p; +} + +ptr int3() { + const ptr &p = ptr(); + return p; +} + +const int *int4(const int &x = 5) { + return &x; +} + +const int *int5(const int &x) { + return &x; +} + +const int *int6() { + const int &x = 11; //expected-note{{binding reference variable 'x' here}} + return &x; //expected-warning{{returning address of local temporary object}} +} + +const int *int7(int x) { + const int &x2 = x; // expected-note{{binding reference variable 'x2' here}} + return &x2; // expected-warning{{address of stack memory associated with local variable 'x' returned}} +} + +const int *int8(const int &x = 5) { + const int &x2 = x; + return &x2; +} + +const int *int9() { + const int &x = 5; // expected-note{{binding reference variable 'x' here}} + const int &x2 = x; // expected-note{{binding reference variable 'x2' here}} + return &x2; // expected-warning{{returning address of local temporary object}} +} +} diff --git a/test/SemaCXX/warn-thread-safety-analysis.cpp b/test/SemaCXX/warn-thread-safety-analysis.cpp index b5d2f8e1de83..bbb4f9b48d36 100644 --- a/test/SemaCXX/warn-thread-safety-analysis.cpp +++ b/test/SemaCXX/warn-thread-safety-analysis.cpp @@ -5160,6 +5160,21 @@ void test3() { } // end namespace GlobalAcquiredBeforeAfterTest +namespace LifetimeExtensionText { + +struct Holder { + virtual ~Holder() throw() {} + int i = 0; +}; + +void test() { + // Should not crash. + const auto &value = Holder().i; +} + +} // end namespace LifetimeExtensionTest + + namespace LockableUnions { union LOCKABLE MutexUnion { diff --git a/test/SemaCXX/warn-unsequenced.cpp b/test/SemaCXX/warn-unsequenced.cpp index 54e16a5e6d50..9e8a5b46c218 100644 --- a/test/SemaCXX/warn-unsequenced.cpp +++ b/test/SemaCXX/warn-unsequenced.cpp @@ -113,3 +113,58 @@ void test() { (__builtin_object_size(&(++a, a), 0) ? 1 : 0) + ++a; // ok (__builtin_expect(++a, 0) ? 1 : 0) + ++a; // expected-warning {{multiple unsequenced modifications}} } + +namespace templates { + +template +struct Bar { + T get() { return 0; } +}; + +template +struct Foo { + int Run(); + Bar bar; +}; + +enum E {e1, e2}; +bool operator&&(E, E); + +void foo(int, int); + +template +int Foo::Run() { + char num = 0; + + // Before instantiation, Clang may consider the builtin operator here as + // unresolved function calls, and treat the arguments as unordered when + // the builtin operator evaluatation is well-ordered. Waiting until + // instantiation to check these expressions will prevent false positives. + if ((num = bar.get()) < 5 && num < 10) { } + if ((num = bar.get()) < 5 || num < 10) { } + if (static_cast((num = bar.get()) < 5) || static_cast(num < 10)) { } + + if (static_cast((num = bar.get()) < 5) && static_cast(num < 10)) { } + // expected-warning@-1 {{unsequenced modification and access to 'num'}} + + foo(num++, num++); + // expected-warning@-1 2{{multiple unsequenced modifications to 'num'}} + return 1; +} + +int x = Foo().Run(); +// expected-note@-1 {{in instantiation of member function 'templates::Foo::Run'}} + + +template +int Run2() { + T t = static_cast(0); + return (t = static_cast(1)) && t; + // expected-warning@-1 {{unsequenced modification and access to 't'}} +} + +int y = Run2(); +int z = Run2(); +// expected-note@-1{{in instantiation of function template specialization 'templates::Run2' requested here}} + +} diff --git a/www/cxx_dr_status.html b/www/cxx_dr_status.html index fb4c0697a2fa..2f679b990f35 100644 --- a/www/cxx_dr_status.html +++ b/www/cxx_dr_status.html @@ -28,7 +28,7 @@

C++ Defect Report Support in Clang

-

Last updated: $Date: 2016-06-28 22:35:53 +0200 (Tue, 28 Jun 2016) $

+

Last updated: $Date: 2016-07-27 18:41:01 +0200 (Wed, 27 Jul 2016) $

C++ defect report implementation status

@@ -7315,7 +7315,7 @@ and POD class
1250 CD3 Cv-qualification of incomplete virtual function return types - SVN + Clang 3.9 1251 @@ -9253,7 +9253,7 @@ and POD class 1573 DRWP Inherited constructor characteristics - SVN + Clang 3.9 1574 @@ -9289,7 +9289,7 @@ and POD class 1579 C++14 Return by converting move constructor - Unknown + Clang 3.9 1580 @@ -9685,7 +9685,7 @@ and POD class 1645 DR Identical inheriting constructors via default arguments - SVN + Clang 3.9 1646 @@ -10105,7 +10105,7 @@ and POD class 1715 DR Access and inherited constructor templates - SVN + Clang 3.9 1716 @@ -10231,7 +10231,7 @@ and POD class 1736 DR Inheriting constructor templates in a local class - SVN + Clang 3.9 1737 @@ -11461,7 +11461,7 @@ and POD class 1941 DR SFINAE and inherited constructor default arguments - SVN + Clang 3.9 1942 @@ -11569,7 +11569,7 @@ and POD class 1959 DR Inadvertently inherited copy constructor - SVN + Clang 3.9 1960 @@ -11761,7 +11761,7 @@ and POD class 1991 DR Inheriting constructors vs default arguments - SVN + Clang 3.9 1992 diff --git a/www/make_cxx_dr_status b/www/make_cxx_dr_status index fe484284c189..9a679ed9f505 100755 --- a/www/make_cxx_dr_status +++ b/www/make_cxx_dr_status @@ -102,10 +102,10 @@ def availability(issue): if status == 'unknown': avail = 'Unknown' avail_style = ' class="none"' - elif status == '3.9': + elif status == '4.0': avail = 'SVN' avail_style = ' class="svn"' - elif status.startswith('3.'): + elif re.match('^[0-9]+\.', status): avail = 'Clang %s' % status avail_style = ' class="full"' elif status == 'yes': -- cgit v1.2.3