Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ template <typename T> class vector {
public:
using iterator = T *;
using const_iterator = const T *;
using reverse_iterator = T*;
using reverse_const_iterator = const T*;
using reverse_iterator = T *;
using reverse_const_iterator = const T *;

constexpr const_iterator begin() const;
constexpr const_iterator end() const;
Expand Down Expand Up @@ -72,8 +72,8 @@ template <typename Container> constexpr auto crend(const Container &Cont) {
return Cont.crend();
}
// Find
template< class InputIt, class T >
InputIt find( InputIt first, InputIt last, const T& value );
template <class InputIt, class T>
InputIt find(InputIt first, InputIt last, const T &value);

// Reverse
template <typename Iter> void reverse(Iter begin, Iter end);
Expand All @@ -82,6 +82,7 @@ template <typename Iter> void reverse(Iter begin, Iter end);
template <class InputIt1, class InputIt2>
bool includes(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2);

inline namespace _V1 {
// IsPermutation
template <class ForwardIt1, class ForwardIt2>
bool is_permutation(ForwardIt1 first1, ForwardIt1 last1, ForwardIt2 first2);
Expand All @@ -97,9 +98,10 @@ template <class InputIt1, class InputIt2>
bool equal(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2);

template <class InputIt1, class InputIt2, class BinaryPred>
bool equal(InputIt1 first1, InputIt1 last1,
InputIt2 first2, InputIt2 last2, BinaryPred p) {
// Need a definition to suppress undefined_internal_type when invoked with lambda
bool equal(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2,
BinaryPred p) {
// Need a definition to suppress undefined_internal_type when invoked with
// lambda
return true;
}

Expand All @@ -108,6 +110,7 @@ void iota(ForwardIt first, ForwardIt last, T value);

template <class ForwardIt>
ForwardIt rotate(ForwardIt first, ForwardIt middle, ForwardIt last);
} // namespace _V1

} // namespace std

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// RUN: %check_clang_tidy %s readability-non-const-parameter %t

static int f();

int f(p)
int *p;
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: pointer parameter 'p' can be pointer to const [readability-non-const-parameter]
// CHECK-FIXES: {{^}} const int *p;{{$}}
{
return *p;
}
10 changes: 8 additions & 2 deletions clang/cmake/caches/Fuchsia-stage2.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ foreach(target armv6m-unknown-eabi;armv7m-unknown-eabi;armv8m.main-unknown-eabi)
foreach(lang C;CXX;ASM)
set(BUILTINS_${target}_CMAKE_${lang}_local_flags "--target=${target} -mthumb")
if(${target} STREQUAL "armv8m.main-unknown-eabi")
set(BUILTINS_${target}_CMAKE_${lang}_local_flags "${BUILTINS_${target}_CMAKE_${lang}_local_flags} -mfloat-abi=hard -march=armv8m.main+fp+dsp -mcpu=cortex-m33" CACHE STRING "")
set(BUILTINS_${target}_CMAKE_${lang}_local_flags "${BUILTINS_${target}_CMAKE_${lang}_local_flags} -mfloat-abi=softfp -march=armv8m.main+fp+dsp -mcpu=cortex-m33" CACHE STRING "")
endif()
set(BUILTINS_${target}_CMAKE_${lang}_FLAGS "${BUILTINS_${target}_CMAKE_${lang}_local_flags}" CACHE STRING "")
endforeach()
Expand All @@ -327,13 +327,18 @@ foreach(target armv6m-unknown-eabi;armv7m-unknown-eabi;armv8m.main-unknown-eabi)
foreach(lang C;CXX;ASM)
# TODO: The preprocessor defines workaround various issues in libc and libc++ integration.
# These should be addressed and removed over time.
set(RUNTIMES_${target}_CMAKE_${lang}_FLAGS "--target=${target} -mthumb -Wno-atomic-alignment \"-Dvfprintf(stream, format, vlist)=vprintf(format, vlist)\" \"-Dfprintf(stream, format, ...)=printf(format)\" \"-Dtimeval=struct timeval{int tv_sec; int tv_usec;}\" \"-Dgettimeofday(tv, tz)\" -D_LIBCPP_PRINT=1" CACHE STRING "")
set(RUNTIMES_${target}_CMAKE_${lang}_local_flags "--target=${target} -mthumb -Wno-atomic-alignment \"-Dvfprintf(stream, format, vlist)=vprintf(format, vlist)\" \"-Dfprintf(stream, format, ...)=printf(format)\" \"-Dtimeval=struct timeval{int tv_sec; int tv_usec;}\" \"-Dgettimeofday(tv, tz)\" -D_LIBCPP_PRINT=1")
if(${target} STREQUAL "armv8m.main-unknown-eabi")
set(RUNTIMES_${target}_CMAKE_${lang}_local_flags "${RUNTIMES_${target}_CMAKE_${lang}_local_flags} -mfloat-abi=softfp -march=armv8m.main+fp+dsp -mcpu=cortex-m33" CACHE STRING "")
endif()
set(RUNTIMES_${target}_CMAKE_${lang}_FLAGS "${RUNTIMES_${target}_CMAKE_${lang}_local_flags}" CACHE STRING "")
endforeach()
foreach(type SHARED;MODULE;EXE)
set(RUNTIMES_${target}_CMAKE_${type}_LINKER_FLAGS "-fuse-ld=lld" CACHE STRING "")
endforeach()
set(RUNTIMES_${target}_LLVM_LIBC_FULL_BUILD ON CACHE BOOL "")
set(RUNTIMES_${target}_LIBC_ENABLE_USE_BY_CLANG ON CACHE BOOL "")
set(RUNTIMES_${target}_LIBC_USE_NEW_HEADER_GEN OFF CACHE BOOL "")
set(RUNTIMES_${target}_LIBCXX_ABI_VERSION 2 CACHE STRING "")
set(RUNTIMES_${target}_LIBCXX_CXX_ABI none CACHE STRING "")
set(RUNTIMES_${target}_LIBCXX_ENABLE_SHARED OFF CACHE BOOL "")
Expand Down Expand Up @@ -385,6 +390,7 @@ foreach(target riscv32-unknown-elf)
endforeach()
set(RUNTIMES_${target}_LLVM_LIBC_FULL_BUILD ON CACHE BOOL "")
set(RUNTIMES_${target}_LIBC_ENABLE_USE_BY_CLANG ON CACHE BOOL "")
set(RUNTIMES_${target}_LIBC_USE_NEW_HEADER_GEN OFF CACHE BOOL "")
set(RUNTIMES_${target}_LIBCXX_ABI_VERSION 2 CACHE STRING "")
set(RUNTIMES_${target}_LIBCXX_CXX_ABI none CACHE STRING "")
set(RUNTIMES_${target}_LIBCXX_ENABLE_SHARED OFF CACHE BOOL "")
Expand Down
3 changes: 0 additions & 3 deletions clang/cmake/caches/Fuchsia.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,6 @@ set(_FUCHSIA_BOOTSTRAP_PASSTHROUGH
SWIG_EXECUTABLE
CMAKE_FIND_PACKAGE_PREFER_CONFIG
CMAKE_SYSROOT
CMAKE_MODULE_LINKER_FLAGS
CMAKE_SHARED_LINKER_FLAGS
CMAKE_EXE_LINKER_FLAGS
LLVM_WINSYSROOT
LLVM_VFSOVERLAY
)
Expand Down
74 changes: 74 additions & 0 deletions clang/docs/ClangNVLinkWrapper.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
====================
Clang nvlink Wrapper
====================

.. contents::
:local:

.. _clang-nvlink-wrapper:

Introduction
============

This tools works as a wrapper around the NVIDIA ``nvlink`` linker. The purpose
of this wrapper is to provide an interface similar to the ``ld.lld`` linker
while still relying on NVIDIA's proprietary linker to produce the final output.

``nvlink`` has a number of known quirks that make it difficult to use in a
unified offloading setting. For example, it does not accept ``.o`` files as they
must be named ``.cubin``. Static archives do not work, so passing a ``.a`` will
provide a linker error. ``nvlink`` also does not support link time optimization
and ignores many standard linker arguments. This tool works around these issues.

Usage
=====

This tool can be used with the following options. Any arguments not intended
only for the linker wrapper will be forwarded to ``nvlink``.

.. code-block:: console
OVERVIEW: A utility that wraps around the NVIDIA 'nvlink' linker.
This enables static linking and LTO handling for NVPTX targets.
USAGE: clang-nvlink-wrapper [options] <options to passed to nvlink>
OPTIONS:
--arch <value> Specify the 'sm_' name of the target architecture.
--cuda-path=<dir> Set the system CUDA path
--dry-run Print generated commands without running.
--feature <value> Specify the '+ptx' freature to use for LTO.
-g Specify that this was a debug compile.
-help-hidden Display all available options
-help Display available options (--help-hidden for more)
-L <dir> Add <dir> to the library search path
-l <libname> Search for library <libname>
-mllvm <arg> Arguments passed to LLVM, including Clang invocations,
for which the '-mllvm' prefix is preserved. Use '-mllvm
--help' for a list of options.
-o <path> Path to file to write output
--plugin-opt=jobs=<value>
Number of LTO codegen partitions
--plugin-opt=lto-partitions=<value>
Number of LTO codegen partitions
--plugin-opt=O<O0, O1, O2, or O3>
Optimization level for LTO
--plugin-opt=thinlto<value>
Enable the thin-lto backend
--plugin-opt=<value> Arguments passed to LLVM, including Clang invocations,
for which the '-mllvm' prefix is preserved. Use '-mllvm
--help' for a list of options.
--save-temps Save intermediate results
--version Display the version number and exit
-v Print verbose information
Example
=======

This tool is intended to be invoked when targeting the NVPTX toolchain directly
as a cross-compiling target. This can be used to create standalone GPU
executables with normal linking semantics similar to standard compilation.

.. code-block:: console
clang --target=nvptx64-nvidia-cuda -march=native -flto=full input.c
5 changes: 2 additions & 3 deletions clang/docs/HLSL/AvailabilityDiagnostics.rst
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ If the compilation target is a shader library, only availability based on shader

As a result, availability based on specific shader stage will only be diagnosed in code that is reachable from a shader entry point or library export function. It also means that function bodies might be scanned multiple time. When that happens, care should be taken not to produce duplicated diagnostics.

========
Examples
========

Expand All @@ -62,7 +61,7 @@ For the example below, the ``WaveActiveCountBits`` API function became available
The availability of ``ddx`` function depends on a shader stage. It is available for pixel shaders in shader model 2.1 and higher, for compute, mesh and amplification shaders in shader model 6.6 and higher. For any other shader stages it is not available.

Compute shader example
======================
----------------------

.. code-block:: c++

Expand Down Expand Up @@ -94,7 +93,7 @@ With strict diagnostic mode, in addition to the 2 errors above Clang will also e
<>:7:13: error: 'WaveActiveCountBits' is only available on Shader Model 6.5 or newer
Shader library example
======================
----------------------

.. code-block:: c++

Expand Down
2 changes: 1 addition & 1 deletion clang/docs/HLSL/ExpectedDifferences.rst
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@

===================================
Expected Differences vs DXC and FXC
===================================

Expand Down
1 change: 1 addition & 0 deletions clang/docs/LanguageExtensions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1546,6 +1546,7 @@ The following type trait primitives are supported by Clang. Those traits marked
* ``__array_extent(type, dim)`` (Embarcadero):
The ``dim``'th array bound in the type ``type``, or ``0`` if
``dim >= __array_rank(type)``.
* ``__builtin_is_virtual_base_of`` (C++, GNU, Microsoft)
* ``__can_pass_in_regs`` (C++)
Returns whether a class can be passed in registers under the current
ABI. This type can only be applied to unqualified class types.
Expand Down
130 changes: 130 additions & 0 deletions clang/docs/MSVCCompatibility.rst
Original file line number Diff line number Diff line change
Expand Up @@ -154,3 +154,133 @@ a hint suggesting how to fix the problem.
As of this writing, Clang is able to compile a simple ATL hello world
application. There are still issues parsing WRL headers for modern Windows 8
apps, but they should be addressed soon.

__forceinline behavior
======================

``__forceinline`` behaves like ``[[clang::always_inline]]``.
Inlining is always attempted regardless of optimization level.

This differs from MSVC where ``__forceinline`` is only respected once inline expansion is enabled
which allows any function marked implicitly or explicitly ``inline`` or ``__forceinline`` to be expanded.
Therefore functions marked ``__forceinline`` will be expanded when the optimization level is ``/Od`` unlike
MSVC where ``__forceinline`` will not be expanded under ``/Od``.

SIMD and instruction set intrinsic behavior
===========================================

Clang follows the GCC model for intrinsics and not the MSVC model.
There are currently no plans to support the MSVC model.

MSVC intrinsics always emit the machine instruction the intrinsic models regardless of the compile time options specified.
For example ``__popcnt`` always emits the x86 popcnt instruction even if the compiler does not have the option enabled to emit popcnt on its own volition.

There are two common cases where code that compiles with MSVC will need reworking to build on clang.
Assume the examples are only built with `-msse2` so we do not have the intrinsics at compile time.

.. code-block:: c++

unsigned PopCnt(unsigned v) {
if (HavePopCnt)
return __popcnt(v);
else
return GenericPopCnt(v);
}

.. code-block:: c++

__m128 dot4_sse3(__m128 v0, __m128 v1) {
__m128 r = _mm_mul_ps(v0, v1);
r = _mm_hadd_ps(r, r);
r = _mm_hadd_ps(r, r);
return r;
}

Clang expects that either you have compile time support for the target features, `-msse3` and `-mpopcnt`, you mark the function with the expected target feature or use runtime detection with an indirect call.

.. code-block:: c++

__attribute__((__target__("sse3"))) __m128 dot4_sse3(__m128 v0, __m128 v1) {
__m128 r = _mm_mul_ps(v0, v1);
r = _mm_hadd_ps(r, r);
r = _mm_hadd_ps(r, r);
return r;
}

The SSE3 dot product can be easily fixed by either building the translation unit with SSE3 support or using `__target__` to compile that specific function with SSE3 support.

.. code-block:: c++

unsigned PopCnt(unsigned v) {
if (HavePopCnt)
return __popcnt(v);
else
return GenericPopCnt(v);
}

The above ``PopCnt`` example must be changed to work with clang. If we mark the function with `__target__("popcnt")` then the compiler is free to emit popcnt at will which we do not want. While this isn't a concern in our small example it is a concern in larger functions with surrounding code around the intrinsics. Similar reasoning for compiling the translation unit with `-mpopcnt`.
We must split each branch into its own function that can be called indirectly instead of using the intrinsic directly.

.. code-block:: c++

__attribute__((__target__("popcnt"))) unsigned hwPopCnt(unsigned v) { return __popcnt(v); }
unsigned (*PopCnt)(unsigned) = HavePopCnt ? hwPopCnt : GenericPopCnt;
.. code-block:: c++

__attribute__((__target__("popcnt"))) unsigned hwPopCnt(unsigned v) { return __popcnt(v); }
unsigned PopCnt(unsigned v) {
if (HavePopCnt)
return hwPopCnt(v);
else
return GenericPopCnt(v);
}

In the above example ``hwPopCnt`` will not be inlined into ``PopCnt`` since ``PopCnt`` doesn't have the popcnt target feature.
With a larger function that does real work the function call overhead is negligible. However in our popcnt example there is the function call
overhead. There is no analog for this specific MSVC behavior in clang.

For clang we effectively have to create the dispatch function ourselves to each specfic implementation.

SIMD vector types
=================

Clang's simd vector types are builtin types and not user defined types as in MSVC. This does have some observable behavior changes.
We will look at the x86 `__m128` type for the examples below but the statements apply to all vector types including ARM's `float32x4_t`.

There are no members that can be accessed on the vector types. Vector types are not structs in clang.
You cannot use ``__m128.m128_f32[0]`` to access the first element of the `__m128`.
This also means struct initialization like ``__m128{ { 0.0f, 0.0f, 0.0f, 0.0f } }`` will not compile with clang.

Since vector types are builtin types, clang implements operators on them natively.

.. code-block:: c++

#ifdef _MSC_VER
__m128 operator+(__m128 a, __m128 b) { return _mm_add_ps(a, b); }
#endif

The above code will fail to compile since overloaded 'operator+' must have at least one parameter of class or enumeration type.
You will need to fix such code to have the check ``#if defined(_MSC_VER) && !defined(__clang__)``.

Since `__m128` is not a class type in clang any overloads after a template definition will not be considered.

.. code-block:: c++

template<class T>
void foo(T) {}

template<class T>
void bar(T t) {
foo(t);
}

void foo(__m128) {}

int main() {
bar(_mm_setzero_ps());
}

With MSVC ``foo(__m128)`` will be selected but with clang ``foo<__m128>()`` will be selected since on clang `__m128` is a builtin type.

In general the takeaway is `__m128` is a builtin type on clang while a class type on MSVC.
1,182 changes: 41 additions & 1,141 deletions clang/docs/ReleaseNotes.rst

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions clang/docs/analyzer/checkers/mismatched_deallocator_example.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ void test() {

// C, C++
void __attribute((ownership_returns(malloc))) *user_malloc(size_t);
void __attribute((ownership_takes(malloc, 1))) *user_free(void *);

void __attribute((ownership_returns(malloc1))) *user_malloc1(size_t);
void __attribute((ownership_takes(malloc1, 1))) *user_free1(void *);

void test() {
int *p = (int *)user_malloc(sizeof(int));
Expand All @@ -24,6 +28,12 @@ void test() {
realloc(p, sizeof(long)); // warn
}

// C, C++
void test() {
int *p = user_malloc(10);
user_free1(p); // warn
}

// C, C++
template <typename T>
struct SimpleSmartPointer {
Expand Down
1 change: 1 addition & 0 deletions clang/docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ Using Clang Tools
ClangFormatStyleOptions
ClangFormattedStatus
ClangLinkerWrapper
ClangNVLinkWrapper
ClangOffloadBundler
ClangOffloadPackager
ClangRepl
Expand Down
8 changes: 7 additions & 1 deletion clang/include/clang/AST/ASTContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -738,6 +738,12 @@ class ASTContext : public RefCountedBase<ASTContext> {
}
void Deallocate(void *Ptr) const {}

llvm::StringRef backupStr(llvm::StringRef S) const {
char *Buf = new (*this) char[S.size()];
std::copy(S.begin(), S.end(), Buf);
return llvm::StringRef(Buf, S.size());
}

/// Allocates a \c DeclListNode or returns one from the \c ListNodeFreeList
/// pool.
DeclListNode *AllocateDeclListNode(clang::NamedDecl *ND) {
Expand Down Expand Up @@ -1287,7 +1293,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
getPointerAuthVTablePointerDiscriminator(const CXXRecordDecl *RD);

/// Return the "other" type-specific discriminator for the given type.
uint16_t getPointerAuthTypeDiscriminator(QualType T) const;
uint16_t getPointerAuthTypeDiscriminator(QualType T);

/// Apply Objective-C protocol qualifiers to the given type.
/// \param allowOnPointerType specifies if we can apply protocol
Expand Down
10 changes: 1 addition & 9 deletions clang/include/clang/AST/ExprCXX.h
Original file line number Diff line number Diff line change
Expand Up @@ -4854,15 +4854,7 @@ class CXXFoldExpr : public Expr {
CXXFoldExpr(QualType T, UnresolvedLookupExpr *Callee,
SourceLocation LParenLoc, Expr *LHS, BinaryOperatorKind Opcode,
SourceLocation EllipsisLoc, Expr *RHS, SourceLocation RParenLoc,
std::optional<unsigned> NumExpansions)
: Expr(CXXFoldExprClass, T, VK_PRValue, OK_Ordinary),
LParenLoc(LParenLoc), EllipsisLoc(EllipsisLoc), RParenLoc(RParenLoc),
NumExpansions(NumExpansions ? *NumExpansions + 1 : 0), Opcode(Opcode) {
SubExprs[SubExpr::Callee] = Callee;
SubExprs[SubExpr::LHS] = LHS;
SubExprs[SubExpr::RHS] = RHS;
setDependence(computeDependence(this));
}
std::optional<unsigned> NumExpansions);

CXXFoldExpr(EmptyShell Empty) : Expr(CXXFoldExprClass, Empty) {}

Expand Down
24 changes: 3 additions & 21 deletions clang/include/clang/AST/StmtOpenMP.h
Original file line number Diff line number Diff line change
Expand Up @@ -281,15 +281,6 @@ class OMPExecutableDirective : public Stmt {
return Data->getClauses();
}

/// Was this directive mapped from an another directive?
/// e.g. 1) omp loop bind(parallel) is mapped to OMPD_for
/// 2) omp loop bind(teams) is mapped to OMPD_distribute
/// 3) omp loop bind(thread) is mapped to OMPD_simd
/// It was necessary to note it down in the Directive because of
/// clang::TreeTransform::TransformOMPExecutableDirective() pass in
/// the frontend.
OpenMPDirectiveKind PrevMappedDirective = llvm::omp::OMPD_unknown;

protected:
/// Data, associated with the directive.
OMPChildren *Data = nullptr;
Expand Down Expand Up @@ -354,10 +345,6 @@ class OMPExecutableDirective : public Stmt {
return Inst;
}

void setMappedDirective(OpenMPDirectiveKind MappedDirective) {
PrevMappedDirective = MappedDirective;
}

public:
/// Iterates over expressions/statements used in the construct.
class used_clauses_child_iterator
Expand Down Expand Up @@ -611,8 +598,6 @@ class OMPExecutableDirective : public Stmt {
"Expected directive with the associated statement.");
return Data->getRawStmt();
}

OpenMPDirectiveKind getMappedDirective() const { return PrevMappedDirective; }
};

/// This represents '#pragma omp parallel' directive.
Expand Down Expand Up @@ -1620,8 +1605,7 @@ class OMPSimdDirective : public OMPLoopDirective {
SourceLocation EndLoc, unsigned CollapsedNum,
ArrayRef<OMPClause *> Clauses,
Stmt *AssociatedStmt,
const HelperExprs &Exprs,
OpenMPDirectiveKind ParamPrevMappedDirective);
const HelperExprs &Exprs);

/// Creates an empty directive with the place
/// for \a NumClauses clauses.
Expand Down Expand Up @@ -1699,8 +1683,7 @@ class OMPForDirective : public OMPLoopDirective {
SourceLocation EndLoc, unsigned CollapsedNum,
ArrayRef<OMPClause *> Clauses,
Stmt *AssociatedStmt, const HelperExprs &Exprs,
Expr *TaskRedRef, bool HasCancel,
OpenMPDirectiveKind ParamPrevMappedDirective);
Expr *TaskRedRef, bool HasCancel);

/// Creates an empty directive with the place
/// for \a NumClauses clauses.
Expand Down Expand Up @@ -4478,8 +4461,7 @@ class OMPDistributeDirective : public OMPLoopDirective {
static OMPDistributeDirective *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
Stmt *AssociatedStmt, const HelperExprs &Exprs,
OpenMPDirectiveKind ParamPrevMappedDirective);
Stmt *AssociatedStmt, const HelperExprs &Exprs);

/// Creates an empty directive with the place
/// for \a NumClauses clauses.
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/AST/Type.h
Original file line number Diff line number Diff line change
Expand Up @@ -8434,7 +8434,7 @@ inline bool Type::isUndeducedType() const {
/// Determines whether this is a type for which one can define
/// an overloaded operator.
inline bool Type::isOverloadableType() const {
if (!CanonicalType->isDependentType())
if (!isDependentType())
return isRecordType() || isEnumeralType();
return !isArrayType() && !isFunctionType() && !isAnyPointerType() &&
!isMemberPointerType();
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Analysis/FlowSensitive/MapLattice.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ template <typename Key, typename ElementLattice> class MapLattice {

MapLattice() = default;

explicit MapLattice(Container C) { C = std::move(C); }
explicit MapLattice(Container C) : C{std::move(C)} {};

// The `bottom` element is the empty map.
static MapLattice bottom() { return MapLattice(); }
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Basic/Attr.td
Original file line number Diff line number Diff line change
Expand Up @@ -902,7 +902,7 @@ def PatchableFunctionEntry
: InheritableAttr,
TargetSpecificAttr<TargetArch<
["aarch64", "aarch64_be", "loongarch32", "loongarch64", "riscv32",
"riscv64", "x86", "x86_64"]>> {
"riscv64", "x86", "x86_64", "ppc", "ppc64"]>> {
let Spellings = [GCC<"patchable_function_entry">];
let Subjects = SubjectList<[Function, ObjCMethod]>;
let Args = [UnsignedArgument<"Count">, DefaultIntArgument<"Offset", 0>];
Expand Down
3 changes: 2 additions & 1 deletion clang/include/clang/Basic/AttrDocs.td
Original file line number Diff line number Diff line change
Expand Up @@ -5800,7 +5800,8 @@ takes precedence over the command line option ``-fpatchable-function-entry=N,M``
``M`` defaults to 0 if omitted.

This attribute is only supported on
aarch64/aarch64-be/loongarch32/loongarch64/riscv32/riscv64/i386/x86-64 targets.
aarch64/aarch64-be/loongarch32/loongarch64/riscv32/riscv64/i386/x86-64/ppc/ppc64 targets.
For ppc/ppc64 targets, AIX is still not supported.
}];
}

Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Basic/BuiltinsWebAssembly.def
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ TARGET_BUILTIN(__builtin_wasm_loadf16_f32, "fh*", "nU", "half-precision")
TARGET_BUILTIN(__builtin_wasm_storef16_f32, "vfh*", "n", "half-precision")
TARGET_BUILTIN(__builtin_wasm_splat_f16x8, "V8hf", "nc", "half-precision")
TARGET_BUILTIN(__builtin_wasm_extract_lane_f16x8, "fV8hi", "nc", "half-precision")
TARGET_BUILTIN(__builtin_wasm_replace_lane_f16x8, "V8hV8hif", "nc", "half-precision")

// Reference Types builtins
// Some builtins are custom type-checked - see 't' as part of the third argument,
Expand Down
103 changes: 2 additions & 101 deletions clang/include/clang/Basic/BuiltinsX86.def
Original file line number Diff line number Diff line change
Expand Up @@ -47,107 +47,8 @@ TARGET_BUILTIN(__builtin_ia32_writeeflags_u32, "vUi", "n", "")
// doesn't work in the presence of re-declaration of _mm_prefetch for windows.
TARGET_BUILTIN(_mm_prefetch, "vcC*i", "nc", "mmx")
TARGET_BUILTIN(__builtin_ia32_emms, "v", "n", "mmx")
TARGET_BUILTIN(__builtin_ia32_paddb, "V8cV8cV8c", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_paddw, "V4sV4sV4s", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_paddd, "V2iV2iV2i", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_paddsb, "V8cV8cV8c", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_paddsw, "V4sV4sV4s", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_paddusb, "V8cV8cV8c", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_paddusw, "V4sV4sV4s", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_psubb, "V8cV8cV8c", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_psubw, "V4sV4sV4s", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_psubd, "V2iV2iV2i", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_psubsb, "V8cV8cV8c", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_psubsw, "V4sV4sV4s", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_psubusb, "V8cV8cV8c", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_psubusw, "V4sV4sV4s", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_pmulhw, "V4sV4sV4s", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_pmullw, "V4sV4sV4s", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_pmaddwd, "V2iV4sV4s", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_pand, "V1OiV1OiV1Oi", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_pandn, "V1OiV1OiV1Oi", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_por, "V1OiV1OiV1Oi", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_pxor, "V1OiV1OiV1Oi", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_psllw, "V4sV4sV1Oi", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_pslld, "V2iV2iV1Oi", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_psllq, "V1OiV1OiV1Oi", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_psrlw, "V4sV4sV1Oi", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_psrld, "V2iV2iV1Oi", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_psrlq, "V1OiV1OiV1Oi", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_psraw, "V4sV4sV1Oi", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_psrad, "V2iV2iV1Oi", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_psllwi, "V4sV4si", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_pslldi, "V2iV2ii", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_psllqi, "V1OiV1Oii", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_psrlwi, "V4sV4si", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_psrldi, "V2iV2ii", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_psrlqi, "V1OiV1Oii", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_psrawi, "V4sV4si", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_psradi, "V2iV2ii", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_packsswb, "V8cV4sV4s", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_packssdw, "V4sV2iV2i", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_packuswb, "V8cV4sV4s", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_punpckhbw, "V8cV8cV8c", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_punpckhwd, "V4sV4sV4s", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_punpckhdq, "V2iV2iV2i", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_punpcklbw, "V8cV8cV8c", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_punpcklwd, "V4sV4sV4s", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_punpckldq, "V2iV2iV2i", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_pcmpeqb, "V8cV8cV8c", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_pcmpeqw, "V4sV4sV4s", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_pcmpeqd, "V2iV2iV2i", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_pcmpgtb, "V8cV8cV8c", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_pcmpgtw, "V4sV4sV4s", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_pcmpgtd, "V2iV2iV2i", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_maskmovq, "vV8cV8cc*", "nV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_movntq, "vV1Oi*V1Oi", "nV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_vec_init_v2si, "V2iii", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_vec_init_v4hi, "V4sssss", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_vec_init_v8qi, "V8ccccccccc", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_vec_ext_v2si, "iV2ii", "ncV:64:", "mmx")

// MMX2 (MMX+SSE) intrinsics
TARGET_BUILTIN(__builtin_ia32_cvtpi2ps, "V4fV4fV2i", "ncV:64:", "mmx,sse")
TARGET_BUILTIN(__builtin_ia32_cvtps2pi, "V2iV4f", "ncV:64:", "mmx,sse")
TARGET_BUILTIN(__builtin_ia32_cvttps2pi, "V2iV4f", "ncV:64:", "mmx,sse")
TARGET_BUILTIN(__builtin_ia32_pavgb, "V8cV8cV8c", "ncV:64:", "mmx,sse")
TARGET_BUILTIN(__builtin_ia32_pavgw, "V4sV4sV4s", "ncV:64:", "mmx,sse")
TARGET_BUILTIN(__builtin_ia32_pmaxsw, "V4sV4sV4s", "ncV:64:", "mmx,sse")
TARGET_BUILTIN(__builtin_ia32_pmaxub, "V8cV8cV8c", "ncV:64:", "mmx,sse")
TARGET_BUILTIN(__builtin_ia32_pminsw, "V4sV4sV4s", "ncV:64:", "mmx,sse")
TARGET_BUILTIN(__builtin_ia32_pminub, "V8cV8cV8c", "ncV:64:", "mmx,sse")
TARGET_BUILTIN(__builtin_ia32_pmovmskb, "iV8c", "ncV:64:", "mmx,sse")
TARGET_BUILTIN(__builtin_ia32_pmulhuw, "V4sV4sV4s", "ncV:64:", "mmx,sse")
TARGET_BUILTIN(__builtin_ia32_psadbw, "V4sV8cV8c", "ncV:64:", "mmx,sse")
TARGET_BUILTIN(__builtin_ia32_pshufw, "V4sV4sIc", "ncV:64:", "mmx,sse")
TARGET_BUILTIN(__builtin_ia32_vec_ext_v4hi, "iV4sIi", "ncV:64:", "mmx,sse")
TARGET_BUILTIN(__builtin_ia32_vec_set_v4hi, "V4sV4siIi", "ncV:64:", "mmx,sse")

// MMX+SSE2
TARGET_BUILTIN(__builtin_ia32_cvtpd2pi, "V2iV2d", "ncV:64:", "mmx,sse2")
TARGET_BUILTIN(__builtin_ia32_cvtpi2pd, "V2dV2i", "ncV:64:", "mmx,sse2")
TARGET_BUILTIN(__builtin_ia32_cvttpd2pi, "V2iV2d", "ncV:64:", "mmx,sse2")
TARGET_BUILTIN(__builtin_ia32_paddq, "V1OiV1OiV1Oi", "ncV:64:", "mmx,sse2")
TARGET_BUILTIN(__builtin_ia32_pmuludq, "V1OiV2iV2i", "ncV:64:", "mmx,sse2")
TARGET_BUILTIN(__builtin_ia32_psubq, "V1OiV1OiV1Oi", "ncV:64:", "mmx,sse2")

// MMX+SSSE3
TARGET_BUILTIN(__builtin_ia32_pabsb, "V8cV8c", "ncV:64:", "mmx,ssse3")
TARGET_BUILTIN(__builtin_ia32_pabsd, "V2iV2i", "ncV:64:", "mmx,ssse3")
TARGET_BUILTIN(__builtin_ia32_pabsw, "V4sV4s", "ncV:64:", "mmx,ssse3")
TARGET_BUILTIN(__builtin_ia32_palignr, "V8cV8cV8cIc", "ncV:64:", "mmx,ssse3")
TARGET_BUILTIN(__builtin_ia32_phaddd, "V2iV2iV2i", "ncV:64:", "mmx,ssse3")
TARGET_BUILTIN(__builtin_ia32_phaddsw, "V4sV4sV4s", "ncV:64:", "mmx,ssse3")
TARGET_BUILTIN(__builtin_ia32_phaddw, "V4sV4sV4s", "ncV:64:", "mmx,ssse3")
TARGET_BUILTIN(__builtin_ia32_phsubd, "V2iV2iV2i", "ncV:64:", "mmx,ssse3")
TARGET_BUILTIN(__builtin_ia32_phsubsw, "V4sV4sV4s", "ncV:64:", "mmx,ssse3")
TARGET_BUILTIN(__builtin_ia32_phsubw, "V4sV4sV4s", "ncV:64:", "mmx,ssse3")
TARGET_BUILTIN(__builtin_ia32_pmaddubsw, "V8cV8cV8c", "ncV:64:", "mmx,ssse3")
TARGET_BUILTIN(__builtin_ia32_pmulhrsw, "V4sV4sV4s", "ncV:64:", "mmx,ssse3")
TARGET_BUILTIN(__builtin_ia32_pshufb, "V8cV8cV8c", "ncV:64:", "mmx,ssse3")
TARGET_BUILTIN(__builtin_ia32_psignw, "V4sV4sV4s", "ncV:64:", "mmx,ssse3")
TARGET_BUILTIN(__builtin_ia32_psignb, "V8cV8cV8c", "ncV:64:", "mmx,ssse3")
TARGET_BUILTIN(__builtin_ia32_psignd, "V2iV2iV2i", "ncV:64:", "mmx,ssse3")
TARGET_BUILTIN(__builtin_ia32_vec_ext_v4hi, "sV4sIi", "ncV:64:", "sse")
TARGET_BUILTIN(__builtin_ia32_vec_set_v4hi, "V4sV4ssIi", "ncV:64:", "sse")

// SSE intrinsics.
TARGET_BUILTIN(__builtin_ia32_comieq, "iV4fV4f", "ncV:128:", "sse")
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Basic/CodeGenOptions.def
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,9 @@ CODEGENOPT(ForceAAPCSBitfieldLoad, 1, 0)
/// Assume that by-value parameters do not alias any other values.
CODEGENOPT(PassByValueIsNoAlias, 1, 0)

/// Whether to store register parameters to stack.
CODEGENOPT(SaveRegParams, 1, 0)

/// Whether to not follow the AAPCS that enforces volatile bit-field access width to be
/// according to the field declaring type width.
CODEGENOPT(AAPCSBitfieldWidth, 1, 1)
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Basic/DiagnosticParseKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -1260,6 +1260,9 @@ def warn_pragma_intrinsic_builtin : Warning<
def warn_pragma_unused_expected_var : Warning<
"expected '#pragma unused' argument to be a variable name">,
InGroup<IgnoredPragmas>;
// - #pragma mc_func
def err_pragma_mc_func_not_supported :
Error<"#pragma mc_func is not supported">;
// - #pragma init_seg
def warn_pragma_init_seg_unsupported_target : Warning<
"'#pragma init_seg' is only supported when targeting a "
Expand Down
19 changes: 12 additions & 7 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -942,13 +942,19 @@ def warn_ptrauth_auth_null_pointer :
InGroup<PtrAuthNullPointers>;
def err_ptrauth_string_not_literal : Error<
"argument must be a string literal%select{| of char type}0">;
def err_ptrauth_type_disc_undiscriminated : Error<
"cannot pass undiscriminated type %0 to "
"'__builtin_ptrauth_type_discriminator'">;

def note_ptrauth_virtual_function_pointer_incomplete_arg_ret :
Note<"cannot take an address of a virtual member function if its return or "
"argument types are incomplete">;
def note_ptrauth_virtual_function_incomplete_arg_ret_type :
Note<"%0 is incomplete">;

def err_ptrauth_indirect_goto_addrlabel_arithmetic : Error<
"%select{subtraction|addition}0 of address-of-label expressions is not "
"supported with ptrauth indirect gotos">;

/// main()
// static main() is not an error in C, just in C++.
Expand Down Expand Up @@ -3328,6 +3334,10 @@ def err_ownership_returns_index_mismatch : Error<
"'ownership_returns' attribute index does not match; here it is %0">;
def note_ownership_returns_index_mismatch : Note<
"declared with index %0 here">;
def err_ownership_takes_class_mismatch : Error<
"'ownership_takes' attribute class does not match; here it is '%0'">;
def note_ownership_takes_class_mismatch : Note<
"declared with class '%0' here">;
def err_format_strftime_third_parameter : Error<
"strftime format attribute requires 3rd parameter to be 0">;
def err_format_attribute_not : Error<"format argument not a string type">;
Expand Down Expand Up @@ -3492,7 +3502,7 @@ def err_attr_tlsmodel_arg : Error<"tls_model must be \"global-dynamic\", "

def err_attr_codemodel_arg : Error<"code model '%0' is not supported on this target">;

def err_aix_attr_unsupported_tls_model : Error<"TLS model '%0' is not yet supported on AIX">;
def err_aix_attr_unsupported : Error<"%0 attribute is not yet supported on AIX">;

def err_tls_var_aligned_over_maximum : Error<
"alignment (%0) of thread-local variable %1 is greater than the maximum supported "
Expand Down Expand Up @@ -3802,8 +3812,6 @@ def warn_sme_locally_streaming_has_vl_args_returns : Warning<
InGroup<AArch64SMEAttributes>, DefaultIgnore;
def err_conflicting_attributes_arm_state : Error<
"conflicting attributes for state '%0'">;
def err_sme_streaming_cannot_be_multiversioned : Error<
"streaming function cannot be multi-versioned">;
def err_unknown_arm_state : Error<
"unknown state '%0'">;
def err_missing_arm_state : Error<
Expand Down Expand Up @@ -5165,7 +5173,7 @@ def warn_cxx11_compat_variable_template : Warning<
InGroup<CXXPre14Compat>, DefaultIgnore;
def err_template_variable_noparams : Error<
"extraneous 'template<>' in declaration of variable %0">;
def err_template_member : Error<"member %0 declared as a template">;
def err_template_member : Error<"non-static data member %0 cannot be declared as a template">;
def err_member_with_template_arguments : Error<"member %0 cannot have template arguments">;
def err_template_member_noparams : Error<
"extraneous 'template<>' in declaration of member %0">;
Expand Down Expand Up @@ -7596,9 +7604,6 @@ def err_nested_non_static_member_use : Error<
def warn_cxx98_compat_non_static_member_use : Warning<
"use of non-static data member %0 in an unevaluated context is "
"incompatible with C++98">, InGroup<CXX98Compat>, DefaultIgnore;
def err_form_ptr_to_member_from_parenthesized_expr : Error<
"cannot form pointer to member from a parenthesized expression; "
"did you mean to remove the parentheses?">;
def err_invalid_incomplete_type_use : Error<
"invalid use of incomplete type %0">;
def err_builtin_func_cast_more_than_one_arg : Error<
Expand Down
2 changes: 2 additions & 0 deletions clang/include/clang/Basic/Features.def
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,11 @@ FEATURE(ptrauth_calls, LangOpts.PointerAuthCalls)
FEATURE(ptrauth_returns, LangOpts.PointerAuthReturns)
FEATURE(ptrauth_vtable_pointer_address_discrimination, LangOpts.PointerAuthVTPtrAddressDiscrimination)
FEATURE(ptrauth_vtable_pointer_type_discrimination, LangOpts.PointerAuthVTPtrTypeDiscrimination)
FEATURE(ptrauth_type_info_vtable_pointer_discrimination, LangOpts.PointerAuthTypeInfoVTPtrDiscrimination)
FEATURE(ptrauth_member_function_pointer_type_discrimination, LangOpts.PointerAuthCalls)
FEATURE(ptrauth_init_fini, LangOpts.PointerAuthInitFini)
FEATURE(ptrauth_function_pointer_type_discrimination, LangOpts.PointerAuthFunctionTypeDiscrimination)
FEATURE(ptrauth_indirect_gotos, LangOpts.PointerAuthIndirectGotos)
EXTENSION(swiftcc,
PP.getTargetInfo().checkCallingConvention(CC_Swift) ==
clang::TargetInfo::CCCR_OK)
Expand Down
4 changes: 2 additions & 2 deletions clang/include/clang/Basic/LangOptions.def
Original file line number Diff line number Diff line change
Expand Up @@ -165,9 +165,11 @@ LANGOPT(ExperimentalLibrary, 1, 0, "enable unstable and experimental library fea
LANGOPT(PointerAuthIntrinsics, 1, 0, "pointer authentication intrinsics")
LANGOPT(PointerAuthCalls , 1, 0, "function pointer authentication")
LANGOPT(PointerAuthReturns, 1, 0, "return pointer authentication")
LANGOPT(PointerAuthIndirectGotos, 1, 0, "indirect gotos pointer authentication")
LANGOPT(PointerAuthAuthTraps, 1, 0, "pointer authentication failure traps")
LANGOPT(PointerAuthVTPtrAddressDiscrimination, 1, 0, "incorporate address discrimination in authenticated vtable pointers")
LANGOPT(PointerAuthVTPtrTypeDiscrimination, 1, 0, "incorporate type discrimination in authenticated vtable pointers")
LANGOPT(PointerAuthTypeInfoVTPtrDiscrimination, 1, 0, "incorporate type and address discrimination in authenticated vtable pointers for std::type_info")
LANGOPT(PointerAuthInitFini, 1, 0, "sign function pointers in init/fini arrays")
BENIGN_LANGOPT(PointerAuthFunctionTypeDiscrimination, 1, 0,
"Use type discrimination when signing function pointers")
Expand Down Expand Up @@ -222,7 +224,6 @@ COMPATIBLE_LANGOPT(GNUInline , 1, 0, "GNU inline semantics")
COMPATIBLE_LANGOPT(NoInlineDefine , 1, 0, "__NO_INLINE__ predefined macro")
COMPATIBLE_LANGOPT(Deprecated , 1, 0, "__DEPRECATED predefined macro")
COMPATIBLE_LANGOPT(FastMath , 1, 0, "fast FP math optimizations, and __FAST_MATH__ predefined macro")
COMPATIBLE_LANGOPT(FiniteMathOnly , 1, 0, "__FINITE_MATH_ONLY__ predefined macro")
COMPATIBLE_LANGOPT(UnsafeFPMath , 1, 0, "Unsafe Floating Point Math")
COMPATIBLE_LANGOPT(ProtectParens , 1, 0, "optimizer honors parentheses "
"when floating-point expressions are evaluated")
Expand Down Expand Up @@ -338,7 +339,6 @@ LANGOPT(SinglePrecisionConstants , 1, 0, "treating double-precision floating poi
LANGOPT(FastRelaxedMath , 1, 0, "OpenCL fast relaxed math")
BENIGN_LANGOPT(CLNoSignedZero , 1, 0, "Permit Floating Point optimization without regard to signed zeros")
COMPATIBLE_LANGOPT(CLUnsafeMath , 1, 0, "Unsafe Floating Point Math")
COMPATIBLE_LANGOPT(CLFiniteMathOnly , 1, 0, "__FINITE_MATH_ONLY__ predefined macro")
/// FP_CONTRACT mode (on/off/fast).
BENIGN_ENUM_LANGOPT(DefaultFPContractMode, FPModeKind, 2, FPM_Off, "FP contraction type")
COMPATIBLE_LANGOPT(ExpStrictFP, 1, false, "Enable experimental strict floating point")
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Basic/OpenMPKinds.def
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ OPENMP_DEVICE_MODIFIER(device_num)
OPENMP_DEFAULTMAP_KIND(scalar)
OPENMP_DEFAULTMAP_KIND(aggregate)
OPENMP_DEFAULTMAP_KIND(pointer)
OPENMP_DEFAULTMAP_KIND(all)

// Modifiers for 'defaultmap' clause.
OPENMP_DEFAULTMAP_MODIFIER(alloc)
Expand Down
11 changes: 11 additions & 0 deletions clang/include/clang/Basic/PointerAuthOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ namespace clang {

constexpr unsigned PointerAuthKeyNone = -1;

/// Constant discriminator for std::type_info vtable pointers: 0xB1EA/45546
/// The value is ptrauth_string_discriminator("_ZTVSt9type_info"), i.e.,
/// the vtable type discriminator for classes derived from std::type_info.
constexpr uint16_t StdTypeInfoVTablePointerConstantDiscrimination = 0xB1EA;

class PointerAuthSchema {
public:
enum class Kind : unsigned {
Expand Down Expand Up @@ -154,6 +159,9 @@ class PointerAuthSchema {
};

struct PointerAuthOptions {
/// Do indirect goto label addresses need to be authenticated?
bool IndirectGotos = false;

/// The ABI for C function pointers.
PointerAuthSchema FunctionPointers;

Expand All @@ -175,6 +183,9 @@ struct PointerAuthOptions {

/// The ABI for variadic C++ virtual function pointers.
PointerAuthSchema CXXVirtualVariadicFunctionPointers;

/// The ABI for C++ member function pointers.
PointerAuthSchema CXXMemberFunctionPointers;
};

} // end namespace clang
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Basic/TokenKinds.def
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,7 @@ TYPE_TRAIT_1(__has_trivial_move_assign, HasTrivialMoveAssign, KEYCXX)
TYPE_TRAIT_1(__has_trivial_move_constructor, HasTrivialMoveConstructor, KEYCXX)

// GNU and MS Type Traits
TYPE_TRAIT_2(__builtin_is_virtual_base_of, IsVirtualBaseOf, KEYCXX)
TYPE_TRAIT_1(__has_nothrow_assign, HasNothrowAssign, KEYCXX)
TYPE_TRAIT_1(__has_nothrow_copy, HasNothrowCopy, KEYCXX)
TYPE_TRAIT_1(__has_nothrow_constructor, HasNothrowConstructor, KEYCXX)
Expand Down Expand Up @@ -596,6 +597,8 @@ ALIAS("__is_same_as", __is_same, KEYCXX)
KEYWORD(__private_extern__ , KEYALL)
KEYWORD(__module_private__ , KEYALL)

UNARY_EXPR_OR_TYPE_TRAIT(__builtin_ptrauth_type_discriminator, PtrAuthTypeDiscriminator, KEYALL)

// Extension that will be enabled for Microsoft, Borland and PS4, but can be
// disabled via '-fno-declspec'.
KEYWORD(__declspec , 0)
Expand Down
64 changes: 32 additions & 32 deletions clang/include/clang/Basic/arm_neon.td
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ def SPLATQ : WInst<"splat_laneq", ".(!Q)I",
"UcUsUicsilPcPsfQUcQUsQUiQcQsQiQPcQPsQflUlQlQUlhdQhQdPlQPl"> {
let isLaneQ = 1;
}
let TargetGuard = "bf16" in {
let TargetGuard = "bf16,neon" in {
def SPLAT_BF : WInst<"splat_lane", ".(!q)I", "bQb">;
def SPLATQ_BF : WInst<"splat_laneq", ".(!Q)I", "bQb"> {
let isLaneQ = 1;
Expand Down Expand Up @@ -323,7 +323,7 @@ def VMLSL : SOpInst<"vmlsl", "(>Q)(>Q)..", "csiUcUsUi", OP_MLSL>;
def VQDMULH : SInst<"vqdmulh", "...", "siQsQi">;
def VQRDMULH : SInst<"vqrdmulh", "...", "siQsQi">;

let TargetGuard = "v8.1a" in {
let TargetGuard = "v8.1a,neon" in {
def VQRDMLAH : SInst<"vqrdmlah", "....", "siQsQi">;
def VQRDMLSH : SInst<"vqrdmlsh", "....", "siQsQi">;
}
Expand Down Expand Up @@ -614,7 +614,7 @@ def A64_VQDMULH_LANE : SInst<"vqdmulh_lane", "..(!q)I", "siQsQi">;
def A64_VQRDMULH_LANE : SInst<"vqrdmulh_lane", "..(!q)I", "siQsQi">;
}

let TargetGuard = "v8.1a" in {
let TargetGuard = "v8.1a,neon" in {
def VQRDMLAH_LANE : SOpInst<"vqrdmlah_lane", "...qI", "siQsQi", OP_QRDMLAH_LN>;
def VQRDMLSH_LANE : SOpInst<"vqrdmlsh_lane", "...qI", "siQsQi", OP_QRDMLSH_LN>;
}
Expand Down Expand Up @@ -957,7 +957,7 @@ def VQDMLAL_HIGH : SOpInst<"vqdmlal_high", "(>Q)(>Q)QQ", "si", OP_QDMLALHi>;
def VQDMLAL_HIGH_N : SOpInst<"vqdmlal_high_n", "(>Q)(>Q)Q1", "si", OP_QDMLALHi_N>;
def VQDMLSL_HIGH : SOpInst<"vqdmlsl_high", "(>Q)(>Q)QQ", "si", OP_QDMLSLHi>;
def VQDMLSL_HIGH_N : SOpInst<"vqdmlsl_high_n", "(>Q)(>Q)Q1", "si", OP_QDMLSLHi_N>;
let TargetGuard = "aes" in {
let TargetGuard = "aes,neon" in {
def VMULL_P64 : SInst<"vmull", "(1>)11", "Pl">;
def VMULL_HIGH_P64 : SOpInst<"vmull_high", "(1>)..", "HPl", OP_MULLHi_P64>;
}
Expand Down Expand Up @@ -1091,7 +1091,7 @@ let isLaneQ = 1 in {
def VQDMULH_LANEQ : SInst<"vqdmulh_laneq", "..QI", "siQsQi">;
def VQRDMULH_LANEQ : SInst<"vqrdmulh_laneq", "..QI", "siQsQi">;
}
let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "v8.1a" in {
let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "v8.1a,neon" in {
def VQRDMLAH_LANEQ : SOpInst<"vqrdmlah_laneq", "...QI", "siQsQi", OP_QRDMLAH_LN> {
let isLaneQ = 1;
}
Expand Down Expand Up @@ -1122,14 +1122,14 @@ def VEXT_A64 : WInst<"vext", "...I", "dQdPlQPl">;

////////////////////////////////////////////////////////////////////////////////
// Crypto
let ArchGuard = "__ARM_ARCH >= 8", TargetGuard = "aes" in {
let ArchGuard = "__ARM_ARCH >= 8", TargetGuard = "aes,neon" in {
def AESE : SInst<"vaese", "...", "QUc">;
def AESD : SInst<"vaesd", "...", "QUc">;
def AESMC : SInst<"vaesmc", "..", "QUc">;
def AESIMC : SInst<"vaesimc", "..", "QUc">;
}

let ArchGuard = "__ARM_ARCH >= 8", TargetGuard = "sha2" in {
let ArchGuard = "__ARM_ARCH >= 8", TargetGuard = "sha2,neon" in {
def SHA1H : SInst<"vsha1h", "11", "Ui">;
def SHA1SU1 : SInst<"vsha1su1", "...", "QUi">;
def SHA256SU0 : SInst<"vsha256su0", "...", "QUi">;
Expand All @@ -1143,7 +1143,7 @@ def SHA256H2 : SInst<"vsha256h2", "....", "QUi">;
def SHA256SU1 : SInst<"vsha256su1", "....", "QUi">;
}

let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "sha3" in {
let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "sha3,neon" in {
def BCAX : SInst<"vbcax", "....", "QUcQUsQUiQUlQcQsQiQl">;
def EOR3 : SInst<"veor3", "....", "QUcQUsQUiQUlQcQsQiQl">;
def RAX1 : SInst<"vrax1", "...", "QUl">;
Expand All @@ -1153,14 +1153,14 @@ def XAR : SInst<"vxar", "...I", "QUl">;
}
}

let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "sha3" in {
let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "sha3,neon" in {
def SHA512SU0 : SInst<"vsha512su0", "...", "QUl">;
def SHA512su1 : SInst<"vsha512su1", "....", "QUl">;
def SHA512H : SInst<"vsha512h", "....", "QUl">;
def SHA512H2 : SInst<"vsha512h2", "....", "QUl">;
}

let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "sm4" in {
let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "sm4,neon" in {
def SM3SS1 : SInst<"vsm3ss1", "....", "QUi">;
def SM3TT1A : SInst<"vsm3tt1a", "....I", "QUi">;
def SM3TT1B : SInst<"vsm3tt1b", "....I", "QUi">;
Expand All @@ -1170,7 +1170,7 @@ def SM3PARTW1 : SInst<"vsm3partw1", "....", "QUi">;
def SM3PARTW2 : SInst<"vsm3partw2", "....", "QUi">;
}

let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "sm4" in {
let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "sm4,neon" in {
def SM4E : SInst<"vsm4e", "...", "QUi">;
def SM4EKEY : SInst<"vsm4ekey", "...", "QUi">;
}
Expand Down Expand Up @@ -1227,7 +1227,7 @@ def FRINTZ_S64 : SInst<"vrnd", "..", "dQd">;
def FRINTI_S64 : SInst<"vrndi", "..", "dQd">;
}

let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "v8.5a" in {
let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "v8.5a,neon" in {
def FRINT32X_S32 : SInst<"vrnd32x", "..", "fQf">;
def FRINT32Z_S32 : SInst<"vrnd32z", "..", "fQf">;
def FRINT64X_S32 : SInst<"vrnd64x", "..", "fQf">;
Expand Down Expand Up @@ -1401,7 +1401,7 @@ def SCALAR_SQDMULH : SInst<"vqdmulh", "111", "SsSi">;
// Scalar Integer Saturating Rounding Doubling Multiply Half High
def SCALAR_SQRDMULH : SInst<"vqrdmulh", "111", "SsSi">;

let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "v8.1a" in {
let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "v8.1a,neon" in {
////////////////////////////////////////////////////////////////////////////////
// Signed Saturating Rounding Doubling Multiply Accumulate Returning High Half
def SCALAR_SQRDMLAH : SInst<"vqrdmlah", "1111", "SsSi">;
Expand Down Expand Up @@ -1632,7 +1632,7 @@ def SCALAR_SQRDMULH_LANEQ : SOpInst<"vqrdmulh_laneq", "11QI", "SsSi", OP_SCALAR_
let isLaneQ = 1;
}

let TargetGuard = "v8.1a" in {
let TargetGuard = "v8.1a,neon" in {
// Signed Saturating Rounding Doubling Multiply Accumulate Returning High Half
def SCALAR_SQRDMLAH_LANE : SOpInst<"vqrdmlah_lane", "111.I", "SsSi", OP_SCALAR_QRDMLAH_LN>;
def SCALAR_SQRDMLAH_LANEQ : SOpInst<"vqrdmlah_laneq", "111QI", "SsSi", OP_SCALAR_QRDMLAH_LN> {
Expand All @@ -1654,7 +1654,7 @@ def SCALAR_VDUP_LANEQ : IInst<"vdup_laneq", "1QI", "ScSsSiSlSfSdSUcSUsSUiSUlSPcS
} // ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)"

// ARMv8.2-A FP16 vector intrinsics for A32/A64.
let TargetGuard = "fullfp16" in {
let TargetGuard = "fullfp16,neon" in {

// ARMv8.2-A FP16 one-operand vector intrinsics.

Expand All @@ -1679,7 +1679,7 @@ let TargetGuard = "fullfp16" in {
def VCVTP_U16 : SInst<"vcvtp_u16", "U.", "hQh">;

// Vector rounding
let ArchGuard = "__ARM_ARCH >= 8 && defined(__ARM_FEATURE_DIRECTED_ROUNDING)", TargetGuard = "fullfp16" in {
let ArchGuard = "__ARM_ARCH >= 8 && defined(__ARM_FEATURE_DIRECTED_ROUNDING)", TargetGuard = "fullfp16,neon" in {
def FRINTZH : SInst<"vrnd", "..", "hQh">;
def FRINTNH : SInst<"vrndn", "..", "hQh">;
def FRINTAH : SInst<"vrnda", "..", "hQh">;
Expand Down Expand Up @@ -1728,7 +1728,7 @@ let TargetGuard = "fullfp16" in {
// Max/Min
def VMAXH : SInst<"vmax", "...", "hQh">;
def VMINH : SInst<"vmin", "...", "hQh">;
let ArchGuard = "__ARM_ARCH >= 8 && defined(__ARM_FEATURE_NUMERIC_MAXMIN)", TargetGuard = "fullfp16" in {
let ArchGuard = "__ARM_ARCH >= 8 && defined(__ARM_FEATURE_NUMERIC_MAXMIN)", TargetGuard = "fullfp16,neon" in {
def FMAXNMH : SInst<"vmaxnm", "...", "hQh">;
def FMINNMH : SInst<"vminnm", "...", "hQh">;
}
Expand Down Expand Up @@ -1775,7 +1775,7 @@ def VEXTH : WInst<"vext", "...I", "hQh">;
def VREV64H : WOpInst<"vrev64", "..", "hQh", OP_REV64>;

// ARMv8.2-A FP16 vector intrinsics for A64 only.
let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "fullfp16" in {
let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "fullfp16,neon" in {

// Vector rounding
def FRINTIH : SInst<"vrndi", "..", "hQh">;
Expand Down Expand Up @@ -1872,19 +1872,19 @@ let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)" in {
}

// v8.2-A dot product instructions.
let TargetGuard = "dotprod" in {
let TargetGuard = "dotprod,neon" in {
def DOT : SInst<"vdot", "..(<<)(<<)", "iQiUiQUi">;
def DOT_LANE : SOpInst<"vdot_lane", "..(<<)(<<q)I", "iUiQiQUi", OP_DOT_LN>;
}
let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "dotprod" in {
let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "dotprod,neon" in {
// Variants indexing into a 128-bit vector are A64 only.
def UDOT_LANEQ : SOpInst<"vdot_laneq", "..(<<)(<<Q)I", "iUiQiQUi", OP_DOT_LNQ> {
let isLaneQ = 1;
}
}

// v8.2-A FP16 fused multiply-add long instructions.
let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "fp16fml" in {
let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "fp16fml,neon" in {
def VFMLAL_LOW : SInst<"vfmlal_low", ">>..", "hQh">;
def VFMLSL_LOW : SInst<"vfmlsl_low", ">>..", "hQh">;
def VFMLAL_HIGH : SInst<"vfmlal_high", ">>..", "hQh">;
Expand All @@ -1909,7 +1909,7 @@ let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "f
}
}

let TargetGuard = "i8mm" in {
let TargetGuard = "i8mm,neon" in {
def VMMLA : SInst<"vmmla", "..(<<)(<<)", "QUiQi">;
def VUSMMLA : SInst<"vusmmla", "..(<<U)(<<)", "Qi">;

Expand All @@ -1926,7 +1926,7 @@ let TargetGuard = "i8mm" in {
}
}

let TargetGuard = "bf16" in {
let TargetGuard = "bf16,neon" in {
def VDOT_BF : SInst<"vbfdot", "..BB", "fQf">;
def VDOT_LANE_BF : SOpInst<"vbfdot_lane", "..B(Bq)I", "fQf", OP_BFDOT_LN>;
def VDOT_LANEQ_BF : SOpInst<"vbfdot_laneq", "..B(BQ)I", "fQf", OP_BFDOT_LNQ> {
Expand Down Expand Up @@ -1970,31 +1970,31 @@ multiclass VCMLA_ROTS<string type, string lanety, string laneqty> {
}

// v8.3-A Vector complex addition intrinsics
let TargetGuard = "v8.3a,fullfp16" in {
let TargetGuard = "v8.3a,fullfp16,neon" in {
def VCADD_ROT90_FP16 : SInst<"vcadd_rot90", "...", "h">;
def VCADD_ROT270_FP16 : SInst<"vcadd_rot270", "...", "h">;
def VCADDQ_ROT90_FP16 : SInst<"vcaddq_rot90", "QQQ", "h">;
def VCADDQ_ROT270_FP16 : SInst<"vcaddq_rot270", "QQQ", "h">;

defm VCMLA_FP16 : VCMLA_ROTS<"h", "uint32x2_t", "uint32x4_t">;
}
let TargetGuard = "v8.3a" in {
let TargetGuard = "v8.3a,neon" in {
def VCADD_ROT90 : SInst<"vcadd_rot90", "...", "f">;
def VCADD_ROT270 : SInst<"vcadd_rot270", "...", "f">;
def VCADDQ_ROT90 : SInst<"vcaddq_rot90", "QQQ", "f">;
def VCADDQ_ROT270 : SInst<"vcaddq_rot270", "QQQ", "f">;

defm VCMLA_F32 : VCMLA_ROTS<"f", "uint64x1_t", "uint64x2_t">;
}
let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "v8.3a" in {
let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "v8.3a,neon" in {
def VCADDQ_ROT90_FP64 : SInst<"vcaddq_rot90", "QQQ", "d">;
def VCADDQ_ROT270_FP64 : SInst<"vcaddq_rot270", "QQQ", "d">;

defm VCMLA_FP64 : VCMLA_ROTS<"d", "uint64x2_t", "uint64x2_t">;
}

// V8.2-A BFloat intrinsics
let TargetGuard = "bf16" in {
let TargetGuard = "bf16,neon" in {
def VCREATE_BF : NoTestOpInst<"vcreate", ".(IU>)", "b", OP_CAST> {
let BigEndianSafe = 1;
}
Expand Down Expand Up @@ -2058,14 +2058,14 @@ let TargetGuard = "bf16" in {
def SCALAR_CVT_F32_BF16 : SOpInst<"vcvtah_f32", "(1F>)(1!)", "b", OP_CVT_F32_BF16>;
}

let ArchGuard = "!defined(__aarch64__) && !defined(__arm64ec__)", TargetGuard = "bf16" in {
let ArchGuard = "!defined(__aarch64__) && !defined(__arm64ec__)", TargetGuard = "bf16,neon" in {
def VCVT_BF16_F32_A32_INTERNAL : WInst<"__a32_vcvt_bf16", "BQ", "f">;
def VCVT_BF16_F32_A32 : SOpInst<"vcvt_bf16", "BQ", "f", OP_VCVT_BF16_F32_A32>;
def VCVT_LOW_BF16_F32_A32 : SOpInst<"vcvt_low_bf16", "BQ", "Qf", OP_VCVT_BF16_F32_LO_A32>;
def VCVT_HIGH_BF16_F32_A32 : SOpInst<"vcvt_high_bf16", "BBQ", "Qf", OP_VCVT_BF16_F32_HI_A32>;
}

let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "bf16" in {
let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "bf16,neon" in {
def VCVT_LOW_BF16_F32_A64_INTERNAL : WInst<"__a64_vcvtq_low_bf16", "BQ", "Hf">;
def VCVT_LOW_BF16_F32_A64 : SOpInst<"vcvt_low_bf16", "BQ", "Qf", OP_VCVT_BF16_F32_LO_A64>;
def VCVT_HIGH_BF16_F32_A64 : SInst<"vcvt_high_bf16", "BBQ", "Qf">;
Expand All @@ -2077,22 +2077,22 @@ let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "b
def COPYQ_LANEQ_BF16 : IOpInst<"vcopy_laneq", "..I.I", "Qb", OP_COPY_LN>;
}

let ArchGuard = "!defined(__aarch64__) && !defined(__arm64ec__)", TargetGuard = "bf16" in {
let ArchGuard = "!defined(__aarch64__) && !defined(__arm64ec__)", TargetGuard = "bf16,neon" in {
let BigEndianSafe = 1 in {
defm VREINTERPRET_BF : REINTERPRET_CROSS_TYPES<
"csilUcUsUiUlhfPcPsPlQcQsQiQlQUcQUsQUiQUlQhQfQPcQPsQPl", "bQb">;
}
}

let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "bf16" in {
let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "bf16,neon" in {
let BigEndianSafe = 1 in {
defm VVREINTERPRET_BF : REINTERPRET_CROSS_TYPES<
"csilUcUsUiUlhfdPcPsPlQcQsQiQlQUcQUsQUiQUlQhQfQdQPcQPsQPlQPk", "bQb">;
}
}

// v8.9a/v9.4a LRCPC3 intrinsics
let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "rcpc3" in {
let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "rcpc3,neon" in {
def VLDAP1_LANE : WInst<"vldap1_lane", ".(c*!).I", "QUlQlUlldQdPlQPl">;
def VSTL1_LANE : WInst<"vstl1_lane", "v*(.!)I", "QUlQlUlldQdPlQPl">;
}
2 changes: 1 addition & 1 deletion clang/include/clang/Basic/arm_neon_incl.td
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ class Inst <string n, string p, string t, Operation o> {
string Prototype = p;
string Types = t;
string ArchGuard = "";
string TargetGuard = "";
string TargetGuard = "neon";

Operation Operation = o;
bit BigEndianSafe = 0;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//===-- CodeGen/ObjectFilePCHContainerOperations.h - ------------*- C++ -*-===//
//===-- CodeGen/ObjectFilePCHContainerWriter.h ------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
Expand Down Expand Up @@ -29,14 +29,6 @@ class ObjectFilePCHContainerWriter : public PCHContainerWriter {
std::shared_ptr<PCHBuffer> Buffer) const override;
};

/// A PCHContainerReader implementation that uses LLVM to
/// wraps Clang modules inside a COFF, ELF, or Mach-O container.
class ObjectFilePCHContainerReader : public PCHContainerReader {
ArrayRef<StringRef> getFormats() const override;

/// Returns the serialized AST inside the PCH container Buffer.
StringRef ExtractPCH(llvm::MemoryBufferRef Buffer) const override;
};
}

#endif
51 changes: 38 additions & 13 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -1117,8 +1117,7 @@ def cl_single_precision_constant : Flag<["-"], "cl-single-precision-constant">,
MarshallingInfoFlag<LangOpts<"SinglePrecisionConstants">>;
def cl_finite_math_only : Flag<["-"], "cl-finite-math-only">, Group<opencl_Group>,
Visibility<[ClangOption, CC1Option]>,
HelpText<"OpenCL only. Allow floating-point optimizations that assume arguments and results are not NaNs or +-Inf.">,
MarshallingInfoFlag<LangOpts<"CLFiniteMathOnly">>;
HelpText<"OpenCL only. Allow floating-point optimizations that assume arguments and results are not NaNs or +-Inf.">;
def cl_kernel_arg_info : Flag<["-"], "cl-kernel-arg-info">, Group<opencl_Group>,
Visibility<[ClangOption, CC1Option]>,
HelpText<"OpenCL only. Generate kernel argument metadata.">,
Expand Down Expand Up @@ -1165,19 +1164,19 @@ def client__name : JoinedOrSeparate<["-"], "client_name">;
def combine : Flag<["-", "--"], "combine">, Flags<[NoXarchOption, Unsupported]>;
def compatibility__version : JoinedOrSeparate<["-"], "compatibility_version">;
def config : Joined<["--"], "config=">, Flags<[NoXarchOption]>,
Visibility<[ClangOption, CLOption, DXCOption]>, MetaVarName<"<file>">,
Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>, MetaVarName<"<file>">,
HelpText<"Specify configuration file">;
def : Separate<["--"], "config">, Alias<config>;
def : Separate<["--"], "config">, Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>, Alias<config>;
def no_default_config : Flag<["--"], "no-default-config">,
Flags<[NoXarchOption]>, Visibility<[ClangOption, CLOption, DXCOption]>,
Flags<[NoXarchOption]>, Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>,
HelpText<"Disable loading default configuration files">;
def config_system_dir_EQ : Joined<["--"], "config-system-dir=">,
Flags<[NoXarchOption, HelpHidden]>,
Visibility<[ClangOption, CLOption, DXCOption]>,
Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>,
HelpText<"System directory for configuration files">;
def config_user_dir_EQ : Joined<["--"], "config-user-dir=">,
Flags<[NoXarchOption, HelpHidden]>,
Visibility<[ClangOption, CLOption, DXCOption]>,
Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>,
HelpText<"User directory for configuration files">;
def coverage : Flag<["-", "--"], "coverage">, Group<Link_Group>,
Visibility<[ClangOption, CLOption]>;
Expand Down Expand Up @@ -2609,13 +2608,12 @@ defm approx_func : BoolFOption<"approx-func", LangOpts<"ApproxFunc">, DefaultFal
"with an approximately equivalent calculation",
[funsafe_math_optimizations.KeyPath]>,
NegFlag<SetFalse, [], [ClangOption, CC1Option, FC1Option, FlangOption]>>;
defm finite_math_only : BoolFOption<"finite-math-only",
LangOpts<"FiniteMathOnly">, DefaultFalse,
defm finite_math_only : BoolOptionWithoutMarshalling<"f", "finite-math-only",
PosFlag<SetTrue, [], [ClangOption, CC1Option],
"Allow floating-point optimizations that "
"assume arguments and results are not NaNs or +-inf. This defines "
"the \\_\\_FINITE\\_MATH\\_ONLY\\_\\_ preprocessor macro.",
[cl_finite_math_only.KeyPath, ffast_math.KeyPath]>,
[ffast_math.KeyPath]>,
NegFlag<SetFalse>>;
defm signed_zeros : BoolFOption<"signed-zeros",
LangOpts<"NoSignedZero">, DefaultFalse,
Expand Down Expand Up @@ -3232,6 +3230,10 @@ def fimplicit_module_maps : Flag <["-"], "fimplicit-module-maps">, Group<f_Group
Visibility<[ClangOption, CC1Option, CLOption]>,
HelpText<"Implicitly search the file system for module map files.">,
MarshallingInfoFlag<HeaderSearchOpts<"ImplicitModuleMaps">>;
defm modulemap_allow_subdirectory_search : BoolFOption <"modulemap-allow-subdirectory-search",
HeaderSearchOpts<"AllowModuleMapSubdirectorySearch">, DefaultTrue,
PosFlag<SetTrue, [], [], "Allow to search for module maps in subdirectories of search paths">,
NegFlag<SetFalse>, BothFlags<[NoXarchOption], [ClangOption, CC1Option]>>;
defm modules : BoolFOption<"modules",
LangOpts<"Modules">, Default<fcxx_modules.KeyPath>,
PosFlag<SetTrue, [], [ClangOption, CC1Option],
Expand Down Expand Up @@ -3998,6 +4000,10 @@ def ftime_trace_granularity_EQ : Joined<["-"], "ftime-trace-granularity=">, Grou
HelpText<"Minimum time granularity (in microseconds) traced by time profiler">,
Visibility<[ClangOption, CC1Option, CLOption, DXCOption]>,
MarshallingInfoInt<FrontendOpts<"TimeTraceGranularity">, "500u">;
def ftime_trace_verbose : Joined<["-"], "ftime-trace-verbose">, Group<f_Group>,
HelpText<"Make time trace capture verbose event details (e.g. source filenames). This can increase the size of the output by 2-3 times">,
Visibility<[ClangOption, CC1Option, CLOption, DXCOption]>,
MarshallingInfoFlag<FrontendOpts<"TimeTraceVerbose">>;
def ftime_trace_EQ : Joined<["-"], "ftime-trace=">, Group<f_Group>,
HelpText<"Similar to -ftime-trace. Specify the JSON file or a directory which will contain the JSON file">,
Visibility<[ClangOption, CC1Option, CLOption, DXCOption]>,
Expand Down Expand Up @@ -4245,9 +4251,13 @@ defm ptrauth_vtable_pointer_address_discrimination :
OptInCC1FFlag<"ptrauth-vtable-pointer-address-discrimination", "Enable address discrimination of vtable pointers">;
defm ptrauth_vtable_pointer_type_discrimination :
OptInCC1FFlag<"ptrauth-vtable-pointer-type-discrimination", "Enable type discrimination of vtable pointers">;
defm ptrauth_type_info_vtable_pointer_discrimination :
OptInCC1FFlag<"ptrauth-type-info-vtable-pointer-discrimination", "Enable type and address discrimination of vtable pointer of std::type_info">;
defm ptrauth_init_fini : OptInCC1FFlag<"ptrauth-init-fini", "Enable signing of function pointers in init/fini arrays">;
defm ptrauth_function_pointer_type_discrimination : OptInCC1FFlag<"ptrauth-function-pointer-type-discrimination",
"Enable type discrimination on C function pointers">;
defm ptrauth_indirect_gotos : OptInCC1FFlag<"ptrauth-indirect-gotos",
"Enable signing and authentication of indirect goto targets">;
}

def fenable_matrix : Flag<["-"], "fenable-matrix">, Group<f_Group>,
Expand Down Expand Up @@ -5077,6 +5087,11 @@ def mspe : Flag<["-"], "mspe">, Group<m_ppc_Features_Group>;
def mno_spe : Flag<["-"], "mno-spe">, Group<m_ppc_Features_Group>;
def mefpu2 : Flag<["-"], "mefpu2">, Group<m_ppc_Features_Group>;
} // let Flags = [TargetSpecific]
def msave_reg_params : Flag<["-"], "msave-reg-params">, Group<m_Group>,
Flags<[TargetSpecific]>,
Visibility<[ClangOption, CC1Option]>,
HelpText<"Save arguments passed by registers to ABI-defined stack positions">,
MarshallingInfoFlag<CodeGenOpts<"SaveRegParams">>;
def mabi_EQ_quadword_atomics : Flag<["-"], "mabi=quadword-atomics">,
Group<m_Group>, Visibility<[ClangOption, CC1Option]>,
HelpText<"Enable quadword atomics ABI on AIX (AIX PPC64 only). Uses lqarx/stqcx. instructions.">,
Expand Down Expand Up @@ -7517,6 +7532,9 @@ def code_completion_brief_comments : Flag<["-"], "code-completion-brief-comments
def code_completion_with_fixits : Flag<["-"], "code-completion-with-fixits">,
HelpText<"Include code completion results which require small fix-its.">,
MarshallingInfoFlag<FrontendOpts<"CodeCompleteOpts.IncludeFixIts">>;
def skip_function_bodies : Flag<["-"], "skip-function-bodies">,
HelpText<"Skip function bodies when possible">,
MarshallingInfoFlag<FrontendOpts<"SkipFunctionBodies">>;
def disable_free : Flag<["-"], "disable-free">,
HelpText<"Disable freeing of memory on exit">,
MarshallingInfoFlag<FrontendOpts<"DisableFree">>;
Expand Down Expand Up @@ -7795,10 +7813,10 @@ def mreassociate : Flag<["-"], "mreassociate">,
MarshallingInfoFlag<LangOpts<"AllowFPReassoc">>, ImpliedByAnyOf<[funsafe_math_optimizations.KeyPath]>;
def menable_no_nans : Flag<["-"], "menable-no-nans">,
HelpText<"Allow optimization to assume there are no NaNs.">,
MarshallingInfoFlag<LangOpts<"NoHonorNaNs">>, ImpliedByAnyOf<[ffinite_math_only.KeyPath]>;
def menable_no_infinities : Flag<["-"], "menable-no-infs">,
MarshallingInfoFlag<LangOpts<"NoHonorNaNs">>, ImpliedByAnyOf<[ffast_math.KeyPath]>;
def menable_no_infs : Flag<["-"], "menable-no-infs">,
HelpText<"Allow optimization to assume there are no infinities.">,
MarshallingInfoFlag<LangOpts<"NoHonorInfs">>, ImpliedByAnyOf<[ffinite_math_only.KeyPath]>;
MarshallingInfoFlag<LangOpts<"NoHonorInfs">>, ImpliedByAnyOf<[ffast_math.KeyPath]>;

def pic_level : Separate<["-"], "pic-level">,
HelpText<"Value for __PIC__">,
Expand Down Expand Up @@ -8078,6 +8096,13 @@ def source_date_epoch : Separate<["-"], "source-date-epoch">,

} // let Visibility = [CC1Option]

defm err_pragma_mc_func_aix : BoolFOption<"err-pragma-mc-func-aix",
PreprocessorOpts<"ErrorOnPragmaMcfuncOnAIX">, DefaultFalse,
PosFlag<SetTrue, [], [ClangOption, CC1Option],
"Treat uses of #pragma mc_func as errors">,
NegFlag<SetFalse,[], [ClangOption, CC1Option],
"Ignore uses of #pragma mc_func">>;

//===----------------------------------------------------------------------===//
// CUDA Options
//===----------------------------------------------------------------------===//
Expand Down
8 changes: 7 additions & 1 deletion clang/include/clang/Frontend/FrontendOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,11 @@ class FrontendOptions {
/// Minimum time granularity (in microseconds) traced by time profiler.
unsigned TimeTraceGranularity;

/// Make time trace capture verbose event details (e.g. source filenames).
/// This can increase the size of the output by 2-3 times.
LLVM_PREFERRED_TYPE(bool)
unsigned TimeTraceVerbose : 1;

/// Path which stores the output files for -ftime-trace
std::string TimeTracePath;

Expand All @@ -601,7 +606,8 @@ class FrontendOptions {
EmitSymbolGraph(false), EmitExtensionSymbolGraphs(false),
EmitSymbolGraphSymbolLabelsForTesting(false),
EmitPrettySymbolGraphs(false), GenReducedBMI(false),
UseClangIRPipeline(false), TimeTraceGranularity(500) {}
UseClangIRPipeline(false), TimeTraceGranularity(500),
TimeTraceVerbose(false) {}

/// getInputKindForExtension - Return the appropriate input kind for a file
/// extension. For example, "c" would return Language::C.
Expand Down
9 changes: 8 additions & 1 deletion clang/include/clang/Lex/HeaderSearchOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,12 @@ class HeaderSearchOptions {
LLVM_PREFERRED_TYPE(bool)
unsigned ModulesIncludeVFSUsage : 1;

/// Whether we should look for a module in module maps only in provided
/// header search paths or if we are allowed to look for module maps in
/// subdirectories of provided paths too.
LLVM_PREFERRED_TYPE(bool)
unsigned AllowModuleMapSubdirectorySearch : 1;

HeaderSearchOptions(StringRef _Sysroot = "/")
: Sysroot(_Sysroot), ModuleFormat("raw"), DisableModuleHash(false),
ImplicitModuleMaps(false), ModuleMapFileHomeIsCwd(false),
Expand All @@ -285,7 +291,8 @@ class HeaderSearchOptions {
ModulesSkipHeaderSearchPaths(false),
ModulesSkipPragmaDiagnosticMappings(false),
ModulesPruneNonAffectingModuleMaps(true), ModulesHashContent(false),
ModulesStrictContextHash(false), ModulesIncludeVFSUsage(false) {}
ModulesStrictContextHash(false), ModulesIncludeVFSUsage(false),
AllowModuleMapSubdirectorySearch(true) {}

/// AddPath - Add the \p Path path to the specified \p Group list.
void AddPath(StringRef Path, frontend::IncludeDirGroup Group,
Expand Down
5 changes: 5 additions & 0 deletions clang/include/clang/Lex/PreprocessorOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,10 @@ class PreprocessorOptions {
/// If set, the UNIX timestamp specified by SOURCE_DATE_EPOCH.
std::optional<uint64_t> SourceDateEpoch;

/// If set, the preprocessor reports an error when processing #pragma mc_func
/// on AIX.
bool ErrorOnPragmaMcfuncOnAIX = false;

public:
PreprocessorOptions() : PrecompiledPreambleBytes(0, false) {}

Expand Down Expand Up @@ -248,6 +252,7 @@ class PreprocessorOptions {
PrecompiledPreambleBytes.first = 0;
PrecompiledPreambleBytes.second = false;
RetainExcludedConditionalBlocks = false;
ErrorOnPragmaMcfuncOnAIX = false;
}
};

Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Parse/Parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ class Parser : public CodeCompletionHandler {
std::unique_ptr<PragmaHandler> MaxTokensHerePragmaHandler;
std::unique_ptr<PragmaHandler> MaxTokensTotalPragmaHandler;
std::unique_ptr<PragmaHandler> RISCVPragmaHandler;
std::unique_ptr<PragmaHandler> MCFuncPragmaHandler;

std::unique_ptr<CommentHandler> CommentSemaHandler;

Expand Down Expand Up @@ -3889,6 +3890,8 @@ class Parser : public CodeCompletionHandler {
ExprResult ParseArrayTypeTrait();
ExprResult ParseExpressionTrait();

ExprResult ParseBuiltinPtrauthTypeDiscriminator();

//===--------------------------------------------------------------------===//
// Preprocessor code-completion pass-through
void CodeCompleteDirective(bool InConditional) override;
Expand Down
4 changes: 3 additions & 1 deletion clang/include/clang/Sema/Overload.h
Original file line number Diff line number Diff line change
Expand Up @@ -998,7 +998,9 @@ class Sema;
private:
friend class OverloadCandidateSet;
OverloadCandidate()
: IsSurrogate(false), IsADLCandidate(CallExpr::NotADL), RewriteKind(CRK_None) {}
: IsSurrogate(false), IgnoreObjectArgument(false),
TookAddressOfOverload(false), IsADLCandidate(CallExpr::NotADL),
RewriteKind(CRK_None) {}
};

/// OverloadCandidateSet - A set of overload candidates, used in C++
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -2214,6 +2214,7 @@ class Sema final : public SemaBase {
FST_FreeBSDKPrintf,
FST_OSTrace,
FST_OSLog,
FST_Syslog,
FST_Unknown
};
static FormatStringType GetFormatStringType(const FormatAttr *Format);
Expand Down Expand Up @@ -3456,6 +3457,8 @@ class Sema final : public SemaBase {
TemplateIdAnnotation *TemplateId,
bool IsMemberSpecialization);

bool checkPointerAuthEnabled(SourceLocation Loc, SourceRange Range);

bool checkConstantPointerAuthKey(Expr *keyExpr, unsigned &key);

/// Diagnose function specifiers on a declaration of an identifier that
Expand Down
23 changes: 1 addition & 22 deletions clang/include/clang/Sema/SemaOpenMP.h
Original file line number Diff line number Diff line change
Expand Up @@ -398,8 +398,7 @@ class SemaOpenMP : public SemaBase {
StmtResult ActOnOpenMPExecutableDirective(
OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName,
OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc,
OpenMPDirectiveKind PrevMappedDirective = llvm::omp::OMPD_unknown);
Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc);
/// Called on well-formed '\#pragma omp parallel' after parsing
/// of the associated statement.
StmtResult ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses,
Expand Down Expand Up @@ -1430,26 +1429,6 @@ class SemaOpenMP : public SemaBase {

/// All `omp assumes` we encountered so far.
SmallVector<OMPAssumeAttr *, 4> OMPAssumeGlobal;

/// OMPD_loop is mapped to OMPD_for, OMPD_distribute or OMPD_simd depending
/// on the parameter of the bind clause. In the methods for the
/// mapped directives, check the parameters of the lastprivate clause.
bool checkLastPrivateForMappedDirectives(ArrayRef<OMPClause *> Clauses);
/// Depending on the bind clause of OMPD_loop map the directive to new
/// directives.
/// 1) loop bind(parallel) --> OMPD_for
/// 2) loop bind(teams) --> OMPD_distribute
/// 3) loop bind(thread) --> OMPD_simd
/// This is being handled in Sema instead of Codegen because of the need for
/// rigorous semantic checking in the new mapped directives.
bool mapLoopConstruct(llvm::SmallVector<OMPClause *> &ClausesWithoutBind,
ArrayRef<OMPClause *> Clauses,
OpenMPBindClauseKind &BindKind,
OpenMPDirectiveKind &Kind,
OpenMPDirectiveKind &PrevMappedDirective,
SourceLocation StartLoc, SourceLocation EndLoc,
const DeclarationNameInfo &DirName,
OpenMPDirectiveKind CancelRegion);
};

} // namespace clang
Expand Down
25 changes: 25 additions & 0 deletions clang/include/clang/Serialization/ObjectFilePCHContainerReader.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//===-- Serialization/ObjectFilePCHContainerReader.h ------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_SERIALIZATION_OBJECTFILEPCHCONTAINERREADER_H
#define LLVM_CLANG_SERIALIZATION_OBJECTFILEPCHCONTAINERREADER_H

#include "clang/Frontend/PCHContainerOperations.h"

namespace clang {
/// A PCHContainerReader implementation that uses LLVM to
/// wraps Clang modules inside a COFF, ELF, or Mach-O container.
class ObjectFilePCHContainerReader : public PCHContainerReader {
ArrayRef<StringRef> getFormats() const override;

/// Returns the serialized AST inside the PCH container Buffer.
StringRef ExtractPCH(llvm::MemoryBufferRef Buffer) const override;
};
} // namespace clang

#endif
12 changes: 0 additions & 12 deletions clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
Original file line number Diff line number Diff line change
Expand Up @@ -1045,18 +1045,6 @@ def MallocOverflowSecurityChecker : Checker<"MallocOverflow">,

def MmapWriteExecChecker : Checker<"MmapWriteExec">,
HelpText<"Warn on mmap() calls that are both writable and executable">,
CheckerOptions<[
CmdLineOption<Integer,
"MmapProtExec",
"Specifies the value of PROT_EXEC",
"0x04",
Released>,
CmdLineOption<Integer,
"MmapProtRead",
"Specifies the value of PROT_READ",
"0x01",
Released>
]>,
Documentation<HasDocumentation>;

def ReturnPointerRangeChecker : Checker<"ReturnPtrRange">,
Expand Down
46 changes: 46 additions & 0 deletions clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,10 @@ class LocAsInteger : public NonLoc {
static bool classof(SVal V) { return V.getKind() == LocAsIntegerKind; }
};

/// The simplest example of a concrete compound value is nonloc::CompoundVal,
/// which represents a concrete r-value of an initializer-list or a string.
/// Internally, it contains an llvm::ImmutableList of SVal's stored inside the
/// literal.
class CompoundVal : public NonLoc {
friend class ento::SValBuilder;

Expand All @@ -346,6 +350,36 @@ class CompoundVal : public NonLoc {
static bool classof(SVal V) { return V.getKind() == CompoundValKind; }
};

/// While nonloc::CompoundVal covers a few simple use cases,
/// nonloc::LazyCompoundVal is a more performant and flexible way to represent
/// an rvalue of record type, so it shows up much more frequently during
/// analysis. This value is an r-value that represents a snapshot of any
/// structure "as a whole" at a given moment during the analysis. Such value is
/// already quite far from being referred to as "concrete", as many fields
/// inside it would be unknown or symbolic. nonloc::LazyCompoundVal operates by
/// storing two things:
/// * a reference to the TypedValueRegion being snapshotted (yes, it is always
/// typed), and also
/// * a reference to the whole Store object, obtained from the ProgramState in
/// which the nonloc::LazyCompoundVal was created.
///
/// Note that the old ProgramState and its Store is kept alive during the
/// analysis because these are immutable functional data structures and each new
/// Store value is represented as "earlier Store" + "additional binding".
///
/// Essentially, nonloc::LazyCompoundVal is a performance optimization for the
/// analyzer. Because Store is immutable, creating a nonloc::LazyCompoundVal is
/// a very cheap operation. Note that the Store contains all region bindings in
/// the program state, not only related to the region. Later, if necessary, such
/// value can be unpacked -- eg. when it is assigned to another variable.
///
/// If you ever need to inspect the contents of the LazyCompoundVal, you can use
/// StoreManager::iterBindings(). It'll iterate through all values in the Store,
/// but you're only interested in the ones that belong to
/// LazyCompoundVal::getRegion(); other bindings are immaterial.
///
/// NOTE: LazyCompoundVal::getRegion() itself is also immaterial (see the actual
/// method docs for details).
class LazyCompoundVal : public NonLoc {
friend class ento::SValBuilder;

Expand All @@ -363,6 +397,18 @@ class LazyCompoundVal : public NonLoc {
/// It might return null.
const void *getStore() const;

/// This function itself is immaterial. It is only an implementation detail.
/// LazyCompoundVal represents only the rvalue, the data (known or unknown)
/// that *was* stored in that region *at some point in the past*. The region
/// should not be used for any purpose other than figuring out what part of
/// the frozen Store you're interested in. The value does not represent the
/// *current* value of that region. Sometimes it may, but this should not be
/// relied upon. Instead, if you want to figure out what region it represents,
/// you typically need to see where you got it from in the first place. The
/// region is absolutely not analogous to the C++ "this" pointer. It is also
/// not a valid way to "materialize" the prvalue into a glvalue in C++,
/// because the region represents the *old* storage (sometimes very old), not
/// the *future* storage.
LLVM_ATTRIBUTE_RETURNS_NONNULL
const TypedValueRegion *getRegion() const;

Expand Down
2 changes: 1 addition & 1 deletion clang/lib/APINotes/APINotesFormat.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const uint16_t VERSION_MAJOR = 0;
/// API notes file minor version number.
///
/// When the format changes IN ANY WAY, this number should be incremented.
const uint16_t VERSION_MINOR = 27; // SingleDeclTableKey
const uint16_t VERSION_MINOR = 28; // nested tags

const uint8_t kSwiftCopyable = 1;
const uint8_t kSwiftNonCopyable = 2;
Expand Down
15 changes: 13 additions & 2 deletions clang/lib/APINotes/APINotesYAMLCompiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,9 @@ template <> struct ScalarEnumerationTraits<EnumConvenienceAliasKind> {
} // namespace llvm

namespace {
struct Tag;
typedef std::vector<Tag> TagsSeq;

struct Tag {
StringRef Name;
AvailabilityItem Availability;
Expand All @@ -421,9 +424,11 @@ struct Tag {
std::optional<EnumConvenienceAliasKind> EnumConvenienceKind;
std::optional<bool> SwiftCopyable;
FunctionsSeq Methods;
};

typedef std::vector<Tag> TagsSeq;
/// Tags that are declared within the current tag. Only the tags that have
/// corresponding API Notes will be listed.
TagsSeq Tags;
};
} // namespace

LLVM_YAML_IS_SEQUENCE_VECTOR(Tag)
Expand Down Expand Up @@ -456,6 +461,7 @@ template <> struct MappingTraits<Tag> {
IO.mapOptional("EnumKind", T.EnumConvenienceKind);
IO.mapOptional("SwiftCopyable", T.SwiftCopyable);
IO.mapOptional("Methods", T.Methods);
IO.mapOptional("Tags", T.Tags);
}
};
} // namespace yaml
Expand Down Expand Up @@ -958,12 +964,17 @@ class YAMLConverter {
ContextInfo CI;
auto TagCtxID = Writer.addContext(ParentContextID, T.Name, ContextKind::Tag,
CI, SwiftVersion);
Context TagCtx(TagCtxID, ContextKind::Tag);

for (const auto &CXXMethod : T.Methods) {
CXXMethodInfo MI;
convertFunction(CXXMethod, MI);
Writer.addCXXMethod(TagCtxID, CXXMethod.Name, MI, SwiftVersion);
}

// Convert nested tags.
for (const auto &Tag : T.Tags)
convertTagContext(TagCtx, Tag, SwiftVersion);
}

void convertTopLevelItems(std::optional<Context> Ctx,
Expand Down
6 changes: 2 additions & 4 deletions clang/lib/AST/ASTConcept.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,9 @@ CreateUnsatisfiedConstraintRecord(const ASTContext &C,
else {
auto &SubstitutionDiagnostic =
*Detail.get<std::pair<SourceLocation, StringRef> *>();
unsigned MessageSize = SubstitutionDiagnostic.second.size();
char *Mem = new (C) char[MessageSize];
memcpy(Mem, SubstitutionDiagnostic.second.data(), MessageSize);
StringRef Message = C.backupStr(SubstitutionDiagnostic.second);
auto *NewSubstDiag = new (C) std::pair<SourceLocation, StringRef>(
SubstitutionDiagnostic.first, StringRef(Mem, MessageSize));
SubstitutionDiagnostic.first, Message);
new (TrailingObject) UnsatisfiedConstraintRecord(NewSubstDiag);
}
}
Expand Down
19 changes: 12 additions & 7 deletions clang/lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3223,14 +3223,16 @@ static void encodeTypeForFunctionPointerAuth(const ASTContext &Ctx,
OS << "<objc_object>";
return;

case Type::Enum:
case Type::Enum: {
// C11 6.7.2.2p4:
// Each enumerated type shall be compatible with char, a signed integer
// type, or an unsigned integer type.
//
// So we have to treat enum types as integers.
QualType UnderlyingType = cast<EnumType>(T)->getDecl()->getIntegerType();
return encodeTypeForFunctionPointerAuth(
Ctx, OS, cast<EnumType>(T)->getDecl()->getIntegerType());
Ctx, OS, UnderlyingType.isNull() ? Ctx.IntTy : UnderlyingType);
}

case Type::FunctionNoProto:
case Type::FunctionProto: {
Expand Down Expand Up @@ -3361,6 +3363,7 @@ static void encodeTypeForFunctionPointerAuth(const ASTContext &Ctx,
#include "clang/Basic/RISCVVTypes.def"
llvm_unreachable("not yet implemented");
}
llvm_unreachable("should never get here");
}
case Type::Record: {
const RecordDecl *RD = T->getAs<RecordType>()->getDecl();
Expand Down Expand Up @@ -3405,7 +3408,7 @@ static void encodeTypeForFunctionPointerAuth(const ASTContext &Ctx,
}
}

uint16_t ASTContext::getPointerAuthTypeDiscriminator(QualType T) const {
uint16_t ASTContext::getPointerAuthTypeDiscriminator(QualType T) {
assert(!T->isDependentType() &&
"cannot compute type discriminator of a dependent type");

Expand All @@ -3415,11 +3418,13 @@ uint16_t ASTContext::getPointerAuthTypeDiscriminator(QualType T) const {
if (T->isFunctionPointerType() || T->isFunctionReferenceType())
T = T->getPointeeType();

if (T->isFunctionType())
if (T->isFunctionType()) {
encodeTypeForFunctionPointerAuth(*this, Out, T);
else
llvm_unreachable(
"type discrimination of non-function type not implemented yet");
} else {
T = T.getUnqualifiedType();
std::unique_ptr<MangleContext> MC(createMangleContext());
MC->mangleCanonicalTypeName(T, Out);
}

return llvm::getPointerAuthStableSipHash(Str);
}
Expand Down
9 changes: 7 additions & 2 deletions clang/lib/AST/ASTImporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2949,7 +2949,7 @@ ExpectedDecl ASTNodeImporter::VisitEnumDecl(EnumDecl *D) {
if (auto *FoundEnum = dyn_cast<EnumDecl>(FoundDecl)) {
if (!hasSameVisibilityContextAndLinkage(FoundEnum, D))
continue;
if (IsStructuralMatch(D, FoundEnum)) {
if (IsStructuralMatch(D, FoundEnum, !SearchName.isEmpty())) {
EnumDecl *FoundDef = FoundEnum->getDefinition();
if (D->isThisDeclarationADefinition() && FoundDef)
return Importer.MapImported(D, FoundDef);
Expand All @@ -2960,7 +2960,12 @@ ExpectedDecl ASTNodeImporter::VisitEnumDecl(EnumDecl *D) {
}
}

if (!ConflictingDecls.empty()) {
// In case of unnamed enums, we try to find an existing similar one, if none
// was found, perform the import always.
// Structural in-equivalence is not detected in this way here, but it may
// be found when the parent decl is imported (if the enum is part of a
// class). To make this totally exact a more difficult solution is needed.
if (SearchName && !ConflictingDecls.empty()) {
ExpectedName NameOrErr = Importer.HandleNameConflict(
SearchName, DC, IDNS, ConflictingDecls.data(),
ConflictingDecls.size());
Expand Down
3 changes: 1 addition & 2 deletions clang/lib/AST/DeclBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -879,8 +879,6 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) {
return IDNS_Ordinary;
case Label:
return IDNS_Label;
case IndirectField:
return IDNS_Ordinary | IDNS_Member;

case Binding:
case NonTypeTemplateParm:
Expand Down Expand Up @@ -918,6 +916,7 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) {
return IDNS_ObjCProtocol;

case Field:
case IndirectField:
case ObjCAtDefsField:
case ObjCIvar:
return IDNS_Member;
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/AST/DeclCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -675,6 +675,9 @@ bool CXXRecordDecl::hasSubobjectAtOffsetZeroOfEmptyBaseType(
if (!IsFirstField && !FD->isZeroSize(Ctx))
continue;

if (FD->isInvalidDecl())
continue;

// -- If X is n array type, [visit the element type]
QualType T = Ctx.getBaseElementType(FD->getType());
if (auto *RD = T->getAsCXXRecordDecl())
Expand Down
25 changes: 17 additions & 8 deletions clang/lib/AST/DeclTemplate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@ using namespace clang;
// TemplateParameterList Implementation
//===----------------------------------------------------------------------===//

template <class TemplateParam>
static bool
DefaultTemplateArgumentContainsUnexpandedPack(const TemplateParam &P) {
return P.hasDefaultArgument() &&
P.getDefaultArgument().getArgument().containsUnexpandedParameterPack();
}

TemplateParameterList::TemplateParameterList(const ASTContext& C,
SourceLocation TemplateLoc,
Expand All @@ -61,27 +67,30 @@ TemplateParameterList::TemplateParameterList(const ASTContext& C,

bool IsPack = P->isTemplateParameterPack();
if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) {
if (!IsPack && NTTP->getType()->containsUnexpandedParameterPack())
if (!IsPack && (NTTP->getType()->containsUnexpandedParameterPack() ||
DefaultTemplateArgumentContainsUnexpandedPack(*NTTP)))
ContainsUnexpandedParameterPack = true;
if (NTTP->hasPlaceholderTypeConstraint())
HasConstrainedParameters = true;
} else if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P)) {
if (!IsPack &&
TTP->getTemplateParameters()->containsUnexpandedParameterPack())
(TTP->getTemplateParameters()->containsUnexpandedParameterPack() ||
DefaultTemplateArgumentContainsUnexpandedPack(*TTP))) {
ContainsUnexpandedParameterPack = true;
}
} else if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) {
if (const TypeConstraint *TC = TTP->getTypeConstraint()) {
if (TC->getImmediatelyDeclaredConstraint()
->containsUnexpandedParameterPack())
ContainsUnexpandedParameterPack = true;
if (!IsPack && DefaultTemplateArgumentContainsUnexpandedPack(*TTP)) {
ContainsUnexpandedParameterPack = true;
} else if (const TypeConstraint *TC = TTP->getTypeConstraint();
TC && TC->getImmediatelyDeclaredConstraint()
->containsUnexpandedParameterPack()) {
ContainsUnexpandedParameterPack = true;
}
if (TTP->hasTypeConstraint())
HasConstrainedParameters = true;
} else {
llvm_unreachable("unexpected template parameter type");
}
// FIXME: If a default argument contains an unexpanded parameter pack, the
// template parameter list does too.
}

if (HasRequiresClause) {
Expand Down
19 changes: 19 additions & 0 deletions clang/lib/AST/ExprCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1944,3 +1944,22 @@ CXXParenListInitExpr *CXXParenListInitExpr::CreateEmpty(ASTContext &C,
alignof(CXXParenListInitExpr));
return new (Mem) CXXParenListInitExpr(Empty, NumExprs);
}

CXXFoldExpr::CXXFoldExpr(QualType T, UnresolvedLookupExpr *Callee,
SourceLocation LParenLoc, Expr *LHS,
BinaryOperatorKind Opcode,
SourceLocation EllipsisLoc, Expr *RHS,
SourceLocation RParenLoc,
std::optional<unsigned> NumExpansions)
: Expr(CXXFoldExprClass, T, VK_PRValue, OK_Ordinary), LParenLoc(LParenLoc),
EllipsisLoc(EllipsisLoc), RParenLoc(RParenLoc),
NumExpansions(NumExpansions ? *NumExpansions + 1 : 0), Opcode(Opcode) {
// We rely on asserted invariant to distinguish left and right folds.
assert(((LHS && LHS->containsUnexpandedParameterPack()) !=
(RHS && RHS->containsUnexpandedParameterPack())) &&
"Exactly one of LHS or RHS should contain an unexpanded pack");
SubExprs[SubExpr::Callee] = Callee;
SubExprs[SubExpr::LHS] = LHS;
SubExprs[SubExpr::RHS] = RHS;
setDependence(computeDependence(this));
}
72 changes: 53 additions & 19 deletions clang/lib/AST/ExprConstant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2401,6 +2401,10 @@ static bool CheckMemberPointerConstantExpression(EvalInfo &Info,
/// produce an appropriate diagnostic.
static bool CheckLiteralType(EvalInfo &Info, const Expr *E,
const LValue *This = nullptr) {
// The restriction to literal types does not exist in C++23 anymore.
if (Info.getLangOpts().CPlusPlus23)
return true;

if (!E->isPRValue() || E->getType()->isLiteralType(Info.Ctx))
return true;

Expand Down Expand Up @@ -2839,6 +2843,8 @@ static bool handleIntIntBinOp(EvalInfo &Info, const BinaryOperator *E,
// During constant-folding, a negative shift is an opposite shift. Such
// a shift is not a constant expression.
Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHS;
if (!Info.noteUndefinedBehavior())
return false;
RHS = -RHS;
goto shift_right;
}
Expand All @@ -2849,19 +2855,23 @@ static bool handleIntIntBinOp(EvalInfo &Info, const BinaryOperator *E,
if (SA != RHS) {
Info.CCEDiag(E, diag::note_constexpr_large_shift)
<< RHS << E->getType() << LHS.getBitWidth();
if (!Info.noteUndefinedBehavior())
return false;
} else if (LHS.isSigned() && !Info.getLangOpts().CPlusPlus20) {
// C++11 [expr.shift]p2: A signed left shift must have a non-negative
// operand, and must not overflow the corresponding unsigned type.
// C++2a [expr.shift]p2: E1 << E2 is the unique value congruent to
// E1 x 2^E2 module 2^N.
if (LHS.isNegative())
if (LHS.isNegative()) {
Info.CCEDiag(E, diag::note_constexpr_lshift_of_negative) << LHS;
else if (LHS.countl_zero() < SA)
if (!Info.noteUndefinedBehavior())
return false;
} else if (LHS.countl_zero() < SA) {
Info.CCEDiag(E, diag::note_constexpr_lshift_discards);
if (!Info.noteUndefinedBehavior())
return false;
}
}
if (Info.EvalStatus.Diag && !Info.EvalStatus.Diag->empty() &&
Info.getLangOpts().CPlusPlus11)
return false;
Result = LHS << SA;
return true;
}
Expand All @@ -2875,20 +2885,22 @@ static bool handleIntIntBinOp(EvalInfo &Info, const BinaryOperator *E,
// During constant-folding, a negative shift is an opposite shift. Such a
// shift is not a constant expression.
Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHS;
if (!Info.noteUndefinedBehavior())
return false;
RHS = -RHS;
goto shift_left;
}
shift_right:
// C++11 [expr.shift]p1: Shift width must be less than the bit width of the
// shifted type.
unsigned SA = (unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
if (SA != RHS)
if (SA != RHS) {
Info.CCEDiag(E, diag::note_constexpr_large_shift)
<< RHS << E->getType() << LHS.getBitWidth();
if (!Info.noteUndefinedBehavior())
return false;
}

if (Info.EvalStatus.Diag && !Info.EvalStatus.Diag->empty() &&
Info.getLangOpts().CPlusPlus11)
return false;
Result = LHS >> SA;
return true;
}
Expand Down Expand Up @@ -12949,19 +12961,35 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
Info.Ctx.getTargetInfo().getMaxAtomicInlineWidth();
if (Size <= Info.Ctx.toCharUnitsFromBits(InlineWidthBits)) {
if (BuiltinOp == Builtin::BI__c11_atomic_is_lock_free ||
Size == CharUnits::One() ||
E->getArg(1)->isNullPointerConstant(Info.Ctx,
Expr::NPC_NeverValueDependent))
// OK, we will inline appropriately-aligned operations of this size,
// and _Atomic(T) is appropriately-aligned.
Size == CharUnits::One())
return Success(1, E);

QualType PointeeType = E->getArg(1)->IgnoreImpCasts()->getType()->
castAs<PointerType>()->getPointeeType();
if (!PointeeType->isIncompleteType() &&
Info.Ctx.getTypeAlignInChars(PointeeType) >= Size) {
// OK, we will inline operations on this object.
// If the pointer argument can be evaluated to a compile-time constant
// integer (or nullptr), check if that value is appropriately aligned.
const Expr *PtrArg = E->getArg(1);
Expr::EvalResult ExprResult;
APSInt IntResult;
if (PtrArg->EvaluateAsRValue(ExprResult, Info.Ctx) &&
ExprResult.Val.toIntegralConstant(IntResult, PtrArg->getType(),
Info.Ctx) &&
IntResult.isAligned(Size.getAsAlign()))
return Success(1, E);

// Otherwise, check if the type's alignment against Size.
if (auto *ICE = dyn_cast<ImplicitCastExpr>(PtrArg)) {
// Drop the potential implicit-cast to 'const volatile void*', getting
// the underlying type.
if (ICE->getCastKind() == CK_BitCast)
PtrArg = ICE->getSubExpr();
}

if (auto PtrTy = PtrArg->getType()->getAs<PointerType>()) {
QualType PointeeType = PtrTy->getPointeeType();
if (!PointeeType->isIncompleteType() &&
Info.Ctx.getTypeAlignInChars(PointeeType) >= Size) {
// OK, we will inline operations on this object.
return Success(1, E);
}
}
}
}
Expand Down Expand Up @@ -14038,6 +14066,12 @@ bool IntExprEvaluator::VisitUnaryExprOrTypeTraitExpr(
E);
}

case UETT_PtrAuthTypeDiscriminator: {
if (E->getArgumentType()->isDependentType())
return false;
return Success(
Info.Ctx.getPointerAuthTypeDiscriminator(E->getArgumentType()), E);
}
case UETT_VecStep: {
QualType Ty = E->getTypeOfArgument();

Expand Down
2 changes: 1 addition & 1 deletion clang/lib/AST/Interp/Boolean.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class Boolean final {
APSInt toAPSInt(unsigned NumBits) const {
return APSInt(toAPSInt().zextOrTrunc(NumBits), true);
}
APValue toAPValue() const { return APValue(toAPSInt()); }
APValue toAPValue(const ASTContext &) const { return APValue(toAPSInt()); }

Boolean toUnsigned() const { return *this; }

Expand Down
4 changes: 3 additions & 1 deletion clang/lib/AST/Interp/ByteCodeEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ using namespace clang::interp;
/// Similar information is available via ASTContext::BuiltinInfo,
/// but that is not correct for our use cases.
static bool isUnevaluatedBuiltin(unsigned BuiltinID) {
return BuiltinID == Builtin::BI__builtin_classify_type;
return BuiltinID == Builtin::BI__builtin_classify_type ||
BuiltinID == Builtin::BI__builtin_os_log_format_buffer_size ||
BuiltinID == Builtin::BI__builtin_constant_p;
}

Function *ByteCodeEmitter::compileFunc(const FunctionDecl *FuncDecl) {
Expand Down
45 changes: 33 additions & 12 deletions clang/lib/AST/Interp/Compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,10 @@ bool InitLink::emit(Compiler<Emitter> *Ctx, const Expr *E) const {
return Ctx->emitGetPtrLocal(Offset, E);
case K_Decl:
return Ctx->visitDeclRef(D, E);
case K_Elem:
if (!Ctx->emitConstUint32(Offset, E))
return false;
return Ctx->emitArrayElemPtrPopUint32(E);
default:
llvm_unreachable("Unhandled InitLink kind");
}
Expand Down Expand Up @@ -1556,6 +1560,7 @@ bool Compiler<Emitter>::visitArrayElemInit(unsigned ElemIndex,
return this->emitInitElem(*T, ElemIndex, Init);
}

InitLinkScope<Emitter> ILS(this, InitLink::Elem(ElemIndex));
// Advance the pointer currently on the stack to the given
// dimension.
if (!this->emitConstUint32(ElemIndex, Init))
Expand Down Expand Up @@ -1698,10 +1703,8 @@ bool Compiler<Emitter>::VisitUnaryExprOrTypeTraitExpr(
if (Kind == UETT_VectorElements) {
if (const auto *VT = E->getTypeOfArgument()->getAs<VectorType>())
return this->emitConst(VT->getNumElements(), E);

// FIXME: Apparently we need to catch the fact that a sizeless vector type
// has been passed and diagnose that (at run time).
assert(E->getTypeOfArgument()->isSizelessVectorType());
return this->emitSizelessVectorElementSize(E);
}

if (Kind == UETT_VecStep) {
Expand Down Expand Up @@ -3196,13 +3199,9 @@ bool Compiler<Emitter>::VisitStmtExpr(const StmtExpr *E) {
}

assert(S == Result);
if (const Expr *ResultExpr = dyn_cast<Expr>(S)) {
if (DiscardResult)
return this->discard(ResultExpr);
if (const Expr *ResultExpr = dyn_cast<Expr>(S))
return this->delegate(ResultExpr);
}

return this->visitStmt(S);
return this->emitUnsupported(E);
}

return BS.destroyLocals();
Expand Down Expand Up @@ -3257,6 +3256,9 @@ bool Compiler<Emitter>::visitInitializer(const Expr *E) {
if (E->containsErrors())
return this->emitError(E);

if (!this->checkLiteralType(E))
return false;

OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/false,
/*NewInitializing=*/true);
return this->Visit(E);
Expand Down Expand Up @@ -3689,6 +3691,9 @@ VarCreationState Compiler<Emitter>::visitVarDecl(const VarDecl *VD, bool Topleve
const Expr *Init = VD->getInit();
std::optional<PrimType> VarT = classify(VD->getType());

if (Init && Init->isValueDependent())
return false;

if (Context::shouldBeGloballyIndexed(VD)) {
auto checkDecl = [&]() -> bool {
bool NeedsOp = !Toplevel && VD->isLocalVarDecl() && VD->isStaticLocal();
Expand Down Expand Up @@ -4154,7 +4159,8 @@ bool Compiler<Emitter>::VisitCXXThisExpr(const CXXThisExpr *E) {
if (InitStackActive && !InitStack.empty()) {
unsigned StartIndex = 0;
for (StartIndex = InitStack.size() - 1; StartIndex > 0; --StartIndex) {
if (InitStack[StartIndex].Kind != InitLink::K_Field)
if (InitStack[StartIndex].Kind != InitLink::K_Field &&
InitStack[StartIndex].Kind != InitLink::K_Elem)
break;
}

Expand Down Expand Up @@ -4695,6 +4701,17 @@ bool Compiler<Emitter>::emitLambdaStaticInvokerBody(const CXXMethodDecl *MD) {
return this->emitRetVoid(MD);
}

template <class Emitter>
bool Compiler<Emitter>::checkLiteralType(const Expr *E) {
if (Ctx.getLangOpts().CPlusPlus23)
return true;

if (!E->isPRValue() || E->getType()->isLiteralType(Ctx.getASTContext()))
return true;

return this->emitCheckLiteralType(E->getType().getTypePtr(), E);
}

template <class Emitter>
bool Compiler<Emitter>::visitFunc(const FunctionDecl *F) {
// Classify the return type.
Expand Down Expand Up @@ -5236,6 +5253,10 @@ bool Compiler<Emitter>::visitDeclRef(const ValueDecl *D, const Expr *E) {
return false;
};

// DecompositionDecls are just proxies for us.
if (isa<DecompositionDecl>(VD))
return revisit(VD);

// Visit local const variables like normal.
if ((VD->hasGlobalStorage() || VD->isLocalVarDecl() ||
VD->isStaticDataMember()) &&
Expand Down Expand Up @@ -5284,8 +5305,8 @@ template <class Emitter>
unsigned Compiler<Emitter>::collectBaseOffset(const QualType BaseType,
const QualType DerivedType) {
const auto extractRecordDecl = [](QualType Ty) -> const CXXRecordDecl * {
if (const auto *PT = dyn_cast<PointerType>(Ty))
return PT->getPointeeType()->getAsCXXRecordDecl();
if (const auto *R = Ty->getPointeeCXXRecordDecl())
return R;
return Ty->getAsCXXRecordDecl();
};
const CXXRecordDecl *BaseDecl = extractRecordDecl(BaseType);
Expand Down
8 changes: 8 additions & 0 deletions clang/lib/AST/Interp/Compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ struct InitLink {
K_Field = 1,
K_Temp = 2,
K_Decl = 3,
K_Elem = 5,
};

static InitLink This() { return InitLink{K_This}; }
Expand All @@ -68,6 +69,11 @@ struct InitLink {
IL.D = D;
return IL;
}
static InitLink Elem(unsigned Index) {
InitLink IL{K_Elem};
IL.Offset = Index;
return IL;
}

InitLink(uint8_t Kind) : Kind(Kind) {}
template <class Emitter>
Expand Down Expand Up @@ -353,6 +359,8 @@ class Compiler : public ConstStmtVisitor<Compiler<Emitter>, bool>,
const QualType DerivedType);
bool emitLambdaStaticInvokerBody(const CXXMethodDecl *MD);

bool checkLiteralType(const Expr *E);

protected:
/// Variable to storage mapping.
llvm::DenseMap<const ValueDecl *, Scope::Local> Locals;
Expand Down
10 changes: 6 additions & 4 deletions clang/lib/AST/Interp/Descriptor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,8 @@ static void initField(Block *B, std::byte *Ptr, bool IsConst, bool IsMutable,
}

static void initBase(Block *B, std::byte *Ptr, bool IsConst, bool IsMutable,
bool IsActive, const Descriptor *D, unsigned FieldOffset) {
bool IsActive, const Descriptor *D, unsigned FieldOffset,
bool IsVirtualBase) {
assert(D);
assert(D->ElemRecord);

Expand All @@ -172,13 +173,14 @@ static void initBase(Block *B, std::byte *Ptr, bool IsConst, bool IsMutable,
Desc->Desc = D;
Desc->IsInitialized = D->IsArray;
Desc->IsBase = true;
Desc->IsVirtualBase = IsVirtualBase;
Desc->IsActive = IsActive && !IsUnion;
Desc->IsConst = IsConst || D->IsConst;
Desc->IsFieldMutable = IsMutable || D->IsMutable;

for (const auto &V : D->ElemRecord->bases())
initBase(B, Ptr + FieldOffset, IsConst, IsMutable, IsActive, V.Desc,
V.Offset);
V.Offset, false);
for (const auto &F : D->ElemRecord->fields())
initField(B, Ptr + FieldOffset, IsConst, IsMutable, IsActive, IsUnion,
F.Desc, F.Offset);
Expand All @@ -187,11 +189,11 @@ static void initBase(Block *B, std::byte *Ptr, bool IsConst, bool IsMutable,
static void ctorRecord(Block *B, std::byte *Ptr, bool IsConst, bool IsMutable,
bool IsActive, const Descriptor *D) {
for (const auto &V : D->ElemRecord->bases())
initBase(B, Ptr, IsConst, IsMutable, IsActive, V.Desc, V.Offset);
initBase(B, Ptr, IsConst, IsMutable, IsActive, V.Desc, V.Offset, false);
for (const auto &F : D->ElemRecord->fields())
initField(B, Ptr, IsConst, IsMutable, IsActive, D->ElemRecord->isUnion(), F.Desc, F.Offset);
for (const auto &V : D->ElemRecord->virtual_bases())
initBase(B, Ptr, IsConst, IsMutable, IsActive, V.Desc, V.Offset);
initBase(B, Ptr, IsConst, IsMutable, IsActive, V.Desc, V.Offset, true);
}

static void destroyField(Block *B, std::byte *Ptr, const Descriptor *D,
Expand Down
2 changes: 2 additions & 0 deletions clang/lib/AST/Interp/Descriptor.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ struct InlineDescriptor {
/// Flag indicating if the field is an embedded base class.
LLVM_PREFERRED_TYPE(bool)
unsigned IsBase : 1;
LLVM_PREFERRED_TYPE(bool)
unsigned IsVirtualBase : 1;
/// Flag indicating if the field is the active member of a union.
LLVM_PREFERRED_TYPE(bool)
unsigned IsActive : 1;
Expand Down
Loading