56 changes: 56 additions & 0 deletions bolt/test/X86/Inputs/blarge_profile_stale.std-hash.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
---
header:
profile-version: 1
binary-name: 'reader-yaml.test.tmp.exe'
binary-build-id: '<unknown>'
profile-flags: [ lbr ]
profile-origin: branch profile reader
profile-events: ''
dfs-order: false
functions:
- name: SolveCubic
fid: 6
hash: 0xC6E9098E973BBE19
exec: 151
nblocks: 18
blocks:
- bid: 0
insns: 43
hash: 0xed4db287e71c0000
exec: 151
succ: [ { bid: 1, cnt: 151, mis: 2 }, { bid: 7, cnt: 0 } ]
- bid: 1
insns: 7
hash: 0x39330000e4560088
succ: [ { bid: 13, cnt: 151 }, { bid: 2, cnt: 0 } ]
- bid: 13
insns: 26
hash: 0xa9700000fe202a7
succ: [ { bid: 3, cnt: 89 }, { bid: 2, cnt: 10 } ]
- bid: 3
insns: 9
hash: 0x62391dad18a700a0
succ: [ { bid: 5, cnt: 151 } ]
- bid: 5
insns: 9
hash: 0x4d906d19ecec0111
- name: usqrt
fid: 7
hash: 0x8B62B1F9AD81EA35
exec: 20
nblocks: 6
blocks:
- bid: 0
insns: 4
hash: 0x1111111111111111
exec: 20
succ: [ { bid: 1, cnt: 0 } ]
- bid: 1
insns: 9
hash: 0x27e43a5e10cd0010
succ: [ { bid: 3, cnt: 320, mis: 171 }, { bid: 2, cnt: 0 } ]
- bid: 3
insns: 2
hash: 0x4db935b6471e0039
succ: [ { bid: 1, cnt: 300, mis: 33 }, { bid: 4, cnt: 20 } ]
...
1 change: 1 addition & 0 deletions bolt/test/X86/Inputs/blarge_profile_stale.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ header:
profile-origin: branch profile reader
profile-events: ''
dfs-order: false
hash-func: xxh3
functions:
- name: SolveCubic
fid: 6
Expand Down
66 changes: 66 additions & 0 deletions bolt/test/X86/dwarf5-two-cu-str-offset-table.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# REQUIRES: system-linux

# RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf5_main.s -o %tmain.o
# RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf5_helper.s -o %thelper.o
# RUN: %clang %cflags -dwarf-5 %tmain.o %thelper.o -o %t.exe -Wl,-q
# RUN: llvm-bolt %t.exe -o %t.bolt --update-debug-sections
# RUN: llvm-dwarfdump --show-form --verbose --debug-str-offsets %t.exe > %t.txt
# RUN: llvm-dwarfdump --show-form --verbose --debug-str-offsets %t.bolt >> %t.txt
# RUN: cat %t.txt | FileCheck --check-prefix=CHECK %s

## This test checks we correclty re-renerate .debug_str_offsets.

# CHECK: .debug_str_offsets contents
# CHECK-NEXT: 0x00000000: Contribution size = 52, Format = DWARF32, Version = 5
# CHECK-NEXT: "clang version 15.0.0"
# CHECK-NEXT: "main.cpp"
# CHECK-NEXT: "/testLocListMultiple"
# CHECK-NEXT: "_Z3usePiS_"
# CHECK-NEXT: "use"
# CHECK-NEXT: "main"
# CHECK-NEXT: "int"
# CHECK-NEXT: "x"
# CHECK-NEXT: "y"
# CHECK-NEXT: "argc"
# CHECK-NEXT: "argv"
# CHECK-NEXT: "char"
# CHECK-NEXT: 0x00000038: Contribution size = 48, Format = DWARF32, Version = 5
# CHECK-NEXT: "clang version 15.0.0)"
# CHECK-NEXT: "foo.cpp"
# CHECK-NEXT: "/testLocListMultiple"
# CHECK-NEXT: "fooVar"
# CHECK-NEXT: "int"
# CHECK-NEXT: "_Z6useFooPi"
# CHECK-NEXT: "useFoo"
# CHECK-NEXT: "x"
# CHECK-NEXT: "_Z3fooi"
# CHECK-NEXT: "foo"
# CHECK-NEXT: "argc"

## Checking post bolt
# CHECK: .debug_str_offsets contents
# CHECK-NEXT: 0x00000000: Contribution size = 52, Format = DWARF32, Version = 5
# CHECK-NEXT: "clang version 15.0.0"
# CHECK-NEXT: "main.cpp"
# CHECK-NEXT: "/testLocListMultiple"
# CHECK-NEXT: "_Z3usePiS_"
# CHECK-NEXT: "use"
# CHECK-NEXT: "main"
# CHECK-NEXT: "int"
# CHECK-NEXT: "x"
# CHECK-NEXT: "y"
# CHECK-NEXT: "argc"
# CHECK-NEXT: "argv"
# CHECK-NEXT: "char"
# CHECK-NEXT: 0x00000038: Contribution size = 48, Format = DWARF32, Version = 5
# CHECK-NEXT: "clang version 15.0.0)"
# CHECK-NEXT: "foo.cpp"
# CHECK-NEXT: "/testLocListMultiple"
# CHECK-NEXT: "fooVar"
# CHECK-NEXT: "int"
# CHECK-NEXT: "_Z6useFooPi"
# CHECK-NEXT: "useFoo"
# CHECK-NEXT: "x"
# CHECK-NEXT: "_Z3fooi"
# CHECK-NEXT: "foo"
# CHECK-NEXT: "argc"
68 changes: 68 additions & 0 deletions bolt/test/X86/reader-stale-yaml-std.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# This script checks that YamlProfileReader in llvm-bolt is reading data
# correctly and stale data is corrected by profile inference.

RUN: yaml2obj %p/Inputs/blarge.yaml &> %t.exe
RUN: llvm-bolt %t.exe -o %t.null -b %p/Inputs/blarge_profile_stale.std-hash.yaml \
RUN: --print-cfg --print-only=usqrt,SolveCubic --infer-stale-profile=1 -v=1 \
RUN: 2>&1 | FileCheck %s

# Verify that yaml reader works as expected.
CHECK: pre-processing profile using YAML profile reader
CHECK: BOLT-INFO: YAML profile with hash: std::hash

# Function "SolveCubic" has stale profile, since there is one jump in the
# profile (from bid=13 to bid=2) which is not in the CFG in the binary. The test
# verifies that the inference is able to match two blocks (bid=1 and bid=13)
# using "loose" hashes and then correctly propagate the counts.

CHECK: Binary Function "SolveCubic" after building cfg {
CHECK: State : CFG constructed
CHECK: Address : 0x400e00
CHECK: Size : 0x368
CHECK: Section : .text
CHECK: IsSimple : 1
CHECK: BB Count : 18
CHECK: Exec Count : 151
CHECK: Branch Count: 552
CHECK: }
# Verify block counts.
CHECK: .LBB00 (43 instructions, align : 1)
CHECK: Successors: .Ltmp[[#BB07:]] (mispreds: 0, count: 0), .LFT[[#BB01:]] (mispreds: 0, count: 151)
CHECK: .LFT[[#BB01:]] (5 instructions, align : 1)
CHECK: Successors: .Ltmp[[#BB013:]] (mispreds: 0, count: 151), .LFT[[#BB02:]] (mispreds: 0, count: 0)
CHECK: .Ltmp[[#BB03:]] (26 instructions, align : 1)
CHECK: Successors: .Ltmp[[#BB05:]] (mispreds: 0, count: 151), .LFT[[#BB04:]] (mispreds: 0, count: 0)
CHECK: .Ltmp[[#BB05:]] (9 instructions, align : 1)
CHECK: .Ltmp[[#BB013:]] (12 instructions, align : 1)
CHECK: Successors: .Ltmp[[#BB03:]] (mispreds: 0, count: 151)
CHECK: End of Function "SolveCubic"

# Function "usqrt" has stale profile, since the number of blocks in the profile
# (nblocks=6) does not match the size of the CFG in the binary. The entry
# block (bid=0) has an incorrect (missing) count, which should be inferred by
# the algorithm.

CHECK: Binary Function "usqrt" after building cfg {
CHECK: State : CFG constructed
CHECK: Address : 0x401170
CHECK: Size : 0x43
CHECK: Section : .text
CHECK: IsSimple : 1
CHECK: BB Count : 5
CHECK: Exec Count : 20
CHECK: Branch Count: 640
CHECK: }
# Verify block counts.
CHECK: .LBB01 (4 instructions, align : 1)
CHECK: Successors: .Ltmp[[#BB113:]] (mispreds: 0, count: 20)
CHECK: .Ltmp[[#BB113:]] (9 instructions, align : 1)
CHECK: Successors: .Ltmp[[#BB112:]] (mispreds: 0, count: 320), .LFT[[#BB10:]] (mispreds: 0, count: 0)
CHECK: .LFT[[#BB10:]] (2 instructions, align : 1)
CHECK: Successors: .Ltmp[[#BB112:]] (mispreds: 0, count: 0)
CHECK: .Ltmp[[#BB112:]] (2 instructions, align : 1)
CHECK: Successors: .Ltmp[[#BB113:]] (mispreds: 0, count: 300), .LFT[[#BB11:]] (mispreds: 0, count: 20)
CHECK: .LFT[[#BB11:]] (2 instructions, align : 1)
CHECK: End of Function "usqrt"
# Check the overall inference stats.
CHECK: 2 out of 7 functions in the binary (28.6%) have non-empty execution profile
CHECK: inferred profile for 2 (100.00% of profiled, 100.00% of stale) functions responsible for {{.*}} samples ({{.*}} out of {{.*}})
2 changes: 1 addition & 1 deletion clang-tools-extra/clang-doc/Mapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ llvm::SmallString<128> MapASTVisitor::getFile(const NamedDecl *D,
.getPresumedLoc(D->getBeginLoc())
.getFilename());
IsFileInRootDir = false;
if (RootDir.empty() || !File.startswith(RootDir))
if (RootDir.empty() || !File.starts_with(RootDir))
return File;
IsFileInRootDir = true;
llvm::SmallString<128> Prefix(RootDir);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ void ExpandModularHeadersPPCallbacks::InclusionDirective(
if (Imported) {
serialization::ModuleFile *MF =
Compiler.getASTReader()->getModuleManager().lookup(
Imported->getASTFile());
*Imported->getASTFile());
handleModuleFile(MF);
}
parseToLocation(DirectiveLoc);
Expand Down
2 changes: 1 addition & 1 deletion clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ void IncludeCleanerCheck::check(const MatchFinder::MatchResult &Result) {
MainFileDecls.push_back(D);
}
llvm::DenseSet<include_cleaner::Symbol> SeenSymbols;
const DirectoryEntry *ResourceDir =
OptionalDirectoryEntryRef ResourceDir =
PP->getHeaderSearchInfo().getModuleMap().getBuiltinDir();
// FIXME: Find a way to have less code duplication between include-cleaner
// analysis implementation and the below code.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "clang/Basic/DiagnosticIDs.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/STLForwardCompat.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
Expand Down Expand Up @@ -167,15 +168,13 @@ static const std::array<const StringRef, 4> Msgs = {{
// Criteria is a bitset, thus a few helpers are needed.
CognitiveComplexity::Criteria operator|(CognitiveComplexity::Criteria LHS,
CognitiveComplexity::Criteria RHS) {
return static_cast<CognitiveComplexity::Criteria>(
static_cast<std::underlying_type_t<CognitiveComplexity::Criteria>>(LHS) |
static_cast<std::underlying_type_t<CognitiveComplexity::Criteria>>(RHS));
return static_cast<CognitiveComplexity::Criteria>(llvm::to_underlying(LHS) |
llvm::to_underlying(RHS));
}
CognitiveComplexity::Criteria operator&(CognitiveComplexity::Criteria LHS,
CognitiveComplexity::Criteria RHS) {
return static_cast<CognitiveComplexity::Criteria>(
static_cast<std::underlying_type_t<CognitiveComplexity::Criteria>>(LHS) &
static_cast<std::underlying_type_t<CognitiveComplexity::Criteria>>(RHS));
return static_cast<CognitiveComplexity::Criteria>(llvm::to_underlying(LHS) &
llvm::to_underlying(RHS));
}
CognitiveComplexity::Criteria &operator|=(CognitiveComplexity::Criteria &LHS,
CognitiveComplexity::Criteria RHS) {
Expand Down
8 changes: 4 additions & 4 deletions clang-tools-extra/clangd/IncludeCleaner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -397,10 +397,10 @@ IncludeCleanerFindings computeIncludeCleanerFindings(ParsedAST &AST) {
std::vector<MissingIncludeDiagInfo> MissingIncludes;
llvm::DenseSet<IncludeStructure::HeaderID> Used;
trace::Span Tracer("include_cleaner::walkUsed");
const DirectoryEntry *ResourceDir = AST.getPreprocessor()
.getHeaderSearchInfo()
.getModuleMap()
.getBuiltinDir();
OptionalDirectoryEntryRef ResourceDir = AST.getPreprocessor()
.getHeaderSearchInfo()
.getModuleMap()
.getBuiltinDir();
include_cleaner::walkUsed(
AST.getLocalTopLevelDecls(), /*MacroRefs=*/Macros,
AST.getPragmaIncludes().get(), AST.getPreprocessor(),
Expand Down
5 changes: 3 additions & 2 deletions clang-tools-extra/clangd/SemanticHighlighting.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,8 @@ class HighlightingsBuilder {
public:
HighlightingsBuilder(const ParsedAST &AST, const HighlightingFilter &Filter)
: TB(AST.getTokens()), SourceMgr(AST.getSourceManager()),
LangOpts(AST.getLangOpts()), Filter(Filter) {}
LangOpts(AST.getLangOpts()), Filter(Filter),
Resolver(AST.getHeuristicResolver()) {}

HighlightingToken &addToken(SourceLocation Loc, HighlightingKind Kind) {
auto Range = getRangeForSourceLocation(Loc);
Expand Down Expand Up @@ -589,7 +590,7 @@ class HighlightingsBuilder {
HighlightingFilter Filter;
std::vector<HighlightingToken> Tokens;
std::map<Range, llvm::SmallVector<HighlightingModifier, 1>> ExtraModifiers;
const HeuristicResolver *Resolver = nullptr;
const HeuristicResolver *Resolver;
// returned from addToken(InvalidLoc)
HighlightingToken InvalidHighlightingToken;
};
Expand Down
6 changes: 3 additions & 3 deletions clang-tools-extra/include-cleaner/lib/Analysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,15 +87,15 @@ analyze(llvm::ArrayRef<Decl *> ASTRoots,
llvm::StringSet<> Missing;
if (!HeaderFilter)
HeaderFilter = [](llvm::StringRef) { return false; };
const DirectoryEntry *ResourceDir =
OptionalDirectoryEntryRef ResourceDir =
PP.getHeaderSearchInfo().getModuleMap().getBuiltinDir();
walkUsed(ASTRoots, MacroRefs, PI, PP,
[&](const SymbolReference &Ref, llvm::ArrayRef<Header> Providers) {
bool Satisfied = false;
for (const Header &H : Providers) {
if (H.kind() == Header::Physical &&
(H.physical() == MainFile ||
H.physical().getDir() == ResourceDir)) {
(ResourceDir && H.physical().getDir() == *ResourceDir))) {
Satisfied = true;
}
for (const Include *I : Inc.match(H)) {
Expand All @@ -114,7 +114,7 @@ analyze(llvm::ArrayRef<Decl *> ASTRoots,
for (const Include &I : Inc.all()) {
if (Used.contains(&I) || !I.Resolved ||
HeaderFilter(I.Resolved->getFileEntry().tryGetRealPathName()) ||
I.Resolved->getFileEntry().getDir() == ResourceDir)
(ResourceDir && I.Resolved->getFileEntry().getDir() == *ResourceDir))
continue;
if (PI) {
if (PI->shouldKeep(*I.Resolved))
Expand Down
2 changes: 1 addition & 1 deletion clang-tools-extra/modularize/ModuleAssistant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ static bool addModuleDescription(Module *RootModule,
llvm::SmallString<256> NativePath, NativePrefix;
llvm::sys::path::native(HeaderFilePath, NativePath);
llvm::sys::path::native(HeaderPrefix, NativePrefix);
if (NativePath.startswith(NativePrefix))
if (NativePath.starts_with(NativePrefix))
FilePath = std::string(NativePath.substr(NativePrefix.size() + 1));
else
FilePath = std::string(HeaderFilePath);
Expand Down
5 changes: 3 additions & 2 deletions clang-tools-extra/pseudo/include/clang-pseudo/Token.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "clang/Basic/LangStandard.h"
#include "clang/Basic/TokenKinds.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/STLForwardCompat.h"
#include "llvm/Support/raw_ostream.h"
#include <cstdint>
#include <limits>
Expand Down Expand Up @@ -71,10 +72,10 @@ struct Token {
Index OriginalIndex = Invalid;
// Helpers to get/set Flags based on `enum class`.
template <class T> bool flag(T Mask) const {
return Flags & uint8_t{static_cast<std::underlying_type_t<T>>(Mask)};
return Flags & uint8_t{llvm::to_underlying(Mask)};
}
template <class T> void setFlag(T Mask) {
Flags |= uint8_t{static_cast<std::underlying_type_t<T>>(Mask)};
Flags |= uint8_t{llvm::to_underlying(Mask)};
}

/// Returns the next token in the stream. this may not be a sentinel.
Expand Down
2 changes: 1 addition & 1 deletion clang/docs/LanguageExtensions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1470,7 +1470,7 @@ Relaxed constexpr __cpp_constexpr C++14
``if constexpr`` __cpp_if_constexpr C++17 C++11
fold expressions __cpp_fold_expressions C++17 C++03
Lambda capture of \*this by value __cpp_capture_star_this C++17 C++11
Attributes on enums __cpp_enumerator_attributes C++17 C++11
Attributes on enums __cpp_enumerator_attributes C++17 C++03
Guaranteed copy elision __cpp_guaranteed_copy_elision C++17 C++03
Hexadecimal floating literals __cpp_hex_float C++17 C++03
``inline`` variables __cpp_inline_variables C++17 C++03
Expand Down
29 changes: 26 additions & 3 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,8 @@ Non-comprehensive list of changes in this release
except that it returns the size of a type ignoring tail padding.
* ``__builtin_classify_type()`` now classifies ``_BitInt`` values as the return value ``18``
and vector types as return value ``19``, to match GCC 14's behavior.
* The default value of `_MSC_VER` was raised from 1920 to 1933.
* Since MSVC 19.33 added undocumented attribute ``[[msvc::constexpr]]``, this release adds the attribute as well.

* Added ``#pragma clang fp reciprocal``.

Expand All @@ -262,6 +264,16 @@ New Compiler Flags

* ``-fopenacc`` was added as a part of the effort to support OpenACC in clang.

* ``-fcx-limited-range`` enables the naive mathematical formulas for complex
division and multiplication with no NaN checking of results. The default is
``-fno-cx-limited-range``, but this option is enabled by ``-ffast-math``.

* ``-fcx-fortran-rules`` enables the naive mathematical formulas for complex
multiplication and enables application of Smith's algorithm for complex
division. See SMITH, R. L. Algorithm 116: Complex division. Commun. ACM 5, 8
(1962). The default is ``-fno-cx-fortran-rules``.


Deprecated Compiler Flags
-------------------------

Expand Down Expand Up @@ -389,9 +401,6 @@ Improvements to Clang's diagnostics
(`#54678: <https://github.com/llvm/llvm-project/issues/54678>`_).
- Clang now prints its 'note' diagnostic in cyan instead of black, to be more compatible
with terminals with dark background colors. This is also more consistent with GCC.
- The fix-it emitted by ``-Wformat`` for scoped enumerations now take the
enumeration's underlying type into account instead of suggesting a type just
based on the format string specifier being used.
- Clang now displays an improved diagnostic and a note when a defaulted special
member is marked ``constexpr`` in a class with a virtual base class
(`#64843: <https://github.com/llvm/llvm-project/issues/64843>`_).
Expand Down Expand Up @@ -511,6 +520,7 @@ Improvements to Clang's diagnostics
48 | static_assert(1 << 4 == 15);
| ~~~~~~~^~~~~
- Clang now diagnoses definitions of friend function specializations, e.g. ``friend void f<>(int) {}``.

Improvements to Clang's time-trace
----------------------------------
Expand Down Expand Up @@ -860,6 +870,10 @@ Miscellaneous Clang Crashes Fixed
`Issue 41302 <https://github.com/llvm/llvm-project/issues/41302>`_
- Fixed a crash when ``-ast-dump=json`` was used for code using class
template deduction guides.
- Fixed a crash when a lambda marked as ``static`` referenced a captured
variable in an expression.
`Issue 74608 <https://github.com/llvm/llvm-project/issues/74608>`_


OpenACC Specific Changes
------------------------
Expand Down Expand Up @@ -960,6 +974,9 @@ CUDA/HIP Language Changes
CUDA Support
^^^^^^^^^^^^

- Clang now supports CUDA SDK up to 12.3
- Added support for sm_90a

AIX Support
^^^^^^^^^^^

Expand Down Expand Up @@ -999,6 +1016,9 @@ Floating Point Support in Clang
``__builtin_exp10f128`` builtins.
- Add ``__builtin_iszero``, ``__builtin_issignaling`` and
``__builtin_issubnormal``.
- Add support for C99's ``#pragma STDC CX_LIMITED_RANGE`` feature. This
enables the naive mathematical formulas for complex multiplication and
division, which are faster but do not correctly handle overflow and infinities.

AST Matchers
------------
Expand Down Expand Up @@ -1053,6 +1073,9 @@ Static Analyzer
`#65888 <https://github.com/llvm/llvm-project/pull/65888>`_, and
`#65887 <https://github.com/llvm/llvm-project/pull/65887>`_

- Move checker ``alpha.cplusplus.EnumCastOutOfRange`` out of the ``alpha``
package to ``optin.core.EnumCastOutOfRange``.

.. _release-notes-sanitizers:

Sanitizers
Expand Down
18 changes: 11 additions & 7 deletions clang/docs/SanitizerSpecialCaseList.rst
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,18 @@ and lines starting with "#" are ignored.

.. note::

In `D154014 <https://reviews.llvm.org/D154014>`_ we transitioned to using globs instead
of regexes to match patterns in special case lists. Since this was a
breaking change, we will temporarily support the original behavior using
regexes. If ``#!special-case-list-v2`` is the first line of the file, then
we will use the new behavior using globs. For more details, see
`this discourse post <https://discourse.llvm.org/t/use-glob-instead-of-regex-for-specialcaselists/71666>`_.
Prior to Clang 18, section names and entries described below use a variant of
regex where ``*`` is translated to ``.*``. Clang 18 (`D154014
<https://reviews.llvm.org/D154014>`) switches to glob and plans to remove
regex support in Clang 19.

For Clang 18, regex is supported if ``#!special-case-list-v1`` is the first
line of the file.

Many special case lists use ``.`` to indicate the literal character and do
not use regex metacharacters such as ``(``, ``)``. They are unaffected by the
regex to glob transition. For more details, see `this discourse post
<https://discourse.llvm.org/t/use-glob-instead-of-regex-for-specialcaselists/71666>`_.

Section names are globs written in square brackets that denote
which sanitizer the following entries apply to. For example, ``[address]``
Expand All @@ -80,7 +85,6 @@ tool-specific docs.

.. code-block:: bash
#!special-case-list-v2
# The line above is explained in the note above
# Lines starting with # are ignored.
# Turn off checks for the source file
Expand Down
19 changes: 17 additions & 2 deletions clang/docs/UsersManual.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1468,6 +1468,7 @@ floating point semantic models: precise (the default), strict, and fast.
With the exception of ``-ffp-contract=fast``, using any of the options
below to disable any of the individual optimizations in ``-ffast-math``
will cause ``__FAST_MATH__`` to no longer be set.
``-ffast-math`` enables ``-fcx-limited-range``.

This option implies:

Expand Down Expand Up @@ -1834,6 +1835,20 @@ floating point semantic models: precise (the default), strict, and fast.
* ``16`` - Forces ``_Float16`` operations to be emitted without using excess
precision arithmetic.

.. option:: -fcx-limited-range:

This option enables the naive mathematical formulas for complex division and
multiplication with no NaN checking of results. The default is
``-fno-cx-limited-range``, but this option is enabled by the ``-ffast-math``
option.

.. option:: -fcx-fortran-rules:

This option enables the naive mathematical formulas for complex
multiplication and enables application of Smith's algorithm for complex
division. See SMITH, R. L. Algorithm 116: Complex division. Commun.
ACM 5, 8 (1962). The default is ``-fno-cx-fortran-rules``.

.. _floating-point-environment:

Accessing the floating point environment
Expand Down Expand Up @@ -3359,8 +3374,8 @@ default for Windows targets.

For compatibility with existing code that compiles with MSVC, clang defines the
``_MSC_VER`` and ``_MSC_FULL_VER`` macros. When on Windows, these default to
either the same value as the currently installed version of cl.exe, or ``1920``
and ``192000000`` (respectively). The ``-fms-compatibility-version=`` flag
either the same value as the currently installed version of cl.exe, or ``1933``
and ``193300000`` (respectively). The ``-fms-compatibility-version=`` flag
overrides these values. It accepts a dotted version tuple, such as 19.00.23506.
Changing the MSVC compatibility version makes clang behave more like that
version of MSVC. For example, ``-fms-compatibility-version=19`` will enable
Expand Down
63 changes: 46 additions & 17 deletions clang/docs/analyzer/checkers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,52 @@ optin
Checkers for portability, performance or coding style specific rules.
.. _optin-core-EnumCastOutOfRange:
optin.core.EnumCastOutOfRange (C, C++)
""""""""""""""""""""""""""""""""""""""
Check for integer to enumeration casts that would produce a value with no
corresponding enumerator. This is not necessarily undefined behavior, but can
lead to nasty surprises, so projects may decide to use a coding standard that
disallows these "unusual" conversions.
Note that no warnings are produced when the enum type (e.g. `std::byte`) has no
enumerators at all.
.. code-block:: cpp
enum WidgetKind { A=1, B, C, X=99 };
void foo() {
WidgetKind c = static_cast<WidgetKind>(3); // OK
WidgetKind x = static_cast<WidgetKind>(99); // OK
WidgetKind d = static_cast<WidgetKind>(4); // warn
}
**Limitations**
This checker does not accept the coding pattern where an enum type is used to
store combinations of flag values:
.. code-block:: cpp
enum AnimalFlags
{
HasClaws = 1,
CanFly = 2,
EatsFish = 4,
Endangered = 8
};
AnimalFlags operator|(AnimalFlags a, AnimalFlags b)
{
return static_cast<AnimalFlags>(static_cast<int>(a) | static_cast<int>(b));
}
auto flags = HasClaws | CanFly;
Projects that use this pattern should not enable this optin checker.
.. _optin-cplusplus-UninitializedObject:
optin.cplusplus.UninitializedObject (C++)
Expand Down Expand Up @@ -2113,23 +2159,6 @@ Reports destructions of polymorphic objects with a non-virtual destructor in the
// destructor
}
.. _alpha-cplusplus-EnumCastOutOfRange:
alpha.cplusplus.EnumCastOutOfRange (C++)
""""""""""""""""""""""""""""""""""""""""
Check for integer to enumeration casts that could result in undefined values.
.. code-block:: cpp
enum TestEnum {
A = 0
};
void foo() {
TestEnum t = static_cast(-1);
// warn: the value provided to the cast expression is not in
// the valid range of values for the enum
.. _alpha-cplusplus-InvalidatedIterator:
alpha.cplusplus.InvalidatedIterator (C++)
Expand Down
13 changes: 2 additions & 11 deletions clang/include/clang/AST/Type.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/STLForwardCompat.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/ADT/iterator_range.h"
Expand Down Expand Up @@ -2384,8 +2385,6 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {

bool isRVVType(unsigned ElementCount) const;

bool isRVVType() const;

bool isRVVType(unsigned Bitwidth, bool IsFloat, bool IsBFloat = false) const;

/// Return the implicit lifetime for this type, which must not be dependent.
Expand Down Expand Up @@ -7284,14 +7283,6 @@ inline bool Type::isOpenCLSpecificType() const {
isQueueT() || isReserveIDT() || isPipeType() || isOCLExtOpaqueType();
}

inline bool Type::isRVVType() const {
#define RVV_TYPE(Name, Id, SingletonId) \
isSpecificBuiltinType(BuiltinType::Id) ||
return
#include "clang/Basic/RISCVVTypes.def"
false; // end of boolean or operation.
}

inline bool Type::isRVVType(unsigned ElementCount) const {
bool Ret = false;
#define RVV_VECTOR_TYPE(Name, Id, SingletonId, NumEls, ElBits, NF, IsSigned, \
Expand Down Expand Up @@ -7524,7 +7515,7 @@ inline const Type *Type::getPointeeOrArrayElementType() const {
/// spaces into a diagnostic with <<.
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &PD,
LangAS AS) {
PD.AddTaggedVal(static_cast<std::underlying_type_t<LangAS>>(AS),
PD.AddTaggedVal(llvm::to_underlying(AS),
DiagnosticsEngine::ArgumentKind::ak_addrspace);
return PD;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ FIXABLE_GADGET(PointerDereference)
FIXABLE_GADGET(UPCAddressofArraySubscript) // '&DRE[any]' in an Unspecified Pointer Context
FIXABLE_GADGET(UPCStandalonePointer)
FIXABLE_GADGET(UPCPreIncrement) // '++Ptr' in an Unspecified Pointer Context
FIXABLE_GADGET(UUCAddAssign) // 'Ptr += n' in an Unspecified Untyped Context
FIXABLE_GADGET(PointerAssignment)
FIXABLE_GADGET(PointerInit)

Expand Down
11 changes: 10 additions & 1 deletion clang/include/clang/Basic/Attr.td
Original file line number Diff line number Diff line change
Expand Up @@ -3646,6 +3646,14 @@ def : MutualExclusions<[Owner, Pointer]>;

// Microsoft-related attributes

def MSConstexpr : InheritableAttr {
let LangOpts = [MicrosoftExt];
let Spellings = [CXX11<"msvc", "constexpr">];
let Subjects = SubjectList<[Function, ReturnStmt], ErrorDiag,
"functions and return statements">;
let Documentation = [MSConstexprDocs];
}

def MSNoVTable : InheritableAttr, TargetSpecificAttr<TargetMicrosoftCXXABI> {
let Spellings = [Declspec<"novtable">];
let Subjects = SubjectList<[CXXRecord]>;
Expand Down Expand Up @@ -4250,7 +4258,8 @@ def HLSLResource : InheritableAttr {
"StructuredBuffer", "CBuffer", "Sampler",
"TBuffer", "RTAccelerationStructure",
"FeedbackTexture2D", "FeedbackTexture2DArray"],
/*opt=*/0, /*fake=*/0, /*isExternalType=*/1>
/*opt=*/0, /*fake=*/0, /*isExternalType=*/1>,
DefaultBoolArgument<"isROV", /*default=*/0>
];
let Documentation = [InternalOnly];
}
Expand Down
15 changes: 15 additions & 0 deletions clang/include/clang/Basic/AttrDocs.td
Original file line number Diff line number Diff line change
Expand Up @@ -3657,6 +3657,21 @@ an error:
}];
}

def MSConstexprDocs : Documentation {
let Category = DocCatStmt;
let Content = [{
The ``[[msvc::constexpr]]`` attribute can be applied only to a function
definition or a ``return`` statement. It does not impact function declarations.
A ``[[msvc::constexpr]]`` function cannot be ``constexpr`` or ``consteval``.
A ``[[msvc::constexpr]]`` function is treated as if it were a ``constexpr`` function
when it is evaluated in a constant context of ``[[msvc::constexpr]] return`` statement.
Otherwise, it is treated as a regular function.

Semantics of this attribute are enabled only under MSVC compatibility
(``-fms-compatibility-version``) 19.33 and later.
}];
}

def MSNoVTableDocs : Documentation {
let Category = DocCatDecl;
let Content = [{
Expand Down
13 changes: 11 additions & 2 deletions clang/include/clang/Basic/BuiltinsNVPTX.def
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@
#pragma push_macro("SM_87")
#pragma push_macro("SM_89")
#pragma push_macro("SM_90")
#define SM_90 "sm_90"
#pragma push_macro("SM_90a")
#define SM_90a "sm_90a"
#define SM_90 "sm_90|" SM_90a
#define SM_89 "sm_89|" SM_90
#define SM_87 "sm_87|" SM_89
#define SM_86 "sm_86|" SM_87
Expand Down Expand Up @@ -56,7 +58,11 @@
#pragma push_macro("PTX78")
#pragma push_macro("PTX80")
#pragma push_macro("PTX81")
#define PTX81 "ptx81"
#pragma push_macro("PTX82")
#pragma push_macro("PTX83")
#define PTX83 "ptx83"
#define PTX82 "ptx82|" PTX83
#define PTX81 "ptx81|" PTX82
#define PTX80 "ptx80|" PTX81
#define PTX78 "ptx78|" PTX80
#define PTX77 "ptx77|" PTX78
Expand Down Expand Up @@ -1055,6 +1061,7 @@ TARGET_BUILTIN(__nvvm_getctarank_shared_cluster, "iv*3", "", AND(SM_90,PTX78))
#pragma pop_macro("SM_87")
#pragma pop_macro("SM_89")
#pragma pop_macro("SM_90")
#pragma pop_macro("SM_90a")
#pragma pop_macro("PTX42")
#pragma pop_macro("PTX60")
#pragma pop_macro("PTX61")
Expand All @@ -1072,3 +1079,5 @@ TARGET_BUILTIN(__nvvm_getctarank_shared_cluster, "iv*3", "", AND(SM_90,PTX78))
#pragma pop_macro("PTX78")
#pragma pop_macro("PTX80")
#pragma pop_macro("PTX81")
#pragma pop_macro("PTX82")
#pragma pop_macro("PTX83")
7 changes: 5 additions & 2 deletions clang/include/clang/Basic/Cuda.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,11 @@ enum class CudaVersion {
CUDA_118,
CUDA_120,
CUDA_121,
FULLY_SUPPORTED = CUDA_118,
CUDA_122,
CUDA_123,
FULLY_SUPPORTED = CUDA_123,
PARTIALLY_SUPPORTED =
CUDA_121, // Partially supported. Proceed with a warning.
CUDA_123, // Partially supported. Proceed with a warning.
NEW = 10000, // Too new. Issue a warning, but allow using it.
};
const char *CudaVersionToString(CudaVersion V);
Expand Down Expand Up @@ -71,6 +73,7 @@ enum class CudaArch {
SM_87,
SM_89,
SM_90,
SM_90a,
GFX600,
GFX601,
GFX602,
Expand Down
6 changes: 5 additions & 1 deletion clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -1669,6 +1669,8 @@ def err_qualified_friend_def : Error<
"friend function definition cannot be qualified with '%0'">;
def err_friend_def_in_local_class : Error<
"friend function cannot be defined in a local class">;
def err_friend_specialization_def : Error<
"friend function specialization cannot be defined">;
def err_friend_not_first_in_declaration : Error<
"'friend' must appear first in a non-function declaration">;
def err_using_decl_friend : Error<
Expand Down Expand Up @@ -2884,6 +2886,8 @@ def warn_cxx11_compat_constexpr_body_multiple_return : Warning<
InGroup<CXXPre14Compat>, DefaultIgnore;
def note_constexpr_body_previous_return : Note<
"previous return statement is here">;
def err_ms_constexpr_cannot_be_applied : Error<
"attribute 'msvc::constexpr' cannot be applied to the %select{constexpr|consteval|virtual}0 function %1">;

// C++20 function try blocks in constexpr
def ext_constexpr_function_try_block_cxx20 : ExtWarn<
Expand Down Expand Up @@ -11998,7 +12002,7 @@ def warn_tcb_enforcement_violation : Warning<

// RISC-V builtin required extension warning
def err_riscv_builtin_requires_extension : Error<
"builtin requires%select{| at least one of the following extensions to be enabled}0: %1">;
"builtin requires%select{| at least one of the following extensions}0: %1">;
def err_riscv_builtin_invalid_lmul : Error<
"LMUL argument must be in the range [0,3] or [5,7]">;
def err_riscv_type_requires_extension : Error<
Expand Down
74 changes: 0 additions & 74 deletions clang/include/clang/Basic/DirectoryEntry.h
Original file line number Diff line number Diff line change
Expand Up @@ -245,78 +245,4 @@ template <> struct DenseMapInfo<clang::DirectoryEntryRef> {

} // end namespace llvm

namespace clang {

/// Wrapper around OptionalDirectoryEntryRef that degrades to 'const
/// DirectoryEntry*', facilitating incremental patches to propagate
/// DirectoryEntryRef.
///
/// This class can be used as return value or field where it's convenient for
/// an OptionalDirectoryEntryRef to degrade to a 'const DirectoryEntry*'. The
/// purpose is to avoid code churn due to dances like the following:
/// \code
/// // Old code.
/// lvalue = rvalue;
///
/// // Temporary code from an incremental patch.
/// OptionalDirectoryEntryRef MaybeF = rvalue;
/// lvalue = MaybeF ? &MaybeF.getDirectoryEntry() : nullptr;
///
/// // Final code.
/// lvalue = rvalue;
/// \endcode
///
/// FIXME: Once DirectoryEntryRef is "everywhere" and DirectoryEntry::LastRef
/// and DirectoryEntry::getName have been deleted, delete this class and
/// replace instances with OptionalDirectoryEntryRef.
class OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr
: public OptionalDirectoryEntryRef {
public:
OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr() = default;
OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr(
OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr &&) = default;
OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr(
const OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr &) = default;
OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr &
operator=(OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr &&) = default;
OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr &
operator=(const OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr &) = default;

OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr(std::nullopt_t) {}
OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr(DirectoryEntryRef Ref)
: OptionalDirectoryEntryRef(Ref) {}
OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr(
OptionalDirectoryEntryRef MaybeRef)
: OptionalDirectoryEntryRef(MaybeRef) {}

OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr &
operator=(std::nullopt_t) {
OptionalDirectoryEntryRef::operator=(std::nullopt);
return *this;
}
OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr &operator=(DirectoryEntryRef Ref) {
OptionalDirectoryEntryRef::operator=(Ref);
return *this;
}
OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr &
operator=(OptionalDirectoryEntryRef MaybeRef) {
OptionalDirectoryEntryRef::operator=(MaybeRef);
return *this;
}

/// Degrade to 'const DirectoryEntry *' to allow DirectoryEntry::LastRef and
/// DirectoryEntry::getName have been deleted, delete this class and replace
/// instances with OptionalDirectoryEntryRef
operator const DirectoryEntry *() const {
return has_value() ? &(*this)->getDirEntry() : nullptr;
}
};

static_assert(std::is_trivially_copyable<
OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr>::value,
"OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr should be "
"trivially copyable");

} // end namespace clang

#endif // LLVM_CLANG_BASIC_DIRECTORYENTRY_H
1 change: 1 addition & 0 deletions clang/include/clang/Basic/FPOptions.def
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,5 @@ OPTION(FPEvalMethod, LangOptions::FPEvalMethodKind, 2, AllowApproxFunc)
OPTION(Float16ExcessPrecision, LangOptions::ExcessPrecisionKind, 2, FPEvalMethod)
OPTION(BFloat16ExcessPrecision, LangOptions::ExcessPrecisionKind, 2, Float16ExcessPrecision)
OPTION(MathErrno, bool, 1, BFloat16ExcessPrecision)
OPTION(ComplexRange, LangOptions::ComplexRangeKind, 2, MathErrno)
#undef OPTION
1 change: 1 addition & 0 deletions clang/include/clang/Basic/Features.def
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ FEATURE(scudo, LangOpts.Sanitize.hasOneOf(SanitizerKind::Scudo))
FEATURE(swiftasynccc,
PP.getTargetInfo().checkCallingConvention(CC_SwiftAsync) ==
clang::TargetInfo::CCCR_OK)
FEATURE(pragma_stdc_cx_limited_range, true)
// Objective-C features
FEATURE(objc_arr, LangOpts.ObjCAutoRefCount) // FIXME: REMOVE?
FEATURE(objc_arc, LangOpts.ObjCAutoRefCount)
Expand Down
66 changes: 0 additions & 66 deletions clang/include/clang/Basic/FileEntry.h
Original file line number Diff line number Diff line change
Expand Up @@ -279,72 +279,6 @@ template <> struct DenseMapInfo<clang::FileEntryRef> {

namespace clang {

/// Wrapper around OptionalFileEntryRef that degrades to 'const FileEntry*',
/// facilitating incremental patches to propagate FileEntryRef.
///
/// This class can be used as return value or field where it's convenient for
/// an OptionalFileEntryRef to degrade to a 'const FileEntry*'. The purpose
/// is to avoid code churn due to dances like the following:
/// \code
/// // Old code.
/// lvalue = rvalue;
///
/// // Temporary code from an incremental patch.
/// OptionalFileEntryRef MaybeF = rvalue;
/// lvalue = MaybeF ? &MaybeF.getFileEntry() : nullptr;
///
/// // Final code.
/// lvalue = rvalue;
/// \endcode
///
/// FIXME: Once FileEntryRef is "everywhere" and FileEntry::LastRef and
/// FileEntry::getName have been deleted, delete this class and replace
/// instances with OptionalFileEntryRef.
class OptionalFileEntryRefDegradesToFileEntryPtr : public OptionalFileEntryRef {
public:
OptionalFileEntryRefDegradesToFileEntryPtr() = default;
OptionalFileEntryRefDegradesToFileEntryPtr(
OptionalFileEntryRefDegradesToFileEntryPtr &&) = default;
OptionalFileEntryRefDegradesToFileEntryPtr(
const OptionalFileEntryRefDegradesToFileEntryPtr &) = default;
OptionalFileEntryRefDegradesToFileEntryPtr &
operator=(OptionalFileEntryRefDegradesToFileEntryPtr &&) = default;
OptionalFileEntryRefDegradesToFileEntryPtr &
operator=(const OptionalFileEntryRefDegradesToFileEntryPtr &) = default;

OptionalFileEntryRefDegradesToFileEntryPtr(std::nullopt_t) {}
OptionalFileEntryRefDegradesToFileEntryPtr(FileEntryRef Ref)
: OptionalFileEntryRef(Ref) {}
OptionalFileEntryRefDegradesToFileEntryPtr(OptionalFileEntryRef MaybeRef)
: OptionalFileEntryRef(MaybeRef) {}

OptionalFileEntryRefDegradesToFileEntryPtr &operator=(std::nullopt_t) {
OptionalFileEntryRef::operator=(std::nullopt);
return *this;
}
OptionalFileEntryRefDegradesToFileEntryPtr &operator=(FileEntryRef Ref) {
OptionalFileEntryRef::operator=(Ref);
return *this;
}
OptionalFileEntryRefDegradesToFileEntryPtr &
operator=(OptionalFileEntryRef MaybeRef) {
OptionalFileEntryRef::operator=(MaybeRef);
return *this;
}

/// Degrade to 'const FileEntry *' to allow FileEntry::LastRef and
/// FileEntry::getName have been deleted, delete this class and replace
/// instances with OptionalFileEntryRef
operator const FileEntry *() const {
return has_value() ? &(*this)->getFileEntry() : nullptr;
}
};

static_assert(
std::is_trivially_copyable<
OptionalFileEntryRefDegradesToFileEntryPtr>::value,
"OptionalFileEntryRefDegradesToFileEntryPtr should be trivially copyable");

inline bool operator==(const FileEntry *LHS, const OptionalFileEntryRef &RHS) {
return LHS == (RHS ? &RHS->getFileEntry() : nullptr);
}
Expand Down
2 changes: 2 additions & 0 deletions clang/include/clang/Basic/LangOptions.def
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,8 @@ BENIGN_LANGOPT(NoSignedZero , 1, 0, "Permit Floating Point optimization wit
BENIGN_LANGOPT(AllowRecip , 1, 0, "Permit Floating Point reciprocal")
BENIGN_LANGOPT(ApproxFunc , 1, 0, "Permit Floating Point approximation")

ENUM_LANGOPT(ComplexRange, ComplexRangeKind, 2, CX_Full, "Enable use of range reduction for complex arithmetics.")

BENIGN_LANGOPT(ObjCGCBitmapPrint , 1, 0, "printing of GC's bitmap layout for __weak/__strong ivars")

BENIGN_LANGOPT(AccessControl , 1, 1, "C++ access control")
Expand Down
4 changes: 4 additions & 0 deletions clang/include/clang/Basic/LangOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ class LangOptions : public LangOptionsBase {
MSVC2019 = 1920,
MSVC2019_5 = 1925,
MSVC2019_8 = 1928,
MSVC2022_3 = 1933,
};

enum SYCLMajorVersion {
Expand Down Expand Up @@ -391,6 +392,8 @@ class LangOptions : public LangOptionsBase {
IncompleteOnly = 3,
};

enum ComplexRangeKind { CX_Full, CX_Limited, CX_Fortran };

public:
/// The used language standard.
LangStandard::Kind LangStd;
Expand Down Expand Up @@ -740,6 +743,7 @@ class FPOptions {
setAllowFEnvAccess(true);
else
setAllowFEnvAccess(LangOptions::FPM_Off);
setComplexRange(LO.getComplexRange());
}

bool allowFPContractWithinStatement() const {
Expand Down
4 changes: 2 additions & 2 deletions clang/include/clang/Basic/Module.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ class alignas(8) Module {
/// The build directory of this module. This is the directory in
/// which the module is notionally built, and relative to which its headers
/// are found.
OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr Directory;
OptionalDirectoryEntryRef Directory;

/// The presumed file name for the module map defining this module.
/// Only non-empty when building from preprocessed source.
Expand Down Expand Up @@ -672,7 +672,7 @@ class alignas(8) Module {
}

/// The serialized AST file for this module, if one was created.
OptionalFileEntryRefDegradesToFileEntryPtr getASTFile() const {
OptionalFileEntryRef getASTFile() const {
return getTopLevelModule()->ASTFile;
}

Expand Down
14 changes: 8 additions & 6 deletions clang/include/clang/Basic/SourceManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ class alignas(8) ContentCache {
///
/// FIXME: Make non-optional using a virtual file as needed, remove \c
/// Filename and use \c OrigEntry.getNameAsRequested() instead.
OptionalFileEntryRefDegradesToFileEntryPtr OrigEntry;
OptionalFileEntryRef OrigEntry;

/// References the file which the contents were actually loaded from.
///
Expand Down Expand Up @@ -1064,8 +1064,8 @@ class SourceManager : public RefCountedBase<SourceManager> {

/// Returns the FileEntry record for the provided FileID.
const FileEntry *getFileEntryForID(FileID FID) const {
if (auto *Entry = getSLocEntryForFile(FID))
return Entry->getFile().getContentCache().OrigEntry;
if (auto FE = getFileEntryRefForID(FID))
return *FE;
return nullptr;
}

Expand All @@ -1083,9 +1083,11 @@ class SourceManager : public RefCountedBase<SourceManager> {
std::optional<StringRef> getNonBuiltinFilenameForID(FileID FID) const;

/// Returns the FileEntry record for the provided SLocEntry.
const FileEntry *getFileEntryForSLocEntry(const SrcMgr::SLocEntry &sloc) const
{
return sloc.getFile().getContentCache().OrigEntry;
const FileEntry *
getFileEntryForSLocEntry(const SrcMgr::SLocEntry &SLocEntry) const {
if (auto FE = SLocEntry.getFile().getContentCache().OrigEntry)
return *FE;
return nullptr;
}

/// Return a StringRef to the source buffer data for the
Expand Down
1 change: 0 additions & 1 deletion clang/include/clang/Basic/TargetInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,6 @@ class TargetInfo : public TransferrableTargetInfo,
LLVM_PREFERRED_TYPE(bool)
unsigned AllowAMDGPUUnsafeFPAtomics : 1;

LLVM_PREFERRED_TYPE(bool)
unsigned ARMCDECoprocMask : 8;

unsigned MaxOpenCLWorkGroupSize;
Expand Down
5 changes: 5 additions & 0 deletions clang/include/clang/Basic/TokenKinds.def
Original file line number Diff line number Diff line change
Expand Up @@ -911,6 +911,11 @@ PRAGMA_ANNOTATION(pragma_fenv_access_ms)
// handles them.
PRAGMA_ANNOTATION(pragma_fenv_round)

// Annotation for #pragma STDC CX_LIMITED_RANGE
// The lexer produces these so that they only take effect when the parser
// handles them.
PRAGMA_ANNOTATION(pragma_cx_limited_range)

// Annotation for #pragma float_control
// The lexer produces these so that they only take effect when the parser
// handles them.
Expand Down
41 changes: 28 additions & 13 deletions clang/include/clang/Basic/arm_sve.td
Original file line number Diff line number Diff line change
Expand Up @@ -1935,16 +1935,25 @@ def SVBGRP : SInst<"svbgrp[_{d}]", "ddd", "UcUsUiUl", MergeNone, "aarch64_sv
def SVBGRP_N : SInst<"svbgrp[_n_{d}]", "dda", "UcUsUiUl", MergeNone, "aarch64_sve_bgrp_x">;
}

let TargetGuard = "sve2p1" in {
def SVFCLAMP : SInst<"svclamp[_{d}]", "dddd", "hfd", MergeNone, "aarch64_sve_fclamp", [], []>;
let TargetGuard = "sve2p1|sme" in {
def SVPSEL_B : SInst<"svpsel_lane_b8", "PPPm", "Pc", MergeNone, "", [IsStreamingCompatible], []>;
def SVPSEL_H : SInst<"svpsel_lane_b16", "PPPm", "Ps", MergeNone, "", [IsStreamingCompatible], []>;
def SVPSEL_S : SInst<"svpsel_lane_b32", "PPPm", "Pi", MergeNone, "", [IsStreamingCompatible], []>;
def SVPSEL_D : SInst<"svpsel_lane_b64", "PPPm", "Pl", MergeNone, "", [IsStreamingCompatible], []>;
def SVPSEL_COUNT_ALIAS_B : SInst<"svpsel_lane_c8", "}}Pm", "Pc", MergeNone, "", [IsStreamingCompatible], []>;
def SVPSEL_COUNT_ALIAS_H : SInst<"svpsel_lane_c16", "}}Pm", "Ps", MergeNone, "", [IsStreamingCompatible], []>;
def SVPSEL_COUNT_ALIAS_S : SInst<"svpsel_lane_c32", "}}Pm", "Pi", MergeNone, "", [IsStreamingCompatible], []>;
def SVPSEL_COUNT_ALIAS_D : SInst<"svpsel_lane_c64", "}}Pm", "Pl", MergeNone, "", [IsStreamingCompatible], []>;
}

def SVPEXT_SINGLE : SInst<"svpext_lane_{d}", "P}i", "QcQsQiQl", MergeNone, "aarch64_sve_pext", [], [ImmCheck<1, ImmCheck0_3>]>;
def SVPEXT_X2 : SInst<"svpext_lane_{d}_x2", "2.P}i", "QcQsQiQl", MergeNone, "aarch64_sve_pext_x2", [], [ImmCheck<1, ImmCheck0_1>]>;
let TargetGuard = "sve2p1|sme2" in {
//FIXME: Replace IsStreamingCompatible with IsStreamingOrHasSVE2p1 when available
def SVPEXT_SINGLE : SInst<"svpext_lane_{d}", "P}i", "QcQsQiQl", MergeNone, "aarch64_sve_pext", [IsStreamingCompatible], [ImmCheck<1, ImmCheck0_3>]>;
def SVPEXT_X2 : SInst<"svpext_lane_{d}_x2", "2.P}i", "QcQsQiQl", MergeNone, "aarch64_sve_pext_x2", [IsStreamingCompatible], [ImmCheck<1, ImmCheck0_1>]>;
}

def SVPSEL_COUNT_ALIAS_B : SInst<"svpsel_lane_c8", "}}Pm", "Pc", MergeNone, "", [], []>;
def SVPSEL_COUNT_ALIAS_H : SInst<"svpsel_lane_c16", "}}Pm", "Ps", MergeNone, "", [], []>;
def SVPSEL_COUNT_ALIAS_S : SInst<"svpsel_lane_c32", "}}Pm", "Pi", MergeNone, "", [], []>;
def SVPSEL_COUNT_ALIAS_D : SInst<"svpsel_lane_c64", "}}Pm", "Pl", MergeNone, "", [], []>;
let TargetGuard = "sve2p1" in {
def SVFCLAMP : SInst<"svclamp[_{d}]", "dddd", "hfd", MergeNone, "aarch64_sve_fclamp", [], []>;

def SVWHILEGE_COUNT : SInst<"svwhilege_{d}", "}lli", "QcQsQiQl", MergeNone, "aarch64_sve_whilege_{d}", [IsOverloadNone], [ImmCheck<2, ImmCheck2_4_Mul2>]>;
def SVWHILEGT_COUNT : SInst<"svwhilegt_{d}", "}lli", "QcQsQiQl", MergeNone, "aarch64_sve_whilegt_{d}", [IsOverloadNone], [ImmCheck<2, ImmCheck2_4_Mul2>]>;
Expand Down Expand Up @@ -2045,11 +2054,6 @@ let TargetGuard = "sve2p1" in {
def SVSCLAMP : SInst<"svclamp[_{d}]", "dddd", "csil", MergeNone, "aarch64_sve_sclamp", [], []>;
def SVUCLAMP : SInst<"svclamp[_{d}]", "dddd", "UcUsUiUl", MergeNone, "aarch64_sve_uclamp", [], []>;

def SVPSEL_B : SInst<"svpsel_lane_b8", "PPPm", "Pc", MergeNone, "", [], []>;
def SVPSEL_H : SInst<"svpsel_lane_b16", "PPPm", "Ps", MergeNone, "", [], []>;
def SVPSEL_S : SInst<"svpsel_lane_b32", "PPPm", "Pi", MergeNone, "", [], []>;
def SVPSEL_D : SInst<"svpsel_lane_b64", "PPPm", "Pl", MergeNone, "", [], []>;

def SVCNTP_COUNT : SInst<"svcntp_{d}", "n}i", "QcQsQiQl", MergeNone, "aarch64_sve_cntp_{d}", [IsOverloadNone], [ImmCheck<1, ImmCheck2_4_Mul2>]>;

defm SVREVD : SInstZPZ<"svrevd", "csilUcUsUiUl", "aarch64_sve_revd">;
Expand Down Expand Up @@ -2258,3 +2262,14 @@ let TargetGuard = "sme2" in {
def SVQCVTN_U16_U64_X4 : SInst<"svqcvtn_u16[_{d}_x4]", "b4.d", "Ul", MergeNone, "aarch64_sve_uqcvtn_x4", [IsStreaming], []>;
def SVQCVTN_U16_S64_X4 : SInst<"svqcvtn_u16[_{d}_x4]", "b4.d", "l", MergeNone, "aarch64_sve_sqcvtun_x4", [IsStreaming], []>;
}

//
// Multi-vector unpack
//

let TargetGuard = "sme2" in {
def SVSUNPK_X2 : SInst<"svunpk_{d}[_{1}_x2]", "2h", "sil", MergeNone, "aarch64_sve_sunpk_x2", [IsStreaming], []>;
def SVUUNPK_X2 : SInst<"svunpk_{d}[_{1}_x2]", "2h", "UsUiUl", MergeNone, "aarch64_sve_uunpk_x2", [IsStreaming], []>;
def SVSUNPK_X4 : SInst<"svunpk_{d}[_{3}_x4]", "42.h", "sil", MergeNone, "aarch64_sve_sunpk_x4", [IsStreaming], []>;
def SVUUNPK_X4 : SInst<"svunpk_{d}[_{3}_x4]", "42.h", "UsUiUl", MergeNone, "aarch64_sve_uunpk_x4", [IsStreaming], []>;
}
30 changes: 30 additions & 0 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -1010,6 +1010,30 @@ defm offload_uniform_block : BoolFOption<"offload-uniform-block",
NegFlag<SetFalse, [], [ClangOption, CC1Option], "Don't assume">,
BothFlags<[], [ClangOption], " that kernels are launched with uniform block sizes (default true for CUDA/HIP and false otherwise)">>;

def fcx_limited_range : Joined<["-"], "fcx-limited-range">,
Group<f_Group>, Visibility<[ClangOption, CC1Option]>,
HelpText<"Basic algebraic expansions of complex arithmetic operations "
"involving are enabled.">;

def fno_cx_limited_range : Joined<["-"], "fno-cx-limited-range">,
Group<f_Group>, Visibility<[ClangOption, CC1Option]>,
HelpText<"Basic algebraic expansions of complex arithmetic operations "
"involving are disabled.">;

def fcx_fortran_rules : Joined<["-"], "fcx-fortran-rules">,
Group<f_Group>, Visibility<[ClangOption, CC1Option]>,
HelpText<"Range reduction is enabled for complex arithmetic operations.">;

def fno_cx_fortran_rules : Joined<["-"], "fno-cx-fortran-rules">,
Group<f_Group>, Visibility<[ClangOption, CC1Option]>,
HelpText<"Range reduction is disabled for complex arithmetic operations.">;

def complex_range_EQ : Joined<["-"], "complex-range=">, Group<f_Group>,
Visibility<[CC1Option]>,
Values<"full,limited,fortran">, NormalizedValuesScope<"LangOptions">,
NormalizedValues<["CX_Full", "CX_Limited", "CX_Fortran"]>,
MarshallingInfoEnum<LangOpts<"ComplexRange">, "CX_Full">;

// OpenCL-only Options
def cl_opt_disable : Flag<["-"], "cl-opt-disable">, Group<opencl_Group>,
Visibility<[ClangOption, CC1Option]>,
Expand Down Expand Up @@ -6354,6 +6378,12 @@ def J : JoinedOrSeparate<["-"], "J">,
Group<gfortran_Group>,
Alias<module_dir>;

let Visibility = [FlangOption] in {
def no_fortran_main : Flag<["-"], "fno-fortran-main">,
Visibility<[FlangOption]>, Group<f_Group>,
HelpText<"Do not include Fortran_main.a (provided by Flang) when linking">;
} // let Visibility = [ FlangOption ]

//===----------------------------------------------------------------------===//
// FC1 Options
//===----------------------------------------------------------------------===//
Expand Down
14 changes: 5 additions & 9 deletions clang/include/clang/Lex/ModuleMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ class ModuleMap {

/// The directory used for Clang-supplied, builtin include headers,
/// such as "stdint.h".
OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr BuiltinIncludeDir;
OptionalDirectoryEntryRef BuiltinIncludeDir;

/// Language options used to parse the module map itself.
///
Expand Down Expand Up @@ -408,16 +408,12 @@ class ModuleMap {
/// Set the target information.
void setTarget(const TargetInfo &Target);

/// Set the directory that contains Clang-supplied include
/// files, such as our stdarg.h or tgmath.h.
void setBuiltinIncludeDir(DirectoryEntryRef Dir) {
BuiltinIncludeDir = Dir;
}
/// Set the directory that contains Clang-supplied include files, such as our
/// stdarg.h or tgmath.h.
void setBuiltinIncludeDir(DirectoryEntryRef Dir) { BuiltinIncludeDir = Dir; }

/// Get the directory that contains Clang-supplied include files.
OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr getBuiltinDir() const {
return BuiltinIncludeDir;
}
OptionalDirectoryEntryRef getBuiltinDir() const { return BuiltinIncludeDir; }

/// Is this a compiler builtin header?
bool isBuiltinHeader(FileEntryRef File);
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Lex/PreprocessorLexer.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ class PreprocessorLexer {

/// getFileEntry - Return the FileEntry corresponding to this FileID. Like
/// getFileID(), this only works for lexers with attached preprocessors.
OptionalFileEntryRefDegradesToFileEntryPtr getFileEntry() const;
OptionalFileEntryRef getFileEntry() const;

/// Iterator that traverses the current stack of preprocessor
/// conditional directives (\#if/\#ifdef/\#ifndef).
Expand Down
4 changes: 4 additions & 0 deletions clang/include/clang/Parse/Parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -769,6 +769,10 @@ class Parser : public CodeCompletionHandler {
/// #pragma STDC FENV_ROUND...
void HandlePragmaFEnvRound();

/// Handle the annotation token produced for
/// #pragma STDC CX_LIMITED_RANGE...
void HandlePragmaCXLimitedRange();

/// Handle the annotation token produced for
/// #pragma float_control
void HandlePragmaFloatControl();
Expand Down
8 changes: 6 additions & 2 deletions clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -7311,8 +7311,7 @@ class Sema final {

/// ActOnLambdaExpr - This is called when the body of a lambda expression
/// was successfully completed.
ExprResult ActOnLambdaExpr(SourceLocation StartLoc, Stmt *Body,
Scope *CurScope);
ExprResult ActOnLambdaExpr(SourceLocation StartLoc, Stmt *Body);

/// Does copying/destroying the captured variable have side effects?
bool CaptureHasSideEffects(const sema::Capture &From);
Expand Down Expand Up @@ -11023,6 +11022,11 @@ class Sema final {
/// \#pragma STDC FENV_ACCESS
void ActOnPragmaFEnvAccess(SourceLocation Loc, bool IsEnabled);

/// ActOnPragmaCXLimitedRange - Called on well formed
/// \#pragma STDC CX_LIMITED_RANGE
void ActOnPragmaCXLimitedRange(SourceLocation Loc,
LangOptions::ComplexRangeKind Range);

/// Called on well formed '\#pragma clang fp' that has option 'exceptions'.
void ActOnPragmaFPExceptions(SourceLocation Loc,
LangOptions::FPExceptionModeKind);
Expand Down
7 changes: 1 addition & 6 deletions clang/include/clang/Serialization/ASTReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -2415,12 +2415,7 @@ class BitsUnpacker {
BitsUnpacker(BitsUnpacker &&) = delete;
BitsUnpacker operator=(const BitsUnpacker &) = delete;
BitsUnpacker operator=(BitsUnpacker &&) = delete;
~BitsUnpacker() {
#ifndef NDEBUG
while (isValid())
assert(!getNextBit() && "There are unprocessed bits!");
#endif
}
~BitsUnpacker() = default;

void updateValue(uint32_t V) {
Value = V;
Expand Down
8 changes: 4 additions & 4 deletions clang/include/clang/Serialization/ModuleFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ class InputFile {
return File;
}

OptionalFileEntryRefDegradesToFileEntryPtr getFile() const {
OptionalFileEntryRef getFile() const {
if (auto *P = Val.getPointer())
return FileEntryRef(*P);
return std::nullopt;
Expand All @@ -123,8 +123,8 @@ class InputFile {
/// other modules.
class ModuleFile {
public:
ModuleFile(ModuleKind Kind, unsigned Generation)
: Kind(Kind), Generation(Generation) {}
ModuleFile(ModuleKind Kind, FileEntryRef File, unsigned Generation)
: Kind(Kind), File(File), Generation(Generation) {}
~ModuleFile();

// === General information ===
Expand Down Expand Up @@ -176,7 +176,7 @@ class ModuleFile {
bool DidReadTopLevelSubmodule = false;

/// The file entry for the module file.
OptionalFileEntryRefDegradesToFileEntryPtr File;
FileEntryRef File;

/// The signature of the module file, which may be used instead of the size
/// and modification time to identify this particular file.
Expand Down
17 changes: 13 additions & 4 deletions clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ def CoreAlpha : Package<"core">, ParentPackage<Alpha>;
// Note: OptIn is *not* intended for checkers that are too noisy to be on by
// default. Such checkers belong in the alpha package.
def OptIn : Package<"optin">;
def CoreOptIn : Package<"core">, ParentPackage<OptIn>;

// In the Portability package reside checkers for finding code that relies on
// implementation-defined behavior. Such checks are wanted for cross-platform
Expand Down Expand Up @@ -439,6 +440,18 @@ def UndefinedNewArraySizeChecker : Checker<"NewArraySize">,

} // end "core.uninitialized"

//===----------------------------------------------------------------------===//
// Optin checkers for core language features
//===----------------------------------------------------------------------===//

let ParentPackage = CoreOptIn in {

def EnumCastOutOfRangeChecker : Checker<"EnumCastOutOfRange">,
HelpText<"Check integer to enumeration casts for out of range values">,
Documentation<HasDocumentation>;

} // end "optin.core"

//===----------------------------------------------------------------------===//
// Unix API checkers.
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -774,10 +787,6 @@ def DeleteWithNonVirtualDtorChecker : Checker<"DeleteWithNonVirtualDtor">,
"destructor in their base class">,
Documentation<HasDocumentation>;

def EnumCastOutOfRangeChecker : Checker<"EnumCastOutOfRange">,
HelpText<"Check integer to enumeration casts for out of range values">,
Documentation<HasDocumentation>;

def IteratorModeling : Checker<"IteratorModeling">,
HelpText<"Models iterators of C++ containers">,
Dependencies<[ContainerModeling]>,
Expand Down
1 change: 1 addition & 0 deletions clang/lib/AST/Decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4150,6 +4150,7 @@ FunctionDecl::setFunctionTemplateSpecialization(ASTContext &C,
assert(TSK != TSK_Undeclared &&
"Must specify the type of function template specialization");
assert((TemplateOrSpecialization.isNull() ||
getFriendObjectKind() != FOK_None ||
TSK == TSK_ExplicitSpecialization) &&
"Member specialization must be an explicit specialization");
FunctionTemplateSpecializationInfo *Info =
Expand Down
48 changes: 40 additions & 8 deletions clang/lib/AST/ExprConstant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -641,6 +641,10 @@ namespace {
return false;
}

/// Whether we're in a context where [[msvc::constexpr]] evaluation is
/// permitted. See MSConstexprDocs for description of permitted contexts.
bool CanEvalMSConstexpr = false;

private:
APValue &createLocal(APValue::LValueBase Base, const void *Key, QualType T,
ScopeKind Scope);
Expand Down Expand Up @@ -674,6 +678,19 @@ namespace {
private:
llvm::TimeTraceScope TimeScope;
};

/// RAII object used to change the current ability of
/// [[msvc::constexpr]] evaulation.
struct MSConstexprContextRAII {
CallStackFrame &Frame;
bool OldValue;
explicit MSConstexprContextRAII(CallStackFrame &Frame, bool Value)
: Frame(Frame), OldValue(Frame.CanEvalMSConstexpr) {
Frame.CanEvalMSConstexpr = Value;
}

~MSConstexprContextRAII() { Frame.CanEvalMSConstexpr = OldValue; }
};
}

static bool HandleDestruction(EvalInfo &Info, const Expr *E,
Expand Down Expand Up @@ -5546,11 +5563,14 @@ static EvalStmtResult EvaluateStmt(StmtResult &Result, EvalInfo &Info,
case Stmt::LabelStmtClass:
return EvaluateStmt(Result, Info, cast<LabelStmt>(S)->getSubStmt(), Case);

case Stmt::AttributedStmtClass:
// As a general principle, C++11 attributes can be ignored without
// any semantic impact.
return EvaluateStmt(Result, Info, cast<AttributedStmt>(S)->getSubStmt(),
Case);
case Stmt::AttributedStmtClass: {
const auto *AS = cast<AttributedStmt>(S);
const auto *SS = AS->getSubStmt();
MSConstexprContextRAII ConstexprContext(
*Info.CurrentCall, hasSpecificAttr<MSConstexprAttr>(AS->getAttrs()) &&
isa<ReturnStmt>(SS));
return EvaluateStmt(Result, Info, SS, Case);
}

case Stmt::CaseStmtClass:
case Stmt::DefaultStmtClass:
Expand Down Expand Up @@ -5621,7 +5641,9 @@ static bool CheckConstexprFunction(EvalInfo &Info, SourceLocation CallLoc,
}

// Can we evaluate this function call?
if (Definition && Definition->isConstexpr() && Body)
if (Definition && Body &&
(Definition->isConstexpr() || (Info.CurrentCall->CanEvalMSConstexpr &&
Definition->hasAttr<MSConstexprAttr>())))
return true;

if (Info.getLangOpts().CPlusPlus11) {
Expand Down Expand Up @@ -8492,14 +8514,24 @@ bool LValueExprEvaluator::VisitVarDecl(const Expr *E, const VarDecl *VD) {
return false;

if (auto *FD = Info.CurrentCall->LambdaCaptureFields.lookup(VD)) {
const auto *MD = cast<CXXMethodDecl>(Info.CurrentCall->Callee);

// Static lambda function call operators can't have captures. We already
// diagnosed this, so bail out here.
if (MD->isStatic()) {
assert(Info.CurrentCall->This == nullptr &&
"This should not be set for a static call operator");
return false;
}

// Start with 'Result' referring to the complete closure object...
if (auto *MD = cast<CXXMethodDecl>(Info.CurrentCall->Callee);
MD->isExplicitObjectMemberFunction()) {
if (MD->isExplicitObjectMemberFunction()) {
APValue *RefValue =
Info.getParamSlot(Info.CurrentCall->Arguments, MD->getParamDecl(0));
Result.setFrom(Info.Ctx, *RefValue);
} else
Result = *Info.CurrentCall->This;

// ... then update it to refer to the field of the closure object
// that represents the capture.
if (!HandleLValueMember(Info, E, Result, FD))
Expand Down
5 changes: 5 additions & 0 deletions clang/lib/AST/Interp/ByteCodeEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@ ByteCodeEmitter::compileFunc(const FunctionDecl *FuncDecl) {
MD->getParent()->getCaptureFields(LC, LTC);

for (auto Cap : LC) {
// Static lambdas cannot have any captures. If this one does,
// it has already been diagnosed and we can only ignore it.
if (MD->isStatic())
return nullptr;

unsigned Offset = R->getField(Cap.second)->Offset;
this->LambdaCaptures[Cap.first] = {
Offset, Cap.second->getType()->isReferenceType()};
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/AST/Interp/Context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ bool Context::Run(State &Parent, const Function *Func, APValue &Result) {
}

// State gets destroyed here, so the Stk.clear() below doesn't accidentally
// remove values the State's destructor might accedd.
// remove values the State's destructor might access.
}

Stk.clear();
Expand Down
12 changes: 4 additions & 8 deletions clang/lib/AST/Interp/IntegralAP.h
Original file line number Diff line number Diff line change
Expand Up @@ -182,17 +182,13 @@ template <bool Signed> class IntegralAP final {
}

static bool increment(IntegralAP A, IntegralAP *R) {
// FIXME: Implement.
assert(false);
*R = IntegralAP(A.V - 1);
return false;
IntegralAP<Signed> One(1, A.bitWidth());
return add(A, One, A.bitWidth() + 1, R);
}

static bool decrement(IntegralAP A, IntegralAP *R) {
// FIXME: Implement.
assert(false);
*R = IntegralAP(A.V - 1);
return false;
IntegralAP<Signed> One(1, A.bitWidth());
return sub(A, One, A.bitWidth() + 1, R);
}

static bool add(IntegralAP A, IntegralAP B, unsigned OpBits, IntegralAP *R) {
Expand Down
12 changes: 9 additions & 3 deletions clang/lib/AST/Interp/Interp.h
Original file line number Diff line number Diff line change
Expand Up @@ -1619,7 +1619,11 @@ bool CastFloatingIntegral(InterpState &S, CodePtr OpPC) {
QualType Type = E->getType();

S.CCEDiag(E, diag::note_constexpr_overflow) << F.getAPFloat() << Type;
return S.noteUndefinedBehavior();
if (S.noteUndefinedBehavior()) {
S.Stk.push<T>(T(Result));
return true;
}
return false;
}

S.Stk.push<T>(T(Result));
Expand Down Expand Up @@ -1822,10 +1826,12 @@ inline bool ArrayElemPtr(InterpState &S, CodePtr OpPC) {
/// Just takes a pointer and checks if its' an incomplete
/// array type.
inline bool ArrayDecay(InterpState &S, CodePtr OpPC) {
const Pointer &Ptr = S.Stk.peek<Pointer>();
const Pointer &Ptr = S.Stk.pop<Pointer>();

if (!Ptr.isUnknownSizeArray())
if (!Ptr.isUnknownSizeArray()) {
S.Stk.push<Pointer>(Ptr.atIndex(0));
return true;
}

const SourceInfo &E = S.Current->getSource(OpPC);
S.FFDiag(E, diag::note_constexpr_unsupported_unsized_array);
Expand Down
67 changes: 67 additions & 0 deletions clang/lib/AST/Interp/InterpBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,40 @@ static bool interp__builtin_expect(InterpState &S, CodePtr OpPC,
return true;
}

/// rotateleft(value, amount)
static bool interp__builtin_rotate(InterpState &S, CodePtr OpPC,
const InterpFrame *Frame,
const Function *Func, const CallExpr *Call,
bool Right) {
PrimType ArgT = *S.getContext().classify(Call->getArg(0)->getType());
assert(ArgT == *S.getContext().classify(Call->getArg(1)->getType()));

APSInt Amount = peekToAPSInt(S.Stk, ArgT);
APSInt Value = peekToAPSInt(S.Stk, ArgT, align(primSize(ArgT)) * 2);

APSInt Result;
if (Right)
Result = APSInt(Value.rotr(Amount.urem(Value.getBitWidth())),
/*IsUnsigned=*/true);
else // Left.
Result = APSInt(Value.rotl(Amount.urem(Value.getBitWidth())),
/*IsUnsigned=*/true);

pushAPSInt(S, Result);
return true;
}

static bool interp__builtin_ffs(InterpState &S, CodePtr OpPC,
const InterpFrame *Frame, const Function *Func,
const CallExpr *Call) {
PrimType ArgT = *S.getContext().classify(Call->getArg(0)->getType());
APSInt Value = peekToAPSInt(S.Stk, ArgT);

uint64_t N = Value.countr_zero();
pushInt(S, N == Value.getBitWidth() ? 0 : N + 1);
return true;
}

bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
const CallExpr *Call) {
InterpFrame *Frame = S.Current;
Expand Down Expand Up @@ -754,6 +788,39 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
return false;
break;

case Builtin::BI__builtin_rotateleft8:
case Builtin::BI__builtin_rotateleft16:
case Builtin::BI__builtin_rotateleft32:
case Builtin::BI__builtin_rotateleft64:
case Builtin::BI_rotl8: // Microsoft variants of rotate left
case Builtin::BI_rotl16:
case Builtin::BI_rotl:
case Builtin::BI_lrotl:
case Builtin::BI_rotl64:
if (!interp__builtin_rotate(S, OpPC, Frame, F, Call, /*Right=*/false))
return false;
break;

case Builtin::BI__builtin_rotateright8:
case Builtin::BI__builtin_rotateright16:
case Builtin::BI__builtin_rotateright32:
case Builtin::BI__builtin_rotateright64:
case Builtin::BI_rotr8: // Microsoft variants of rotate right
case Builtin::BI_rotr16:
case Builtin::BI_rotr:
case Builtin::BI_lrotr:
case Builtin::BI_rotr64:
if (!interp__builtin_rotate(S, OpPC, Frame, F, Call, /*Right=*/true))
return false;
break;

case Builtin::BI__builtin_ffs:
case Builtin::BI__builtin_ffsl:
case Builtin::BI__builtin_ffsll:
if (!interp__builtin_ffs(S, OpPC, Frame, F, Call))
return false;
break;

default:
return false;
}
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/AST/Interp/InterpFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ Pointer InterpFrame::getParamPointer(unsigned Off) {
SourceInfo InterpFrame::getSource(CodePtr PC) const {
// Implicitly created functions don't have any code we could point at,
// so return the call site.
if (Func && Func->getDecl()->isImplicit() && Caller)
if (Func && (!Func->hasBody() || Func->getDecl()->isImplicit()) && Caller)
return Caller->getSource(RetPC);

return S.getSource(Func, PC);
Expand All @@ -243,7 +243,7 @@ SourceLocation InterpFrame::getLocation(CodePtr PC) const {
}

SourceRange InterpFrame::getRange(CodePtr PC) const {
if (Func && Func->getDecl()->isImplicit() && Caller)
if (Func && (!Func->hasBody() || Func->getDecl()->isImplicit()) && Caller)
return Caller->getRange(RetPC);

return S.getRange(Func, PC);
Expand Down
8 changes: 4 additions & 4 deletions clang/lib/AST/MicrosoftMangle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3809,14 +3809,14 @@ void MicrosoftMangleContextImpl::mangleCXXRTTICompleteObjectLocator(
llvm::raw_svector_ostream Stream(VFTableMangling);
mangleCXXVFTable(Derived, BasePath, Stream);

if (VFTableMangling.startswith("??@")) {
assert(VFTableMangling.endswith("@"));
if (VFTableMangling.starts_with("??@")) {
assert(VFTableMangling.ends_with("@"));
Out << VFTableMangling << "??_R4@";
return;
}

assert(VFTableMangling.startswith("??_7") ||
VFTableMangling.startswith("??_S"));
assert(VFTableMangling.starts_with("??_7") ||
VFTableMangling.starts_with("??_S"));

Out << "??_R4" << VFTableMangling.str().drop_front(4);
}
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/AST/RecordLayoutBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2942,8 +2942,8 @@ void MicrosoftRecordLayoutBuilder::layoutNonVirtualBase(
}

if (!FoundBase) {
if (MDCUsesEBO && BaseDecl->isEmpty()) {
assert(BaseLayout.getNonVirtualSize() == CharUnits::Zero());
if (MDCUsesEBO && BaseDecl->isEmpty() &&
(BaseLayout.getNonVirtualSize() == CharUnits::Zero())) {
BaseOffset = CharUnits::Zero();
} else {
// Otherwise, lay the base out at the end of the MDC.
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Analysis/UninitializedValues.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ static bool isTrackedVar(const VarDecl *vd, const DeclContext *dc) {
QualType ty = vd->getType();
if (const auto *RD = ty->getAsRecordDecl())
return recordIsNotEmpty(RD);
return ty->isScalarType() || ty->isVectorType() || ty->isRVVType();
return ty->isScalarType() || ty->isVectorType() || ty->isRVVSizelessBuiltinType();
}
return false;
}
Expand Down
101 changes: 94 additions & 7 deletions clang/lib/Analysis/UnsafeBufferUsage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1028,6 +1028,46 @@ class UPCPreIncrementGadget : public FixableGadget {
}
};

// Representing a pointer type expression of the form `Ptr += n` in an
// Unspecified Untyped Context (UUC):
class UUCAddAssignGadget : public FixableGadget {
private:
static constexpr const char *const UUCAddAssignTag =
"PointerAddAssignUnderUUC";
static constexpr const char *const OffsetTag = "Offset";

const BinaryOperator *Node; // the `Ptr += n` node
const Expr *Offset = nullptr;

public:
UUCAddAssignGadget(const MatchFinder::MatchResult &Result)
: FixableGadget(Kind::UUCAddAssign),
Node(Result.Nodes.getNodeAs<BinaryOperator>(UUCAddAssignTag)),
Offset(Result.Nodes.getNodeAs<Expr>(OffsetTag)) {
assert(Node != nullptr && "Expecting a non-null matching result");
}

static bool classof(const Gadget *G) {
return G->getKind() == Kind::UUCAddAssign;
}

static Matcher matcher() {
return stmt(isInUnspecifiedUntypedContext(expr(ignoringImpCasts(
binaryOperator(hasOperatorName("+="),
hasLHS(declRefExpr(toSupportedVariable())),
hasRHS(expr().bind(OffsetTag)))
.bind(UUCAddAssignTag)))));
}

virtual std::optional<FixItList> getFixits(const Strategy &S) const override;

virtual const Stmt *getBaseStmt() const override { return Node; }

virtual DeclUseList getClaimedVarUseSites() const override {
return {dyn_cast<DeclRefExpr>(Node->getLHS())};
}
};

// Representing a fixable expression of the form `*(ptr + 123)` or `*(123 +
// ptr)`:
class DerefSimplePtrArithFixableGadget : public FixableGadget {
Expand Down Expand Up @@ -1312,21 +1352,29 @@ PointerInitGadget::getFixits(const Strategy &S) const {
return std::nullopt;
}

static bool isNonNegativeIntegerExpr(const Expr *Expr, const VarDecl *VD,
const ASTContext &Ctx) {
if (auto ConstVal = Expr->getIntegerConstantExpr(Ctx)) {
if (ConstVal->isNegative())
return false;
} else if (!Expr->getType()->isUnsignedIntegerType())
return false;
return true;
}

std::optional<FixItList>
ULCArraySubscriptGadget::getFixits(const Strategy &S) const {
if (const auto *DRE =
dyn_cast<DeclRefExpr>(Node->getBase()->IgnoreImpCasts()))
if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) {
switch (S.lookup(VD)) {
case Strategy::Kind::Span: {

// If the index has a negative constant value, we give up as no valid
// fix-it can be generated:
const ASTContext &Ctx = // FIXME: we need ASTContext to be passed in!
VD->getASTContext();
if (auto ConstVal = Node->getIdx()->getIntegerConstantExpr(Ctx)) {
if (ConstVal->isNegative())
return std::nullopt;
} else if (!Node->getIdx()->getType()->isUnsignedIntegerType())
if (!isNonNegativeIntegerExpr(Node->getIdx(), VD, Ctx))
return std::nullopt;
// no-op is a good fix-it, otherwise
return FixItList{};
Expand Down Expand Up @@ -1405,10 +1453,8 @@ static std::optional<SourceLocation> getPastLoc(const NodeTy *Node,
const LangOptions &LangOpts) {
SourceLocation Loc =
Lexer::getLocForEndOfToken(Node->getEndLoc(), 0, SM, LangOpts);

if (Loc.isValid())
return Loc;

return std::nullopt;
}

Expand Down Expand Up @@ -1488,7 +1534,7 @@ static bool hasUnsupportedSpecifiers(const VarDecl *VD,
// returned by this function is the last location of the last token.
static SourceRange getSourceRangeToTokenEnd(const Decl *D,
const SourceManager &SM,
LangOptions LangOpts) {
const LangOptions &LangOpts) {
SourceLocation Begin = D->getBeginLoc();
SourceLocation
End = // `D->getEndLoc` should always return the starting location of the
Expand Down Expand Up @@ -1766,6 +1812,47 @@ fixUPCAddressofArraySubscriptWithSpan(const UnaryOperator *Node) {
FixItHint::CreateReplacement(Node->getSourceRange(), SS.str())};
}

std::optional<FixItList>
UUCAddAssignGadget::getFixits(const Strategy &S) const {
DeclUseList DREs = getClaimedVarUseSites();

if (DREs.size() != 1)
return std::nullopt; // In cases of `Ptr += n` where `Ptr` is not a DRE, we
// give up
if (const VarDecl *VD = dyn_cast<VarDecl>(DREs.front()->getDecl())) {
if (S.lookup(VD) == Strategy::Kind::Span) {
FixItList Fixes;

const Stmt *AddAssignNode = getBaseStmt();
StringRef varName = VD->getName();
const ASTContext &Ctx = VD->getASTContext();

if (!isNonNegativeIntegerExpr(Offset, VD, Ctx))
return std::nullopt;

// To transform UUC(p += n) to UUC(p = p.subspan(..)):
bool NotParenExpr =
(Offset->IgnoreParens()->getBeginLoc() == Offset->getBeginLoc());
std::string SS = varName.str() + " = " + varName.str() + ".subspan";
if (NotParenExpr)
SS += "(";

std::optional<SourceLocation> AddAssignLocation = getEndCharLoc(
AddAssignNode, Ctx.getSourceManager(), Ctx.getLangOpts());
if (!AddAssignLocation)
return std::nullopt;

Fixes.push_back(FixItHint::CreateReplacement(
SourceRange(AddAssignNode->getBeginLoc(), Node->getOperatorLoc()),
SS));
if (NotParenExpr)
Fixes.push_back(FixItHint::CreateInsertion(
Offset->getEndLoc().getLocWithOffset(1), ")"));
return Fixes;
}
}
return std::nullopt; // Not in the cases that we can handle for now, give up.
}

std::optional<FixItList> UPCPreIncrementGadget::getFixits(const Strategy &S) const {
DeclUseList DREs = getClaimedVarUseSites();
Expand Down
5 changes: 5 additions & 0 deletions clang/lib/Basic/Cuda.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ static const CudaVersionMapEntry CudaNameVersionMap[] = {
CUDA_ENTRY(11, 8),
CUDA_ENTRY(12, 0),
CUDA_ENTRY(12, 1),
CUDA_ENTRY(12, 2),
CUDA_ENTRY(12, 3),
{"", CudaVersion::NEW, llvm::VersionTuple(std::numeric_limits<int>::max())},
{"unknown", CudaVersion::UNKNOWN, {}} // End of list tombstone.
};
Expand Down Expand Up @@ -93,6 +95,7 @@ static const CudaArchToStringMap arch_names[] = {
SM(87), // Jetson/Drive AGX Orin
SM(89), // Ada Lovelace
SM(90), // Hopper
SM(90a), // Hopper
GFX(600), // gfx600
GFX(601), // gfx601
GFX(602), // gfx602
Expand Down Expand Up @@ -209,6 +212,8 @@ CudaVersion MinVersionForCudaArch(CudaArch A) {
case CudaArch::SM_89:
case CudaArch::SM_90:
return CudaVersion::CUDA_118;
case CudaArch::SM_90a:
return CudaVersion::CUDA_120;
default:
llvm_unreachable("invalid enum");
}
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Basic/Module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ static bool isPlatformEnvironment(const TargetInfo &Target, StringRef Feature) {
// where both are valid examples of the same platform+environment but in the
// variant (2) the simulator is hardcoded as part of the platform name. Both
// forms above should match for "iossimulator" requirement.
if (Target.getTriple().isOSDarwin() && PlatformEnv.endswith("simulator"))
if (Target.getTriple().isOSDarwin() && PlatformEnv.ends_with("simulator"))
return PlatformEnv == Feature || CmpPlatformEnv(PlatformEnv, Feature);

return PlatformEnv == Feature;
Expand Down
3 changes: 2 additions & 1 deletion clang/lib/Basic/Targets/AArch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -574,11 +574,12 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts,
else if (*ArchInfo == llvm::AArch64::ARMV9_5A)
getTargetDefinesARMV95A(Opts, Builder);

// All of the __sync_(bool|val)_compare_and_swap_(1|2|4|8) builtins work.
// All of the __sync_(bool|val)_compare_and_swap_(1|2|4|8|16) builtins work.
Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16");

// Allow detection of fast FMA support.
Builder.defineMacro("__FP_FAST_FMA", "1");
Expand Down
80 changes: 40 additions & 40 deletions clang/lib/Basic/Targets/AMDGPU.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,50 +37,50 @@ static const char *const DataLayoutStringAMDGCN =
"-ni:7:8";

const LangASMap AMDGPUTargetInfo::AMDGPUDefIsGenMap = {
Generic, // Default
Global, // opencl_global
Local, // opencl_local
Constant, // opencl_constant
Private, // opencl_private
Generic, // opencl_generic
Global, // opencl_global_device
Global, // opencl_global_host
Global, // cuda_device
Constant, // cuda_constant
Local, // cuda_shared
Global, // sycl_global
Global, // sycl_global_device
Global, // sycl_global_host
Local, // sycl_local
Private, // sycl_private
Generic, // ptr32_sptr
Generic, // ptr32_uptr
Generic, // ptr64
Generic, // hlsl_groupshared
llvm::AMDGPUAS::FLAT_ADDRESS, // Default
llvm::AMDGPUAS::GLOBAL_ADDRESS, // opencl_global
llvm::AMDGPUAS::LOCAL_ADDRESS, // opencl_local
llvm::AMDGPUAS::CONSTANT_ADDRESS, // opencl_constant
llvm::AMDGPUAS::PRIVATE_ADDRESS, // opencl_private
llvm::AMDGPUAS::FLAT_ADDRESS, // opencl_generic
llvm::AMDGPUAS::GLOBAL_ADDRESS, // opencl_global_device
llvm::AMDGPUAS::GLOBAL_ADDRESS, // opencl_global_host
llvm::AMDGPUAS::GLOBAL_ADDRESS, // cuda_device
llvm::AMDGPUAS::CONSTANT_ADDRESS, // cuda_constant
llvm::AMDGPUAS::LOCAL_ADDRESS, // cuda_shared
llvm::AMDGPUAS::GLOBAL_ADDRESS, // sycl_global
llvm::AMDGPUAS::GLOBAL_ADDRESS, // sycl_global_device
llvm::AMDGPUAS::GLOBAL_ADDRESS, // sycl_global_host
llvm::AMDGPUAS::LOCAL_ADDRESS, // sycl_local
llvm::AMDGPUAS::PRIVATE_ADDRESS, // sycl_private
llvm::AMDGPUAS::FLAT_ADDRESS, // ptr32_sptr
llvm::AMDGPUAS::FLAT_ADDRESS, // ptr32_uptr
llvm::AMDGPUAS::FLAT_ADDRESS, // ptr64
llvm::AMDGPUAS::FLAT_ADDRESS, // hlsl_groupshared
};

const LangASMap AMDGPUTargetInfo::AMDGPUDefIsPrivMap = {
Private, // Default
Global, // opencl_global
Local, // opencl_local
Constant, // opencl_constant
Private, // opencl_private
Generic, // opencl_generic
Global, // opencl_global_device
Global, // opencl_global_host
Global, // cuda_device
Constant, // cuda_constant
Local, // cuda_shared
llvm::AMDGPUAS::PRIVATE_ADDRESS, // Default
llvm::AMDGPUAS::GLOBAL_ADDRESS, // opencl_global
llvm::AMDGPUAS::LOCAL_ADDRESS, // opencl_local
llvm::AMDGPUAS::CONSTANT_ADDRESS, // opencl_constant
llvm::AMDGPUAS::PRIVATE_ADDRESS, // opencl_private
llvm::AMDGPUAS::FLAT_ADDRESS, // opencl_generic
llvm::AMDGPUAS::GLOBAL_ADDRESS, // opencl_global_device
llvm::AMDGPUAS::GLOBAL_ADDRESS, // opencl_global_host
llvm::AMDGPUAS::GLOBAL_ADDRESS, // cuda_device
llvm::AMDGPUAS::CONSTANT_ADDRESS, // cuda_constant
llvm::AMDGPUAS::LOCAL_ADDRESS, // cuda_shared
// SYCL address space values for this map are dummy
Generic, // sycl_global
Generic, // sycl_global_device
Generic, // sycl_global_host
Generic, // sycl_local
Generic, // sycl_private
Generic, // ptr32_sptr
Generic, // ptr32_uptr
Generic, // ptr64
Generic, // hlsl_groupshared
llvm::AMDGPUAS::FLAT_ADDRESS, // sycl_global
llvm::AMDGPUAS::FLAT_ADDRESS, // sycl_global_device
llvm::AMDGPUAS::FLAT_ADDRESS, // sycl_global_host
llvm::AMDGPUAS::FLAT_ADDRESS, // sycl_local
llvm::AMDGPUAS::FLAT_ADDRESS, // sycl_private
llvm::AMDGPUAS::FLAT_ADDRESS, // ptr32_sptr
llvm::AMDGPUAS::FLAT_ADDRESS, // ptr32_uptr
llvm::AMDGPUAS::FLAT_ADDRESS, // ptr64
llvm::AMDGPUAS::FLAT_ADDRESS, // hlsl_groupshared

};
} // namespace targets
Expand Down
19 changes: 7 additions & 12 deletions clang/lib/Basic/Targets/AMDGPU.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/TargetOptions.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/Support/AMDGPUAddrSpace.h"
#include "llvm/Support/Compiler.h"
#include "llvm/TargetParser/TargetParser.h"
#include "llvm/TargetParser/Triple.h"
Expand All @@ -29,13 +30,6 @@ class LLVM_LIBRARY_VISIBILITY AMDGPUTargetInfo final : public TargetInfo {

static const char *const GCCRegNames[];

enum AddrSpace {
Generic = 0,
Global = 1,
Local = 3,
Constant = 4,
Private = 5
};
static const LangASMap AMDGPUDefIsGenMap;
static const LangASMap AMDGPUDefIsPrivMap;

Expand Down Expand Up @@ -106,7 +100,8 @@ class LLVM_LIBRARY_VISIBILITY AMDGPUTargetInfo final : public TargetInfo {
return 32;
unsigned TargetAS = getTargetAddressSpace(AS);

if (TargetAS == Private || TargetAS == Local)
if (TargetAS == llvm::AMDGPUAS::PRIVATE_ADDRESS ||
TargetAS == llvm::AMDGPUAS::LOCAL_ADDRESS)
return 32;

return 64;
Expand Down Expand Up @@ -376,7 +371,7 @@ class LLVM_LIBRARY_VISIBILITY AMDGPUTargetInfo final : public TargetInfo {
}

std::optional<LangAS> getConstantAddressSpace() const override {
return getLangASFromTargetAS(Constant);
return getLangASFromTargetAS(llvm::AMDGPUAS::CONSTANT_ADDRESS);
}

const llvm::omp::GV &getGridValue() const override {
Expand All @@ -392,7 +387,7 @@ class LLVM_LIBRARY_VISIBILITY AMDGPUTargetInfo final : public TargetInfo {

/// \returns Target specific vtbl ptr address space.
unsigned getVtblPtrAddressSpace() const override {
return static_cast<unsigned>(Constant);
return static_cast<unsigned>(llvm::AMDGPUAS::CONSTANT_ADDRESS);
}

/// \returns If a target requires an address within a target specific address
Expand All @@ -405,9 +400,9 @@ class LLVM_LIBRARY_VISIBILITY AMDGPUTargetInfo final : public TargetInfo {
getDWARFAddressSpace(unsigned AddressSpace) const override {
const unsigned DWARF_Private = 1;
const unsigned DWARF_Local = 2;
if (AddressSpace == Private) {
if (AddressSpace == llvm::AMDGPUAS::PRIVATE_ADDRESS) {
return DWARF_Private;
} else if (AddressSpace == Local) {
} else if (AddressSpace == llvm::AMDGPUAS::LOCAL_ADDRESS) {
return DWARF_Local;
} else {
return std::nullopt;
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/Basic/Targets/NVPTX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -262,11 +262,14 @@ void NVPTXTargetInfo::getTargetDefines(const LangOptions &Opts,
case CudaArch::SM_89:
return "890";
case CudaArch::SM_90:
case CudaArch::SM_90a:
return "900";
}
llvm_unreachable("unhandled CudaArch");
}();
Builder.defineMacro("__CUDA_ARCH__", CUDAArchCode);
if (GPU == CudaArch::SM_90a)
Builder.defineMacro("__CUDA_ARCH_FEAT_SM90_ALL", "1");
}
}

Expand Down
3 changes: 3 additions & 0 deletions clang/lib/Basic/Targets/OSTargets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,9 @@ static void addVisualCDefines(const LangOptions &Opts, MacroBuilder &Builder) {
else if (Opts.CPlusPlus14)
Builder.defineMacro("_MSVC_LANG", "201402L");
}

if (Opts.isCompatibleWithMSVC(LangOptions::MSVC2022_3))
Builder.defineMacro("_MSVC_CONSTEXPR_ATTRIBUTE");
}

if (Opts.MicrosoftExt) {
Expand Down
26 changes: 15 additions & 11 deletions clang/lib/Basic/Targets/RISCV.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ static unsigned getVersionValue(unsigned MajorVersion, unsigned MinorVersion) {
void RISCVTargetInfo::getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const {
Builder.defineMacro("__riscv");
bool Is64Bit = getTriple().getArch() == llvm::Triple::riscv64;
bool Is64Bit = getTriple().isRISCV64();
Builder.defineMacro("__riscv_xlen", Is64Bit ? "64" : "32");
StringRef CodeModel = getTargetOpts().CodeModel;
unsigned FLen = ISAInfo->getFLen();
Expand Down Expand Up @@ -281,7 +281,7 @@ bool RISCVTargetInfo::initFeatureMap(

unsigned XLen = 32;

if (getTriple().getArch() == llvm::Triple::riscv64) {
if (getTriple().isRISCV64()) {
Features["64bit"] = true;
XLen = 64;
} else {
Expand All @@ -304,11 +304,18 @@ bool RISCVTargetInfo::initFeatureMap(

// RISCVISAInfo makes implications for ISA features
std::vector<std::string> ImpliedFeatures = (*ParseResult)->toFeatureVector();
// Add non-ISA features like `relax` and `save-restore` back
for (const std::string &Feature : NewFeaturesVec)
if (!llvm::is_contained(ImpliedFeatures, Feature))
ImpliedFeatures.push_back(Feature);

// parseFeatures normalizes the feature set by dropping any explicit
// negatives, and non-extension features. We need to preserve the later
// for correctness and want to preserve the former for consistency.
for (auto &Feature : NewFeaturesVec) {
StringRef ExtName = Feature;
assert(ExtName.size() > 1 && (ExtName[0] == '+' || ExtName[0] == '-'));
ExtName = ExtName.drop_front(1); // Drop '+' or '-'
if (!llvm::is_contained(ImpliedFeatures, ("+" + ExtName).str()) &&
!llvm::is_contained(ImpliedFeatures, ("-" + ExtName).str()))
ImpliedFeatures.push_back(Feature);
}
return TargetInfo::initFeatureMap(Features, Diags, CPU, ImpliedFeatures);
}

Expand Down Expand Up @@ -336,7 +343,7 @@ RISCVTargetInfo::getVScaleRange(const LangOptions &LangOpts) const {

/// Return true if has this feature, need to sync with handleTargetFeatures.
bool RISCVTargetInfo::hasFeature(StringRef Feature) const {
bool Is64Bit = getTriple().getArch() == llvm::Triple::riscv64;
bool Is64Bit = getTriple().isRISCV64();
auto Result = llvm::StringSwitch<std::optional<bool>>(Feature)
.Case("riscv", true)
.Case("riscv32", !Is64Bit)
Expand All @@ -347,10 +354,7 @@ bool RISCVTargetInfo::hasFeature(StringRef Feature) const {
if (Result)
return *Result;

if (ISAInfo->isSupportedExtensionFeature(Feature))
return ISAInfo->hasExtension(Feature);

return false;
return ISAInfo->hasExtension(Feature);
}

/// Perform initialization based on the user configured set of features.
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CodeGen/BackendUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -982,7 +982,7 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
getInstrProfOptions(CodeGenOpts, LangOpts))
PB.registerPipelineStartEPCallback(
[Options](ModulePassManager &MPM, OptimizationLevel Level) {
MPM.addPass(InstrProfiling(*Options, false));
MPM.addPass(InstrProfilingLoweringPass(*Options, false));
});

// TODO: Consider passing the MemoryProfileOutput to the pass builder via
Expand Down
11 changes: 5 additions & 6 deletions clang/lib/CodeGen/CGCall.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "clang/AST/CanonicalType.h"
#include "clang/AST/GlobalDecl.h"
#include "clang/AST/Type.h"
#include "llvm/ADT/STLForwardCompat.h"
#include "llvm/IR/Value.h"

namespace llvm {
Expand Down Expand Up @@ -406,15 +407,13 @@ enum class FnInfoOpts {
};

inline FnInfoOpts operator|(FnInfoOpts A, FnInfoOpts B) {
return static_cast<FnInfoOpts>(
static_cast<std::underlying_type_t<FnInfoOpts>>(A) |
static_cast<std::underlying_type_t<FnInfoOpts>>(B));
return static_cast<FnInfoOpts>(llvm::to_underlying(A) |
llvm::to_underlying(B));
}

inline FnInfoOpts operator&(FnInfoOpts A, FnInfoOpts B) {
return static_cast<FnInfoOpts>(
static_cast<std::underlying_type_t<FnInfoOpts>>(A) &
static_cast<std::underlying_type_t<FnInfoOpts>>(B));
return static_cast<FnInfoOpts>(llvm::to_underlying(A) &
llvm::to_underlying(B));
}

inline FnInfoOpts operator|=(FnInfoOpts A, FnInfoOpts B) {
Expand Down
10 changes: 6 additions & 4 deletions clang/lib/CodeGen/CGDebugInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -554,14 +554,16 @@ void CGDebugInfo::CreateCompileUnit() {
// If the main file name provided is identical to the input file name, and
// if the input file is a preprocessed source, use the module name for
// debug info. The module name comes from the name specified in the first
// linemarker if the input is a preprocessed source.
// linemarker if the input is a preprocessed source. In this case we don't
// know the content to compute a checksum.
if (MainFile->getName() == MainFileName &&
FrontendOptions::getInputKindForExtension(
MainFile->getName().rsplit('.').second)
.isPreprocessed())
.isPreprocessed()) {
MainFileName = CGM.getModule().getName().str();

CSKind = computeChecksum(SM.getMainFileID(), Checksum);
} else {
CSKind = computeChecksum(SM.getMainFileID(), Checksum);
}
}

llvm::dwarf::SourceLanguage LangTag;
Expand Down
166 changes: 134 additions & 32 deletions clang/lib/CodeGen/CGExprComplex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,10 @@ class ComplexExprEmitter
ComplexPairTy EmitBinSub(const BinOpInfo &Op);
ComplexPairTy EmitBinMul(const BinOpInfo &Op);
ComplexPairTy EmitBinDiv(const BinOpInfo &Op);
ComplexPairTy EmitAlgebraicDiv(llvm::Value *A, llvm::Value *B, llvm::Value *C,
llvm::Value *D);
ComplexPairTy EmitRangeReductionDiv(llvm::Value *A, llvm::Value *B,
llvm::Value *C, llvm::Value *D);

ComplexPairTy EmitComplexBinOpLibCall(StringRef LibCallName,
const BinOpInfo &Op);
Expand Down Expand Up @@ -781,6 +785,10 @@ ComplexPairTy ComplexExprEmitter::EmitBinMul(const BinOpInfo &Op) {
ResR = Builder.CreateFSub(AC, BD, "mul_r");
ResI = Builder.CreateFAdd(AD, BC, "mul_i");

if (Op.FPFeatures.getComplexRange() == LangOptions::CX_Limited ||
Op.FPFeatures.getComplexRange() == LangOptions::CX_Fortran)
return ComplexPairTy(ResR, ResI);

// Emit the test for the real part becoming NaN and create a branch to
// handle it. We test for NaN by comparing the number to itself.
Value *IsRNaN = Builder.CreateFCmpUNO(ResR, ResR, "isnan_cmp");
Expand Down Expand Up @@ -846,23 +854,139 @@ ComplexPairTy ComplexExprEmitter::EmitBinMul(const BinOpInfo &Op) {
return ComplexPairTy(ResR, ResI);
}

ComplexPairTy ComplexExprEmitter::EmitAlgebraicDiv(llvm::Value *LHSr,
llvm::Value *LHSi,
llvm::Value *RHSr,
llvm::Value *RHSi) {
// (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd))
llvm::Value *DSTr, *DSTi;

llvm::Value *AC = Builder.CreateFMul(LHSr, RHSr); // a*c
llvm::Value *BD = Builder.CreateFMul(LHSi, RHSi); // b*d
llvm::Value *ACpBD = Builder.CreateFAdd(AC, BD); // ac+bd

llvm::Value *CC = Builder.CreateFMul(RHSr, RHSr); // c*c
llvm::Value *DD = Builder.CreateFMul(RHSi, RHSi); // d*d
llvm::Value *CCpDD = Builder.CreateFAdd(CC, DD); // cc+dd

llvm::Value *BC = Builder.CreateFMul(LHSi, RHSr); // b*c
llvm::Value *AD = Builder.CreateFMul(LHSr, RHSi); // a*d
llvm::Value *BCmAD = Builder.CreateFSub(BC, AD); // bc-ad

DSTr = Builder.CreateFDiv(ACpBD, CCpDD);
DSTi = Builder.CreateFDiv(BCmAD, CCpDD);
return ComplexPairTy(DSTr, DSTi);
}

// EmitFAbs - Emit a call to @llvm.fabs.
static llvm::Value *EmitllvmFAbs(CodeGenFunction &CGF, llvm::Value *Value) {
llvm::Function *Func =
CGF.CGM.getIntrinsic(llvm::Intrinsic::fabs, Value->getType());
llvm::Value *Call = CGF.Builder.CreateCall(Func, Value);
return Call;
}

// EmitRangeReductionDiv - Implements Smith's algorithm for complex division.
// SMITH, R. L. Algorithm 116: Complex division. Commun. ACM 5, 8 (1962).
ComplexPairTy ComplexExprEmitter::EmitRangeReductionDiv(llvm::Value *LHSr,
llvm::Value *LHSi,
llvm::Value *RHSr,
llvm::Value *RHSi) {
// (a + ib) / (c + id) = (e + if)
llvm::Value *FAbsRHSr = EmitllvmFAbs(CGF, RHSr); // |c|
llvm::Value *FAbsRHSi = EmitllvmFAbs(CGF, RHSi); // |d|
// |c| >= |d|
llvm::Value *IsR = Builder.CreateFCmpUGT(FAbsRHSr, FAbsRHSi, "abs_cmp");

llvm::BasicBlock *TrueBB =
CGF.createBasicBlock("abs_rhsr_greater_or_equal_abs_rhsi");
llvm::BasicBlock *FalseBB =
CGF.createBasicBlock("abs_rhsr_less_than_abs_rhsi");
llvm::BasicBlock *ContBB = CGF.createBasicBlock("complex_div");
Builder.CreateCondBr(IsR, TrueBB, FalseBB);

CGF.EmitBlock(TrueBB);
// abs(c) >= abs(d)
// r = d/c
// tmp = c + rd
// e = (a + br)/tmp
// f = (b - ar)/tmp
llvm::Value *DdC = Builder.CreateFDiv(RHSi, RHSr); // r=d/c

llvm::Value *RD = Builder.CreateFMul(DdC, RHSi); // rd
llvm::Value *CpRD = Builder.CreateFAdd(RHSr, RD); // tmp=c+rd

llvm::Value *T3 = Builder.CreateFMul(LHSi, DdC); // br
llvm::Value *T4 = Builder.CreateFAdd(LHSr, T3); // a+br
llvm::Value *DSTTr = Builder.CreateFDiv(T4, CpRD); // (a+br)/tmp

llvm::Value *T5 = Builder.CreateFMul(LHSr, DdC); // ar
llvm::Value *T6 = Builder.CreateFSub(LHSi, T5); // b-ar
llvm::Value *DSTTi = Builder.CreateFDiv(T6, CpRD); // (b-ar)/tmp
Builder.CreateBr(ContBB);

CGF.EmitBlock(FalseBB);
// abs(c) < abs(d)
// r = c/d
// tmp = d + rc
// e = (ar + b)/tmp
// f = (br - a)/tmp
llvm::Value *CdD = Builder.CreateFDiv(RHSr, RHSi); // r=c/d

llvm::Value *RC = Builder.CreateFMul(CdD, RHSr); // rc
llvm::Value *DpRC = Builder.CreateFAdd(RHSi, RC); // tmp=d+rc

llvm::Value *T7 = Builder.CreateFMul(LHSr, RC); // ar
llvm::Value *T8 = Builder.CreateFAdd(T7, LHSi); // ar+b
llvm::Value *DSTFr = Builder.CreateFDiv(T8, DpRC); // (ar+b)/tmp

llvm::Value *T9 = Builder.CreateFMul(LHSi, CdD); // br
llvm::Value *T10 = Builder.CreateFSub(T9, LHSr); // br-a
llvm::Value *DSTFi = Builder.CreateFDiv(T10, DpRC); // (br-a)/tmp
Builder.CreateBr(ContBB);

// Phi together the computation paths.
CGF.EmitBlock(ContBB);
llvm::PHINode *VALr = Builder.CreatePHI(DSTTr->getType(), 2);
VALr->addIncoming(DSTTr, TrueBB);
VALr->addIncoming(DSTFr, FalseBB);
llvm::PHINode *VALi = Builder.CreatePHI(DSTTi->getType(), 2);
VALi->addIncoming(DSTTi, TrueBB);
VALi->addIncoming(DSTFi, FalseBB);
return ComplexPairTy(VALr, VALi);
}

// See C11 Annex G.5.1 for the semantics of multiplicative operators on complex
// typed values.
ComplexPairTy ComplexExprEmitter::EmitBinDiv(const BinOpInfo &Op) {
llvm::Value *LHSr = Op.LHS.first, *LHSi = Op.LHS.second;
llvm::Value *RHSr = Op.RHS.first, *RHSi = Op.RHS.second;

llvm::Value *DSTr, *DSTi;
if (LHSr->getType()->isFloatingPointTy()) {
// If we have a complex operand on the RHS and FastMath is not allowed, we
// delegate to a libcall to handle all of the complexities and minimize
// underflow/overflow cases. When FastMath is allowed we construct the
// divide inline using the same algorithm as for integer operands.
//
// FIXME: We would be able to avoid the libcall in many places if we
// supported imaginary types in addition to complex types.
CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op.FPFeatures);
if (RHSi && !CGF.getLangOpts().FastMath) {
if (!RHSi) {
assert(LHSi && "Can have at most one non-complex operand!");

DSTr = Builder.CreateFDiv(LHSr, RHSr);
DSTi = Builder.CreateFDiv(LHSi, RHSr);
return ComplexPairTy(DSTr, DSTi);
}
llvm::Value *OrigLHSi = LHSi;
if (!LHSi)
LHSi = llvm::Constant::getNullValue(RHSi->getType());
if (Op.FPFeatures.getComplexRange() == LangOptions::CX_Fortran)
return EmitRangeReductionDiv(LHSr, LHSi, RHSr, RHSi);
else if (Op.FPFeatures.getComplexRange() == LangOptions::CX_Limited)
return EmitAlgebraicDiv(LHSr, LHSi, RHSr, RHSi);
else if (!CGF.getLangOpts().FastMath) {
LHSi = OrigLHSi;
// If we have a complex operand on the RHS and FastMath is not allowed, we
// delegate to a libcall to handle all of the complexities and minimize
// underflow/overflow cases. When FastMath is allowed we construct the
// divide inline using the same algorithm as for integer operands.
//
// FIXME: We would be able to avoid the libcall in many places if we
// supported imaginary types in addition to complex types.
BinOpInfo LibCallOp = Op;
// If LHS was a real, supply a null imaginary part.
if (!LHSi)
Expand All @@ -884,30 +1008,8 @@ ComplexPairTy ComplexExprEmitter::EmitBinDiv(const BinOpInfo &Op) {
case llvm::Type::FP128TyID:
return EmitComplexBinOpLibCall("__divtc3", LibCallOp);
}
} else if (RHSi) {
if (!LHSi)
LHSi = llvm::Constant::getNullValue(RHSi->getType());

// (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd))
llvm::Value *AC = Builder.CreateFMul(LHSr, RHSr); // a*c
llvm::Value *BD = Builder.CreateFMul(LHSi, RHSi); // b*d
llvm::Value *ACpBD = Builder.CreateFAdd(AC, BD); // ac+bd

llvm::Value *CC = Builder.CreateFMul(RHSr, RHSr); // c*c
llvm::Value *DD = Builder.CreateFMul(RHSi, RHSi); // d*d
llvm::Value *CCpDD = Builder.CreateFAdd(CC, DD); // cc+dd

llvm::Value *BC = Builder.CreateFMul(LHSi, RHSr); // b*c
llvm::Value *AD = Builder.CreateFMul(LHSr, RHSi); // a*d
llvm::Value *BCmAD = Builder.CreateFSub(BC, AD); // bc-ad

DSTr = Builder.CreateFDiv(ACpBD, CCpDD);
DSTi = Builder.CreateFDiv(BCmAD, CCpDD);
} else {
assert(LHSi && "Can have at most one non-complex operand!");

DSTr = Builder.CreateFDiv(LHSr, RHSr);
DSTi = Builder.CreateFDiv(LHSi, RHSr);
return EmitAlgebraicDiv(LHSr, LHSi, RHSr, RHSi);
}
} else {
assert(Op.LHS.second && Op.RHS.second &&
Expand Down
9 changes: 6 additions & 3 deletions clang/lib/CodeGen/CGHLSLRuntime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,8 @@ void CGHLSLRuntime::finishCodeGen() {
: llvm::hlsl::ResourceKind::TBuffer;
std::string TyName =
Buf.Name.str() + (Buf.IsCBuffer ? ".cb." : ".tb.") + "ty";
addBufferResourceAnnotation(GV, TyName, RC, RK, Buf.Binding);
addBufferResourceAnnotation(GV, TyName, RC, RK, /*IsROV=*/false,
Buf.Binding);
}
}

Expand All @@ -196,6 +197,7 @@ void CGHLSLRuntime::addBufferResourceAnnotation(llvm::GlobalVariable *GV,
llvm::StringRef TyName,
llvm::hlsl::ResourceClass RC,
llvm::hlsl::ResourceKind RK,
bool IsROV,
BufferResBinding &Binding) {
llvm::Module &M = CGM.getModule();

Expand All @@ -219,7 +221,7 @@ void CGHLSLRuntime::addBufferResourceAnnotation(llvm::GlobalVariable *GV,
"ResourceMD must have been set by the switch above.");

llvm::hlsl::FrontendResource Res(
GV, TyName, RK, Binding.Reg.value_or(UINT_MAX), Binding.Space);
GV, TyName, RK, IsROV, Binding.Reg.value_or(UINT_MAX), Binding.Space);
ResourceMD->addOperand(Res.getMetadata());
}

Expand All @@ -236,10 +238,11 @@ void CGHLSLRuntime::annotateHLSLResource(const VarDecl *D, GlobalVariable *GV) {

llvm::hlsl::ResourceClass RC = Attr->getResourceClass();
llvm::hlsl::ResourceKind RK = Attr->getResourceKind();
bool IsROV = Attr->getIsROV();

QualType QT(Ty, 0);
BufferResBinding Binding(D->getAttr<HLSLResourceBindingAttr>());
addBufferResourceAnnotation(GV, QT.getAsString(), RC, RK, Binding);
addBufferResourceAnnotation(GV, QT.getAsString(), RC, RK, IsROV, Binding);
}

CGHLSLRuntime::BufferResBinding::BufferResBinding(
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CodeGen/CGHLSLRuntime.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ class CGHLSLRuntime {
void addBufferResourceAnnotation(llvm::GlobalVariable *GV,
llvm::StringRef TyName,
llvm::hlsl::ResourceClass RC,
llvm::hlsl::ResourceKind RK,
llvm::hlsl::ResourceKind RK, bool IsROV,
BufferResBinding &Binding);
void addConstant(VarDecl *D, Buffer &CB);
void addBufferDecls(const DeclContext *DC, Buffer &CB);
Expand Down
1 change: 1 addition & 0 deletions clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3483,6 +3483,7 @@ void CGOpenMPRuntimeGPU::processRequiresDirective(
case CudaArch::SM_87:
case CudaArch::SM_89:
case CudaArch::SM_90:
case CudaArch::SM_90a:
case CudaArch::GFX600:
case CudaArch::GFX601:
case CudaArch::GFX602:
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CrossTU/CrossTranslationUnit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -551,7 +551,7 @@ CrossTranslationUnitContext::ASTLoader::load(StringRef Identifier) {
// Normalize by removing relative path components.
llvm::sys::path::remove_dots(Path, /*remove_dot_dot*/ true, PathStyle);

if (Path.endswith(".ast"))
if (Path.ends_with(".ast"))
return loadFromDump(Path);
else
return loadFromSource(Path);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
#include "llvm/Support/AlignOf.h"
#include "llvm/Support/Errno.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/Path.h"
#include <atomic>
#include <condition_variable>
Expand All @@ -25,6 +24,7 @@
#include <vector>

#include <fcntl.h>
#include <limits.h>
#include <optional>
#include <sys/epoll.h>
#include <sys/inotify.h>
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Driver/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1522,7 +1522,7 @@ bool Driver::getCrashDiagnosticFile(StringRef ReproCrashFilename,
// (or /Library/Logs/DiagnosticReports for root) and has the filename pattern
// clang-<VERSION>_<YYYY-MM-DD-HHMMSS>_<hostname>.crash.
path::home_directory(CrashDiagDir);
if (CrashDiagDir.startswith("/var/root"))
if (CrashDiagDir.starts_with("/var/root"))
CrashDiagDir = "/";
path::append(CrashDiagDir, "Library/Logs/DiagnosticReports");
int PID =
Expand Down
9 changes: 2 additions & 7 deletions clang/lib/Driver/ToolChains/Arch/RISCV.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,13 +171,8 @@ void riscv::getRISCVTargetFeatures(const Driver &D, const llvm::Triple &Triple,
Features.push_back("-save-restore");

// -mno-unaligned-access is default, unless -munaligned-access is specified.
if (const Arg *A = Args.getLastArg(options::OPT_munaligned_access,
options::OPT_mno_unaligned_access)) {
if (A->getOption().matches(options::OPT_munaligned_access))
Features.push_back("+fast-unaligned-access");
else
Features.push_back("-fast-unaligned-access");
}
AddTargetFeature(Args, Features, options::OPT_munaligned_access,
options::OPT_mno_unaligned_access, "fast-unaligned-access");

// Now add any that the user explicitly requested on the command line,
// which may override the defaults.
Expand Down
Loading