55 changes: 38 additions & 17 deletions clang-tools-extra/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -229,18 +229,18 @@ New checks

Finds nested conditional operator.

- New :doc:`readability-reference-to-constructed-temporary
<clang-tidy/checks/readability/reference-to-constructed-temporary>` check.

Detects C++ code where a reference variable is used to extend the lifetime
of a temporary object that has just been constructed.

- New :doc:`readability-avoid-return-with-void-value
<clang-tidy/checks/readability/avoid-return-with-void-value>` check.

Finds return statements with ``void`` values used within functions with
``void`` result types.

- New :doc:`readability-reference-to-constructed-temporary
<clang-tidy/checks/readability/reference-to-constructed-temporary>` check.

Detects C++ code where a reference variable is used to extend the lifetime
of a temporary object that has just been constructed.

New check aliases
^^^^^^^^^^^^^^^^^

Expand All @@ -265,6 +265,14 @@ Changes in existing checks
casting during type conversions at variable initialization, now with improved
compatibility for C++17 and later versions.

- Improved :doc:`bugprone-exception-escape
<clang-tidy/checks/bugprone/exception-escape>` check by extending the default
check function names to include ``iter_swap`` and ``iter_move``.

- Improved :doc:`bugprone-implicit-widening-of-multiplication-result
<clang-tidy/checks/bugprone/implicit-widening-of-multiplication-result>` check
to correctly emit fixes.

- Improved :doc:`bugprone-lambda-function-name
<clang-tidy/checks/bugprone/lambda-function-name>` check by adding option
`IgnoreMacros` to ignore warnings in macros.
Expand Down Expand Up @@ -392,7 +400,7 @@ Changes in existing checks

- Improved :doc:`misc-unused-using-decls
<clang-tidy/checks/misc/unused-using-decls>` check to avoid false positive when
using in elaborated type and only check cpp files.
using in elaborated type and only check C++ files.

- Improved :doc:`modernize-avoid-bind
<clang-tidy/checks/modernize/avoid-bind>` check to
Expand Down Expand Up @@ -432,38 +440,41 @@ Changes in existing checks

- Improved :doc:`modernize-use-using
<clang-tidy/checks/modernize/use-using>` check to fix function pointer and
forward declared ``typedef`` correctly. Added option `IgnoreExternC` to ignore ``typedef``
declaration in ``extern "C"`` scope.
forward declared ``typedef`` correctly. Added option `IgnoreExternC` to ignore
``typedef`` declaration in ``extern "C"`` scope.

- Improved :doc:`performance-faster-string-find
<clang-tidy/checks/performance/faster-string-find>` check to properly escape
single quotes.

- Improved :doc:`performance-noexcept-move-constructor
<clang-tidy/checks/performance/noexcept-move-constructor>` to better handle
conditional noexcept expressions, eliminating false-positives.
conditional ``noexcept`` expressions, eliminating false-positives.

- Improved :doc:`performance-noexcept-swap
<clang-tidy/checks/performance/noexcept-swap>` check to enforce a stricter
match with the swap function signature and better handling of condition
noexcept expressions, eliminating false-positives.
``noexcept`` expressions, eliminating false-positives. ``iter_swap`` function
name is checked by default.

- Improved :doc:`readability-braces-around-statements
<clang-tidy/checks/readability/braces-around-statements>` check to
ignore false-positive for ``if constexpr`` in lambda expression.

- Improved :doc:`readability-avoid-const-params-in-decls
<clang-tidy/checks/readability/avoid-const-params-in-decls>` diagnositics to
highlight the const location
<clang-tidy/checks/readability/avoid-const-params-in-decls>` diagnostics to
highlight the ``const`` location

- Improved :doc:`readability-container-contains
<clang-tidy/checks/readability/container-contains>` to correctly handle
interger literals with suffixes in fix-its.
integer literals with suffixes in fix-its.

- Improved :doc:`readability-container-size-empty
<clang-tidy/checks/readability/container-size-empty>` check to
detect comparison between string and empty string literals and support
``length()`` method as an alternative to ``size()``.
``length()`` method as an alternative to ``size()``. Resolved false positives
tied to negative values from size-like methods, and one triggered by size
checks below zero.

- Improved :doc:`readability-function-size
<clang-tidy/checks/readability/function-size>` check configuration to use
Expand All @@ -481,13 +492,14 @@ Changes in existing checks
``camel_Snake_Case`` now detect more invalid identifier names. Fields in
anonymous records (i.e. anonymous structs and unions) now can be checked with
the naming rules associated with their enclosing scopes rather than the naming
rules of public struct/union members.
rules of public ``struct``/``union`` members.

- Improved :doc:`readability-implicit-bool-conversion
<clang-tidy/checks/readability/implicit-bool-conversion>` check to take
do-while loops into account for the `AllowIntegerConditions` and
`AllowPointerConditions` options. It also now provides more consistent
suggestions when parentheses are added to the return value.
suggestions when parentheses are added to the return value. It also ignores
false-positives for comparison containing bool bitfield.

- Improved :doc:`readability-misleading-indentation
<clang-tidy/checks/readability/misleading-indentation>` check to ignore
Expand All @@ -497,6 +509,15 @@ Changes in existing checks
<clang-tidy/checks/readability/non-const-parameter>` check to ignore
false-positives in initializer list of record.

- Improved :doc:`readability-redundant-member-init
<clang-tidy/checks/readability/redundant-member-init>` check to now also
detect redundant in-class initializers.

- Improved :doc:`readability-simplify-boolean-expr
<clang-tidy/checks/readability/simplify-boolean-expr>` check by adding the
new option `IgnoreMacros` that allows to ignore boolean expressions originating
from expanded macros.

- Improved :doc:`readability-simplify-subscript-expr
<clang-tidy/checks/readability/simplify-subscript-expr>` check by extending
the default value of the `Types` option to include ``std::span``.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ should not. The functions which should not throw exceptions are the following:
* Move assignment operators
* The ``main()`` functions
* ``swap()`` functions
* ``iter_swap()`` functions
* ``iter_move()`` functions
* Functions marked with ``throw()`` or ``noexcept``
* Other functions given as option

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
performance-noexcept-swap
=========================

The check flags user-defined swap functions not marked with ``noexcept`` or
The check flags user-defined swap and iter_swap functions not marked with ``noexcept`` or
marked with ``noexcept(expr)`` where ``expr`` evaluates to ``false``
(but is not a ``false`` literal itself).

When a swap function is marked as ``noexcept``, it assures the compiler that
When a swap or iter_swap function is marked as ``noexcept``, it assures the compiler that
no exceptions will be thrown during the swapping of two objects, which allows
the compiler to perform certain optimizations such as omitting exception
handling code.
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@ Example

.. code-block:: c++

// Explicitly initializing the member s is unnecessary.
// Explicitly initializing the member s and v is unnecessary.
class Foo {
public:
Foo() : s() {}

private:
std::string s;
std::vector<int> v {};
};

Options
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@ Examples:
Options
-------

.. option:: IgnoreMacros

If `true`, ignore boolean expressions originating from expanded macros.
Default is `false`.

.. option:: ChainedConditionalReturn

If `true`, conditional boolean return statements at the end of an
Expand All @@ -99,8 +104,8 @@ Options

.. option:: SimplifyDeMorganRelaxed

If `true`, :option:`SimplifyDeMorgan` will also transform negated
conjunctions and disjunctions where there is no negation on either operand.
If `true`, :option:`SimplifyDeMorgan` will also transform negated
conjunctions and disjunctions where there is no negation on either operand.
This option has no effect if :option:`SimplifyDeMorgan` is `false`.
Default is `false`.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,16 @@ void swap(int&, int&) {
throw 1;
}

void iter_swap(int&, int&) {
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'iter_swap' which should not throw exceptions
throw 1;
}

void iter_move(int&) {
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'iter_move' which should not throw exceptions
throw 1;
}

namespace std {
class bad_alloc {};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ char *t0(char *base, int a, int b) {
// CHECK-NOTES-CXX: static_cast<ptrdiff_t>( )
// CHECK-NOTES-ALL: :[[@LINE-5]]:16: note: perform multiplication in a wider type
// CHECK-NOTES-C: (ptrdiff_t)
// CHECK-NOTES-CXX: static_cast<ptrdiff_t>()
// CHECK-NOTES-CXX: static_cast<ptrdiff_t>( )
}
void *t1(char *base, int a, int b) {
return &((a * b)[base]);
Expand All @@ -35,7 +35,7 @@ char *t2(char *base, unsigned int a, int b) {
// CHECK-NOTES-CXX: static_cast<size_t>( )
// CHECK-NOTES-ALL: :[[@LINE-5]]:16: note: perform multiplication in a wider type
// CHECK-NOTES-C: (size_t)
// CHECK-NOTES-CXX: static_cast<size_t>()
// CHECK-NOTES-CXX: static_cast<size_t>( )
}

char *t3(char *base, int a, unsigned int b) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ long t0(int a, int b) {
// CHECK-NOTES-CXX: static_cast<long>( )
// CHECK-NOTES-ALL: :[[@LINE-5]]:10: note: perform multiplication in a wider type
// CHECK-NOTES-C: (long)
// CHECK-NOTES-CXX: static_cast<long>()
// CHECK-NOTES-CXX: static_cast<long>( )
}
unsigned long t1(int a, int b) {
return a * b;
Expand All @@ -28,7 +28,7 @@ unsigned long t1(int a, int b) {
// CHECK-NOTES-CXX: static_cast<unsigned long>( )
// CHECK-NOTES-ALL: :[[@LINE-5]]:10: note: perform multiplication in a wider type
// CHECK-NOTES-C: (long)
// CHECK-NOTES-CXX: static_cast<long>()
// CHECK-NOTES-CXX: static_cast<long>( )
}

long t2(unsigned int a, int b) {
Expand All @@ -39,7 +39,7 @@ long t2(unsigned int a, int b) {
// CHECK-NOTES-CXX: static_cast<long>( )
// CHECK-NOTES-ALL: :[[@LINE-5]]:10: note: perform multiplication in a wider type
// CHECK-NOTES-C: (unsigned long)
// CHECK-NOTES-CXX: static_cast<unsigned long>()
// CHECK-NOTES-CXX: static_cast<unsigned long>( )
}
unsigned long t3(unsigned int a, int b) {
return a * b;
Expand All @@ -49,7 +49,7 @@ unsigned long t3(unsigned int a, int b) {
// CHECK-NOTES-CXX: static_cast<unsigned long>( )
// CHECK-NOTES-ALL: :[[@LINE-5]]:10: note: perform multiplication in a wider type
// CHECK-NOTES-C: (unsigned long)
// CHECK-NOTES-CXX: static_cast<unsigned long>()
// CHECK-NOTES-CXX: static_cast<unsigned long>( )
}

long t4(int a, unsigned int b) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ char *t0(char *base, int a, int b) {
// CHECK-NOTES-CXX: static_cast<ptrdiff_t>( )
// CHECK-NOTES-ALL: :[[@LINE-5]]:17: note: perform multiplication in a wider type
// CHECK-NOTES-C: (ptrdiff_t)
// CHECK-NOTES-CXX: static_cast<ptrdiff_t>()
// CHECK-NOTES-CXX: static_cast<ptrdiff_t>( )
}
char *t1(char *base, int a, int b) {
return a * b + base;
Expand All @@ -35,7 +35,7 @@ char *t2(char *base, unsigned int a, int b) {
// CHECK-NOTES-CXX: static_cast<size_t>( )
// CHECK-NOTES-ALL: :[[@LINE-5]]:17: note: perform multiplication in a wider type
// CHECK-NOTES-C: (size_t)
// CHECK-NOTES-CXX: static_cast<size_t>()
// CHECK-NOTES-CXX: static_cast<size_t>( )
}

char *t3(char *base, int a, unsigned int b) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ void swap(A &, A &);
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: swap functions should be marked noexcept [performance-noexcept-swap]
// CHECK-FIXES: void swap(A &, A &) noexcept ;

void iter_swap(A &, A &);
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: swap functions should be marked noexcept [performance-noexcept-swap]
// CHECK-FIXES: void iter_swap(A &, A &) noexcept ;

struct B {
static constexpr bool kFalse = false;
void swap(B &) noexcept(kFalse);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class TemplatedContainer {
public:
bool operator==(const TemplatedContainer<T>& other) const;
bool operator!=(const TemplatedContainer<T>& other) const;
int size() const;
unsigned long size() const;
bool empty() const;
};

Expand All @@ -42,7 +42,7 @@ class PrivateEmpty {
public:
bool operator==(const PrivateEmpty<T>& other) const;
bool operator!=(const PrivateEmpty<T>& other) const;
int size() const;
unsigned long size() const;
private:
bool empty() const;
};
Expand All @@ -61,7 +61,7 @@ struct EnumSize {
class Container {
public:
bool operator==(const Container& other) const;
int size() const;
unsigned long size() const;
bool empty() const;
};

Expand All @@ -70,13 +70,13 @@ class Derived : public Container {

class Container2 {
public:
int size() const;
unsigned long size() const;
bool empty() const { return size() == 0; }
};

class Container3 {
public:
int size() const;
unsigned long size() const;
bool empty() const;
};

Expand All @@ -85,7 +85,7 @@ bool Container3::empty() const { return this->size() == 0; }
class Container4 {
public:
bool operator==(const Container4& rhs) const;
int size() const;
unsigned long size() const;
bool empty() const { return *this == Container4(); }
};

Expand Down Expand Up @@ -815,3 +815,49 @@ bool testNotEmptyStringLiterals(const std::string& s)
using namespace std::string_literals;
return s == "foo"s;
}

namespace PR72619 {
struct SS {
bool empty() const;
int size() const;
};

struct SU {
bool empty() const;
unsigned size() const;
};

void f(const SU& s) {
if (s.size() < 0) {}
if (0 > s.size()) {}
if (s.size() >= 0) {}
if (0 <= s.size()) {}
if (s.size() < 1)
;
// CHECK-MESSAGES: :[[@LINE-2]]:9: warning: the 'empty' method should be used to check for emptiness instead of 'size' [readability-container-size-empty]
// CHECK-FIXES: {{^ }}if (s.empty()){{$}}
if (1 > s.size())
;
// CHECK-MESSAGES: :[[@LINE-2]]:13: warning: the 'empty' method should be used to check for emptiness instead of 'size' [readability-container-size-empty]
// CHECK-FIXES: {{^ }}if (s.empty()){{$}}
if (s.size() <= 0)
;
// CHECK-MESSAGES: :[[@LINE-2]]:9: warning: the 'empty' method should be used to check for emptiness instead of 'size' [readability-container-size-empty]
// CHECK-FIXES: {{^ }}if (s.empty()){{$}}
if (0 >= s.size())
;
// CHECK-MESSAGES: :[[@LINE-2]]:14: warning: the 'empty' method should be used to check for emptiness instead of 'size' [readability-container-size-empty]
// CHECK-FIXES: {{^ }}if (s.empty()){{$}}
}

void f(const SS& s) {
if (s.size() < 0) {}
if (0 > s.size()) {}
if (s.size() >= 0) {}
if (0 <= s.size()) {}
if (s.size() < 1) {}
if (1 > s.size()) {}
if (s.size() <= 0) {}
if (0 >= s.size()) {}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ int* functionReturningPointer();
struct Struct {
int member;
unsigned bitfield : 1;
bool boolfield : 1;
};


Expand All @@ -28,6 +29,8 @@ void implicitConversionIntegerToBoolInConditionalsIsAllowed() {
if (!s.member) {}
if (s.bitfield) {}
if (!s.bitfield) {}
if (s.boolfield == true) {}
if (s.boolfield != true) {}
if (functionReturningInt()) {}
if (!functionReturningInt()) {}
if (functionReturningInt() && functionReturningPointer()) {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -250,3 +250,55 @@ struct NF15 {
S s2;
};
};

// Direct in-class initialization with default constructor
struct D1 {
S f1 {};
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: initializer for member 'f1' is redundant
// CHECK-FIXES: S f1;
};

// Direct in-class initialization with constructor with default argument
struct D2 {
T f2 {};
// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: initializer for member 'f2' is redundant
// CHECK-FIXES: T f2;
};

// Direct in-class initialization with default constructor (assign)
struct D3 {
S f3 = {};
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: initializer for member 'f3' is redundant
// CHECK-FIXES: S f3;
};

// Direct in-class initialization with constructor with default argument (assign)
struct D4 {
T f4 = {};
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: initializer for member 'f4' is redundant
// CHECK-FIXES: T f4;
};

// Templated class independent type
template <class V>
struct D5 {
S f5 /*comment*/ = S();
// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: initializer for member 'f5' is redundant
// CHECK-FIXES: S f5 /*comment*/;
};
D5<int> d5i;
D5<S> d5s;

struct D6 {
UsesCleanup uc2{};
// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: initializer for member 'uc2' is redundant
// CHECK-FIXES: UsesCleanup uc2;
};

template<typename V>
struct D7 {
V f7;
};

D7<int> d7i;
D7<S> d7s;
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// RUN: %check_clang_tidy -check-suffixes=,MACROS %s readability-simplify-boolean-expr %t

// Ignore expressions in macros.
// RUN: %check_clang_tidy %s readability-simplify-boolean-expr %t \
// RUN: -- -config="{CheckOptions: {readability-simplify-boolean-expr.IgnoreMacros: true}}" \
// RUN: --

#define NEGATE(expr) !(expr)

bool without_macro(bool a, bool b) {
return !(!a && b);
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: boolean expression can be simplified by DeMorgan's theorem
// CHECK-FIXES: return a || !b;
}

bool macro(bool a, bool b) {
return NEGATE(!a && b);
// CHECK-MESSAGES-MACROS: :[[@LINE-1]]:12: warning: boolean expression can be simplified by DeMorgan's theorem
// CHECK-FIXES: return NEGATE(!a && b);
}
5 changes: 5 additions & 0 deletions clang/docs/ClangFormatStyleOptions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4432,6 +4432,11 @@ the configuration (without a prefix: ``Auto``).
**PenaltyBreakOpenParenthesis** (``Unsigned``) :versionbadge:`clang-format 14` :ref:`<PenaltyBreakOpenParenthesis>`
The penalty for breaking after ``(``.

.. _PenaltyBreakScopeResolution:

**PenaltyBreakScopeResolution** (``Unsigned``) :versionbadge:`clang-format 18` :ref:`<PenaltyBreakScopeResolution>`
The penalty for breaking after ``::``.

.. _PenaltyBreakString:

**PenaltyBreakString** (``Unsigned``) :versionbadge:`clang-format 3.7` :ref:`<PenaltyBreakString>`
Expand Down
1 change: 1 addition & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1131,6 +1131,7 @@ clang-format
- Add ``BreakAdjacentStringLiterals`` option.
- Add ``ObjCPropertyAttributeOrder`` which can be used to sort ObjC property
attributes (like ``nonatomic, strong, nullable``).
- Add ``PenaltyBreakScopeResolution`` option.
- Add ``.clang-format-ignore`` files.
- Add ``AlignFunctionPointers`` sub-option for ``AlignConsecutiveDeclarations``.

Expand Down
54 changes: 54 additions & 0 deletions clang/docs/UsersManual.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3963,6 +3963,60 @@ implicitly included in later levels.
- ``-march=x86-64-v3``: (close to Haswell) AVX, AVX2, BMI1, BMI2, F16C, FMA, LZCNT, MOVBE, XSAVE
- ``-march=x86-64-v4``: AVX512F, AVX512BW, AVX512CD, AVX512DQ, AVX512VL

`Intel AVX10 ISA <https://cdrdv2.intel.com/v1/dl/getContent/784267>`_ is
a major new vector ISA incorporating the modern vectorization aspects of
Intel AVX-512. This ISA will be supported on all future Intel processors.
Users are supposed to use the new options ``-mavx10.N`` and ``-mavx10.N-512``
on these processors and should not use traditional AVX512 options anymore.

The ``N`` in ``-mavx10.N`` represents a continuous integer number starting
from ``1``. ``-mavx10.N`` is an alias of ``-mavx10.N-256``, which means to
enable all instructions within AVX10 version N at a maximum vector length of
256 bits. ``-mavx10.N-512`` enables all instructions at a maximum vector
length of 512 bits, which is a superset of instructions ``-mavx10.N`` enabled.

Current binaries built with AVX512 features can run on Intel AVX10/512 capable
processors without re-compile, but cannot run on AVX10/256 capable processors.
Users need to re-compile their code with ``-mavx10.N``, and maybe update some
code that calling to 512-bit X86 specific intrinsics and passing or returning
512-bit vector types in function call, if they want to run on AVX10/256 capable
processors. Binaries built with ``-mavx10.N`` can run on both AVX10/256 and
AVX10/512 capable processors.

Users can add a ``-mno-evex512`` in the command line with AVX512 options if
they want to run the binary on both legacy AVX512 and new AVX10/256 capable
processors. The option has the same constraints as ``-mavx10.N``, i.e.,
cannot call to 512-bit X86 specific intrinsics and pass or return 512-bit vector
types in function call.

Users should avoid using AVX512 features in function target attributes when
developing code for AVX10. If they have to do so, they need to add an explicit
``evex512`` or ``no-evex512`` together with AVX512 features for 512-bit or
non-512-bit functions respectively to avoid unexpected code generation. Both
command line option and target attribute of EVEX512 feature can only be used
with AVX512. They don't affect vector size of AVX10.

User should not mix the use AVX10 and AVX512 options together at any time,
because the option combinations are conflicting sometimes. For example, a
combination of ``-mavx512f -mavx10.1-256`` doesn't show a clear intention to
compiler, since instructions in AVX512F and AVX10.1/256 intersect but do not
overlap. In this case, compiler will emit warning for it, but the behavior
is determined. It will generate the same code as option ``-mavx10.1-512``.
A similar case is ``-mavx512f -mavx10.2-256``, which equals to
``-mavx10.1-512 -mavx10.2-256``, because ``avx10.2-256`` implies ``avx10.1-256``
and ``-mavx512f -mavx10.1-256`` equals to ``-mavx10.1-512``.

There are some new macros introduced with AVX10 support. ``-mavx10.1-256`` will
enable ``__AVX10_1__`` and ``__EVEX256__``, while ``-mavx10.1-512`` enables
``__AVX10_1__``, ``__EVEX256__``, ``__EVEX512__`` and ``__AVX10_1_512__``.
Besides, both ``-mavx10.1-256`` and ``-mavx10.1-512`` will enable all AVX512
feature specific macros. A AVX512 feature will enable both ``__EVEX256__``,
``__EVEX512__`` and its own macro. So ``__EVEX512__`` can be used to guard code
that can run on both legacy AVX512 and AVX10/512 capable processors but cannot
run on AVX10/256, while a AVX512 macro like ``__AVX512F__`` cannot tell the
difference among the three options. Users need to check additional macros
``__AVX10_1__`` and ``__EVEX512__`` if they want to make distinction.

ARM
^^^

Expand Down
44 changes: 22 additions & 22 deletions clang/include/clang/Basic/riscv_vector.td
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ multiclass RVVIndexedLoad<string op> {
defvar eew = eew_list[0];
defvar eew_type = eew_list[1];
let Name = op # eew # "_v", IRName = op, MaskedIRName = op # "_mask",
RequiredFeatures = !if(!eq(type, "x"), ["ZvfhminOrZvfh"],
RequiredFeatures = !if(!eq(type, "x"), ["Zvfhmin"],
[]<string>) in {
def: RVVOutOp1Builtin<"v", "vPCe" # eew_type # "Uv", type>;
if !not(IsFloat<type>.val) then {
Expand All @@ -128,7 +128,7 @@ multiclass RVVIndexedLoad<string op> {
defvar eew64 = "64";
defvar eew64_type = "(Log2EEW:6)";
let Name = op # eew64 # "_v", IRName = op, MaskedIRName = op # "_mask",
RequiredFeatures = !if(!eq(type, "x"), ["ZvfhminOrZvfh", "RV64"],
RequiredFeatures = !if(!eq(type, "x"), ["Zvfhmin", "RV64"],
["RV64"]) in {
def: RVVOutOp1Builtin<"v", "vPCe" # eew64_type # "Uv", type>;
if !not(IsFloat<type>.val) then {
Expand Down Expand Up @@ -222,7 +222,7 @@ multiclass RVVIndexedStore<string op> {
defvar eew = eew_list[0];
defvar eew_type = eew_list[1];
let Name = op # eew # "_v", IRName = op, MaskedIRName = op # "_mask",
RequiredFeatures = !if(!eq(type, "x"), ["ZvfhminOrZvfh"],
RequiredFeatures = !if(!eq(type, "x"), ["Zvfhmin"],
[]<string>) in {
def : RVVBuiltin<"v", "0Pe" # eew_type # "Uvv", type>;
if !not(IsFloat<type>.val) then {
Expand All @@ -233,7 +233,7 @@ multiclass RVVIndexedStore<string op> {
defvar eew64 = "64";
defvar eew64_type = "(Log2EEW:6)";
let Name = op # eew64 # "_v", IRName = op, MaskedIRName = op # "_mask",
RequiredFeatures = !if(!eq(type, "x"), ["ZvfhminOrZvfh", "RV64"],
RequiredFeatures = !if(!eq(type, "x"), ["Zvfhmin", "RV64"],
["RV64"]) in {
def : RVVBuiltin<"v", "0Pe" # eew64_type # "Uvv", type>;
if !not(IsFloat<type>.val) then {
Expand Down Expand Up @@ -681,30 +681,30 @@ let HasBuiltinAlias = false,
def vlm: RVVVLEMaskBuiltin;
defm vle8: RVVVLEBuiltin<["c"]>;
defm vle16: RVVVLEBuiltin<["s"]>;
let Name = "vle16_v", RequiredFeatures = ["ZvfhminOrZvfh"] in
let Name = "vle16_v", RequiredFeatures = ["Zvfhmin"] in
defm vle16_h: RVVVLEBuiltin<["x"]>;
defm vle32: RVVVLEBuiltin<["i","f"]>;
defm vle64: RVVVLEBuiltin<["l","d"]>;

def vsm : RVVVSEMaskBuiltin;
defm vse8 : RVVVSEBuiltin<["c"]>;
defm vse16: RVVVSEBuiltin<["s"]>;
let Name = "vse16_v", RequiredFeatures = ["ZvfhminOrZvfh"] in
let Name = "vse16_v", RequiredFeatures = ["Zvfhmin"] in
defm vse16_h: RVVVSEBuiltin<["x"]>;
defm vse32: RVVVSEBuiltin<["i","f"]>;
defm vse64: RVVVSEBuiltin<["l","d"]>;

// 7.5. Vector Strided Instructions
defm vlse8: RVVVLSEBuiltin<["c"]>;
defm vlse16: RVVVLSEBuiltin<["s"]>;
let Name = "vlse16_v", RequiredFeatures = ["ZvfhminOrZvfh"] in
let Name = "vlse16_v", RequiredFeatures = ["Zvfhmin"] in
defm vlse16_h: RVVVLSEBuiltin<["x"]>;
defm vlse32: RVVVLSEBuiltin<["i","f"]>;
defm vlse64: RVVVLSEBuiltin<["l","d"]>;

defm vsse8 : RVVVSSEBuiltin<["c"]>;
defm vsse16: RVVVSSEBuiltin<["s"]>;
let Name = "vsse16_v", RequiredFeatures = ["ZvfhminOrZvfh"] in
let Name = "vsse16_v", RequiredFeatures = ["Zvfhmin"] in
defm vsse16_h: RVVVSSEBuiltin<["x"]>;
defm vsse32: RVVVSSEBuiltin<["i","f"]>;
defm vsse64: RVVVSSEBuiltin<["l","d"]>;
Expand All @@ -719,7 +719,7 @@ defm : RVVIndexedStore<"vsoxei">;
// 7.7. Unit-stride Fault-Only-First Loads
defm vle8ff: RVVVLEFFBuiltin<["c"]>;
defm vle16ff: RVVVLEFFBuiltin<["s"]>;
let Name = "vle16ff_v", RequiredFeatures = ["ZvfhminOrZvfh"] in
let Name = "vle16ff_v", RequiredFeatures = ["Zvfhmin"] in
defm vle16ff: RVVVLEFFBuiltin<["x"]>;
defm vle32ff: RVVVLEFFBuiltin<["i", "f"]>;
defm vle64ff: RVVVLEFFBuiltin<["l", "d"]>;
Expand All @@ -738,7 +738,7 @@ multiclass RVVUnitStridedSegLoadTuple<string op> {
IRName = op # nf,
MaskedIRName = op # nf # "_mask",
NF = nf,
RequiredFeatures = !if(!eq(type, "x"), ["ZvfhminOrZvfh"],
RequiredFeatures = !if(!eq(type, "x"), ["Zvfhmin"],
[]<string>),
ManualCodegen = [{
{
Expand Down Expand Up @@ -800,7 +800,7 @@ multiclass RVVUnitStridedSegStoreTuple<string op> {
MaskedIRName = op # nf # "_mask",
NF = nf,
HasMaskedOffOperand = false,
RequiredFeatures = !if(!eq(type, "x"), ["ZvfhminOrZvfh"],
RequiredFeatures = !if(!eq(type, "x"), ["Zvfhmin"],
[]<string>),
ManualCodegen = [{
{
Expand Down Expand Up @@ -852,7 +852,7 @@ multiclass RVVUnitStridedSegLoadFFTuple<string op> {
IRName = op # nf # "ff",
MaskedIRName = op # nf # "ff_mask",
NF = nf,
RequiredFeatures = !if(!eq(type, "x"), ["ZvfhminOrZvfh"],
RequiredFeatures = !if(!eq(type, "x"), ["Zvfhmin"],
[]<string>),
ManualCodegen = [{
{
Expand Down Expand Up @@ -927,7 +927,7 @@ multiclass RVVStridedSegLoadTuple<string op> {
IRName = op # nf,
MaskedIRName = op # nf # "_mask",
NF = nf,
RequiredFeatures = !if(!eq(type, "x"), ["ZvfhminOrZvfh"],
RequiredFeatures = !if(!eq(type, "x"), ["Zvfhmin"],
[]<string>),
ManualCodegen = [{
{
Expand Down Expand Up @@ -991,7 +991,7 @@ multiclass RVVStridedSegStoreTuple<string op> {
NF = nf,
HasMaskedOffOperand = false,
MaskedPolicyScheme = NonePolicy,
RequiredFeatures = !if(!eq(type, "x"), ["ZvfhminOrZvfh"],
RequiredFeatures = !if(!eq(type, "x"), ["Zvfhmin"],
[]<string>),
ManualCodegen = [{
{
Expand Down Expand Up @@ -1040,7 +1040,7 @@ multiclass RVVIndexedSegLoadTuple<string op> {
IRName = op # nf,
MaskedIRName = op # nf # "_mask",
NF = nf,
RequiredFeatures = !if(!eq(type, "x"), ["ZvfhminOrZvfh"],
RequiredFeatures = !if(!eq(type, "x"), ["Zvfhmin"],
[]<string>),
ManualCodegen = [{
{
Expand Down Expand Up @@ -1103,7 +1103,7 @@ multiclass RVVIndexedSegStoreTuple<string op> {
NF = nf,
HasMaskedOffOperand = false,
MaskedPolicyScheme = NonePolicy,
RequiredFeatures = !if(!eq(type, "x"), ["ZvfhminOrZvfh"],
RequiredFeatures = !if(!eq(type, "x"), ["Zvfhmin"],
[]<string>),
ManualCodegen = [{
{
Expand Down Expand Up @@ -1345,7 +1345,7 @@ let HasMasked = false,
[["v", "Uv", "UvUv"]]>;
defm vmv_v : RVVOutBuiltinSet<"vmv_v_v", "csilfd",
[["v", "v", "vv"]]>;
let RequiredFeatures = ["ZvfhminOrZvfh"] in
let RequiredFeatures = ["Zvfhmin"] in
defm vmv_v : RVVOutBuiltinSet<"vmv_v_v", "x",
[["v", "v", "vv"]]>;
let SupportOverloading = false in
Expand Down Expand Up @@ -1841,7 +1841,7 @@ let HasMasked = false,
}] in {
defm vmerge : RVVOutOp1BuiltinSet<"vmerge", "fd",
[["vvm", "v", "vvvm"]]>;
let RequiredFeatures = ["ZvfhminOrZvfh"] in
let RequiredFeatures = ["Zvfhmin"] in
defm vmerge : RVVOutOp1BuiltinSet<"vmerge", "x",
[["vvm", "v", "vvvm"]]>;
defm vfmerge : RVVOutOp1BuiltinSet<"vfmerge", "xfd",
Expand Down Expand Up @@ -1869,7 +1869,7 @@ let Log2LMUL = [-3, -2, -1, 0, 1, 2] in {
def vfwcvt_f_xu_v : RVVConvBuiltin<"Fw", "FwUv", "csi", "vfwcvt_f">;
def vfwcvt_f_x_v : RVVConvBuiltin<"Fw", "Fwv", "csi", "vfwcvt_f">;
def vfwcvt_f_f_v : RVVConvBuiltin<"w", "wv", "f", "vfwcvt_f">;
let RequiredFeatures = ["ZvfhminOrZvfh"] in
let RequiredFeatures = ["Zvfhmin"] in
def vfwcvt_f_f_v_fp16 : RVVConvBuiltin<"w", "wv", "x", "vfwcvt_f"> {
let Name = "vfwcvt_f_f_v";
let IRName = "vfwcvt_f_f_v";
Expand Down Expand Up @@ -1966,7 +1966,7 @@ let ManualCodegen = [{
}
let OverloadedName = "vfncvt_f" in {
defm : RVVConvBuiltinSet<"vfncvt_f_f_w", "f", [["v", "vwu"]]>;
let RequiredFeatures = ["ZvfhminOrZvfh"] in
let RequiredFeatures = ["Zvfhmin"] in
defm : RVVConvBuiltinSet<"vfncvt_f_f_w", "x", [["v", "vwu"]]>;
}
}
Expand Down Expand Up @@ -2011,7 +2011,7 @@ let ManualCodegen = [{
}
let OverloadedName = "vfncvt_f" in {
defm : RVVConvBuiltinSet<"vfncvt_f_f_w", "f", [["v", "vw"]]>;
let RequiredFeatures = ["ZvfhminOrZvfh"] in
let RequiredFeatures = ["Zvfhmin"] in
defm : RVVConvBuiltinSet<"vfncvt_f_f_w", "x", [["v", "vw"]]>;
}
}
Expand Down Expand Up @@ -2271,7 +2271,7 @@ let HasMasked = false, HasVL = false, IRName = "" in {
def vreinterpret_u_f : RVVBuiltin<"FvUv", "UvFv", "il", "Uv">;
def vreinterpret_f_i : RVVBuiltin<"vFv", "Fvv", "il", "Fv">;
def vreinterpret_f_u : RVVBuiltin<"UvFv", "FvUv", "il", "Fv">;
let RequiredFeatures = ["ZvfhminOrZvfh"] in {
let RequiredFeatures = ["Zvfhmin"] in {
def vreinterpret_i_h : RVVBuiltin<"Fvv", "vFv", "s", "v">;
def vreinterpret_u_h : RVVBuiltin<"FvUv", "UvFv", "s", "Uv">;
def vreinterpret_h_i : RVVBuiltin<"vFv", "Fvv", "s", "Fv">;
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -5172,7 +5172,7 @@ def module_file_info : Flag<["-"], "module-file-info">, Flags<[]>,
HelpText<"Provide information about a particular module file">;
def mthumb : Flag<["-"], "mthumb">, Group<m_Group>;
def mtune_EQ : Joined<["-"], "mtune=">, Group<m_Group>,
HelpText<"Only supported on AArch64, PowerPC, RISC-V, SystemZ, and X86">;
HelpText<"Only supported on AArch64, PowerPC, RISC-V, SPARC, SystemZ, and X86">;
def multi__module : Flag<["-"], "multi_module">;
def multiply__defined__unused : Separate<["-"], "multiply_defined_unused">;
def multiply__defined : Separate<["-"], "multiply_defined">;
Expand Down
5 changes: 5 additions & 0 deletions clang/include/clang/Format/Format.h
Original file line number Diff line number Diff line change
Expand Up @@ -3398,6 +3398,10 @@ struct FormatStyle {
/// \version 14
unsigned PenaltyBreakOpenParenthesis;

/// The penalty for breaking after ``::``.
/// \version 18
unsigned PenaltyBreakScopeResolution;

/// The penalty for each line break introduced inside a string literal.
/// \version 3.7
unsigned PenaltyBreakString;
Expand Down Expand Up @@ -4873,6 +4877,7 @@ struct FormatStyle {
PenaltyBreakComment == R.PenaltyBreakComment &&
PenaltyBreakFirstLessLess == R.PenaltyBreakFirstLessLess &&
PenaltyBreakOpenParenthesis == R.PenaltyBreakOpenParenthesis &&
PenaltyBreakScopeResolution == R.PenaltyBreakScopeResolution &&
PenaltyBreakString == R.PenaltyBreakString &&
PenaltyBreakTemplateDeclaration ==
R.PenaltyBreakTemplateDeclaration &&
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Support/RISCVVIntrinsicUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -488,7 +488,7 @@ class RVVIntrinsic {
enum RVVRequire : uint32_t {
RVV_REQ_None = 0,
RVV_REQ_RV64 = 1 << 0,
RVV_REQ_ZvfhminOrZvfh = 1 << 1,
RVV_REQ_Zvfhmin = 1 << 1,
RVV_REQ_Xsfvcp = 1 << 2,
RVV_REQ_Xsfvfnrclipxfqf = 1 << 3,
RVV_REQ_Xsfvfwmaccqqq = 1 << 4,
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/AST/Interp/ByteCodeExprGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2337,7 +2337,7 @@ bool ByteCodeExprGen<Emitter>::visitDecl(const VarDecl *VD) {
auto GlobalIndex = P.getGlobal(VD);
assert(GlobalIndex); // visitVarDecl() didn't return false.
if (VarT) {
if (!this->emitGetGlobal(*VarT, *GlobalIndex, VD))
if (!this->emitGetGlobalUnchecked(*VarT, *GlobalIndex, VD))
return false;
} else {
if (!this->emitGetPtrGlobal(*GlobalIndex, VD))
Expand Down
48 changes: 38 additions & 10 deletions clang/lib/AST/Interp/Interp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,21 @@ static bool Jf(InterpState &S, CodePtr &PC, int32_t Offset) {
return true;
}

static void diagnoseNonConstVariable(InterpState &S, CodePtr OpPC,
const ValueDecl *VD) {
if (!S.getLangOpts().CPlusPlus)
return;

const SourceInfo &Loc = S.Current->getSource(OpPC);
S.FFDiag(Loc,
VD->getType()->isIntegralOrEnumerationType()
? diag::note_constexpr_ltor_non_const_int
: diag::note_constexpr_ltor_non_constexpr,
1)
<< VD;
S.Note(VD->getLocation(), diag::note_declared_at);
}

static bool CheckActive(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
AccessKinds AK) {
if (Ptr.isActive())
Expand Down Expand Up @@ -171,9 +186,7 @@ bool CheckExtern(InterpState &S, CodePtr OpPC, const Pointer &Ptr) {

if (!S.checkingPotentialConstantExpression() && S.getLangOpts().CPlusPlus) {
const auto *VD = Ptr.getDeclDesc()->asValueDecl();
const SourceInfo &Loc = S.Current->getSource(OpPC);
S.FFDiag(Loc, diag::note_constexpr_ltor_non_constexpr, 1) << VD;
S.Note(VD->getLocation(), diag::note_declared_at);
diagnoseNonConstVariable(S, OpPC, VD);
}
return false;
}
Expand Down Expand Up @@ -216,6 +229,24 @@ bool CheckLive(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
return true;
}

bool CheckConstant(InterpState &S, CodePtr OpPC, const Descriptor *Desc) {
assert(Desc);
if (const auto *D = Desc->asValueDecl()) {
if (const auto *VD = dyn_cast<VarDecl>(D);
VD && VD->hasGlobalStorage() &&
!(VD->isConstexpr() || VD->getType().isConstQualified())) {
diagnoseNonConstVariable(S, OpPC, VD);
return false;
}
}

return true;
}

static bool CheckConstant(InterpState &S, CodePtr OpPC, const Pointer &Ptr) {
return CheckConstant(S, OpPC, Ptr.getDeclDesc());
}

bool CheckDummy(InterpState &S, CodePtr OpPC, const Pointer &Ptr) {
return !Ptr.isZero() && !Ptr.isDummy();
}
Expand Down Expand Up @@ -304,6 +335,9 @@ bool CheckInitialized(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
bool CheckLoad(InterpState &S, CodePtr OpPC, const Pointer &Ptr) {
if (!CheckLive(S, OpPC, Ptr, AK_Read))
return false;
if (!CheckConstant(S, OpPC, Ptr))
return false;

if (!CheckDummy(S, OpPC, Ptr))
return false;
if (!CheckExtern(S, OpPC, Ptr))
Expand Down Expand Up @@ -605,13 +639,7 @@ bool CheckDeclRef(InterpState &S, CodePtr OpPC, const DeclRefExpr *DR) {
}
} else if (const auto *VD = dyn_cast<VarDecl>(D)) {
if (!VD->getType().isConstQualified()) {
S.FFDiag(E,
VD->getType()->isIntegralOrEnumerationType()
? diag::note_constexpr_ltor_non_const_int
: diag::note_constexpr_ltor_non_constexpr,
1)
<< VD;
S.Note(VD->getLocation(), diag::note_declared_at) << VD->getSourceRange();
diagnoseNonConstVariable(S, OpPC, VD);
return false;
}

Expand Down
14 changes: 14 additions & 0 deletions clang/lib/AST/Interp/Interp.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ bool CheckSubobject(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
/// Checks if a pointer points to const storage.
bool CheckConst(InterpState &S, CodePtr OpPC, const Pointer &Ptr);

/// Checks if the Descriptor is of a constexpr or const global variable.
bool CheckConstant(InterpState &S, CodePtr OpPC, const Descriptor *Desc);

/// Checks if a pointer points to a mutable field.
bool CheckMutable(InterpState &S, CodePtr OpPC, const Pointer &Ptr);

Expand Down Expand Up @@ -1004,12 +1007,23 @@ bool SetThisField(InterpState &S, CodePtr OpPC, uint32_t I) {
template <PrimType Name, class T = typename PrimConv<Name>::T>
bool GetGlobal(InterpState &S, CodePtr OpPC, uint32_t I) {
const Block *B = S.P.getGlobal(I);

if (!CheckConstant(S, OpPC, B->getDescriptor()))
return false;
if (B->isExtern())
return false;
S.Stk.push<T>(B->deref<T>());
return true;
}

/// Same as GetGlobal, but without the checks.
template <PrimType Name, class T = typename PrimConv<Name>::T>
bool GetGlobalUnchecked(InterpState &S, CodePtr OpPC, uint32_t I) {
auto *B = S.P.getGlobal(I);
S.Stk.push<T>(B->deref<T>());
return true;
}

template <PrimType Name, class T = typename PrimConv<Name>::T>
bool SetGlobal(InterpState &S, CodePtr OpPC, uint32_t I) {
// TODO: emit warning.
Expand Down
1 change: 1 addition & 0 deletions clang/lib/AST/Interp/Opcodes.td
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,7 @@ def CheckGlobalCtor : Opcode {}

// [] -> [Value]
def GetGlobal : AccessOpcode;
def GetGlobalUnchecked : AccessOpcode;
// [Value] -> []
def InitGlobal : AccessOpcode;
// [Value] -> []
Expand Down
6 changes: 3 additions & 3 deletions clang/lib/CodeGen/CoverageMappingGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -730,8 +730,8 @@ struct MCDCCoverageBuilder {
return;

// If binary expression is disqualified, don't do mapping.
if (NestLevel.empty() && MCDCBitmapMap.find(CodeGenFunction::stripCond(
E)) == MCDCBitmapMap.end())
if (NestLevel.empty() &&
!MCDCBitmapMap.contains(CodeGenFunction::stripCond(E)))
NotMapped = true;

// Push Stmt on 'NestLevel' stack to keep track of nest location.
Expand All @@ -744,7 +744,7 @@ struct MCDCCoverageBuilder {
// If the operator itself has an assigned ID, this means it represents a
// larger subtree. In this case, pop its ID out of the RHS stack and
// assign that ID to its LHS node. Its RHS will receive a new ID.
if (CondIDs.find(CodeGenFunction::stripCond(E)) != CondIDs.end()) {
if (CondIDs.contains(CodeGenFunction::stripCond(E))) {
// If Stmt has an ID, assign its ID to LHS
CondIDs[CodeGenFunction::stripCond(E->getLHS())] = CondIDs[E];

Expand Down
3 changes: 3 additions & 0 deletions clang/lib/Format/Format.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1054,6 +1054,8 @@ template <> struct MappingTraits<FormatStyle> {
Style.PenaltyBreakFirstLessLess);
IO.mapOptional("PenaltyBreakOpenParenthesis",
Style.PenaltyBreakOpenParenthesis);
IO.mapOptional("PenaltyBreakScopeResolution",
Style.PenaltyBreakScopeResolution);
IO.mapOptional("PenaltyBreakString", Style.PenaltyBreakString);
IO.mapOptional("PenaltyBreakTemplateDeclaration",
Style.PenaltyBreakTemplateDeclaration);
Expand Down Expand Up @@ -1602,6 +1604,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
LLVMStyle.PenaltyReturnTypeOnItsOwnLine = 60;
LLVMStyle.PenaltyBreakBeforeFirstCallParameter = 19;
LLVMStyle.PenaltyBreakOpenParenthesis = 0;
LLVMStyle.PenaltyBreakScopeResolution = 500;
LLVMStyle.PenaltyBreakTemplateDeclaration = prec::Relational;
LLVMStyle.PenaltyIndentedWhitespace = 0;

Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Format/TokenAnnotator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3765,7 +3765,7 @@ unsigned TokenAnnotator::splitPenalty(const AnnotatedLine &Line,
}

if (Left.is(tok::coloncolon))
return 500;
return Style.PenaltyBreakScopeResolution;
if (Right.isOneOf(TT_StartOfName, TT_FunctionDeclarationName) ||
Right.is(tok::kw_operator)) {
if (Line.startsWith(tok::kw_for) && Right.PartOfMultiVariableDeclStmt)
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Frontend/CompilerInstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2204,7 +2204,7 @@ void CompilerInstance::createModuleFromSource(SourceLocation ImportLoc,
// Build the module, inheriting any modules that we've built locally.
if (compileModuleImpl(*this, ImportLoc, ModuleName, Input, StringRef(),
ModuleFileName, PreBuildStep, PostBuildStep)) {
BuiltModules[std::string(ModuleName)] = std::string(ModuleFileName.str());
BuiltModules[std::string(ModuleName)] = std::string(ModuleFileName);
llvm::sys::RemoveFileOnSignal(ModuleFileName);
}
}
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Frontend/Rewrite/FrontendActions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ class FixItActionSuffixInserter : public FixItOptions {
SmallString<128> Path(Filename);
llvm::sys::path::replace_extension(Path,
NewSuffix + llvm::sys::path::extension(Path));
return std::string(Path.str());
return std::string(Path);
}
};

Expand Down
5 changes: 2 additions & 3 deletions clang/lib/Sema/SemaRISCVVectorLookup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -274,9 +274,8 @@ void RISCVIntrinsicManagerImpl::ConstructRVVIntrinsics(
continue;

if (BaseType == BasicType::Float16) {
if ((Record.RequiredExtensions & RVV_REQ_ZvfhminOrZvfh) ==
RVV_REQ_ZvfhminOrZvfh) {
if (!TI.hasFeature("zvfh") && !TI.hasFeature("zvfhmin"))
if ((Record.RequiredExtensions & RVV_REQ_Zvfhmin) == RVV_REQ_Zvfhmin) {
if (!TI.hasFeature("zvfhmin"))
continue;
} else if (!TI.hasFeature("zvfh")) {
continue;
Expand Down
32 changes: 32 additions & 0 deletions clang/test/AST/Interp/arrays.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -566,3 +566,35 @@ namespace GH69115 {
static_assert(foo2() == 0, "");
#endif
}

namespace NonConstReads {
#if __cplusplus >= 202002L
void *p = nullptr; // ref-note {{declared here}} \
// expected-note {{declared here}}

int arr[!p]; // ref-error {{not allowed at file scope}} \
// expected-error {{not allowed at file scope}} \
// ref-warning {{variable length arrays}} \
// ref-note {{read of non-constexpr variable 'p'}} \
// expected-warning {{variable length arrays}} \
// expected-note {{read of non-constexpr variable 'p'}}
int z; // ref-note {{declared here}} \
// expected-note {{declared here}}
int a[z]; // ref-error {{not allowed at file scope}} \
// expected-error {{not allowed at file scope}} \
// ref-warning {{variable length arrays}} \
// ref-note {{read of non-const variable 'z'}} \
// expected-warning {{variable length arrays}} \
// expected-note {{read of non-const variable 'z'}}
#else
void *p = nullptr;
int arr[!p]; // ref-error {{not allowed at file scope}} \
// expected-error {{not allowed at file scope}}
int z;
int a[z]; // ref-error {{not allowed at file scope}} \
// expected-error {{not allowed at file scope}}
#endif

const int y = 0;
int yy[y];
}
22 changes: 16 additions & 6 deletions clang/test/AST/Interp/cxx23.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,22 +25,32 @@ constexpr int g(int n) { // ref20-error {{constexpr function never produc
}

constexpr int c_thread_local(int n) { // ref20-error {{constexpr function never produces a constant expression}} \
// ref23-error {{constexpr function never produces a constant expression}}
// ref23-error {{constexpr function never produces a constant expression}} \
// expected20-error {{constexpr function never produces a constant expression}} \
// expected23-error {{constexpr function never produces a constant expression}}
static _Thread_local int m = 0; // ref20-note {{control flows through the definition of a thread_local variable}} \
// ref20-warning {{is a C++23 extension}} \
// ref23-note {{control flows through the definition of a thread_local variable}} \
// expected20-warning {{is a C++23 extension}}
return m;
// expected20-warning {{is a C++23 extension}} \
// expected20-note {{declared here}} \
// expected23-note {{declared here}}
return m; // expected20-note {{read of non-const variable}} \
// expected23-note {{read of non-const variable}}
}


constexpr int gnu_thread_local(int n) { // ref20-error {{constexpr function never produces a constant expression}} \
// ref23-error {{constexpr function never produces a constant expression}}
// ref23-error {{constexpr function never produces a constant expression}} \
// expected20-error {{constexpr function never produces a constant expression}} \
// expected23-error {{constexpr function never produces a constant expression}}
static __thread int m = 0; // ref20-note {{control flows through the definition of a thread_local variable}} \
// ref20-warning {{is a C++23 extension}} \
// ref23-note {{control flows through the definition of a thread_local variable}} \
// expected20-warning {{is a C++23 extension}}
return m;
// expected20-warning {{is a C++23 extension}} \
// expected20-note {{declared here}} \
// expected23-note {{declared here}}
return m; // expected20-note {{read of non-const variable}} \
// expected23-note {{read of non-const variable}}
}

constexpr int h(int n) { // ref20-error {{constexpr function never produces a constant expression}} \
Expand Down
27 changes: 24 additions & 3 deletions clang/test/AST/Interp/literals.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1181,8 +1181,29 @@ namespace InvalidDeclRefs {
// expected-error {{not an integral constant expression}} \
// expected-note {{initializer of 'b02' is unknown}}

/// FIXME: This should also be diagnosed in the new interpreter.
int b03 = 3; // ref-note {{declared here}}
int b03 = 3; // ref-note {{declared here}} \
// expected-note {{declared here}}
static_assert(b03, ""); // ref-error {{not an integral constant expression}} \
// ref-note {{read of non-const variable}}
// ref-note {{read of non-const variable}} \
// expected-error {{not an integral constant expression}} \
// expected-note {{read of non-const variable}}
}

namespace NonConstReads {
void *p = nullptr; // ref-note {{declared here}} \
// expected-note {{declared here}}
static_assert(!p, ""); // ref-error {{not an integral constant expression}} \
// ref-note {{read of non-constexpr variable 'p'}} \
// expected-error {{not an integral constant expression}} \
// expected-note {{read of non-constexpr variable 'p'}}

int arr[!p]; // ref-error {{variable length array}} \
// expected-error {{variable length array}}

int z; // ref-note {{declared here}} \
// expected-note {{declared here}}
static_assert(z == 0, ""); // ref-error {{not an integral constant expression}} \
// ref-note {{read of non-const variable 'z'}} \
// expected-error {{not an integral constant expression}} \
// expected-note {{read of non-const variable 'z'}}
}
202 changes: 101 additions & 101 deletions clang/test/CXX/drs/dr0xx.cpp

Large diffs are not rendered by default.

73 changes: 73 additions & 0 deletions clang/test/CXX/drs/dr13xx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ void caller() {
#endif // __cplusplus >= 201103L
} // namespace dr1307

// dr1308: sup 1330

namespace dr1310 { // dr1310: 5
struct S {} * sp = new S::S;
// expected-error@-1 {{qualified reference to 'S' is a constructor name rather than a type in this context}}
Expand Down Expand Up @@ -379,6 +381,77 @@ namespace dr1347 { // dr1347: 3.1
#endif
}

namespace dr1350 { // dr1350: 3.5
#if __cplusplus >= 201103L
struct NoexceptCtor {
NoexceptCtor(int) noexcept {}
};

struct ThrowingNSDMI : NoexceptCtor {
int a = []() noexcept(false) { return 0; }();
using NoexceptCtor::NoexceptCtor;
};

static_assert(!__is_nothrow_constructible(ThrowingNSDMI, int), "");

struct ThrowingCtor {
ThrowingCtor() noexcept(false) {}
};

struct ThrowingNSDM : NoexceptCtor {
ThrowingCtor c;
using NoexceptCtor::NoexceptCtor;
};

static_assert(!__is_nothrow_constructible(ThrowingNSDM, int), "");

struct ThrowingCtorTemplate {
template <typename = int>
ThrowingCtorTemplate() noexcept(false) {}
};

struct ThrowingNSDM2 : NoexceptCtor {
ThrowingCtorTemplate c;
using NoexceptCtor::NoexceptCtor;
};

static_assert(!__is_nothrow_constructible(ThrowingNSDM2, int), "");

struct D1 : NoexceptCtor, ThrowingCtor {
using NoexceptCtor::NoexceptCtor;
};

static_assert(!__is_nothrow_constructible(D1, int), "");

struct D2 : NoexceptCtor, ThrowingCtorTemplate {
using NoexceptCtor::NoexceptCtor;
};

static_assert(!__is_nothrow_constructible(D2, int), "");

struct ThrowingDefaultArg {
ThrowingDefaultArg(ThrowingCtor = {}) {}
};

struct D3 : NoexceptCtor, ThrowingDefaultArg {
using NoexceptCtor::NoexceptCtor;
};

static_assert(!__is_nothrow_constructible(D3, int), "");

struct ThrowingDefaultArgTemplate {
template <typename = int>
ThrowingDefaultArgTemplate(ThrowingCtor = {}) {}
};

struct D4 : NoexceptCtor, ThrowingDefaultArgTemplate {
using NoexceptCtor::NoexceptCtor;
};

static_assert(!__is_nothrow_constructible(D4, int), "");
#endif
} // namespace dr1350

namespace dr1358 { // dr1358: 3.1
#if __cplusplus >= 201103L
struct Lit { constexpr operator int() const { return 0; } };
Expand Down
7 changes: 7 additions & 0 deletions clang/test/CXX/drs/dr15xx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,13 @@ namespace dr1573 { // dr1573: 3.9
H h(0);
// since-cxx11-error@-1 {{constructor inherited by 'H' from base class 'G' is implicitly deleted}}
// since-cxx11-note@#dr1573-H {{constructor inherited by 'H' is implicitly deleted because field 'g' has no default constructor}}

// deleted definition of constructor is inherited
struct I { I(int) = delete; }; // #dr1573-I
struct J : I { using I::I; };
J j(0);
// since-cxx11-error@-1 {{call to deleted constructor of 'J'}}
// since-cxx11-note@#dr1573-I {{'I' has been explicitly marked deleted here}}
#endif
}

Expand Down
28 changes: 28 additions & 0 deletions clang/test/CXX/drs/dr18xx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,34 @@ namespace dr1881 { // dr1881: 7
static_assert(!__is_standard_layout(D), "");
}

namespace dr1890 { // dr1890: no drafting
// FIXME: current consensus for CWG2335 is that the examples are well-formed.
namespace ex1 {
#if __cplusplus >= 201402L
struct A {
struct B {
auto foo() { return 0; } // #dr1890-foo
};
decltype(B().foo()) x;
// since-cxx14-error@-1 {{function 'foo' with deduced return type cannot be used before it is defined}}
// since-cxx14-note@#dr1890-foo {{'foo' declared here}}
};
#endif
} // namespace ex1

namespace ex2 {
#if __cplusplus >= 201103L
struct Bar {
struct Baz {
int a = 0;
};
static_assert(__is_constructible(Baz), "");
// since-cxx11-error@-1 {{static assertion failed due to requirement '__is_constructible(dr1890::ex2::Bar::Baz)'}}
};
#endif
} // namespace ex2
} // namespace dr1890

void dr1891() { // dr1891: 4
#if __cplusplus >= 201103L
int n;
Expand Down
134 changes: 67 additions & 67 deletions clang/test/CXX/drs/dr1xx.cpp

Large diffs are not rendered by default.

48 changes: 48 additions & 0 deletions clang/test/CXX/drs/dr2335.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// RUN: %clang_cc1 -std=c++98 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors
// RUN: %clang_cc1 -std=c++11 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors
// RUN: %clang_cc1 -std=c++14 %s -verify=expected,since-cxx14 -fexceptions -fcxx-exceptions -pedantic-errors
// RUN: %clang_cc1 -std=c++17 %s -verify=expected,since-cxx14 -fexceptions -fcxx-exceptions -pedantic-errors
// RUN: %clang_cc1 -std=c++20 %s -verify=expected,since-cxx14 -fexceptions -fcxx-exceptions -pedantic-errors
// RUN: %clang_cc1 -std=c++23 %s -verify=expected,since-cxx14 -fexceptions -fcxx-exceptions -pedantic-errors
// RUN: %clang_cc1 -std=c++2c %s -verify=expected,since-cxx14 -fexceptions -fcxx-exceptions -pedantic-errors

#if __cplusplus <= 201103L
// expected-no-diagnostics
#endif

namespace dr2335 { // dr2335: no drafting
// FIXME: current consensus is that the examples are well-formed.
#if __cplusplus >= 201402L
namespace ex1 {
template <class...> struct partition_indices {
static auto compute_right() {}
static constexpr auto right = compute_right;
};
template struct partition_indices<int>;
} // namespace ex1

namespace ex2 {
template <int> struct X {};
template <class T> struct partition_indices {
static auto compute_right() { return X<I>(); }
// since-cxx14-error@-1 {{no member 'I' in 'dr2335::ex2::partition_indices<int>'; it has not yet been instantiated}}
// since-cxx14-note@#dr2335-ex2-right {{in instantiation of member function 'dr2335::ex2::partition_indices<int>::compute_right' requested here}}
// since-cxx14-note@#dr2335-ex2-inst {{in instantiation of template class 'dr2335::ex2::partition_indices<int>' requested here}}
// since-cxx14-note@#dr2335-ex2-I {{not-yet-instantiated member is declared here}}
static constexpr auto right = compute_right; // #dr2335-ex2-right
static constexpr int I = sizeof(T); // #dr2335-ex2-I
};
template struct partition_indices<int>; // #dr2335-ex2-inst
} // namespace ex2

namespace ex3 {
struct partition_indices {
static auto compute_right() {} // #dr2335-compute_right
static constexpr auto right = compute_right; // #dr2335-ex3-right
// since-cxx14-error@-1 {{function 'compute_right' with deduced return type cannot be used before it is defined}}
// since-cxx14-note@#dr2335-compute_right {{'compute_right' declared here}}
// since-cxx14-error@#dr2335-ex3-right {{declaration of variable 'right' with deduced type 'const auto' requires an initializer}}
};
} // namespace ex3
#endif
} // namespace dr2335
1 change: 1 addition & 0 deletions clang/test/CXX/drs/dr23xx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ void g() {
#endif

// dr2331: na
// dr2335 is in dr2335.cxx

#if __cplusplus >= 201103L
namespace dr2338 { // dr2338: 12
Expand Down
10 changes: 5 additions & 5 deletions clang/test/CXX/drs/dr26xx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,11 +106,11 @@ int \N{Λ} = 0;
// expected-error@-2 {{expected unqualified-id}}
const char* emoji = "\N{🤡}";
// expected-error@-1 {{'🤡' is not a valid Unicode character name}}
// expected-note@-2 {{did you mean OX ('🐂' U+1F402)?}}
// expected-note@-3 {{did you mean ANT ('🐜' U+1F41C)?}}
// expected-note@-4 {{did you mean ARC ('⌒' U+2312)?}}
// expected-note@-5 {{did you mean AXE ('🪓' U+1FA93)?}}
// expected-note@-6 {{did you mean BAT ('🦇' U+1F987)?}}
// expected-note@-2 {{did you mean OX ('🐂' U+1F402)?}}
// expected-note@-3 {{did you mean ANT ('🐜' U+1F41C)?}}
// expected-note@-4 {{did you mean ARC ('⌒' U+2312)?}}
// expected-note@-5 {{did you mean AXE ('🪓' U+1FA93)?}}
// expected-note@-6 {{did you mean BAT ('🦇' U+1F987)?}}

#define z(x) 0
#define dr2640_a z(
Expand Down
158 changes: 79 additions & 79 deletions clang/test/CXX/drs/dr2xx.cpp

Large diffs are not rendered by default.

172 changes: 86 additions & 86 deletions clang/test/CXX/drs/dr3xx.cpp

Large diffs are not rendered by default.

134 changes: 67 additions & 67 deletions clang/test/CXX/drs/dr4xx.cpp

Large diffs are not rendered by default.

16 changes: 8 additions & 8 deletions clang/test/CXX/drs/dr6xx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -779,7 +779,7 @@ namespace dr657 { // dr657: partial

struct C { C(Abs) {} };
// expected-error@-1 {{parameter type 'Abs' is an abstract class}}
// expected-note@#dr657-Abs {{unimplemented pure virtual method 'x' in 'Abs'}}
// expected-note@#dr657-Abs {{unimplemented pure virtual method 'x' in 'Abs'}}
struct Q { operator Abs() { __builtin_unreachable(); } } q;
// expected-error@-1 {{return type 'Abs' is an abstract class}}
#if __cplusplus >= 201703L
Expand Down Expand Up @@ -809,7 +809,7 @@ namespace dr659 { // dr659: 3.0
struct A; // #dr659-A
int m = alignof(A&);
// since-cxx11-error@-1 {{invalid application of 'alignof' to an incomplete type 'A'}}
// since-cxx11-note@#dr659-A {{forward declaration of 'dr659::A'}}
// since-cxx11-note@#dr659-A {{forward declaration of 'dr659::A'}}
}
#endif

Expand All @@ -836,7 +836,7 @@ namespace dr662 { // dr662: yes
T &tr = t;
T *tp = &t;
// expected-error@-1 {{'tp' declared as a pointer to a reference of type 'int &'}}
// expected-note@#dr662-f-call {{in instantiation of function template specialization 'dr662::f<int &>' requested here}}
// expected-note@#dr662-f-call {{in instantiation of function template specialization 'dr662::f<int &>' requested here}}
#if __cplusplus >= 201103L
auto *ap = &t;
#endif
Expand Down Expand Up @@ -1302,12 +1302,12 @@ namespace dr692 { // dr692: 16
e2(b2);
f<int>(42);
// expected-error@-1 {{call to 'f' is ambiguous}}
// expected-note@#dr692-f-deleted {{candidate function [with T = int, U = int] has been explicitly deleted}}
// expected-note@#dr692-f {{candidate function [with U = int]}}
// expected-note@#dr692-f-deleted {{candidate function [with T = int, U = int] has been explicitly deleted}}
// expected-note@#dr692-f {{candidate function [with U = int]}}
g(42);
// expected-error@-1 {{ambiguous}}
// expected-note@#dr692-g {{candidate function [with T = int]}}
// expected-note@#dr692-g-variadic {{candidate function [with T = int, U = <>]}}
// expected-note@#dr692-g {{candidate function [with T = int]}}
// expected-note@#dr692-g-variadic {{candidate function [with T = int, U = <>]}}
}
}

Expand Down Expand Up @@ -1371,7 +1371,7 @@ namespace dr696 { // dr696: 3.1
int arr[N]; (void)arr;
f(&N);
// expected-error@-1 {{reference to local variable 'N' declared in enclosing function 'dr696::g'}}
// expected-note@#dr696-N {{'N' declared here}}
// expected-note@#dr696-N {{'N' declared here}}
}
};
#if __cplusplus >= 201103L
Expand Down
46 changes: 25 additions & 21 deletions clang/test/Format/clang-format-ignore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,41 +7,45 @@
// RUN: echo "level*/*.c*" >> .clang-format-ignore
// RUN: echo "*/*2/foo.*" >> .clang-format-ignore
// RUN: touch foo.cc
// RUN: clang-format -verbose .clang-format-ignore foo.cc 2> %t.stderr
// RUN: not grep Formatting %t.stderr
// RUN: clang-format -verbose .clang-format-ignore foo.cc 2>&1 \
// RUN: | FileCheck %s -allow-empty

// RUN: cd level1
// RUN: touch bar.cc baz.c
// RUN: clang-format -verbose bar.cc baz.c 2> %t.stderr
// RUN: not grep Formatting %t.stderr
// RUN: clang-format -verbose bar.cc baz.c 2>&1 | FileCheck %s -allow-empty

// RUN: cd level2
// RUN: touch foo.c foo.js
// RUN: clang-format -verbose foo.c foo.js 2> %t.stderr
// RUN: not grep Formatting %t.stderr
// RUN: clang-format -verbose foo.c foo.js 2>&1 | FileCheck %s -allow-empty

// CHECK-NOT: Formatting

// RUN: touch .clang-format-ignore
// RUN: clang-format -verbose foo.c foo.js 2> %t.stderr
// RUN: grep -Fx "Formatting [1/2] foo.c" %t.stderr
// RUN: grep -Fx "Formatting [2/2] foo.js" %t.stderr
// RUN: clang-format -verbose foo.c foo.js 2>&1 \
// RUN: | FileCheck %s -check-prefix=CHECK2 -match-full-lines
// CHECK2: Formatting [1/2] foo.c
// CHECK2-NEXT: Formatting [2/2] foo.js

// RUN: echo "*.js" > .clang-format-ignore
// RUN: clang-format -verbose foo.c foo.js 2> %t.stderr
// RUN: grep -Fx "Formatting [1/2] foo.c" %t.stderr
// RUN: not grep -F foo.js %t.stderr
// RUN: clang-format -verbose foo.c foo.js 2>&1 \
// RUN: | FileCheck %s -check-prefix=CHECK3 -match-full-lines
// CHECK3: Formatting [1/2] foo.c
// CHECK3-NOT: foo.js

// RUN: cd ../..
// RUN: clang-format -verbose *.cc level1/*.c* level1/level2/foo.* 2> %t.stderr
// RUN: grep -x "Formatting \[1/5] .*foo\.c" %t.stderr
// RUN: not grep -F foo.js %t.stderr
// RUN: clang-format -verbose *.cc level1/*.c* level1/level2/foo.* 2>&1 \
// RUN: | FileCheck %s -check-prefix=CHECK4 -match-full-lines
// CHECK4: {{Formatting \[1/5] .*foo\.c}}
// CHECK4-NOT: foo.js

// RUN: rm .clang-format-ignore
// RUN: clang-format -verbose *.cc level1/*.c* level1/level2/foo.* 2> %t.stderr
// RUN: grep -x "Formatting \[1/5] .*foo\.cc" %t.stderr
// RUN: grep -x "Formatting \[2/5] .*bar\.cc" %t.stderr
// RUN: grep -x "Formatting \[3/5] .*baz\.c" %t.stderr
// RUN: grep -x "Formatting \[4/5] .*foo\.c" %t.stderr
// RUN: not grep -F foo.js %t.stderr
// RUN: clang-format -verbose *.cc level1/*.c* level1/level2/foo.* 2>&1 \
// RUN: | FileCheck %s -check-prefix=CHECK5 -match-full-lines
// CHECK5: {{Formatting \[1/5] .*foo\.cc}}
// CHECK5-NEXT: {{Formatting \[2/5] .*bar\.cc}}
// CHECK5-NEXT: {{Formatting \[3/5] .*baz\.c}}
// CHECK5-NEXT: {{Formatting \[4/5] .*foo\.c}}
// CHECK5-NOT: foo.js

// RUN: cd ..
// RUN: rm -r %t.dir
2 changes: 1 addition & 1 deletion clang/tools/driver/driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ std::string GetExecutablePath(const char *Argv0, bool CanonicalPrefixes) {
if (llvm::ErrorOr<std::string> P =
llvm::sys::findProgramByName(ExecutablePath))
ExecutablePath = *P;
return std::string(ExecutablePath.str());
return std::string(ExecutablePath);
}

// This just needs to be some symbol in the binary; C++ doesn't
Expand Down
2 changes: 1 addition & 1 deletion clang/tools/libclang/linker-script-to-export-list.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@
output_file = open(sys.argv[2], "w")

for line in input_file:
m = re.search("^\s+(clang_[^;]+)", line)
m = re.search(r"^\s+(clang_[^;]+)", line)
if m:
output_file.write(m.group(1) + "\n")
2 changes: 2 additions & 0 deletions clang/unittests/Format/ConfigParseTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,8 @@ TEST(ConfigParseTest, ParsesConfiguration) {
PenaltyBreakTemplateDeclaration, 1234u);
CHECK_PARSE("PenaltyBreakOpenParenthesis: 1234", PenaltyBreakOpenParenthesis,
1234u);
CHECK_PARSE("PenaltyBreakScopeResolution: 1234", PenaltyBreakScopeResolution,
1234u);
CHECK_PARSE("PenaltyExcessCharacter: 1234", PenaltyExcessCharacter, 1234u);
CHECK_PARSE("PenaltyReturnTypeOnItsOwnLine: 1234",
PenaltyReturnTypeOnItsOwnLine, 1234u);
Expand Down
13 changes: 13 additions & 0 deletions clang/unittests/Format/FormatTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21567,6 +21567,19 @@ TEST_F(FormatTest, BreakPenaltyAfterForLoopLParen) {
Style);
}

TEST_F(FormatTest, BreakPenaltyScopeResolution) {
FormatStyle Style = getLLVMStyle();
Style.ColumnLimit = 20;
Style.PenaltyExcessCharacter = 100;
verifyFormat("unsigned long\n"
"foo::bar();",
Style);
Style.PenaltyBreakScopeResolution = 10;
verifyFormat("unsigned long foo::\n"
" bar();",
Style);
}

TEST_F(FormatTest, WorksFor8bitEncodings) {
// FIXME: unstable test case
EXPECT_EQ("\"\xce\xe4\xed\xe0\xe6\xe4\xfb \xe2 \"\n"
Expand Down
2 changes: 1 addition & 1 deletion clang/utils/TableGen/RISCVVEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -656,7 +656,7 @@ void RVVEmitter::createRVVIntrinsics(
RVVRequire RequireExt =
StringSwitch<RVVRequire>(RequiredFeature)
.Case("RV64", RVV_REQ_RV64)
.Case("ZvfhminOrZvfh", RVV_REQ_ZvfhminOrZvfh)
.Case("Zvfhmin", RVV_REQ_Zvfhmin)
.Case("Xsfvcp", RVV_REQ_Xsfvcp)
.Case("Xsfvfnrclipxfqf", RVV_REQ_Xsfvfnrclipxfqf)
.Case("Xsfvfwmaccqqq", RVV_REQ_Xsfvfwmaccqqq)
Expand Down
10 changes: 5 additions & 5 deletions clang/www/cxx_dr_status.html
Original file line number Diff line number Diff line change
Expand Up @@ -2662,7 +2662,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
<td><a href="https://cplusplus.github.io/CWG/issues/437.html">437</a></td>
<td>CD1</td>
<td>Is type of class allowed in member function exception specification?</td>
<td class="unknown" align="center">Superseded by <a href="#1308">1308</a></td>
<td class="full" align="center">Superseded by <a href="#1308">1308</a></td>
</tr>
<tr id="438">
<td><a href="https://cplusplus.github.io/CWG/issues/438.html">438</a></td>
Expand Down Expand Up @@ -7656,7 +7656,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
<td><a href="https://cplusplus.github.io/CWG/issues/1308.html">1308</a></td>
<td>CD3</td>
<td>Completeness of class type within an <I>exception-specification</I></td>
<td class="unknown" align="center">Unknown</td>
<td class="full" align="center">Superseded by <a href="#1330">1330</a></td>
</tr>
<tr id="1309">
<td><a href="https://cplusplus.github.io/CWG/issues/1309.html">1309</a></td>
Expand Down Expand Up @@ -7908,7 +7908,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
<td><a href="https://cplusplus.github.io/CWG/issues/1350.html">1350</a></td>
<td>CD3</td>
<td>Incorrect exception specification for inherited constructors</td>
<td class="unknown" align="center">Unknown</td>
<td class="full" align="center">Clang 3.5</td>
</tr>
<tr id="1351">
<td><a href="https://cplusplus.github.io/CWG/issues/1351.html">1351</a></td>
Expand Down Expand Up @@ -11148,7 +11148,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
<td><a href="https://cplusplus.github.io/CWG/issues/1890.html">1890</a></td>
<td>drafting</td>
<td>Member type depending on definition of member function</td>
<td align="center">Not resolved</td>
<td class="none" align="center">No</td>
</tr>
<tr id="1891">
<td><a href="https://cplusplus.github.io/CWG/issues/1891.html">1891</a></td>
Expand Down Expand Up @@ -13818,7 +13818,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
<td><a href="https://cplusplus.github.io/CWG/issues/2335.html">2335</a></td>
<td>drafting</td>
<td>Deduced return types vs member types</td>
<td align="center">Not resolved</td>
<td class="none" align="center">No</td>
</tr>
<tr id="2336">
<td><a href="https://cplusplus.github.io/CWG/issues/2336.html">2336</a></td>
Expand Down
26 changes: 17 additions & 9 deletions compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,19 +160,24 @@ static zx_status_t GetSanitizerHeapVmar(zx_handle_t *vmar) {

static zx_status_t TryVmoMapSanitizerVmar(zx_vm_option_t options,
size_t vmar_offset, zx_handle_t vmo,
size_t size, uintptr_t *addr) {
size_t size, uintptr_t *addr,
zx_handle_t *vmar_used = nullptr) {
zx_handle_t vmar;
zx_status_t status = GetSanitizerHeapVmar(&vmar);
if (status != ZX_OK)
return status;

status = _zx_vmar_map(gSanitizerHeapVmar, options, vmar_offset, vmo,
/*vmo_offset=*/0, size, addr);
if (status == ZX_ERR_NO_RESOURCES) {
if (vmar_used)
*vmar_used = gSanitizerHeapVmar;
if (status == ZX_ERR_NO_RESOURCES || status == ZX_ERR_INVALID_ARGS) {
// This means there's no space in the heap VMAR, so fallback to the root
// VMAR.
status = _zx_vmar_map(_zx_vmar_root_self(), options, vmar_offset, vmo,
/*vmo_offset=*/0, size, addr);
if (vmar_used)
*vmar_used = _zx_vmar_root_self();
}

return status;
Expand Down Expand Up @@ -367,30 +372,33 @@ void *MmapAlignedOrDieOnFatalError(uptr size, uptr alignment,
// beginning of the VMO, and unmap the excess before and after.
size_t map_size = size + alignment;
uintptr_t addr;
zx_handle_t vmar_used;
status = TryVmoMapSanitizerVmar(ZX_VM_PERM_READ | ZX_VM_PERM_WRITE,
/*vmar_offset=*/0, vmo, map_size, &addr);
/*vmar_offset=*/0, vmo, map_size, &addr,
&vmar_used);
if (status == ZX_OK) {
uintptr_t map_addr = addr;
uintptr_t map_end = map_addr + map_size;
addr = RoundUpTo(map_addr, alignment);
uintptr_t end = addr + size;
if (addr != map_addr) {
zx_info_vmar_t info;
status = _zx_object_get_info(gSanitizerHeapVmar, ZX_INFO_VMAR, &info,
sizeof(info), NULL, NULL);
status = _zx_object_get_info(vmar_used, ZX_INFO_VMAR, &info, sizeof(info),
NULL, NULL);
if (status == ZX_OK) {
uintptr_t new_addr;
status = TryVmoMapSanitizerVmar(
status = _zx_vmar_map(
vmar_used,
ZX_VM_PERM_READ | ZX_VM_PERM_WRITE | ZX_VM_SPECIFIC_OVERWRITE,
addr - info.base, vmo, size, &new_addr);
addr - info.base, vmo, 0, size, &new_addr);
if (status == ZX_OK)
CHECK_EQ(new_addr, addr);
}
}
if (status == ZX_OK && addr != map_addr)
status = _zx_vmar_unmap(_zx_vmar_root_self(), map_addr, addr - map_addr);
status = _zx_vmar_unmap(vmar_used, map_addr, addr - map_addr);
if (status == ZX_OK && end != map_end)
status = _zx_vmar_unmap(_zx_vmar_root_self(), end, map_end - end);
status = _zx_vmar_unmap(vmar_used, end, map_end - end);
}
_zx_handle_close(vmo);

Expand Down
58 changes: 40 additions & 18 deletions flang/docs/Intrinsics.md
Original file line number Diff line number Diff line change
Expand Up @@ -847,7 +847,7 @@ used in constant expressions have currently no folding support at all.

#### Usage and Info

- **Standard:** Fortran 2008 and later, specified in 16.9.73
- **Standard:** Fortran 2008 and later, specified in subclause 16.9.73
- **Class:** Subroutine
- **Syntax:** `CALL EXECUTE_COMMAND_LINE(COMMAND [, WAIT, EXITSTAT, CMDSTAT, CMDMSG ])`
- **Arguments:**
Expand All @@ -862,28 +862,50 @@ used in constant expressions have currently no folding support at all.

#### Implementation Specifics

- **`COMMAND`:**
- Must be preset.
##### `COMMAND`:

- **`WAIT`:**
- If set to `false`, the command is executed asynchronously. If not preset or set to `false`, it is executed synchronously.
- Sync: achieved by passing command into `std::system` on all systems.
- Async: achieved by calling a `fork()` on POSIX-compatible systems, or `CreateProcess()` on Windows.
- Must be preset.

- **`CMDSTAT`:**
##### `WAIT`:

- If set to `false`, the command is executed asynchronously.
- If not preset or set to `true`, it is executed synchronously.
- Synchronous execution is achieved by passing the command into `std::system` on all systems.
- Asynchronous execution is achieved by calling `fork()` on POSIX-compatible systems or `CreateProcess()` on Windows.

##### `EXITSTAT`:

- Synchronous execution:
- Inferred by the return value of `std::system(cmd)`.
- On POSIX-compatible systems: return value is first passed into `WEXITSTATUS(status)`, then assigned to `EXITSTAT`.
- On Windows, the value is directly assigned as the return value of `std::system()`.
- Asynchronous execution:
- Value is not modified.

##### `CMDSTAT`:

- Synchronous execution:
- -2: No error condition occurs, but `WAIT` is present with the value `false`, and the processor does not support asynchronous execution.
- -1: The processor does not support command line execution.
- \+ (positive value): An error condition occurs.
- 1: Fork Error, where `pid_t < 0`, would only occur on POSIX-compatible systems.
- 2: Execution Error, a command exits with status -1.
- 3: Invalid Command Error, determined by the exit code depending on the system.
- On Windows, if the exit code is 1.
- On POSIX-compatible systems, if the exit code is 127 or 126.
- 4: Signal error, either it is stopped or killed by signal, would only occur on POSIX-compatible systems.
- 1: Fork Error (occurs only on POSIX-compatible systems).
- 2: Execution Error (command exits with status -1).
- 3: Invalid Command Error (determined by the exit code depending on the system).
- On Windows: exit code is 1.
- On POSIX-compatible systems: exit code is 127 or 126.
- 4: Signal error (either stopped or killed by signal, occurs only on POSIX-compatible systems).
- 0: Otherwise.
- Asynchronous execution:
- 0 will always be assigned.

##### `CMDMSG`:

- **`CMDMSG`:**
- If an error condition occurs, it is assigned an explanatory message. Otherwise, it remains unchanged.
- Synchronous execution:
- If an error condition occurs, it is assigned an explanatory message; otherwise, it remains unchanged.
- If a condition occurs that would assign a nonzero value to `CMDSTAT` but the `CMDSTAT` variable is not present, error termination is initiated (applies to both POSIX-compatible systems and Windows).
- Asynchronous execution:
- The value is unchanged.
- If a condition occurs that would assign a nonzero value to `CMDSTAT` but the `CMDSTAT` variable is not present, error termination is initiated.
- On POSIX-compatible systems, this applies to both synchronous and asynchronous error termination. When the execution mode is set to async with error termination, the child process (async process) will be terminated with no effect on the parent process (continues).
- On Windows, this only applies to synchronous error termination.
- On POSIX-compatible systems, the child process (async process) will be terminated with no effect on the parent process (continues).
- On Windows, error termination is not initiated.

2 changes: 1 addition & 1 deletion flang/runtime/execute.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ void RTNAME(ExecuteCommandLine)(const Descriptor &command, bool wait,
const Descriptor *exitstat, const Descriptor *cmdstat,
const Descriptor *cmdmsg, const char *sourceFile, int line) {
Terminator terminator{sourceFile, line};
const char *newCmd{EnsureNullTerminated(
char *newCmd{EnsureNullTerminated(
command.OffsetElement(), command.ElementBytes(), terminator)};

if (exitstat) {
Expand Down
4 changes: 2 additions & 2 deletions flang/runtime/tools.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -173,8 +173,8 @@ RT_API_ATTRS void ShallowCopy(const Descriptor &to, const Descriptor &from) {
ShallowCopy(to, from, to.IsContiguous(), from.IsContiguous());
}

RT_API_ATTRS const char *EnsureNullTerminated(
const char *str, std::size_t length, Terminator &terminator) {
RT_API_ATTRS char *EnsureNullTerminated(
char *str, std::size_t length, Terminator &terminator) {
if (std::memchr(str, '\0', length) == nullptr) {
char *newCmd{(char *)AllocateMemoryOrCrash(terminator, length + 1)};
std::memcpy(newCmd, str, length);
Expand Down
4 changes: 2 additions & 2 deletions flang/runtime/tools.h
Original file line number Diff line number Diff line change
Expand Up @@ -441,8 +441,8 @@ RT_API_ATTRS void ShallowCopy(const Descriptor &to, const Descriptor &from);
// size memory for null-terminator if necessary. Returns the original or a newly
// allocated null-terminated string (responsibility for deallocation is on the
// caller).
RT_API_ATTRS const char *EnsureNullTerminated(
const char *str, std::size_t length, Terminator &terminator);
RT_API_ATTRS char *EnsureNullTerminated(
char *str, std::size_t length, Terminator &terminator);

RT_API_ATTRS bool IsValidCharDescriptor(const Descriptor *value);

Expand Down
2 changes: 1 addition & 1 deletion flang/test/Driver/isysroot.f90
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
! RUN: %flang -### --target=aarch64-linux-gnu -isysroot /path/to/sysroot \
! RUN: %s 2>&1 | FileCheck %s --check-prefix=CHECK-LINUX

! CHECK-DARWIN: "{{.*[\/]}}ld" {{.*}}"-syslibroot" "/path/to/sysroot"
! CHECK-DARWIN: "{{.*}}ld{{(64)?(\.lld)?}}" {{.*}}"-syslibroot" "/path/to/sysroot"
! Unused on Linux.
! CHECK-LINUX: warning: argument unused during compilation: '-isysroot /path/to/sysroot'
! CHECK-LINUX-NOT: /path/to/sysroot
6 changes: 3 additions & 3 deletions libcxx/docs/ReleaseNotes/18.rst
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,10 @@ Implemented Papers
- P2905R2 - Runtime format strings
- P2918R2 - Runtime format strings II
- P2871R3 - Remove Deprecated Unicode Conversion Facets from C++26
- P2870R3 - Remove basic_string::reserve()
- P2870R3 - Remove ``basic_string::reserve()``
- P2909R4 - Fix formatting of code units as integers (Dude, where’s my ``char``?)
- P2821R5 - span.at()
- P0521R0 - Proposed Resolution for CA 14 (shared_ptr use_count/unique)
- P2821R5 - ``span.at()``
- P0521R0 - Proposed Resolution for CA 14 (``shared_ptr`` ``use_count/unique``)
- P1759R6 - Native handles and file streams
- P2517R1 - Add a conditional ``noexcept`` specification to ``std::apply``

Expand Down
2 changes: 1 addition & 1 deletion libcxx/docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ Compiler Versions Restrictions Support policy
Clang 16, 17, 18-git latest two stable releases per `LLVM's release page <https://releases.llvm.org>`_ and the development version
AppleClang 15 latest stable release per `Xcode's release page <https://developer.apple.com/documentation/xcode-release-notes>`_
Open XL 17.1 (AIX) latest stable release per `Open XL's documentation page <https://www.ibm.com/docs/en/openxl-c-and-cpp-aix>`_
GCC 12 In C++11 or later only latest stable release per `GCC's release page <https://gcc.gnu.org/releases.html>`_
GCC 13 In C++11 or later only latest stable release per `GCC's release page <https://gcc.gnu.org/releases.html>`_
============ =============== ========================== =====================

Libc++ also supports common platforms and architectures:
Expand Down
4 changes: 4 additions & 0 deletions libcxx/include/__concepts/arithmetic.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,13 @@ concept floating_point = is_floating_point_v<_Tp>;

template <class _Tp>
concept __libcpp_unsigned_integer = __libcpp_is_unsigned_integer<_Tp>::value;

template <class _Tp>
concept __libcpp_signed_integer = __libcpp_is_signed_integer<_Tp>::value;

template <class _Tp>
concept __libcpp_integer = __libcpp_unsigned_integer<_Tp> || __libcpp_signed_integer<_Tp>;

#endif // _LIBCPP_STD_VER >= 20

_LIBCPP_END_NAMESPACE_STD
Expand Down
3 changes: 1 addition & 2 deletions libcxx/include/string
Original file line number Diff line number Diff line change
Expand Up @@ -1891,8 +1891,7 @@ private:
#if !defined(_LIBCPP_HAS_NO_ASAN) && defined(_LIBCPP_INSTRUMENTED_WITH_ASAN)
const void* __begin = data();
const void* __end = data() + capacity() + 1;
if (!__libcpp_is_constant_evaluated() && __begin != nullptr &&
is_same<allocator_type, __default_allocator_type>::value)
if (__asan_annotate_container_with_allocator<allocator_type>::value && !__libcpp_is_constant_evaluated())
__sanitizer_annotate_contiguous_container(__begin, __end, __old_mid, __new_mid);
#endif
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14, c++17

// Concept helpers for the internal type traits for the fundamental types.

// template <class _Tp>
// concept __libcpp_integer;

#include <concepts>

#include "test_macros.h"

struct SomeObject {};

enum SomeEnum {};

enum class SomeScopedEnum {};

// Unsigned
static_assert(std::__libcpp_integer<unsigned char>);
static_assert(std::__libcpp_integer<unsigned short int>);
static_assert(std::__libcpp_integer<unsigned int>);
static_assert(std::__libcpp_integer<unsigned long int>);
static_assert(std::__libcpp_integer<unsigned long long int>);
static_assert(std::__libcpp_integer<unsigned short int>);
#ifndef _LIBCPP_HAS_NO_INT128
static_assert(std::__libcpp_integer<__uint128_t>);
#endif
// Signed
static_assert(std::__libcpp_integer<signed char>);
static_assert(std::__libcpp_integer<short int>);
static_assert(std::__libcpp_integer<int>);
static_assert(std::__libcpp_integer<long int>);
static_assert(std::__libcpp_integer<long long int>);
static_assert(std::__libcpp_integer<short int>);
#ifndef _LIBCPP_HAS_NO_INT128
static_assert(std::__libcpp_integer<__int128_t>);
#endif
// Non-integer
static_assert(!std::__libcpp_integer<bool>);
static_assert(!std::__libcpp_integer<char>);
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
static_assert(!std::__libcpp_integer<wchar_t>);
#endif
static_assert(!std::__libcpp_integer<char8_t>);
static_assert(!std::__libcpp_integer<char16_t>);
static_assert(!std::__libcpp_integer<char32_t>);
static_assert(!std::__libcpp_integer<float>);
static_assert(!std::__libcpp_integer<double>);
static_assert(!std::__libcpp_integer<long double>);
static_assert(!std::__libcpp_integer<void>);
static_assert(!std::__libcpp_integer<int*>);
static_assert(!std::__libcpp_integer<unsigned int*>);
static_assert(!std::__libcpp_integer<SomeObject>);
static_assert(!std::__libcpp_integer<SomeEnum>);
static_assert(!std::__libcpp_integer<SomeScopedEnum>);
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14, c++17

// Concept helpers for the internal type traits for the fundamental types.

// template <class _Tp>
// concept __libcpp_signed_integer;

#include <concepts>

#include "test_macros.h"

struct SomeObject {};

enum SomeEnum {};

enum class SomeScopedEnum {};

// Unsigned
static_assert(!std::__libcpp_signed_integer<unsigned char>);
static_assert(!std::__libcpp_signed_integer<unsigned short int>);
static_assert(!std::__libcpp_signed_integer<unsigned int>);
static_assert(!std::__libcpp_signed_integer<unsigned long int>);
static_assert(!std::__libcpp_signed_integer<unsigned long long int>);
static_assert(!std::__libcpp_signed_integer<unsigned short int>);
#ifndef _LIBCPP_HAS_NO_INT128
static_assert(!std::__libcpp_signed_integer<__uint128_t>);
#endif
// Signed
static_assert(std::__libcpp_signed_integer<signed char>);
static_assert(std::__libcpp_signed_integer<short int>);
static_assert(std::__libcpp_signed_integer<int>);
static_assert(std::__libcpp_signed_integer<long int>);
static_assert(std::__libcpp_signed_integer<long long int>);
static_assert(std::__libcpp_signed_integer<short int>);
#ifndef _LIBCPP_HAS_NO_INT128
static_assert(std::__libcpp_signed_integer<__int128_t>);
#endif
// Non-integer
static_assert(!std::__libcpp_signed_integer<bool>);
static_assert(!std::__libcpp_signed_integer<char>);
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
static_assert(!std::__libcpp_signed_integer<wchar_t>);
#endif
static_assert(!std::__libcpp_signed_integer<char8_t>);
static_assert(!std::__libcpp_signed_integer<char16_t>);
static_assert(!std::__libcpp_signed_integer<char32_t>);
static_assert(!std::__libcpp_signed_integer<float>);
static_assert(!std::__libcpp_signed_integer<double>);
static_assert(!std::__libcpp_signed_integer<long double>);
static_assert(!std::__libcpp_signed_integer<void>);
static_assert(!std::__libcpp_signed_integer<int*>);
static_assert(!std::__libcpp_signed_integer<unsigned int*>);
static_assert(!std::__libcpp_signed_integer<SomeObject>);
static_assert(!std::__libcpp_signed_integer<SomeEnum>);
static_assert(!std::__libcpp_signed_integer<SomeScopedEnum>);
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14, c++17

// Concept helpers for the internal type traits for the fundamental types.

// template <class _Tp>
// concept __libcpp_unsigned_integer;

#include <concepts>

#include "test_macros.h"

struct SomeObject {};

enum SomeEnum {};

enum class SomeScopedEnum {};

// Unsigned
static_assert(std::__libcpp_unsigned_integer<unsigned char>);
static_assert(std::__libcpp_unsigned_integer<unsigned short int>);
static_assert(std::__libcpp_unsigned_integer<unsigned int>);
static_assert(std::__libcpp_unsigned_integer<unsigned long int>);
static_assert(std::__libcpp_unsigned_integer<unsigned long long int>);
static_assert(std::__libcpp_unsigned_integer<unsigned short int>);
#ifndef _LIBCPP_HAS_NO_INT128
static_assert(std::__libcpp_unsigned_integer<__uint128_t>);
#endif
// Signed
static_assert(!std::__libcpp_unsigned_integer<signed char>);
static_assert(!std::__libcpp_unsigned_integer<short int>);
static_assert(!std::__libcpp_unsigned_integer<int>);
static_assert(!std::__libcpp_unsigned_integer<long int>);
static_assert(!std::__libcpp_unsigned_integer<long long int>);
static_assert(!std::__libcpp_unsigned_integer<short int>);
#ifndef _LIBCPP_HAS_NO_INT128
static_assert(!std::__libcpp_unsigned_integer<__int128_t>);
#endif
// Non-integer
static_assert(!std::__libcpp_unsigned_integer<bool>);
static_assert(!std::__libcpp_unsigned_integer<char>);
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
static_assert(!std::__libcpp_unsigned_integer<wchar_t>);
#endif
static_assert(!std::__libcpp_unsigned_integer<char8_t>);
static_assert(!std::__libcpp_unsigned_integer<char16_t>);
static_assert(!std::__libcpp_unsigned_integer<char32_t>);
static_assert(!std::__libcpp_unsigned_integer<float>);
static_assert(!std::__libcpp_unsigned_integer<double>);
static_assert(!std::__libcpp_unsigned_integer<long double>);
static_assert(!std::__libcpp_unsigned_integer<void>);
static_assert(!std::__libcpp_unsigned_integer<int*>);
static_assert(!std::__libcpp_unsigned_integer<unsigned int*>);
static_assert(!std::__libcpp_unsigned_integer<SomeObject>);
static_assert(!std::__libcpp_unsigned_integer<SomeEnum>);
static_assert(!std::__libcpp_unsigned_integer<SomeScopedEnum>);
56 changes: 56 additions & 0 deletions libcxx/test/libcxx/containers/strings/basic.string/asan.pass.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

// REQUIRES: asan
// UNSUPPORTED: c++03

// Basic test if ASan annotations work for basic_string.

#include <string>
#include <cassert>
#include <cstdlib>

#include "asan_testing.h"
#include "min_allocator.h"
#include "test_iterators.h"
#include "test_macros.h"

extern "C" void __sanitizer_set_death_callback(void (*callback)(void));

void do_exit() { exit(0); }

int main(int, char**) {
{
typedef cpp17_input_iterator<char*> MyInputIter;
// Should not trigger ASan.
std::basic_string<char, std::char_traits<char>, safe_allocator<char>> v;
char i[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'a', 'b', 'c', 'd', 'e',
'f', 'g', 'h', 'i', 'j', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'};

v.insert(v.begin(), MyInputIter(i), MyInputIter(i + 29));
assert(v[0] == 'a');
assert(is_string_asan_correct(v));
}

__sanitizer_set_death_callback(do_exit);
{
using T = char;
using C = std::basic_string<T, std::char_traits<T>, safe_allocator<T>>;
const T t[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'a', 'b', 'c', 'd', 'e',
'f', 'g', 'h', 'i', 'j', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'};
C c(std::begin(t), std::end(t));
assert(is_string_asan_correct(c));
assert(__sanitizer_verify_contiguous_container(c.data(), c.data() + c.size() + 1, c.data() + c.capacity() + 1) !=
0);
T foo = c[c.size() + 1]; // should trigger ASAN and call do_exit().
assert(false); // if we got here, ASAN didn't trigger
((void)foo);

return 0;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

// REQUIRES: asan
// UNSUPPORTED: c++03

// Test based on: https://bugs.chromium.org/p/chromium/issues/detail?id=1419798#c5
// Some allocators during deallocation may not call destructors and just reuse memory.
// In those situations, one may want to deactivate annotations for a specific allocator.
// It's possible with __asan_annotate_container_with_allocator template class.
// This test confirms that those allocators work after turning off annotations.
//
// A context to this test is a situations when memory is repurposed and destructors are not called.
// Related issue: https://github.com/llvm/llvm-project/issues/60384
//
// That issue appeared in the past and was addressed here: https://reviews.llvm.org/D145628
//
// There was also a discussion, if it's UB.
// Related discussion: https://reviews.llvm.org/D136765#4155262
// Related notes: https://eel.is/c++draft/basic.life#6
// Probably it's no longer UB due a change in CWG2523.
// https://cplusplus.github.io/CWG/issues/2523.html
//
// Therefore we make sure that it works that way, also because people rely on this behavior.
// Annotations are turned off only, if a user explicitly turns off annotations for a specific allocator.

#include <assert.h>
#include <stdlib.h>
#include <string>
#include <new>

// Allocator with pre-allocated (with malloc in constructor) buffers.
// Memory may be freed without calling destructors.
struct reuse_allocator {
static size_t const N = 100;
reuse_allocator() {
for (size_t i = 0; i < N; ++i)
__buffers[i] = malloc(8 * 1024);
}
~reuse_allocator() {
for (size_t i = 0; i < N; ++i)
free(__buffers[i]);
}
void* alloc() {
assert(__next_id < N);
return __buffers[__next_id++];
}
void reset() { __next_id = 0; }
void* __buffers[N];
size_t __next_id = 0;
} reuse_buffers;

template <typename T>
struct user_allocator {
using value_type = T;
user_allocator() = default;
template <class U>
user_allocator(user_allocator<U>) {}
friend bool operator==(user_allocator, user_allocator) { return true; }
friend bool operator!=(user_allocator x, user_allocator y) { return !(x == y); }

T* allocate(size_t n) {
if (n * sizeof(T) > 8 * 1024)
throw std::bad_array_new_length();
return (T*)reuse_buffers.alloc();
}
void deallocate(T*, size_t) noexcept {}
};

// Turn off annotations for user_allocator:
template <class T>
struct std::__asan_annotate_container_with_allocator<user_allocator<T>> {
static bool const value = false;
};

int main(int, char**) {
using S = std::basic_string<char, std::char_traits<char>, user_allocator<char>>;

{
// Create a string with a buffer from reuse allocator object:
S* s = new (reuse_buffers.alloc()) S();
// Use string, so it's poisoned, if container annotations for that allocator are not turned off:
for (int i = 0; i < 40; i++)
s->push_back('a');
}
// Reset the state of the allocator, don't call destructors, allow memory to be reused:
reuse_buffers.reset();
{
// Create a next string with the same allocator, so the same buffer due to the reset:
S s;
// Use memory inside the string again, if it's poisoned, an error will be raised:
for (int i = 0; i < 60; i++)
s.push_back('a');
}

return 0;
}
2 changes: 1 addition & 1 deletion libcxx/test/support/asan_testing.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ TEST_CONSTEXPR bool is_string_asan_correct(const std::basic_string<ChrT, TraitsT
return true;

if (!is_string_short(c) || _LIBCPP_SHORT_STRING_ANNOTATIONS_ALLOWED) {
if (std::is_same<Alloc, std::allocator<ChrT>>::value)
if (std::__asan_annotate_container_with_allocator<Alloc>::value)
return __sanitizer_verify_contiguous_container(c.data(), c.data() + c.size() + 1, c.data() + c.capacity() + 1) !=
0;
else
Expand Down
6 changes: 2 additions & 4 deletions lld/COFF/DriverUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -310,13 +310,11 @@ void LinkerDriver::parseManifestUAC(StringRef arg) {
arg = arg.ltrim();
if (arg.empty())
return;
if (arg.starts_with_insensitive("level=")) {
arg = arg.substr(strlen("level="));
if (arg.consume_front_insensitive("level=")) {
std::tie(ctx.config.manifestLevel, arg) = arg.split(" ");
continue;
}
if (arg.starts_with_insensitive("uiaccess=")) {
arg = arg.substr(strlen("uiaccess="));
if (arg.consume_front_insensitive("uiaccess=")) {
std::tie(ctx.config.manifestUIAccess, arg) = arg.split(" ");
continue;
}
Expand Down
4 changes: 2 additions & 2 deletions lld/Common/Args.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ static int64_t getInteger(opt::InputArgList &args, unsigned key,

int64_t v;
StringRef s = a->getValue();
if (base == 16 && (s.starts_with("0x") || s.starts_with("0X")))
s = s.drop_front(2);
if (base == 16)
s.consume_front_insensitive("0x");
if (to_integer(s, v, base))
return v;

Expand Down
3 changes: 1 addition & 2 deletions lld/MachO/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -952,8 +952,7 @@ static std::vector<SectionAlign> parseSectAlign(const opt::InputArgList &args) {
StringRef segName = arg->getValue(0);
StringRef sectName = arg->getValue(1);
StringRef alignStr = arg->getValue(2);
if (alignStr.starts_with("0x") || alignStr.starts_with("0X"))
alignStr = alignStr.drop_front(2);
alignStr.consume_front_insensitive("0x");
uint32_t align;
if (alignStr.getAsInteger(16, align)) {
error("-sectalign: failed to parse '" + StringRef(arg->getValue(2)) +
Expand Down
57 changes: 57 additions & 0 deletions lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1039,6 +1039,7 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren |
eTypeOptionHideValue,
"day=${var.__d_%u}")));

AddCXXSummary(cpp_category_sp,
lldb_private::formatters::LibcxxChronoMonthSummaryProvider,
"libc++ std::chrono::month summary provider",
Expand All @@ -1050,6 +1051,23 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
TypeSummaryImplSP(new StringSummaryFormat(
eTypeOptionHideChildren | eTypeOptionHideValue, "year=${var.__y_}")));

AddCXXSummary(cpp_category_sp,
lldb_private::formatters::LibcxxChronoWeekdaySummaryProvider,
"libc++ std::chrono::weekday summary provider",
"^std::__[[:alnum:]]+::chrono::weekday$",
eTypeOptionHideChildren | eTypeOptionHideValue, true);

cpp_category_sp->AddTypeSummary(
"^std::__[[:alnum:]]+::chrono::weekday_indexed$", eFormatterMatchRegex,
TypeSummaryImplSP(new StringSummaryFormat(
eTypeOptionHideChildren | eTypeOptionHideValue,
"${var.__wd_} index=${var.__idx_%u}")));

cpp_category_sp->AddTypeSummary(
"^std::__[[:alnum:]]+::chrono::weekday_last$", eFormatterMatchRegex,
TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren |
eTypeOptionHideValue,
"${var.__wd_} index=last")));
cpp_category_sp->AddTypeSummary(
"^std::__[[:alnum:]]+::chrono::month_day$", eFormatterMatchRegex,
TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren |
Expand All @@ -1060,12 +1078,51 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren |
eTypeOptionHideValue,
"${var.__m_} day=last")));

cpp_category_sp->AddTypeSummary(
"^std::__[[:alnum:]]+::chrono::month_weekday$", eFormatterMatchRegex,
TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren |
eTypeOptionHideValue,
"${var.__m_} ${var.__wdi_}")));

cpp_category_sp->AddTypeSummary(
"^std::__[[:alnum:]]+::chrono::month_weekday_last$", eFormatterMatchRegex,
TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren |
eTypeOptionHideValue,
"${var.__m_} ${var.__wdl_}")));

cpp_category_sp->AddTypeSummary(
"^std::__[[:alnum:]]+::chrono::year_month$", eFormatterMatchRegex,
TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren |
eTypeOptionHideValue,
"${var.__y_} ${var.__m_}")));

AddCXXSummary(
cpp_category_sp,
lldb_private::formatters::LibcxxChronoYearMonthDaySummaryProvider,
"libc++ std::chrono::year_month_day summary provider",
"^std::__[[:alnum:]]+::chrono::year_month_day$",
eTypeOptionHideChildren | eTypeOptionHideValue, true);

cpp_category_sp->AddTypeSummary(
"^std::__[[:alnum:]]+::chrono::year_month_day_last$",
eFormatterMatchRegex,
TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren |
eTypeOptionHideValue,
"${var.__y_} ${var.__mdl_}")));

cpp_category_sp->AddTypeSummary(
"^std::__[[:alnum:]]+::chrono::year_month_weekday$", eFormatterMatchRegex,
TypeSummaryImplSP(new StringSummaryFormat(
eTypeOptionHideChildren | eTypeOptionHideValue,
"${var.__y_} ${var.__m_} ${var.__wdi_}")));

cpp_category_sp->AddTypeSummary(
"^std::__[[:alnum:]]+::chrono::year_month_weekday_last$",
eFormatterMatchRegex,
TypeSummaryImplSP(new StringSummaryFormat(
eTypeOptionHideChildren | eTypeOptionHideValue,
"${var.__y_} ${var.__m_} ${var.__wdl_}")));
}

static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
Expand Down
21 changes: 21 additions & 0 deletions lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1106,6 +1106,27 @@ bool lldb_private::formatters::LibcxxChronoMonthSummaryProvider(
return true;
}

bool lldb_private::formatters::LibcxxChronoWeekdaySummaryProvider(
ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
// FIXME: These are the names used in the C++20 ostream operator. Since LLVM
// uses C++17 it's not possible to use the ostream operator directly.
static const std::array<std::string_view, 7> weekdays = {
"Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday"};

ValueObjectSP ptr_sp = valobj.GetChildMemberWithName("__wd_");
if (!ptr_sp)
return false;

const unsigned weekday = ptr_sp->GetValueAsUnsigned(0);
if (weekday >= 0 && weekday < 7)
stream << "weekday=" << weekdays[weekday];
else
stream.Printf("weekday=%u", weekday);

return true;
}

bool lldb_private::formatters::LibcxxChronoYearMonthDaySummaryProvider(
ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
ValueObjectSP ptr_sp = valobj.GetChildMemberWithName("__y_");
Expand Down
4 changes: 4 additions & 0 deletions lldb/source/Plugins/Language/CPlusPlus/LibCxx.h
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,10 @@ bool LibcxxChronoMonthSummaryProvider(
ValueObject &valobj, Stream &stream,
const TypeSummaryOptions &options); // libc++ std::chrono::month

bool LibcxxChronoWeekdaySummaryProvider(
ValueObject &valobj, Stream &stream,
const TypeSummaryOptions &options); // libc++ std::chrono::weekday

bool LibcxxChronoYearMonthDaySummaryProvider(
ValueObject &valobj, Stream &stream,
const TypeSummaryOptions &options); // libc++ std::chrono::year_month_day
Expand Down
Loading