Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,13 @@ unsigned getNumberOfDesignated(const InitListExpr *SyntacticInitList) {
});
}

AST_MATCHER(CXXRecordDecl, isAggregate) { return Node.isAggregate(); }
AST_MATCHER(CXXRecordDecl, isAggregate) {
return Node.hasDefinition() && Node.isAggregate();
}

AST_MATCHER(CXXRecordDecl, isPOD) { return Node.isPOD(); }
AST_MATCHER(CXXRecordDecl, isPOD) {
return Node.hasDefinition() && Node.isPOD();
}

AST_MATCHER(InitListExpr, isFullyDesignated) {
if (const InitListExpr *SyntacticForm =
Expand Down
24 changes: 16 additions & 8 deletions clang-tools-extra/clang-tidy/readability/EnumInitialValueCheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,13 @@ AST_MATCHER(EnumDecl, hasSequentialInitialValues) {
return !AllEnumeratorsArePowersOfTwo;
}

std::string getName(const EnumDecl *Decl) {
if (!Decl->getDeclName())
return "<unnamed>";

return Decl->getQualifiedNameAsString();
}

} // namespace

EnumInitialValueCheck::EnumInitialValueCheck(StringRef Name,
Expand Down Expand Up @@ -160,10 +167,11 @@ void EnumInitialValueCheck::registerMatchers(MatchFinder *Finder) {
void EnumInitialValueCheck::check(const MatchFinder::MatchResult &Result) {
if (const auto *Enum = Result.Nodes.getNodeAs<EnumDecl>("inconsistent")) {
DiagnosticBuilder Diag =
diag(Enum->getBeginLoc(),
"initial values in enum %0 are not consistent, consider explicit "
"initialization of all, none or only the first enumerator")
<< Enum;
diag(
Enum->getBeginLoc(),
"initial values in enum '%0' are not consistent, consider explicit "
"initialization of all, none or only the first enumerator")
<< getName(Enum);
for (const EnumConstantDecl *ECD : Enum->enumerators())
if (ECD->getInitExpr() == nullptr) {
const SourceLocation EndLoc = Lexer::getLocForEndOfToken(
Expand All @@ -183,16 +191,16 @@ void EnumInitialValueCheck::check(const MatchFinder::MatchResult &Result) {
if (Loc.isInvalid() || Loc.isMacroID())
return;
DiagnosticBuilder Diag = diag(Loc, "zero initial value for the first "
"enumerator in %0 can be disregarded")
<< Enum;
"enumerator in '%0' can be disregarded")
<< getName(Enum);
cleanInitialValue(Diag, ECD, *Result.SourceManager, getLangOpts());
return;
}
if (const auto *Enum = Result.Nodes.getNodeAs<EnumDecl>("sequential")) {
DiagnosticBuilder Diag =
diag(Enum->getBeginLoc(),
"sequential initial value in %0 can be ignored")
<< Enum;
"sequential initial value in '%0' can be ignored")
<< getName(Enum);
for (const EnumConstantDecl *ECD : llvm::drop_begin(Enum->enumerators()))
cleanInitialValue(Diag, ECD, *Result.SourceManager, getLangOpts());
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "../utils/FixItHintUtils.h"
#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/Lex/Lexer.h"
#include "clang/Tooling/FixIt.h"
#include <queue>
Expand All @@ -26,6 +27,8 @@ AST_MATCHER(Stmt, isMacroExpansion) {
return SM.isMacroBodyExpansion(Loc) || SM.isMacroArgExpansion(Loc);
}

AST_MATCHER(Stmt, isC23) { return Finder->getASTContext().getLangOpts().C23; }

bool isNULLMacroExpansion(const Stmt *Statement, ASTContext &Context) {
SourceManager &SM = Context.getSourceManager();
const LangOptions &LO = Context.getLangOpts();
Expand Down Expand Up @@ -298,6 +301,11 @@ void ImplicitBoolConversionCheck::registerMatchers(MatchFinder *Finder) {
hasCastKind(CK_FloatingToBoolean),
hasCastKind(CK_PointerToBoolean),
hasCastKind(CK_MemberPointerToBoolean)),
// Exclude cases of C23 comparison result.
unless(allOf(isC23(),
hasSourceExpression(ignoringParens(
binaryOperator(hasAnyOperatorName(
">", ">=", "==", "!=", "<", "<=")))))),
// Exclude case of using if or while statements with variable
// declaration, e.g.:
// if (int var = functionCall()) {}
Expand Down
16 changes: 14 additions & 2 deletions clang-tools-extra/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,12 @@ New checks
Warns about code that tries to cast between pointers by means of
``std::bit_cast`` or ``memcpy``.

- New :doc:`bugprone-nondeterministic-pointer-iteration-order
<clang-tidy/checks/bugprone/nondeterministic-pointer-iteration-order>`
check.

Finds nondeterministic usages of pointers in unordered containers.

- New :doc:`bugprone-tagged-union-member-count
<clang-tidy/checks/bugprone/tagged-union-member-count>` check.

Expand Down Expand Up @@ -210,6 +216,10 @@ Changes in existing checks
a false positive when only an implicit conversion happened inside an
initializer list.

- Improved :doc:`modernize-use-designated-initializers
<clang-tidy/checks/modernize/use-designated-initializers>` check to fix a
crash when a class is declared but not defined.

- Improved :doc:`modernize-use-nullptr
<clang-tidy/checks/modernize/use-nullptr>` check to also recognize
``NULL``/``__null`` (but not ``0``) when used with a templated type.
Expand Down Expand Up @@ -243,13 +253,15 @@ Changes in existing checks

- Improved :doc:`readability-enum-initial-value
<clang-tidy/checks/readability/enum-initial-value>` check by only issuing
diagnostics for the definition of an ``enum``, and by fixing a typo in the
diagnostics for the definition of an ``enum``, by not emitting a redundant
file path for anonymous enums in the diagnostic, and by fixing a typo in the
diagnostic.

- Improved :doc:`readability-implicit-bool-conversion
<clang-tidy/checks/readability/implicit-bool-conversion>` check
by adding the option `UseUpperCaseLiteralSuffix` to select the
case of the literal suffix in fixes.
case of the literal suffix in fixes and fixing false positive for implicit
conversion of comparison result in C23.

- Improved :doc:`readability-redundant-smartptr-get
<clang-tidy/checks/readability/redundant-smartptr-get>` check to
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
.. title:: clang-tidy - bugprone-nondeterministic-pointer-iteration-order

bugprone-nondeterministic-pointer-iteration-order
=================================================

Finds nondeterministic usages of pointers in unordered containers.

One canonical example is iteration across a container of pointers.

.. code-block:: c++

{
int a = 1, b = 2;
std::unordered_set<int *> UnorderedPtrSet = {&a, &b};
for (auto i : UnorderedPtrSet)
f(i);
}
Another such example is sorting a container of pointers.

.. code-block:: c++

{
int a = 1, b = 2;
std::vector<int *> VectorOfPtr = {&a, &b};
std::sort(VectorOfPtr.begin(), VectorOfPtr.end());
}
Iteration of a containers of pointers may present the order of different
pointers differently across different runs of a program. In some cases this
may be acceptable behavior, in others this may be unexpected behavior. This
check is advisory for this reason.

This check only detects range-based for loops over unordered sets and maps. It
also detects calls sorting-like algorithms on containers holding pointers.
Other similar usages will not be found and are false negatives.

Limitations:

* This check currently does not check if a nondeterministic iteration order is
likely to be a mistake, and instead marks all such iterations as bugprone.
* std::reference_wrapper is not considered yet.
* Only for loops are considered, other iterators can be included in
improvements.
1 change: 1 addition & 0 deletions clang-tools-extra/docs/clang-tidy/checks/list.rst
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ Clang-Tidy Checks
:doc:`bugprone-multiple-new-in-one-expression <bugprone/multiple-new-in-one-expression>`,
:doc:`bugprone-multiple-statement-macro <bugprone/multiple-statement-macro>`,
:doc:`bugprone-no-escape <bugprone/no-escape>`,
:doc:`bugprone-nondeterministic-pointer-iteration-order <bugprone/nondeterministic-pointer-iteration-order>`,
:doc:`bugprone-non-zero-enum-to-bool-conversion <bugprone/non-zero-enum-to-bool-conversion>`,
:doc:`bugprone-not-null-terminated-result <bugprone/not-null-terminated-result>`, "Yes"
:doc:`bugprone-optional-value-conversion <bugprone/optional-value-conversion>`, "Yes"
Expand Down
7 changes: 3 additions & 4 deletions clang-tools-extra/modularize/CoverageChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -223,10 +223,9 @@ bool CoverageChecker::collectModuleHeaders(const Module &Mod) {
return false;
}

for (auto &HeaderKind : Mod.Headers)
for (auto &Header : HeaderKind)
ModuleMapHeadersSet.insert(
ModularizeUtilities::getCanonicalPath(Header.Entry.getName()));
for (const auto &Header : Mod.getAllHeaders())
ModuleMapHeadersSet.insert(
ModularizeUtilities::getCanonicalPath(Header.Entry.getName()));

for (auto *Submodule : Mod.submodules())
collectModuleHeaders(*Submodule);
Expand Down
14 changes: 3 additions & 11 deletions clang-tools-extra/modularize/ModularizeUtilities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ bool ModularizeUtilities::collectModuleHeaders(const clang::Module &Mod) {
} else if (std::optional<clang::Module::DirectoryName> UmbrellaDir =
Mod.getUmbrellaDirAsWritten()) {
// If there normal headers, assume these are umbrellas and skip collection.
if (Mod.Headers->size() == 0) {
if (Mod.getHeaders(Module::HK_Normal).empty()) {
// Collect headers in umbrella directory.
if (!collectUmbrellaHeaders(UmbrellaDir->Entry.getName(),
UmbrellaDependents))
Expand All @@ -371,16 +371,8 @@ bool ModularizeUtilities::collectModuleHeaders(const clang::Module &Mod) {
// modules or because they are meant to be included by another header,
// and thus should be ignored by modularize.

int NormalHeaderCount = Mod.Headers[clang::Module::HK_Normal].size();

for (int Index = 0; Index < NormalHeaderCount; ++Index) {
DependentsVector NormalDependents;
// Collect normal header.
const clang::Module::Header &Header(
Mod.Headers[clang::Module::HK_Normal][Index]);
std::string HeaderPath = getCanonicalPath(Header.Entry.getName());
HeaderFileNames.push_back(HeaderPath);
}
for (const auto &Header : Mod.getHeaders(clang::Module::HK_Normal))
HeaderFileNames.push_back(getCanonicalPath(Header.Entry.getName()));

int MissingCountThisModule = Mod.MissingHeaders.size();

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#ifndef _SIM_ALGORITHM
#define _SIM_ALGORITHM

#pragma clang system_header

namespace std {

template<class ForwardIt>
bool is_sorted(ForwardIt first, ForwardIt last);

template <class RandomIt>
void nth_element(RandomIt first, RandomIt nth, RandomIt last);

template<class RandomIt>
void partial_sort(RandomIt first, RandomIt middle, RandomIt last);

template<class RandomIt>
void sort (RandomIt first, RandomIt last);

template<class RandomIt>
void stable_sort(RandomIt first, RandomIt last);

template<class BidirIt, class UnaryPredicate>
BidirIt partition(BidirIt first, BidirIt last, UnaryPredicate p);

template<class BidirIt, class UnaryPredicate>
BidirIt stable_partition(BidirIt first, BidirIt last, UnaryPredicate p);

} // namespace std

#endif // _SIM_ALGORITHM
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#ifndef _SIM_CPP_CONFIG_H
#define _SIM_CPP_CONFIG_H

#pragma clang system_header

typedef unsigned char uint8_t;

typedef __typeof__(sizeof(int)) size_t;
typedef __typeof__((char*)0-(char*)0) ptrdiff_t;

#endif // _SIM_CPP_CONFIG_H
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#ifndef _INITIALIZER_LIST
#define _INITIALIZER_LIST

#pragma clang system_header
#
#include "sim_c++config.h" // size_t

namespace std {

template <class _E>
class initializer_list {
const _E* __begin_;
size_t __size_;

initializer_list(const _E* __b, size_t __s)
: __begin_(__b),
__size_(__s)
{}

public:
typedef _E value_type;
typedef const _E& reference;
typedef const _E& const_reference;
typedef size_t size_type;

typedef const _E* iterator;
typedef const _E* const_iterator;

initializer_list() : __begin_(0), __size_(0) {}

size_t size() const {return __size_;}
const _E* begin() const {return __begin_;}
const _E* end() const {return __begin_ + __size_;}

}; // class initializer_list

} // namespace std

#endif // _INITIALIZER_LIST
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#ifndef _SIM_ITERATOR_BASE
#define _SIM_ITERATOR_BASE

namespace std {

struct input_iterator_tag { };
struct output_iterator_tag { };
struct forward_iterator_tag : public input_iterator_tag { };
struct bidirectional_iterator_tag : public forward_iterator_tag { };
struct random_access_iterator_tag : public bidirectional_iterator_tag { };

template <typename Iterator> struct iterator_traits {
typedef typename Iterator::difference_type difference_type;
typedef typename Iterator::value_type value_type;
typedef typename Iterator::pointer pointer;
typedef typename Iterator::reference reference;
typedef typename Iterator::iterator_category iterator_category;
};

} // namespace std

#endif // _SIM_ITERATOR_BASE
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@

#ifndef _SIM_MAP
#define _SIM_MAP

#pragma clang system_header
#include "sim_stl_pair"

namespace std {

template <typename Key, typename Value>
class map {
public:
using value_type = pair<Key, Value>;
map();
map(initializer_list<pair<Key, Value>> initList);
value_type& operator[](const Key& key);
value_type& operator[](Key&& key);
class iterator {
public:
iterator(Key *key): ptr(key) {}
iterator& operator++() { ++ptr; return *this; }
bool operator!=(const iterator &other) const { return ptr != other.ptr; }
const Key &operator*() const { return *ptr; }
private:
Key *ptr;
};
Key *val;
iterator begin() const { return iterator(val); }
iterator end() const { return iterator(val + 1); }
};

} // namespace std

#endif // _SIM_MAP
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@

#ifndef _SIM_SET
#define _SIM_SET

#pragma clang system_header
#include "sim_initializer_list"

namespace std {

template< class T = void >
struct less;

template< class T >
struct allocator;

template< class Key >
struct hash;

template<
class Key,
class Compare = std::less<Key>,
class Alloc = std::allocator<Key>
> class set {
public:
set(initializer_list<Key> __list) {}

class iterator {
public:
iterator(Key *key): ptr(key) {}
iterator& operator++() { ++ptr; return *this; }
bool operator!=(const iterator &other) const { return ptr != other.ptr; }
const Key &operator*() const { return *ptr; }
private:
Key *ptr;
};

Key *val;
iterator begin() const { return iterator(val); }
iterator end() const { return iterator(val + 1); }
};

} // namespace std

#endif // _SIM_SET
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#ifndef _SIM_STL_PAIR
#define _SIM_STL_PAIR

#pragma clang system_header

#include "sim_type_traits"

namespace std {

template <class T1, class T2>
struct pair {
T1 first;
T2 second;

pair() : first(), second() {}
pair(const T1 &a, const T2 &b) : first(a), second(b) {}

template<class U1, class U2>
pair(const pair<U1, U2> &other) : first(other.first),
second(other.second) {}
};

template <typename T1, typename T2>
pair<typename remove_reference<T1>::type, typename remove_reference<T2>::type>
make_pair(T1 &&, T2 &&) {
return {};
};

} // namespace std

#endif // _SIM_STL_PAIR

Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@

#ifndef _SIM_TYPE_TRAITS
#define _SIM_TYPE_TRAITS

#pragma clang system_header
namespace std {

template< class T > struct remove_reference {typedef T type;};
template< class T > struct remove_reference<T&> {typedef T type;};
template< class T > struct remove_reference<T&&> {typedef T type;};

template<typename T> typename remove_reference<T>::type&& move(T&& a);

template< class T >
using remove_reference_t = typename remove_reference<T>::type;

} // namespace std

#endif // _SIM_TYPE_TRAITS
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#ifndef _SIM_UNORDERED_MAP
#define _SIM_UNORDERED_MAP

#pragma clang system_header
#include "sim_initializer_list"

namespace std {

template <typename Key, typename Value>
class unordered_map {
public:
using value_type = pair<Key, Value>;
unordered_map();
unordered_map(initializer_list<pair<Key, Value>> initList);
value_type& operator[](const Key& key);
value_type& operator[](Key&& key);
class iterator {
public:
iterator(Key *key): ptr(key) {}
iterator& operator++() { ++ptr; return *this; }
bool operator!=(const iterator &other) const { return ptr != other.ptr; }
const Key &operator*() const { return *ptr; }
private:
Key *ptr;
};
Key *val;
iterator begin() const { return iterator(val); }
iterator end() const { return iterator(val + 1); }
};

} // namespace std

#endif // _SIM_UNORDERED_MAP
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#ifndef _SIM_UNORDERED_SET
#define _SIM_UNORDERED_SET

#pragma clang system_header
#include "sim_initializer_list"

namespace std {

template<
class Key,
class Hash = std::hash<Key>,
class Compare = std::less<Key>,
class Alloc = std::allocator<Key>
> class unordered_set {
public:
unordered_set(initializer_list<Key> __list) {}

class iterator {
public:
iterator(Key *key): ptr(key) {}
iterator& operator++() { ++ptr; return *this; }
bool operator!=(const iterator &other) const { return ptr != other.ptr; }
const Key &operator*() const { return *ptr; }
private:
Key *ptr;
};

Key *val;
iterator begin() const { return iterator(val); }
iterator end() const { return iterator(val + 1); }
};

} // namespace std

#endif // _SIM_UNORDERED_SET
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
#ifndef _SIM_VECTOR
#define _SIM_VECTOR

#pragma clang system_header

#include "sim_iterator_base"

namespace std {

template <typename T, typename Ptr, typename Ref> struct __vector_iterator {
typedef __vector_iterator<T, T *, T &> iterator;
typedef __vector_iterator<T, const T *, const T &> const_iterator;

typedef ptrdiff_t difference_type;
typedef T value_type;
typedef Ptr pointer;
typedef Ref reference;
typedef std::random_access_iterator_tag iterator_category;

__vector_iterator(const Ptr p = 0) : ptr(p) {}
__vector_iterator(const iterator &rhs): ptr(rhs.base()) {}
__vector_iterator<T, Ptr, Ref>& operator++() { ++ ptr; return *this; }
__vector_iterator<T, Ptr, Ref> operator++(int) {
auto tmp = *this;
++ ptr;
return tmp;
}
__vector_iterator<T, Ptr, Ref> operator--() { -- ptr; return *this; }
__vector_iterator<T, Ptr, Ref> operator--(int) {
auto tmp = *this; -- ptr;
return tmp;
}
__vector_iterator<T, Ptr, Ref> operator+(difference_type n) {
return ptr + n;
}
friend __vector_iterator<T, Ptr, Ref> operator+(
difference_type n,
const __vector_iterator<T, Ptr, Ref> &iter) {
return n + iter.ptr;
}
__vector_iterator<T, Ptr, Ref> operator-(difference_type n) {
return ptr - n;
}
__vector_iterator<T, Ptr, Ref> operator+=(difference_type n) {
return ptr += n;
}
__vector_iterator<T, Ptr, Ref> operator-=(difference_type n) {
return ptr -= n;
}

template<typename U, typename Ptr2, typename Ref2>
difference_type operator-(const __vector_iterator<U, Ptr2, Ref2> &rhs);

Ref operator*() const { return *ptr; }
Ptr operator->() const { return ptr; }

Ref operator[](difference_type n) {
return *(ptr+n);
}

bool operator==(const iterator &rhs) const { return ptr == rhs.ptr; }
bool operator==(const const_iterator &rhs) const { return ptr == rhs.ptr; }

bool operator!=(const iterator &rhs) const { return ptr != rhs.ptr; }
bool operator!=(const const_iterator &rhs) const { return ptr != rhs.ptr; }

const Ptr& base() const { return ptr; }

private:
Ptr ptr;
};

template<typename T>
class vector {
T *_start;
T *_finish;
T *_end_of_storage;

public:
typedef T value_type;
typedef size_t size_type;
typedef __vector_iterator<T, T *, T &> iterator;
typedef __vector_iterator<T, const T *, const T &> const_iterator;

vector() : _start(0), _finish(0), _end_of_storage(0) {}
template <typename InputIterator>
vector(InputIterator first, InputIterator last);
vector(const vector &other);
vector(vector &&other);
~vector();

size_t size() const {
return size_t(_finish - _start);
}

vector& operator=(const vector &other);
vector& operator=(vector &&other);
vector& operator=(std::initializer_list<T> ilist);

void assign(size_type count, const T &value);
template <typename InputIterator >
void assign(InputIterator first, InputIterator last);
void assign(std::initializer_list<T> ilist);

void clear();

void push_back(const T &value);
void push_back(T &&value);
template<class... Args>
void emplace_back(Args&&... args);
void pop_back();

iterator insert(const_iterator position, const value_type &val);
iterator insert(const_iterator position, size_type n,
const value_type &val);
template <typename InputIterator>
iterator insert(const_iterator position, InputIterator first,
InputIterator last);
iterator insert(const_iterator position, value_type &&val);
iterator insert(const_iterator position, initializer_list<value_type> il);

template <class... Args>
iterator emplace(const_iterator position, Args&&... args);

iterator erase(const_iterator position);
iterator erase(const_iterator first, const_iterator last);

T &operator[](size_t n) {
return _start[n];
}

const T &operator[](size_t n) const {
return _start[n];
}

iterator begin() { return iterator(_start); }
const_iterator begin() const { return const_iterator(_start); }
const_iterator cbegin() const { return const_iterator(_start); }
iterator end() { return iterator(_finish); }
const_iterator end() const { return const_iterator(_finish); }
const_iterator cend() const { return const_iterator(_finish); }
T& front() { return *begin(); }
const T& front() const { return *begin(); }
T& back() { return *(end() - 1); }
const T& back() const { return *(end() - 1); }
};

} // namespace std

#endif // _SIM_VECTOR
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// RUN: %check_clang_tidy %s bugprone-nondeterministic-pointer-iteration-order %t -- -- -I%S -std=c++!4

#include "Inputs/system-header-simulator/sim_set"
#include "Inputs/system-header-simulator/sim_unordered_set"
#include "Inputs/system-header-simulator/sim_map"
#include "Inputs/system-header-simulator/sim_unordered_map"
#include "Inputs/system-header-simulator/sim_vector"
#include "Inputs/system-header-simulator/sim_algorithm"

template<class T>
void f(T x);

void PointerIteration() {
int a = 1, b = 2;
std::set<int> OrderedIntSet = {a, b};
std::set<int *> OrderedPtrSet = {&a, &b};
std::unordered_set<int> UnorderedIntSet = {a, b};
std::unordered_set<int *> UnorderedPtrSet = {&a, &b};
std::map<int, int> IntMap = { std::make_pair(a,a), std::make_pair(b,b) };
std::map<int*, int*> PtrMap = { std::make_pair(&a,&a), std::make_pair(&b,&b) };
std::unordered_map<int, int> IntUnorderedMap = { std::make_pair(a,a), std::make_pair(b,b) };
std::unordered_map<int*, int*> PtrUnorderedMap = { std::make_pair(&a,&a), std::make_pair(&b,&b) };

for (auto i : OrderedIntSet) // no-warning
f(i);

for (auto i : OrderedPtrSet) // no-warning
f(i);

for (auto i : UnorderedIntSet) // no-warning
f(i);

for (auto i : UnorderedPtrSet)
f(i);
// CHECK-MESSAGES: :[[@LINE-2]]:17: warning: iteration of pointers is nondeterministic

for (auto &i : UnorderedPtrSet)
f(i);
// CHECK-MESSAGES: :[[@LINE-2]]:18: warning: iteration of pointers is nondeterministic

for (auto &i : IntMap) // no-warning
f(i);

for (auto &i : PtrMap) // no-warning
f(i);

for (auto &i : IntUnorderedMap) // no-warning
f(i);

for (auto &i : PtrUnorderedMap)
f(i);
// CHECK-MESSAGES: :[[@LINE-2]]:18: warning: iteration of pointers is nondeterministic
}

bool g (int *x) { return true; }
bool h (int x) { return true; }

void PointerSorting() {
int a = 1, b = 2, c = 3;
std::vector<int> V1 = {a, b};
std::vector<int *> V2 = {&a, &b};

std::is_sorted(V1.begin(), V1.end()); // no-warning
std::nth_element(V1.begin(), V1.begin() + 1, V1.end()); // no-warning
std::partial_sort(V1.begin(), V1.begin() + 1, V1.end()); // no-warning
std::sort(V1.begin(), V1.end()); // no-warning
std::stable_sort(V1.begin(), V1.end()); // no-warning
std::partition(V1.begin(), V1.end(), h); // no-warning
std::stable_partition(V1.begin(), V1.end(), h); // no-warning
std::is_sorted(V2.begin(), V2.end());
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: sorting pointers is nondeterministic
std::nth_element(V2.begin(), V2.begin() + 1, V2.end());
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: sorting pointers is nondeterministic
std::partial_sort(V2.begin(), V2.begin() + 1, V2.end());
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: sorting pointers is nondeterministic
std::sort(V2.begin(), V2.end());
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: sorting pointers is nondeterministic
std::stable_sort(V2.begin(), V2.end());
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: sorting pointers is nondeterministic
std::partition(V2.begin(), V2.end(), g);
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: sorting pointers is nondeterministic
std::stable_partition(V2.begin(), V2.end(), g);
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: sorting pointers is nondeterministic
}
Original file line number Diff line number Diff line change
Expand Up @@ -201,3 +201,11 @@ DECLARE_S93;
// CHECK-MESSAGES-MACROS: :[[@LINE-1]]:1: warning: use designated initializer list to initialize 'S9' [modernize-use-designated-initializers]
// CHECK-MESSAGES-MACROS: :[[@LINE-4]]:28: note: expanded from macro 'DECLARE_S93'
// CHECK-MESSAGES-MACROS: :[[@LINE-71]]:1: note: aggregate type is defined here

// Issue #113652.
struct S14;

struct S15{
S15(S14& d):d{d}{}
S14& d;
};
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,17 @@ enum EMacro2 {
// CHECK-FIXES: EMacro2_c = 3,
};


enum {
// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: initial values in enum '<unnamed>' are not consistent
// CHECK-MESSAGES-ENABLE: :[[@LINE-2]]:1: warning: initial values in enum '<unnamed>' are not consistent
EAnonymous_a = 1,
EAnonymous_b,
// CHECK-FIXES: EAnonymous_b = 2,
EAnonymous_c = 3,
};


enum EnumZeroFirstInitialValue {
EnumZeroFirstInitialValue_0 = 0,
// CHECK-MESSAGES-ENABLE: :[[@LINE-1]]:3: warning: zero initial value for the first enumerator in 'EnumZeroFirstInitialValue' can be disregarded
Expand Down Expand Up @@ -114,4 +125,3 @@ enum WithFwdDeclSequential : int {
EFS2 = 4,
// CHECK-FIXES-ENABLE: EFS2 ,
};

Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,15 @@ void implicitConversionToBoolFromUnaryMinusAndZeroLiterals() {
// CHECK-FIXES: functionTakingBool((-0.0) != 0.0);
}

void ignoreImplicitCastToBoolForComparisonResult() {
bool boolFromComparison0 = 1 != 0;
bool boolFromComparison1 = 1 == 0;
bool boolFromComparison2 = 1 > 0;
bool boolFromComparison3 = 1 >= 0;
bool boolFromComparison4 = 1 < 0;
bool boolFromComparison5 = 1 <= 0;
}

void ignoreExplicitCastsToBool() {
int integer = 10;
bool boolComingFromInt = (bool)integer;
Expand Down
45 changes: 45 additions & 0 deletions clang/Maintainers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ AST matchers
| aaron\@aaronballman.com (email), aaron.ballman (Phabricator), AaronBallman (GitHub), AaronBallman (Discourse), aaronballman (Discord), AaronBallman (IRC)

AST Visitors
~~~~~~~~~~~~
| Sirraide
| aeternalmail\@gmail.com (email), Sirraide (GitHub), Ætérnal (Discord), Sirraide (Discourse)

Clang LLVM IR generation
~~~~~~~~~~~~~~~~~~~~~~~~
| John McCall
Expand All @@ -57,6 +63,12 @@ Analysis & CFG
| sgatev\@google.com (email), sgatev (Phabricator), sgatev (GitHub)

Sema
~~~~
| Sirraide
| aeternalmail\@gmail.com (email), Sirraide (GitHub), Ætérnal (Discord), Sirraide (Discourse)

Experimental new constant interpreter
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| Timm Bäder
Expand All @@ -71,13 +83,22 @@ Modules & serialization
| Michael Spencer
| bigcheesegs\@gmail.com (email), Bigcheese (Phabricator), Bigcheese (GitHub)
| Vassil Vassilev
| Vassil.Vassilev\@cern.ch (email), v.g.vassilev (Phabricator), vgvassilev (GitHub)

Templates
~~~~~~~~~
| Erich Keane
| ekeane\@nvidia.com (email), ErichKeane (Phabricator), erichkeane (GitHub)

Lambdas
~~~~~~~
| Corentin Jabot
| corentin.jabot\@gmail.com (email), cor3ntin (Phabricator), cor3ntin (GitHub)

Debug information
~~~~~~~~~~~~~~~~~
| Adrian Prantl
Expand Down Expand Up @@ -172,6 +193,12 @@ Attributes
| ekeane\@nvidia.com (email), ErichKeane (Phabricator), erichkeane (GitHub)

Plugins
~~~~~~~
| Vassil Vassilev
| Vassil.Vassilev\@cern.ch (email), v.g.vassilev (Phabricator), vgvassilev (GitHub)

Inline assembly
~~~~~~~~~~~~~~~
| Eric Christopher
Expand Down Expand Up @@ -225,6 +252,18 @@ C++ conformance
| Hubert Tong
| hubert.reinterpretcast\@gmail.com (email), hubert.reinterpretcast (Phabricator), hubert-reinterpretcast (GitHub)
| Shafik Yaghmour
| shafik.yaghmour\@intel.com (email), shafik (GitHub), shafik.yaghmour (Discord), shafik (Discourse)
| Vlad Serebrennikov
| serebrennikov.vladislav\@gmail.com (email), Endilll (GitHub), Endill (Discord), Endill (Discourse)

C++ Defect Reports
~~~~~~~~~~~~~~~~~~
| Vlad Serebrennikov
| serebrennikov.vladislav\@gmail.com (email), Endilll (GitHub), Endill (Discord), Endill (Discourse)

Objective-C/C++ conformance
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Expand All @@ -244,6 +283,12 @@ OpenCL conformance
| anastasia\@compiler-experts.com (email), Anastasia (Phabricator), AnastasiaStulova (GitHub)

OpenACC
~~~~~~~
| Erich Keane
| ekeane\@nvidia.com (email), ErichKeane (Phabricator), erichkeane (GitHub)

SYCL conformance
~~~~~~~~~~~~~~~~
| Alexey Bader
Expand Down
2 changes: 1 addition & 1 deletion clang/docs/AddressSanitizer.rst
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Typical slowdown introduced by AddressSanitizer is **2x**.
How to build
============

Build LLVM/Clang with `CMake <https://llvm.org/docs/CMake.html>` and enable
Build LLVM/Clang with `CMake <https://llvm.org/docs/CMake.html>`_ and enable
the ``compiler-rt`` runtime. An example CMake configuration that will allow
for the use/testing of AddressSanitizer:

Expand Down
535 changes: 535 additions & 0 deletions clang/docs/FunctionEffectAnalysis.rst

Large diffs are not rendered by default.

70 changes: 65 additions & 5 deletions clang/docs/RealtimeSanitizer.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ The runtime slowdown introduced by RealtimeSanitizer is negligible.
How to build
============

Build LLVM/Clang with `CMake <https://llvm.org/docs/CMake.html>` and enable the
Build LLVM/Clang with `CMake <https://llvm.org/docs/CMake.html>`_ and enable the
``compiler-rt`` runtime. An example CMake configuration that will allow for the
use/testing of RealtimeSanitizer:

Expand Down Expand Up @@ -183,6 +183,10 @@ A **partial** list of flags RealtimeSanitizer respects:
- ``true``
- boolean
- If set, use the symbolizer to turn virtual addresses to file/line locations. If false, can greatly speed up the error reporting.
* - ``suppressions``
- ""
- path
- If set to a valid suppressions file, will suppress issue reporting. See details in "Disabling", below.


Some issues with flags can be debugged using the ``verbosity=$NUM`` flag:
Expand All @@ -194,12 +198,43 @@ Some issues with flags can be debugged using the ``verbosity=$NUM`` flag:
misspelled_flag
...
Disabling
---------
Disabling and suppressing
-------------------------

In some circumstances, you may want to suppress error reporting in a specific scope.
There are multiple ways to disable error reporting when using RealtimeSanitizer.

In C++, this is achieved via ``__rtsan::ScopedDisabler``. Within the scope where the ``ScopedDisabler`` object is instantiated, all sanitizer error reports are suppressed. This suppression applies to the current scope as well as all invoked functions, including any functions called transitively.
In general, ``ScopedDisabler`` should be preferred, as it is the most performant.

.. list-table:: Suppression methods
:widths: 30 15 15 10 70
:header-rows: 1

* - Method
- Specified at?
- Scope
- Run-time cost
- Description
* - ``ScopedDisabler``
- Compile-time
- Stack
- Very low
- Violations are ignored for the lifetime of the ``ScopedDisabler`` object.
* - ``function-name-matches`` suppression
- Run-time
- Single function
- Medium
- Suppresses intercepted and ``[[clang::blocking]]`` function calls by name.
* - ``call-stack-contains`` suppression
- Run-time
- Stack
- High
- Suppresses any stack trace contaning the specified pattern.


``ScopedDisabler``
##################

At compile time, RealtimeSanitizer may be disabled using ``__rtsan::ScopedDisabler``. RTSan ignores any errors originating within the ``ScopedDisabler`` instance variable scope.

.. code-block:: c++

Expand Down Expand Up @@ -233,6 +268,31 @@ In C, you can use the ``__rtsan_disable()`` and ``rtsan_enable()`` functions to

Each call to ``__rtsan_disable()`` must be paired with a subsequent call to ``__rtsan_enable()`` to restore normal sanitizer functionality. If a corresponding ``rtsan_enable()`` call is not made, the behavior is undefined.

Suppression file
################

At run-time, suppressions may be specified using a suppressions file passed in ``RTSAN_OPTIONS``. Run-time suppression may be useful if the source cannot be changed.

.. code-block:: console
> cat suppressions.supp
call-stack-contains:MallocViolation
call-stack-contains:std::*vector
function-name-matches:free
function-name-matches:CustomMarkedBlocking*
> RTSAN_OPTIONS="suppressions=suppressions.supp" ./a.out
...
Suppressions specified in this file are one of two flavors.

``function-name-matches`` suppresses reporting of any intercepted library call, or function marked ``[[clang::blocking]]`` by name. If, for instance, you know that ``malloc`` is real-time safe on your system, you can disable the check for it via ``function-name-matches:malloc``.

``call-stack-contains`` suppresses reporting of errors in any stack that contains a string matching the pattern specified. For example, suppressing error reporting of any non-real-time-safe behavior in ``std::vector`` may be specified ``call-stack-contains:std::*vector``. You must include symbols in your build for this method to be effective, unsymbolicated stack traces cannot be matched. ``call-stack-contains`` has the highest run-time cost of any method of suppression.

Patterns may be exact matches or are "regex-light" patterns, containing special characters such as ``^$*``.

The number of potential errors suppressed via this method may be seen on exit when using the ``print_stats_on_exit`` flag.

Compile-time sanitizer detection
--------------------------------

Expand Down
52 changes: 51 additions & 1 deletion clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ code bases.

- The ``clang-rename`` tool has been removed.

- Removed support for RenderScript targets. This technology is
`officially deprecated <https://developer.android.com/guide/topics/renderscript/compute>`_
and users are encouraged to
`migrate to Vulkan <https://developer.android.com/guide/topics/renderscript/migrate>`_
or other options.

C/C++ Language Potentially Breaking Changes
-------------------------------------------

Expand Down Expand Up @@ -133,6 +139,15 @@ C++ Specific Potentially Breaking Changes
// Fixed version:
unsigned operator""_udl_name(unsigned long long);

- Clang will now produce an error diagnostic when [[clang::lifetimebound]] is
applied on a parameter of a function that returns void. This was previously
ignored and had no effect. (#GH107556)

.. code-block:: c++

// Now diagnoses with an error.
void f(int& i [[clang::lifetimebound]]);

ABI Changes in This Version
---------------------------

Expand Down Expand Up @@ -302,6 +317,16 @@ Modified Compiler Flags
the ``promoted`` algorithm for complex division when possible rather than the
less basic (limited range) algorithm.

- The ``-fveclib`` option has been updated to enable ``-fno-math-errno`` for
``-fveclib=ArmPL`` and ``-fveclib=SLEEF``. This gives Clang more opportunities
to utilize these vector libraries. The behavior for all other vector function
libraries remains unchanged.

- The ``-Wnontrivial-memaccess`` warning has been updated to also warn about
passing non-trivially-copyable destrination parameter to ``memcpy``,
``memset`` and similar functions for which it is a documented undefined
behavior.

Removed Compiler Flags
-------------------------

Expand Down Expand Up @@ -424,6 +449,8 @@ Improvements to Clang's diagnostics
name was a reserved name, which we improperly allowed to suppress the
diagnostic.

- Clang now diagnoses ``[[deprecated]]`` attribute usage on local variables (#GH90073).

Improvements to Clang's time-trace
----------------------------------

Expand Down Expand Up @@ -544,7 +571,8 @@ Bug Fixes to C++ Support
- Clang incorrectly considered a class with an anonymous union member to not be
const-default-constructible even if a union member has a default member initializer.
(#GH95854).
- Fixed an assertion failure when evaluating an invalid expression in an array initializer (#GH112140)
- Fixed an assertion failure when evaluating an invalid expression in an array initializer. (#GH112140)
- Fixed an assertion failure in range calculations for conditional throw expressions. (#GH111854)

Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down Expand Up @@ -612,6 +640,10 @@ X86 Support
* Supported MINMAX intrinsics of ``*_(mask(z)))_minmax(ne)_p[s|d|h|bh]`` and
``*_(mask(z)))_minmax_s[s|d|h]``.

- Supported intrinsics for ``SM4 and AVX10.2``.
* Supported SM4 intrinsics of ``_mm512_sm4key4_epi32`` and
``_mm512_sm4rnds4_epi32``.

- All intrinsics in adcintrin.h can now be used in constant expressions.

- All intrinsics in adxintrin.h can now be used in constant expressions.
Expand All @@ -624,6 +656,9 @@ X86 Support

- All intrinsics in tbmintrin.h can now be used in constant expressions.

- Supported intrinsics for ``MOVRS AND AVX10.2``.
* Supported intrinsics of ``_mm(256|512)_(mask(z))_loadrs_epi(8|16|32|64)``.

Arm and AArch64 Support
^^^^^^^^^^^^^^^^^^^^^^^

Expand Down Expand Up @@ -671,6 +706,15 @@ NetBSD Support
WebAssembly Support
^^^^^^^^^^^^^^^^^^^

The default target CPU, "generic", now enables the `-mnontrapping-fptoint`
and `-mbulk-memory` flags, which correspond to the [Bulk Memory Operations]
and [Non-trapping float-to-int Conversions] language features, which are
[widely implemented in engines].

[Bulk Memory Operations]: https://github.com/WebAssembly/bulk-memory-operations/blob/master/proposals/bulk-memory-operations/Overview.md
[Non-trapping float-to-int Conversions]: https://github.com/WebAssembly/spec/blob/master/proposals/nontrapping-float-to-int-conversion/Overview.md
[widely implemented in engines]: https://webassembly.org/features/

AVR Support
^^^^^^^^^^^

Expand Down Expand Up @@ -754,6 +798,12 @@ Moved checkers
To detect too large arguments passed to malloc, consider using the checker
``alpha.taint.TaintedAlloc``.

- The checkers ``alpha.nondeterministic.PointerSorting`` and
``alpha.nondeterministic.PointerIteration`` were moved to a new bugprone
checker named ``bugprone-nondeterministic-pointer-iteration-order``. The
original checkers were implemented only using AST matching and make more
sense as a single clang-tidy check.

.. _release-notes-sanitizers:

Sanitizers
Expand Down
31 changes: 0 additions & 31 deletions clang/docs/analyzer/checkers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3447,37 +3447,6 @@ Limitations:
More details at the corresponding `GitHub issue <https://github.com/llvm/llvm-project/issues/43459>`_.
.. _alpha-nondeterminism-PointerIteration:
alpha.nondeterminism.PointerIteration (C++)
"""""""""""""""""""""""""""""""""""""""""""
Check for non-determinism caused by iterating unordered containers of pointers.
.. code-block:: c
void test() {
int a = 1, b = 2;
std::unordered_set<int *> UnorderedPtrSet = {&a, &b};
for (auto i : UnorderedPtrSet) // warn
f(i);
}
.. _alpha-nondeterminism-PointerSorting:
alpha.nondeterminism.PointerSorting (C++)
"""""""""""""""""""""""""""""""""""""""""
Check for non-determinism caused by sorting of pointers.
.. code-block:: c
void test() {
int a = 1, b = 2;
std::vector<int *> V = {&a, &b};
std::sort(V.begin(), V.end()); // warn
}
alpha.WebKit
^^^^^^^^^^^^
Expand Down
1 change: 1 addition & 0 deletions clang/docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ Using Clang as a Compiler
ThreadSafetyAnalysis
SafeBuffers
DataFlowAnalysisIntro
FunctionEffectAnalysis
AddressSanitizer
ThreadSanitizer
MemorySanitizer
Expand Down
12 changes: 3 additions & 9 deletions clang/include/clang/AST/ASTContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
mutable llvm::ContextualFoldingSet<DependentTemplateSpecializationType,
ASTContext&>
DependentTemplateSpecializationTypes;
llvm::FoldingSet<PackExpansionType> PackExpansionTypes;
mutable llvm::FoldingSet<PackExpansionType> PackExpansionTypes;
mutable llvm::FoldingSet<ObjCObjectTypeImpl> ObjCObjectTypes;
mutable llvm::FoldingSet<ObjCObjectPointerType> ObjCObjectPointerTypes;
mutable llvm::FoldingSet<DependentUnaryTransformType>
Expand Down Expand Up @@ -1778,13 +1778,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
const IdentifierInfo *Name, ArrayRef<TemplateArgument> Args) const;

TemplateArgument getInjectedTemplateArg(NamedDecl *ParamDecl);

/// Get a template argument list with one argument per template parameter
/// in a template parameter list, such as for the injected class name of
/// a class template.
void getInjectedTemplateArgs(const TemplateParameterList *Params,
SmallVectorImpl<TemplateArgument> &Args);
TemplateArgument getInjectedTemplateArg(NamedDecl *ParamDecl) const;

/// Form a pack expansion type with the given pattern.
/// \param NumExpansions The number of expansions for the pack, if known.
Expand All @@ -1795,7 +1789,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// if this is the canonical type of another pack expansion type.
QualType getPackExpansionType(QualType Pattern,
std::optional<unsigned> NumExpansions,
bool ExpectPackInType = true);
bool ExpectPackInType = true) const;

QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl,
ObjCInterfaceDecl *PrevDecl = nullptr) const;
Expand Down
44 changes: 20 additions & 24 deletions clang/include/clang/AST/DeclTemplate.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ NamedDecl *getAsNamedDecl(TemplateParameter P);
class TemplateParameterList final
: private llvm::TrailingObjects<TemplateParameterList, NamedDecl *,
Expr *> {
/// The template argument list of the template parameter list.
TemplateArgument *InjectedArgs = nullptr;

/// The location of the 'template' keyword.
SourceLocation TemplateLoc;

Expand Down Expand Up @@ -196,6 +199,9 @@ class TemplateParameterList final

bool hasAssociatedConstraints() const;

/// Get the template argument list of the template parameter list.
ArrayRef<TemplateArgument> getInjectedTemplateArgs(const ASTContext &Context);

SourceLocation getTemplateLoc() const { return TemplateLoc; }
SourceLocation getLAngleLoc() const { return LAngleLoc; }
SourceLocation getRAngleLoc() const { return RAngleLoc; }
Expand Down Expand Up @@ -793,15 +799,6 @@ class RedeclarableTemplateDecl : public TemplateDecl,
/// The first value in the array is the number of specializations/partial
/// specializations that follow.
GlobalDeclID *LazySpecializations = nullptr;

/// The set of "injected" template arguments used within this
/// template.
///
/// This pointer refers to the template arguments (there are as
/// many template arguments as template parameters) for the
/// template, and is allocated lazily, since most templates do not
/// require the use of this information.
TemplateArgument *InjectedArgs = nullptr;
};

/// Pointer to the common data shared by all declarations of this
Expand Down Expand Up @@ -927,7 +924,10 @@ class RedeclarableTemplateDecl : public TemplateDecl,
/// Although the C++ standard has no notion of the "injected" template
/// arguments for a template, the notion is convenient when
/// we need to perform substitutions inside the definition of a template.
ArrayRef<TemplateArgument> getInjectedTemplateArgs();
ArrayRef<TemplateArgument>
getInjectedTemplateArgs(const ASTContext &Context) const {
return getTemplateParameters()->getInjectedTemplateArgs(Context);
}

using redecl_range = redeclarable_base::redecl_range;
using redecl_iterator = redeclarable_base::redecl_iterator;
Expand Down Expand Up @@ -2087,10 +2087,6 @@ class ClassTemplatePartialSpecializationDecl
/// The list of template parameters
TemplateParameterList *TemplateParams = nullptr;

/// The set of "injected" template arguments used within this
/// partial specialization.
TemplateArgument *InjectedArgs = nullptr;

/// The class template partial specialization from which this
/// class template partial specialization was instantiated.
///
Expand Down Expand Up @@ -2136,9 +2132,11 @@ class ClassTemplatePartialSpecializationDecl
return TemplateParams;
}

/// Retrieve the template arguments list of the template parameter list
/// of this template.
ArrayRef<TemplateArgument> getInjectedTemplateArgs();
/// Get the template argument list of the template parameter list.
ArrayRef<TemplateArgument>
getInjectedTemplateArgs(const ASTContext &Context) const {
return getTemplateParameters()->getInjectedTemplateArgs(Context);
}

/// \brief All associated constraints of this partial specialization,
/// including the requires clause and any constraints derived from
Expand Down Expand Up @@ -2864,10 +2862,6 @@ class VarTemplatePartialSpecializationDecl
/// The list of template parameters
TemplateParameterList *TemplateParams = nullptr;

/// The set of "injected" template arguments used within this
/// partial specialization.
TemplateArgument *InjectedArgs = nullptr;

/// The variable template partial specialization from which this
/// variable template partial specialization was instantiated.
///
Expand Down Expand Up @@ -2914,9 +2908,11 @@ class VarTemplatePartialSpecializationDecl
return TemplateParams;
}

/// Retrieve the template arguments list of the template parameter list
/// of this template.
ArrayRef<TemplateArgument> getInjectedTemplateArgs();
/// Get the template argument list of the template parameter list.
ArrayRef<TemplateArgument>
getInjectedTemplateArgs(const ASTContext &Context) const {
return getTemplateParameters()->getInjectedTemplateArgs(Context);
}

/// \brief All associated constraints of this partial specialization,
/// including the requires clause and any constraints derived from
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,14 @@ struct UncheckedOptionalAccessModelOptions {
/// can't identify when their results are used safely (across calls),
/// resulting in false positives in all such cases. Note: this option does not
/// cover access through `operator[]`.
/// FIXME: we currently cache and equate the result of const accessors
/// returning pointers, so cover the case of operator-> followed by
/// operator->, which covers the common case of smart pointers. We also cover
/// some limited cases of returning references (if return type is an optional
/// type), so cover some cases of operator* followed by operator*. We don't
/// cover mixing operator-> and operator*. Once we are confident in this const
/// accessor caching, we shouldn't need the IgnoreSmartPointerDereference
/// option anymore.
bool IgnoreSmartPointerDereference = false;
};

Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Analysis/FlowSensitive/NoopLattice.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_NOOP_LATTICE_H

#include "clang/Analysis/FlowSensitive/DataflowLattice.h"
#include "clang/Support/Compiler.h"
#include "llvm/ADT/Any.h"
#include <ostream>

Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Basic/AArch64SVEACLETypes.def
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,6 @@
AARCH64_VECTOR_TYPE(Name, MangledName, Id, SingletonId)
#endif


//===- Vector point types -----------------------------------------------===//

SVE_VECTOR_TYPE_INT("__SVInt8_t", "__SVInt8_t", SveInt8, SveInt8Ty, 16, 8, 1, true)
Expand Down Expand Up @@ -201,6 +200,7 @@ SVE_PREDICATE_TYPE_ALL("__clang_svboolx4_t", "svboolx4_t", SveBoolx4, SveBoolx4T

SVE_OPAQUE_TYPE("__SVCount_t", "__SVCount_t", SveCount, SveCountTy)

AARCH64_VECTOR_TYPE_MFLOAT("__MFloat8_t", "__MFloat8_t", MFloat8, MFloat8Ty, 1, 8, 1)
AARCH64_VECTOR_TYPE_MFLOAT("__MFloat8x8_t", "__MFloat8x8_t", MFloat8x8, MFloat8x8Ty, 8, 8, 1)
AARCH64_VECTOR_TYPE_MFLOAT("__MFloat8x16_t", "__MFloat8x16_t", MFloat8x16, MFloat8x16Ty, 16, 8, 1)

Expand Down
8 changes: 8 additions & 0 deletions clang/include/clang/Basic/AMDGPUTypes.def
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,15 @@
AMDGPU_TYPE(Name, Id, SingletonId, Width, Align)
#endif

#ifndef AMDGPU_NAMED_BARRIER_TYPE
#define AMDGPU_NAMED_BARRIER_TYPE(Name, Id, SingletonId, Width, Align, Scope) \
AMDGPU_TYPE(Name, Id, SingletonId, Width, Align)
#endif

AMDGPU_OPAQUE_PTR_TYPE("__amdgpu_buffer_rsrc_t", AMDGPUBufferRsrc, AMDGPUBufferRsrcTy, 128, 128, 8)

AMDGPU_NAMED_BARRIER_TYPE("__amdgpu_named_workgroup_barrier_t", AMDGPUNamedWorkgroupBarrier, AMDGPUNamedWorkgroupBarrierTy, 128, 32, 0)

#undef AMDGPU_TYPE
#undef AMDGPU_OPAQUE_PTR_TYPE
#undef AMDGPU_NAMED_BARRIER_TYPE
9 changes: 0 additions & 9 deletions clang/include/clang/Basic/Attr.td
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,6 @@ def SYCL : LangOpt<"SYCLIsDevice">;
def COnly : LangOpt<"", "!LangOpts.CPlusPlus">;
def CPlusPlus : LangOpt<"CPlusPlus">;
def OpenCL : LangOpt<"OpenCL">;
def RenderScript : LangOpt<"RenderScript">;
def ObjC : LangOpt<"ObjC">;
def BlocksSupported : LangOpt<"Blocks">;
def ObjCAutoRefCount : LangOpt<"ObjCAutoRefCount">;
Expand Down Expand Up @@ -1629,14 +1628,6 @@ def OpenCLNoSVM : Attr {
let ASTNode = 0;
}

def RenderScriptKernel : Attr {
let Spellings = [GNU<"kernel">];
let Subjects = SubjectList<[Function]>;
let Documentation = [RenderScriptKernelAttributeDocs];
let LangOpts = [RenderScript];
let SimpleHandler = 1;
}

def Deprecated : InheritableAttr {
let Spellings = [GCC<"deprecated">, Declspec<"deprecated">,
CXX11<"","deprecated", 201309>,
Expand Down
15 changes: 0 additions & 15 deletions clang/include/clang/Basic/AttrDocs.td
Original file line number Diff line number Diff line change
Expand Up @@ -5831,21 +5831,6 @@ provided with the regular ``visibility`` attribute.
}];
}

def RenderScriptKernelAttributeDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
``__attribute__((kernel))`` is used to mark a ``kernel`` function in
RenderScript.

In RenderScript, ``kernel`` functions are used to express data-parallel
computations. The RenderScript runtime efficiently parallelizes ``kernel``
functions to run on computational resources such as multi-core CPUs and GPUs.
See the RenderScript_ documentation for more information.

.. _RenderScript: https://developer.android.com/guide/topics/renderscript/compute.html
}];
}

def XRayDocs : Documentation {
let Category = DocCatFunction;
let Heading = "xray_always_instrument, xray_never_instrument, xray_log_args";
Expand Down
6 changes: 6 additions & 0 deletions clang/include/clang/Basic/Builtins.td
Original file line number Diff line number Diff line change
Expand Up @@ -4871,6 +4871,12 @@ def HLSLRadians : LangBuiltin<"HLSL_LANG"> {
let Prototype = "void(...)";
}

def HLSLSplitDouble: LangBuiltin<"HLSL_LANG"> {
let Spellings = ["__builtin_hlsl_elementwise_splitdouble"];
let Attributes = [NoThrow, Const];
let Prototype = "void(...)";
}

// Builtins for XRay.
def XRayCustomEvent : Builtin {
let Spellings = ["__xray_customevent"];
Expand Down
4 changes: 4 additions & 0 deletions clang/include/clang/Basic/BuiltinsX86.def
Original file line number Diff line number Diff line change
Expand Up @@ -2179,6 +2179,10 @@ TARGET_BUILTIN(__builtin_ia32_vsm4key4256, "V8UiV8UiV8Ui", "nV:256:", "sm4")
TARGET_BUILTIN(__builtin_ia32_vsm4rnds4128, "V4UiV4UiV4Ui", "nV:128:", "sm4")
TARGET_BUILTIN(__builtin_ia32_vsm4rnds4256, "V8UiV8UiV8Ui", "nV:256:", "sm4")

// SM4_EVEX
TARGET_BUILTIN(__builtin_ia32_vsm4key4512, "V16UiV16UiV16Ui", "nV:512:", "avx10.2-512,sm4")
TARGET_BUILTIN(__builtin_ia32_vsm4rnds4512, "V16UiV16UiV16Ui", "nV:512:", "avx10.2-512,sm4")

// AVX10 MINMAX
TARGET_BUILTIN(__builtin_ia32_vminmaxnepbf16128, "V8yV8yV8yIi", "nV:128:", "avx10.2-256")
TARGET_BUILTIN(__builtin_ia32_vminmaxnepbf16256, "V16yV16yV16yIi", "nV:256:", "avx10.2-256")
Expand Down
14 changes: 14 additions & 0 deletions clang/include/clang/Basic/BuiltinsX86_64.def
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,20 @@ TARGET_BUILTIN(__builtin_ia32_aand64, "vv*SOi", "n", "raoint")
TARGET_BUILTIN(__builtin_ia32_aor64, "vv*SOi", "n", "raoint")
TARGET_BUILTIN(__builtin_ia32_axor64, "vv*SOi", "n", "raoint")

// MOVRS and AVX10.2
TARGET_BUILTIN(__builtin_ia32_vmovrsb128, "V16cV16cC*", "nV:128:", "movrs,avx10.2-256")
TARGET_BUILTIN(__builtin_ia32_vmovrsb256, "V32cV32cC*", "nV:256:", "movrs,avx10.2-256")
TARGET_BUILTIN(__builtin_ia32_vmovrsb512, "V64cV64cC*", "nV:512:", "movrs,avx10.2-512")
TARGET_BUILTIN(__builtin_ia32_vmovrsd128, "V4iV4iC*", "nV:128:", "movrs,avx10.2-256")
TARGET_BUILTIN(__builtin_ia32_vmovrsd256, "V8iV8iC*", "nV:256:", "movrs,avx10.2-256")
TARGET_BUILTIN(__builtin_ia32_vmovrsd512, "V16iV16iC*", "nV:512:", "movrs,avx10.2-512")
TARGET_BUILTIN(__builtin_ia32_vmovrsq128, "V2OiV2OiC*", "nV:128:", "movrs,avx10.2-256")
TARGET_BUILTIN(__builtin_ia32_vmovrsq256, "V4OiV4OiC*", "nV:256:", "movrs,avx10.2-256")
TARGET_BUILTIN(__builtin_ia32_vmovrsq512, "V8OiV8OiC*", "nV:512:", "movrs,avx10.2-512")
TARGET_BUILTIN(__builtin_ia32_vmovrsw128, "V8sV8sC*", "nV:128:", "movrs,avx10.2-256")
TARGET_BUILTIN(__builtin_ia32_vmovrsw256, "V16sV16sC*", "nV:256:", "movrs,avx10.2-256")
TARGET_BUILTIN(__builtin_ia32_vmovrsw512, "V32sV32sC*", "nV:512:", "movrs,avx10.2-512")

#undef BUILTIN
#undef TARGET_BUILTIN
#undef TARGET_HEADER_BUILTIN
2 changes: 2 additions & 0 deletions clang/include/clang/Basic/CodeGenOptions.def
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,8 @@ CODEGENOPT(XRayIgnoreLoops , 1, 0)
///< Emit the XRay function index section.
CODEGENOPT(XRayFunctionIndex , 1, 1)

///< Set when -fxray-shared is enabled
CODEGENOPT(XRayShared , 1, 0)

///< Set the minimum number of instructions in a function to determine selective
///< XRay instrumentation.
Expand Down
7 changes: 7 additions & 0 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -795,6 +795,10 @@ def warn_cstruct_memaccess : Warning<
"%1 call is a pointer to record %2 that is not trivial to "
"%select{primitive-default-initialize|primitive-copy}3">,
InGroup<NonTrivialMemaccess>;
def warn_cxxstruct_memaccess : Warning<
"first argument in call to "
"%0 is a pointer to non-trivially copyable type %1">,
InGroup<NonTrivialMemaccess>;
def note_nontrivial_field : Note<
"field is non-trivial to %select{copy|default-initialize}0">;
def err_non_trivial_c_union_in_invalid_context : Error<
Expand Down Expand Up @@ -10097,6 +10101,9 @@ def err_lifetimebound_no_object_param : Error<
def err_lifetimebound_ctor_dtor : Error<
"'lifetimebound' attribute cannot be applied to a "
"%select{constructor|destructor}0">;
def err_lifetimebound_void_return_type : Error<
"'lifetimebound' attribute cannot be applied to a parameter of a function "
"that returns void">;

// CHECK: returning address/reference of stack memory
def warn_ret_stack_addr_ref : Warning<
Expand Down
1 change: 0 additions & 1 deletion clang/include/clang/Basic/LangOptions.def
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,6 @@ LANGOPT(OpenMPNoNestedParallelism , 1, 0, "Assume that no thread in a parallel
LANGOPT(OpenMPOffloadMandatory , 1, 0, "Assert that offloading is mandatory and do not create a host fallback.")
LANGOPT(OpenMPForceUSM , 1, 0, "Enable OpenMP unified shared memory mode via compiler.")
LANGOPT(NoGPULib , 1, 0, "Indicate a build without the standard GPU libraries.")
LANGOPT(RenderScript , 1, 0, "RenderScript")

LANGOPT(HLSL, 1, 0, "HLSL")
ENUM_LANGOPT(HLSLVersion, HLSLLangStd, 16, HLSL_Unset, "HLSL Version")
Expand Down
1 change: 0 additions & 1 deletion clang/include/clang/Basic/LangStandard.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ enum class Language : uint8_t {
OpenCL,
OpenCLCXX,
CUDA,
RenderScript,
HIP,
HLSL,
///@}
Expand Down
34 changes: 25 additions & 9 deletions clang/include/clang/Basic/Module.h
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ class alignas(8) Module {

/// A mapping from the submodule name to the index into the
/// \c SubModules vector at which that submodule resides.
llvm::StringMap<unsigned> SubModuleIndex;
mutable llvm::StringMap<unsigned> SubModuleIndex;

/// The AST file if this is a top-level module which has a
/// corresponding serialized AST file, or null otherwise.
Expand All @@ -253,8 +253,6 @@ class alignas(8) Module {
HK_PrivateTextual,
HK_Excluded
};
static const int NumHeaderKinds = HK_Excluded + 1;

/// Information about a header directive as found in the module map
/// file.
struct Header {
Expand All @@ -263,17 +261,36 @@ class alignas(8) Module {
FileEntryRef Entry;
};

/// Information about a directory name as found in the module map
/// file.
private:
static const int NumHeaderKinds = HK_Excluded + 1;
// The begin index for a HeaderKind also acts the end index of HeaderKind - 1.
// The extra element at the end acts as the end index of the last HeaderKind.
unsigned HeaderKindBeginIndex[NumHeaderKinds + 1] = {};
SmallVector<Header, 2> HeadersStorage;

public:
ArrayRef<Header> getAllHeaders() const { return HeadersStorage; }
ArrayRef<Header> getHeaders(HeaderKind HK) const {
assert(HK < NumHeaderKinds && "Invalid Module::HeaderKind");
auto BeginIt = HeadersStorage.begin() + HeaderKindBeginIndex[HK];
auto EndIt = HeadersStorage.begin() + HeaderKindBeginIndex[HK + 1];
return {BeginIt, EndIt};
}
void addHeader(HeaderKind HK, Header H) {
assert(HK < NumHeaderKinds && "Invalid Module::HeaderKind");
auto EndIt = HeadersStorage.begin() + HeaderKindBeginIndex[HK + 1];
HeadersStorage.insert(EndIt, std::move(H));
for (unsigned HKI = HK + 1; HKI != NumHeaderKinds + 1; ++HKI)
++HeaderKindBeginIndex[HKI];
}

/// Information about a directory name as found in the module map file.
struct DirectoryName {
std::string NameAsWritten;
std::string PathRelativeToRootModuleDirectory;
DirectoryEntryRef Entry;
};

/// The headers that are part of this module.
SmallVector<Header, 2> Headers[5];

/// Stored information about a header directive that was found in the
/// module map file but has not been resolved to a file.
struct UnresolvedHeaderDirective {
Expand Down Expand Up @@ -595,7 +612,6 @@ class alignas(8) Module {
void setParent(Module *M) {
assert(!Parent);
Parent = M;
Parent->SubModuleIndex[Name] = Parent->SubModules.size();
Parent->SubModules.push_back(this);
}

Expand Down
6 changes: 0 additions & 6 deletions clang/include/clang/Basic/TargetInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -262,9 +262,6 @@ class TargetInfo : public TransferrableTargetInfo,
LLVM_PREFERRED_TYPE(bool)
unsigned HasBuiltinMSVaList : 1;

LLVM_PREFERRED_TYPE(bool)
unsigned IsRenderScriptTarget : 1;

LLVM_PREFERRED_TYPE(bool)
unsigned HasAArch64SVETypes : 1;

Expand Down Expand Up @@ -1031,9 +1028,6 @@ class TargetInfo : public TransferrableTargetInfo,
/// available on this target.
bool hasBuiltinMSVaList() const { return HasBuiltinMSVaList; }

/// Returns true for RenderScript.
bool isRenderScriptTarget() const { return IsRenderScriptTarget; }

/// Returns whether or not the AArch64 SVE built-in types are
/// available on this target.
bool hasAArch64SVETypes() const { return HasAArch64SVETypes; }
Expand Down
16 changes: 4 additions & 12 deletions clang/include/clang/CodeGen/CGFunctionInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -271,12 +271,8 @@ class ABIArgInfo {
// in the unpadded type.
unsigned unpaddedIndex = 0;
for (auto eltType : coerceToType->elements()) {
if (isPaddingForCoerceAndExpand(eltType)) continue;
if (unpaddedStruct) {
assert(unpaddedStruct->getElementType(unpaddedIndex) == eltType);
} else {
assert(unpaddedIndex == 0 && unpaddedCoerceToType == eltType);
}
if (isPaddingForCoerceAndExpand(eltType))
continue;
unpaddedIndex++;
}

Expand All @@ -295,12 +291,8 @@ class ABIArgInfo {
}

static bool isPaddingForCoerceAndExpand(llvm::Type *eltType) {
if (eltType->isArrayTy()) {
assert(eltType->getArrayElementType()->isIntegerTy(8));
return true;
} else {
return false;
}
return eltType->isArrayTy() &&
eltType->getArrayElementType()->isIntegerTy(8);
}

Kind getKind() const { return TheKind; }
Expand Down
30 changes: 24 additions & 6 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -627,7 +627,6 @@ defvar c23 = LangOpts<"C23">;
defvar lang_std = LangOpts<"LangStd">;
defvar open_cl = LangOpts<"OpenCL">;
defvar cuda = LangOpts<"CUDA">;
defvar render_script = LangOpts<"RenderScript">;
defvar hip = LangOpts<"HIP">;
defvar gnu_mode = LangOpts<"GNUMode">;
defvar asm_preprocessor = LangOpts<"AsmPreprocessor">;
Expand Down Expand Up @@ -1787,6 +1786,12 @@ defm debug_info_for_profiling : BoolFOption<"debug-info-for-profiling",
PosFlag<SetTrue, [], [ClangOption, CC1Option],
"Emit extra debug info to make sample profile more accurate">,
NegFlag<SetFalse>>;
def fprofile_generate_cold_function_coverage : Flag<["-"], "fprofile-generate-cold-function-coverage">,
Group<f_Group>, Visibility<[ClangOption, CLOption]>,
HelpText<"Generate instrumented code to collect coverage info for cold functions into default.profraw file (overridden by '=' form of option or LLVM_PROFILE_FILE env var)">;
def fprofile_generate_cold_function_coverage_EQ : Joined<["-"], "fprofile-generate-cold-function-coverage=">,
Group<f_Group>, Visibility<[ClangOption, CLOption]>, MetaVarName<"<directory>">,
HelpText<"Generate instrumented code to collect coverage info for cold functions into <directory>/default.profraw (overridden by LLVM_PROFILE_FILE env var)">;
def fprofile_instr_generate : Flag<["-"], "fprofile-instr-generate">,
Group<f_Group>, Visibility<[ClangOption, CLOption]>,
HelpText<"Generate instrumented code to collect execution counts into default.profraw file (overridden by '=' form of option or LLVM_PROFILE_FILE env var)">;
Expand Down Expand Up @@ -2948,6 +2953,11 @@ def fxray_selected_function_group :
HelpText<"When using -fxray-function-groups, select which group of functions to instrument. Valid range is 0 to fxray-function-groups - 1">,
MarshallingInfoInt<CodeGenOpts<"XRaySelectedFunctionGroup">, "0">;

defm xray_shared : BoolFOption<"xray-shared",
CodeGenOpts<"XRayShared">, DefaultFalse,
PosFlag<SetTrue, [], [ClangOption, CC1Option],
"Enable shared library instrumentation with XRay">,
NegFlag<SetFalse>>;

defm fine_grained_bitfield_accesses : BoolOption<"f", "fine-grained-bitfield-accesses",
CodeGenOpts<"FineGrainedBitfieldAccesses">, DefaultFalse,
Expand Down Expand Up @@ -4668,7 +4678,8 @@ def malign_loops_EQ : Joined<["-"], "malign-loops=">, Group<clang_ignored_m_Grou
def malign_jumps_EQ : Joined<["-"], "malign-jumps=">, Group<clang_ignored_m_Group>;

let Flags = [TargetSpecific] in {
def mabi_EQ : Joined<["-"], "mabi=">, Group<m_Group>;
def mabi_EQ : Joined<["-"], "mabi=">, Group<m_Group>,
Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>;
def malign_branch_EQ : CommaJoined<["-"], "malign-branch=">, Group<m_Group>,
HelpText<"Specify types of branches to align">;
def malign_branch_boundary_EQ : Joined<["-"], "malign-branch-boundary=">, Group<m_Group>,
Expand Down Expand Up @@ -5400,9 +5411,9 @@ def mfrecipe : Flag<["-"], "mfrecipe">, Group<m_loongarch_Features_Group>,
def mno_frecipe : Flag<["-"], "mno-frecipe">, Group<m_loongarch_Features_Group>,
HelpText<"Disable frecipe.{s/d} and frsqrte.{s/d}">;
def mlam_bh : Flag<["-"], "mlam-bh">, Group<m_loongarch_Features_Group>,
HelpText<"Enable amswap_[db].{b/h} and amadd_[db].{b/h}">;
HelpText<"Enable amswap[_db].{b/h} and amadd[_db].{b/h}">;
def mno_lam_bh : Flag<["-"], "mno-lam-bh">, Group<m_loongarch_Features_Group>,
HelpText<"Disable amswap_[db].{b/h} and amadd_[db].{b/h}">;
HelpText<"Disable amswap[_db].{b/h} and amadd[_db].{b/h}">;
def mannotate_tablejump : Flag<["-"], "mannotate-tablejump">, Group<m_loongarch_Features_Group>,
HelpText<"Enable annotate table jump instruction to correlate it with the jump table.">;
def mno_annotate_tablejump : Flag<["-"], "mno-annotate-tablejump">, Group<m_loongarch_Features_Group>,
Expand Down Expand Up @@ -5628,6 +5639,7 @@ def noprebind : Flag<["-"], "noprebind">;
def noprofilelib : Flag<["-"], "noprofilelib">;
def noseglinkedit : Flag<["-"], "noseglinkedit">;
def nostartfiles : Flag<["-"], "nostartfiles">, Group<Link_Group>;
def startfiles : Flag<["-"], "startfiles">, Group<Link_Group>;
def nostdinc : Flag<["-"], "nostdinc">,
Visibility<[ClangOption, CLOption, DXCOption]>, Group<IncludePath_Group>,
HelpText<"Disable both standard system #include directories and builtin #include directories">;
Expand All @@ -5640,6 +5652,9 @@ def nostdincxx : Flag<["-"], "nostdinc++">, Visibility<[ClangOption, CC1Option]>
def nostdlib : Flag<["-"], "nostdlib">,
Visibility<[ClangOption, CLOption, FlangOption, DXCOption]>,
Group<Link_Group>;
def stdlib : Flag<["-"], "stdlib">,
Visibility<[ClangOption, CLOption, FlangOption, DXCOption]>,
Group<Link_Group>;
def nostdlibxx : Flag<["-"], "nostdlib++">;
def object : Flag<["-"], "object">;
def o : JoinedOrSeparate<["-"], "o">,
Expand Down Expand Up @@ -6424,6 +6439,8 @@ def mmovdiri : Flag<["-"], "mmovdiri">, Group<m_x86_Features_Group>;
def mno_movdiri : Flag<["-"], "mno-movdiri">, Group<m_x86_Features_Group>;
def mmovdir64b : Flag<["-"], "mmovdir64b">, Group<m_x86_Features_Group>;
def mno_movdir64b : Flag<["-"], "mno-movdir64b">, Group<m_x86_Features_Group>;
def mmovrs : Flag<["-"], "mmovrs">, Group<m_x86_Features_Group>;
def mno_movrs : Flag<["-"], "mno-movrs">, Group<m_x86_Features_Group>;
def mmwaitx : Flag<["-"], "mmwaitx">, Group<m_x86_Features_Group>;
def mno_mwaitx : Flag<["-"], "mno-mwaitx">, Group<m_x86_Features_Group>;
def mpku : Flag<["-"], "mpku">, Group<m_x86_Features_Group>;
Expand Down Expand Up @@ -7347,6 +7364,7 @@ def mabi_EQ_ieeelongdouble : Flag<["-"], "mabi=ieeelongdouble">,
HelpText<"Use IEEE 754 quadruple-precision for long double">,
MarshallingInfoFlag<LangOpts<"PPCIEEELongDouble">>;
def mabi_EQ_vec_extabi : Flag<["-"], "mabi=vec-extabi">,
Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>,
HelpText<"Enable the extended Altivec ABI on AIX. Use volatile and nonvolatile vector registers">,
MarshallingInfoFlag<LangOpts<"EnableAIXExtendedAltivecABI">>;
def mfloat_abi : Separate<["-"], "mfloat-abi">,
Expand Down Expand Up @@ -8107,11 +8125,11 @@ def vtordisp_mode_EQ : Joined<["-"], "vtordisp-mode=">,
def fnative_half_type: Flag<["-"], "fnative-half-type">,
HelpText<"Use the native half type for __fp16 instead of promoting to float">,
MarshallingInfoFlag<LangOpts<"NativeHalfType">>,
ImpliedByAnyOf<[open_cl.KeyPath, render_script.KeyPath]>;
ImpliedByAnyOf<[open_cl.KeyPath]>;
def fnative_half_arguments_and_returns : Flag<["-"], "fnative-half-arguments-and-returns">,
HelpText<"Use the native __fp16 type for arguments and returns (and skip ABI-specific lowering)">,
MarshallingInfoFlag<LangOpts<"NativeHalfArgsAndReturns">>,
ImpliedByAnyOf<[open_cl.KeyPath, render_script.KeyPath, hlsl.KeyPath, hip.KeyPath]>;
ImpliedByAnyOf<[open_cl.KeyPath, hlsl.KeyPath, hip.KeyPath]>;
def fdefault_calling_conv_EQ : Joined<["-"], "fdefault-calling-conv=">,
HelpText<"Set default calling convention">,
Values<"cdecl,fastcall,stdcall,vectorcall,regcall,rtdcall">,
Expand Down
1 change: 0 additions & 1 deletion clang/include/clang/Driver/Types.def
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ TYPE("c++", CXX, PP_CXX, "cpp", phases
TYPE("objective-c++-cpp-output", PP_ObjCXX, INVALID, "mii", phases::Compile, phases::Backend, phases::Assemble, phases::Link)
TYPE("objc++-cpp-output", PP_ObjCXX_Alias, INVALID, "mii", phases::Compile, phases::Backend, phases::Assemble, phases::Link)
TYPE("objective-c++", ObjCXX, PP_ObjCXX, "mm", phases::Preprocess, phases::Compile, phases::Backend, phases::Assemble, phases::Link)
TYPE("renderscript", RenderScript, PP_C, "rs", phases::Preprocess, phases::Compile, phases::Backend, phases::Assemble, phases::Link)
TYPE("hlsl", HLSL, PP_CXX, "hlsl", phases::Preprocess, phases::Compile, phases::Backend, phases::Assemble)

// C family input files to precompile.
Expand Down
2 changes: 2 additions & 0 deletions clang/include/clang/Driver/XRayArgs.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class XRayArgs {
XRayInstrSet InstrumentationBundle;
llvm::opt::Arg *XRayInstrument = nullptr;
bool XRayRT = true;
bool XRayShared = false;

public:
/// Parses the XRay arguments from an argument list.
Expand All @@ -35,6 +36,7 @@ class XRayArgs {
llvm::opt::ArgStringList &CmdArgs, types::ID InputType) const;

bool needsXRayRt() const { return XRayInstrument && XRayRT; }
bool needsXRayDSORt() const { return XRayInstrument && XRayRT && XRayShared; }
llvm::ArrayRef<std::string> modeList() const { return Modes; }
XRayInstrSet instrumentationBundle() const { return InstrumentationBundle; }
};
Expand Down
11 changes: 11 additions & 0 deletions clang/include/clang/Lex/ModuleMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,17 @@ class ModuleMap {
std::pair<Module *, bool> findOrCreateModule(StringRef Name, Module *Parent,
bool IsFramework,
bool IsExplicit);
/// Call \c ModuleMap::findOrCreateModule and throw away the information
/// whether the module was found or created.
Module *findOrCreateModuleFirst(StringRef Name, Module *Parent,
bool IsFramework, bool IsExplicit) {
return findOrCreateModule(Name, Parent, IsFramework, IsExplicit).first;
}
/// Create new submodule, assuming it does not exist. This function can only
/// be called when it is guaranteed that this submodule does not exist yet.
/// The parameters have same semantics as \c ModuleMap::findOrCreateModule.
Module *createModule(StringRef Name, Module *Parent, bool IsFramework,
bool IsExplicit);

/// Create a global module fragment for a C++ module unit.
///
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Lex/Preprocessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -1490,7 +1490,7 @@ class Preprocessor {
/// Mark the file as included.
/// Returns true if this is the first time the file was included.
bool markIncluded(FileEntryRef File) {
HeaderInfo.getFileInfo(File);
HeaderInfo.getFileInfo(File).IsLocallyIncluded = true;
return IncludedFiles.insert(File).second;
}

Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Sema/SemaInternal.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ inline InheritableAttr *getDLLAttr(Decl *D) {
}

/// Retrieve the depth and index of a template parameter.
inline std::pair<unsigned, unsigned> getDepthAndIndex(NamedDecl *ND) {
inline std::pair<unsigned, unsigned> getDepthAndIndex(const NamedDecl *ND) {
if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(ND))
return std::make_pair(TTP->getDepth(), TTP->getIndex());

Expand Down
6 changes: 3 additions & 3 deletions clang/include/clang/Serialization/ASTBitCodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ namespace serialization {
/// Version 4 of AST files also requires that the version control branch and
/// revision match exactly, since there is no backward compatibility of
/// AST files at this time.
const unsigned VERSION_MAJOR = 31;
const unsigned VERSION_MAJOR = 32;

/// AST file minor version number supported by this version of
/// Clang.
Expand All @@ -54,7 +54,7 @@ const unsigned VERSION_MAJOR = 31;
/// for the previous version could still support reading the new
/// version by ignoring new kinds of subblocks), this number
/// should be increased.
const unsigned VERSION_MINOR = 1;
const unsigned VERSION_MINOR = 0;

/// An ID number that refers to an identifier in an AST file.
///
Expand Down Expand Up @@ -1149,7 +1149,7 @@ enum PredefinedTypeIDs {
///
/// Type IDs for non-predefined types will start at
/// NUM_PREDEF_TYPE_IDs.
const unsigned NUM_PREDEF_TYPE_IDS = 511;
const unsigned NUM_PREDEF_TYPE_IDS = 513;

// Ensure we do not overrun the predefined types we reserved
// in the enum PredefinedTypeIDs above.
Expand Down
2 changes: 2 additions & 0 deletions clang/include/clang/Serialization/ASTReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -2335,6 +2335,8 @@ class ASTReader
/// Translate a FileID from another module file's FileID space into ours.
FileID TranslateFileID(ModuleFile &F, FileID FID) const {
assert(FID.ID >= 0 && "Reading non-local FileID.");
if (FID.isInvalid())
return FID;
return FileID::get(F.SLocEntryBaseID + FID.ID - 1);
}

Expand Down
18 changes: 0 additions & 18 deletions clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,6 @@ def Debug : Package<"debug">, Hidden;

def CloneDetectionAlpha : Package<"clone">, ParentPackage<Alpha>;

def NonDeterminismAlpha : Package<"nondeterminism">, ParentPackage<Alpha>;

def Fuchsia : Package<"fuchsia">;
def FuchsiaAlpha : Package<"fuchsia">, ParentPackage<Alpha>;

Expand Down Expand Up @@ -1711,22 +1709,6 @@ def TaintedDivChecker: Checker<"TaintedDiv">,

} // end "optin.taint"

//===----------------------------------------------------------------------===//
// NonDeterminism checkers.
//===----------------------------------------------------------------------===//

let ParentPackage = NonDeterminismAlpha in {

def PointerIterationChecker : Checker<"PointerIteration">,
HelpText<"Checks for non-determinism caused by iteration of unordered containers of pointers">,
Documentation<HasDocumentation>;

def PointerSortingChecker : Checker<"PointerSorting">,
HelpText<"Check for non-determinism caused by sorting of pointers">,
Documentation<HasDocumentation>;

} // end alpha.nondeterminism

//===----------------------------------------------------------------------===//
// Fuchsia checkers.
//===----------------------------------------------------------------------===//
Expand Down
16 changes: 4 additions & 12 deletions clang/lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5634,7 +5634,7 @@ ASTContext::getDependentTemplateSpecializationType(
return QualType(T, 0);
}

TemplateArgument ASTContext::getInjectedTemplateArg(NamedDecl *Param) {
TemplateArgument ASTContext::getInjectedTemplateArg(NamedDecl *Param) const {
TemplateArgument Arg;
if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
QualType ArgType = getTypeDeclType(TTP);
Expand Down Expand Up @@ -5678,23 +5678,15 @@ TemplateArgument ASTContext::getInjectedTemplateArg(NamedDecl *Param) {
}

if (Param->isTemplateParameterPack())
Arg = TemplateArgument::CreatePackCopy(*this, Arg);
Arg =
TemplateArgument::CreatePackCopy(const_cast<ASTContext &>(*this), Arg);

return Arg;
}

void
ASTContext::getInjectedTemplateArgs(const TemplateParameterList *Params,
SmallVectorImpl<TemplateArgument> &Args) {
Args.reserve(Args.size() + Params->size());

for (NamedDecl *Param : *Params)
Args.push_back(getInjectedTemplateArg(Param));
}

QualType ASTContext::getPackExpansionType(QualType Pattern,
std::optional<unsigned> NumExpansions,
bool ExpectPackInType) {
bool ExpectPackInType) const {
assert((!ExpectPackInType || Pattern->containsUnexpandedParameterPack()) &&
"Pack expansions must expand one or more parameter packs");

Expand Down
11 changes: 8 additions & 3 deletions clang/lib/AST/ByteCode/Interp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,7 @@ bool CheckConstant(InterpState &S, CodePtr OpPC, const Descriptor *Desc) {
}

static bool CheckConstant(InterpState &S, CodePtr OpPC, const Pointer &Ptr) {
if (!Ptr.isBlockPointer())
if (!Ptr.isStatic() || !Ptr.isBlockPointer())
return true;
return CheckConstant(S, OpPC, Ptr.getDeclDesc());
}
Expand Down Expand Up @@ -513,8 +513,8 @@ bool CheckMutable(InterpState &S, CodePtr OpPC, const Pointer &Ptr) {
return false;
}

bool CheckVolatile(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
AccessKinds AK) {
static bool CheckVolatile(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
AccessKinds AK) {
assert(Ptr.isLive());

// FIXME: This check here might be kinda expensive. Maybe it would be better
Expand Down Expand Up @@ -1451,6 +1451,11 @@ bool CheckNewTypeMismatch(InterpState &S, CodePtr OpPC, const Expr *E,
<< StorageType << AllocType;
return false;
}

// Can't activate fields in a union, unless the direct base is the union.
if (Ptr.inUnion() && !Ptr.isActive() && !Ptr.getBase().getRecord()->isUnion())
return CheckActive(S, OpPC, Ptr, AK_Construct);

return true;
}

Expand Down
14 changes: 14 additions & 0 deletions clang/lib/AST/ByteCode/InterpBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1670,6 +1670,15 @@ static bool interp__builtin_operator_delete(InterpState &S, CodePtr OpPC,
S, OpPC, *AllocForm, DynamicAllocator::Form::Operator, BlockDesc, Source);
}

static bool interp__builtin_arithmetic_fence(InterpState &S, CodePtr OpPC,
const InterpFrame *Frame,
const Function *Func,
const CallExpr *Call) {
const Floating &Arg0 = S.Stk.peek<Floating>();
S.Stk.push<Floating>(Arg0);
return true;
}

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

case Builtin::BI__arithmetic_fence:
if (!interp__builtin_arithmetic_fence(S, OpPC, Frame, F, Call))
return false;
break;

default:
S.FFDiag(S.Current->getLocation(OpPC),
diag::note_invalid_subexpr_in_const_expr)
Expand Down
9 changes: 0 additions & 9 deletions clang/lib/AST/ByteCode/Pointer.h
Original file line number Diff line number Diff line change
Expand Up @@ -653,15 +653,6 @@ class Pointer {
return *reinterpret_cast<T *>(asBlockPointer().Pointee->rawData() + Offset);
}

/// Dereferences a primitive element.
template <typename T> T &elem(unsigned I) const {
assert(I < getNumElems());
assert(isBlockPointer());
assert(asBlockPointer().Pointee);
return reinterpret_cast<T *>(asBlockPointer().Pointee->data() +
sizeof(InitMapPtr))[I];
}

/// Whether this block can be read from at all. This is only true for
/// block pointers that point to a valid location inside that block.
bool isDereferencable() const {
Expand Down
64 changes: 14 additions & 50 deletions clang/lib/AST/DeclTemplate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ DefaultTemplateArgumentContainsUnexpandedPack(const TemplateParam &P) {
P.getDefaultArgument().getArgument().containsUnexpandedParameterPack();
}

TemplateParameterList::TemplateParameterList(const ASTContext& C,
TemplateParameterList::TemplateParameterList(const ASTContext &C,
SourceLocation TemplateLoc,
SourceLocation LAngleLoc,
ArrayRef<NamedDecl *> Params,
Expand Down Expand Up @@ -244,6 +244,17 @@ bool TemplateParameterList::hasAssociatedConstraints() const {
return HasRequiresClause || HasConstrainedParameters;
}

ArrayRef<TemplateArgument>
TemplateParameterList::getInjectedTemplateArgs(const ASTContext &Context) {
if (!InjectedArgs) {
InjectedArgs = new (Context) TemplateArgument[size()];
llvm::transform(*this, InjectedArgs, [&](NamedDecl *ND) {
return Context.getInjectedTemplateArg(ND);
});
}
return {InjectedArgs, NumParams};
}

bool TemplateParameterList::shouldIncludeTypeForArgument(
const PrintingPolicy &Policy, const TemplateParameterList *TPL,
unsigned Idx) {
Expand Down Expand Up @@ -396,22 +407,6 @@ void RedeclarableTemplateDecl::addSpecializationImpl(
SETraits::getDecl(Entry));
}

ArrayRef<TemplateArgument> RedeclarableTemplateDecl::getInjectedTemplateArgs() {
TemplateParameterList *Params = getTemplateParameters();
auto *CommonPtr = getCommonPtr();
if (!CommonPtr->InjectedArgs) {
auto &Context = getASTContext();
SmallVector<TemplateArgument, 16> TemplateArgs;
Context.getInjectedTemplateArgs(Params, TemplateArgs);
CommonPtr->InjectedArgs =
new (Context) TemplateArgument[TemplateArgs.size()];
std::copy(TemplateArgs.begin(), TemplateArgs.end(),
CommonPtr->InjectedArgs);
}

return llvm::ArrayRef(CommonPtr->InjectedArgs, Params->size());
}

//===----------------------------------------------------------------------===//
// FunctionTemplateDecl Implementation
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -631,13 +626,10 @@ ClassTemplateDecl::getInjectedClassNameSpecialization() {
// expansion (14.5.3) whose pattern is the name of the template parameter
// pack.
ASTContext &Context = getASTContext();
TemplateParameterList *Params = getTemplateParameters();
SmallVector<TemplateArgument, 16> TemplateArgs;
Context.getInjectedTemplateArgs(Params, TemplateArgs);
TemplateName Name = Context.getQualifiedTemplateName(
/*NNS=*/nullptr, /*TemplateKeyword=*/false, TemplateName(this));
CommonPtr->InjectedClassNameType =
Context.getTemplateSpecializationType(Name, TemplateArgs);
CommonPtr->InjectedClassNameType = Context.getTemplateSpecializationType(
Name, getTemplateParameters()->getInjectedTemplateArgs(Context));
return CommonPtr->InjectedClassNameType;
}

Expand Down Expand Up @@ -1184,20 +1176,6 @@ SourceRange ClassTemplatePartialSpecializationDecl::getSourceRange() const {
return Range;
}

ArrayRef<TemplateArgument>
ClassTemplatePartialSpecializationDecl::getInjectedTemplateArgs() {
TemplateParameterList *Params = getTemplateParameters();
auto *First = cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
if (!First->InjectedArgs) {
auto &Context = getASTContext();
SmallVector<TemplateArgument, 16> TemplateArgs;
Context.getInjectedTemplateArgs(Params, TemplateArgs);
First->InjectedArgs = new (Context) TemplateArgument[TemplateArgs.size()];
std::copy(TemplateArgs.begin(), TemplateArgs.end(), First->InjectedArgs);
}
return llvm::ArrayRef(First->InjectedArgs, Params->size());
}

//===----------------------------------------------------------------------===//
// FriendTemplateDecl Implementation
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -1548,20 +1526,6 @@ SourceRange VarTemplatePartialSpecializationDecl::getSourceRange() const {
return Range;
}

ArrayRef<TemplateArgument>
VarTemplatePartialSpecializationDecl::getInjectedTemplateArgs() {
TemplateParameterList *Params = getTemplateParameters();
auto *First = cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
if (!First->InjectedArgs) {
auto &Context = getASTContext();
SmallVector<TemplateArgument, 16> TemplateArgs;
Context.getInjectedTemplateArgs(Params, TemplateArgs);
First->InjectedArgs = new (Context) TemplateArgument[TemplateArgs.size()];
std::copy(TemplateArgs.begin(), TemplateArgs.end(), First->InjectedArgs);
}
return llvm::ArrayRef(First->InjectedArgs, Params->size());
}

static TemplateParameterList *
createMakeIntegerSeqParameterList(const ASTContext &C, DeclContext *DC) {
// typename T
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,11 @@ auto isZeroParamConstMemberCall() {
callee(cxxMethodDecl(parameterCountIs(0), isConst())));
}

auto isZeroParamConstMemberOperatorCall() {
return cxxOperatorCallExpr(
callee(cxxMethodDecl(parameterCountIs(0), isConst())));
}

auto isNonConstMemberCall() {
return cxxMemberCallExpr(callee(cxxMethodDecl(unless(isConst()))));
}
Expand Down Expand Up @@ -572,9 +577,10 @@ void handleConstMemberCall(const CallExpr *CE,
return;
}

// Cache if the const method returns a boolean type.
// Cache if the const method returns a boolean or pointer type.
// We may decide to cache other return types in the future.
if (RecordLoc != nullptr && CE->getType()->isBooleanType()) {
if (RecordLoc != nullptr &&
(CE->getType()->isBooleanType() || CE->getType()->isPointerType())) {
Value *Val = State.Lattice.getOrCreateConstMethodReturnValue(*RecordLoc, CE,
State.Env);
if (Val == nullptr)
Expand All @@ -597,14 +603,26 @@ void transferValue_ConstMemberCall(const CXXMemberCallExpr *MCE,
MCE, dataflow::getImplicitObjectLocation(*MCE, State.Env), Result, State);
}

void transferValue_ConstMemberOperatorCall(
const CXXOperatorCallExpr *OCE, const MatchFinder::MatchResult &Result,
LatticeTransferState &State) {
auto *RecordLoc = cast_or_null<dataflow::RecordStorageLocation>(
State.Env.getStorageLocation(*OCE->getArg(0)));
handleConstMemberCall(OCE, RecordLoc, Result, State);
}

void handleNonConstMemberCall(const CallExpr *CE,
dataflow::RecordStorageLocation *RecordLoc,
const MatchFinder::MatchResult &Result,
LatticeTransferState &State) {
// When a non-const member function is called, reset some state.
if (RecordLoc != nullptr) {
// When a non-const member function is called, clear all (non-const)
// optional fields of the receiver. Const-qualified fields can't be
// changed (at least, not without UB).
for (const auto &[Field, FieldLoc] : RecordLoc->children()) {
if (isSupportedOptionalType(Field->getType())) {
QualType FieldType = Field->getType();
if (!FieldType.isConstQualified() &&
isSupportedOptionalType(Field->getType())) {
auto *FieldRecordLoc = cast_or_null<RecordStorageLocation>(FieldLoc);
if (FieldRecordLoc) {
setHasValue(*FieldRecordLoc, State.Env.makeAtomicBoolValue(),
Expand Down Expand Up @@ -1016,6 +1034,8 @@ auto buildTransferMatchSwitch() {
// const accessor calls
.CaseOfCFGStmt<CXXMemberCallExpr>(isZeroParamConstMemberCall(),
transferValue_ConstMemberCall)
.CaseOfCFGStmt<CXXOperatorCallExpr>(isZeroParamConstMemberOperatorCall(),
transferValue_ConstMemberOperatorCall)
// non-const member calls that may modify the state of an object.
.CaseOfCFGStmt<CXXMemberCallExpr>(isNonConstMemberCall(),
transferValue_NonConstMemberCall)
Expand Down
2 changes: 0 additions & 2 deletions clang/lib/Basic/LangOptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,8 +203,6 @@ void LangOptions::setLangDefaults(LangOptions &Opts, Language Lang,
Opts.setDefaultFPContractMode(LangOptions::FPM_Fast);
}

Opts.RenderScript = Lang == Language::RenderScript;

// OpenCL, C++ and C23 have bool, true, false keywords.
Opts.Bool = Opts.OpenCL || Opts.CPlusPlus || Opts.C23;

Expand Down
4 changes: 0 additions & 4 deletions clang/lib/Basic/LangStandards.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,6 @@ StringRef clang::languageToString(Language L) {
return "OpenCLC++";
case Language::CUDA:
return "CUDA";
case Language::RenderScript:
return "RenderScript";
case Language::HIP:
return "HIP";
case Language::HLSL:
Expand Down Expand Up @@ -114,8 +112,6 @@ LangStandard::Kind clang::getDefaultLanguageStandard(clang::Language Lang,
case Language::CUDA:
case Language::HIP:
return LangStandard::lang_gnucxx17;
case Language::RenderScript:
return LangStandard::lang_c99;
case Language::HLSL:
return LangStandard::lang_hlsl202x;
}
Expand Down
14 changes: 8 additions & 6 deletions clang/lib/Basic/Module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ Module::Module(ModuleConstructorTag, StringRef Name,
NoUndeclaredIncludes = Parent->NoUndeclaredIncludes;
ModuleMapIsPrivate = Parent->ModuleMapIsPrivate;

Parent->SubModuleIndex[Name] = Parent->SubModules.size();
Parent->SubModules.push_back(this);
}
}
Expand Down Expand Up @@ -351,11 +350,14 @@ void Module::markUnavailable(bool Unimportable) {
}

Module *Module::findSubmodule(StringRef Name) const {
llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name);
if (Pos == SubModuleIndex.end())
return nullptr;
// Add new submodules into the index.
for (unsigned I = SubModuleIndex.size(), E = SubModules.size(); I != E; ++I)
SubModuleIndex[SubModules[I]->Name] = I;

return SubModules[Pos->getValue()];
if (auto It = SubModuleIndex.find(Name); It != SubModuleIndex.end())
return SubModules[It->second];

return nullptr;
}

Module *Module::getGlobalModuleFragment() const {
Expand Down Expand Up @@ -528,7 +530,7 @@ void Module::print(raw_ostream &OS, unsigned Indent, bool Dump) const {

for (auto &K : Kinds) {
assert(&K == &Kinds[K.Kind] && "kinds in wrong order");
for (auto &H : Headers[K.Kind]) {
for (auto &H : getHeaders(K.Kind)) {
OS.indent(Indent + 2);
OS << K.Prefix << "header \"";
OS.write_escaped(H.NameAsWritten);
Expand Down
1 change: 0 additions & 1 deletion clang/lib/Basic/TargetInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,6 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : Triple(T) {
SSERegParmMax = 0;
HasAlignMac68kSupport = false;
HasBuiltinMSVaList = false;
IsRenderScriptTarget = false;
HasAArch64SVETypes = false;
HasRISCVVTypes = false;
AllowAMDGPUUnsafeFPAtomics = false;
Expand Down
6 changes: 0 additions & 6 deletions clang/lib/Basic/Targets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -710,12 +710,6 @@ std::unique_ptr<TargetInfo> AllocateTarget(const llvm::Triple &Triple,

case llvm::Triple::dxil:
return std::make_unique<DirectXTargetInfo>(Triple, Opts);
case llvm::Triple::renderscript32:
return std::make_unique<LinuxTargetInfo<RenderScript32TargetInfo>>(Triple,
Opts);
case llvm::Triple::renderscript64:
return std::make_unique<LinuxTargetInfo<RenderScript64TargetInfo>>(Triple,
Opts);

case llvm::Triple::ve:
return std::make_unique<LinuxTargetInfo<VETargetInfo>>(Triple, Opts);
Expand Down
16 changes: 0 additions & 16 deletions clang/lib/Basic/Targets/AArch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1723,19 +1723,3 @@ TargetInfo::BuiltinVaListKind
DarwinAArch64TargetInfo::getBuiltinVaListKind() const {
return TargetInfo::CharPtrBuiltinVaList;
}

// 64-bit RenderScript is aarch64
RenderScript64TargetInfo::RenderScript64TargetInfo(const llvm::Triple &Triple,
const TargetOptions &Opts)
: AArch64leTargetInfo(llvm::Triple("aarch64", Triple.getVendorName(),
Triple.getOSName(),
Triple.getEnvironmentName()),
Opts) {
IsRenderScriptTarget = true;
}

void RenderScript64TargetInfo::getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const {
Builder.defineMacro("__RENDERSCRIPT__");
AArch64leTargetInfo::getTargetDefines(Opts, Builder);
}
11 changes: 0 additions & 11 deletions clang/lib/Basic/Targets/AArch64.h
Original file line number Diff line number Diff line change
Expand Up @@ -319,17 +319,6 @@ class LLVM_LIBRARY_VISIBILITY DarwinAArch64TargetInfo
MacroBuilder &Builder) const override;
};

// 64-bit RenderScript is aarch64
class LLVM_LIBRARY_VISIBILITY RenderScript64TargetInfo
: public AArch64leTargetInfo {
public:
RenderScript64TargetInfo(const llvm::Triple &Triple,
const TargetOptions &Opts);

void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const override;
};

} // namespace targets
} // namespace clang

Expand Down
16 changes: 0 additions & 16 deletions clang/lib/Basic/Targets/ARM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1498,19 +1498,3 @@ void DarwinARMTargetInfo::getOSDefines(const LangOptions &Opts,
MacroBuilder &Builder) const {
getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
}

RenderScript32TargetInfo::RenderScript32TargetInfo(const llvm::Triple &Triple,
const TargetOptions &Opts)
: ARMleTargetInfo(llvm::Triple("armv7", Triple.getVendorName(),
Triple.getOSName(),
Triple.getEnvironmentName()),
Opts) {
IsRenderScriptTarget = true;
LongWidth = LongAlign = 64;
}

void RenderScript32TargetInfo::getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const {
Builder.defineMacro("__RENDERSCRIPT__");
ARMleTargetInfo::getTargetDefines(Opts, Builder);
}
11 changes: 0 additions & 11 deletions clang/lib/Basic/Targets/ARM.h
Original file line number Diff line number Diff line change
Expand Up @@ -310,17 +310,6 @@ class LLVM_LIBRARY_VISIBILITY DarwinARMTargetInfo
DarwinARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts);
};

// 32-bit RenderScript is armv7 with width and align of 'long' set to 8-bytes
class LLVM_LIBRARY_VISIBILITY RenderScript32TargetInfo
: public ARMleTargetInfo {
public:
RenderScript32TargetInfo(const llvm::Triple &Triple,
const TargetOptions &Opts);

void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const override;
};

} // namespace targets
} // namespace clang

Expand Down
7 changes: 7 additions & 0 deletions clang/lib/Basic/Targets/RISCV.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,13 @@ class RISCVTargetInfo : public TargetInfo {
return true;
}

bool
checkCFProtectionReturnSupported(DiagnosticsEngine &Diags) const override {
if (ISAInfo->hasExtension("zicfiss"))
return true;
return TargetInfo::checkCFProtectionReturnSupported(Diags);
}

CFBranchLabelSchemeKind getDefaultCFBranchLabelScheme() const override {
return CFBranchLabelSchemeKind::FuncSig;
}
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/Basic/Targets/WebAssembly.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,20 +154,20 @@ bool WebAssemblyTargetInfo::initFeatureMap(
llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
const std::vector<std::string> &FeaturesVec) const {
auto addGenericFeatures = [&]() {
Features["bulk-memory"] = true;
Features["multivalue"] = true;
Features["mutable-globals"] = true;
Features["nontrapping-fptoint"] = true;
Features["reference-types"] = true;
Features["sign-ext"] = true;
};
auto addBleedingEdgeFeatures = [&]() {
addGenericFeatures();
Features["atomics"] = true;
Features["bulk-memory"] = true;
Features["exception-handling"] = true;
Features["extended-const"] = true;
Features["fp16"] = true;
Features["multimemory"] = true;
Features["nontrapping-fptoint"] = true;
Features["tail-call"] = true;
Features["wide-arithmetic"] = true;
setSIMDLevel(Features, RelaxedSIMD, true);
Expand Down
8 changes: 7 additions & 1 deletion clang/lib/Basic/Targets/X86.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,8 @@ bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
HasSM4 = true;
} else if (Feature == "+movbe") {
HasMOVBE = true;
} else if (Feature == "+movrs") {
HasMOVRS = true;
} else if (Feature == "+sgx") {
HasSGX = true;
} else if (Feature == "+cx8") {
Expand Down Expand Up @@ -915,6 +917,8 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
Builder.defineMacro("__MOVDIRI__");
if (HasMOVDIR64B)
Builder.defineMacro("__MOVDIR64B__");
if (HasMOVRS)
Builder.defineMacro("__MOVRS__");
if (HasPCONFIG)
Builder.defineMacro("__PCONFIG__");
if (HasPTWRITE)
Expand Down Expand Up @@ -1116,6 +1120,7 @@ bool X86TargetInfo::isValidFeatureName(StringRef Name) const {
.Case("lzcnt", true)
.Case("mmx", true)
.Case("movbe", true)
.Case("movrs", true)
.Case("movdiri", true)
.Case("movdir64b", true)
.Case("mwaitx", true)
Expand Down Expand Up @@ -1233,6 +1238,7 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const {
.Case("lzcnt", HasLZCNT)
.Case("mmx", HasMMX)
.Case("movbe", HasMOVBE)
.Case("movrs", HasMOVRS)
.Case("movdiri", HasMOVDIRI)
.Case("movdir64b", HasMOVDIR64B)
.Case("mwaitx", HasMWAITX)
Expand Down Expand Up @@ -1459,7 +1465,7 @@ bool X86TargetInfo::validateAsmConstraint(
}
case 'f': // Any x87 floating point stack register.
// Constraint 'f' cannot be used for output operands.
if (Info.ConstraintStr[0] == '=')
if (Info.ConstraintStr[0] == '=' || Info.ConstraintStr[0] == '+')
return false;
Info.setAllowsRegister();
return true;
Expand Down
1 change: 1 addition & 0 deletions clang/lib/Basic/Targets/X86.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo {
bool HasCLFLUSHOPT = false;
bool HasCLWB = false;
bool HasMOVBE = false;
bool HasMOVRS = false;
bool HasPREFETCHI = false;
bool HasRDPID = false;
bool HasRDPRU = false;
Expand Down
10 changes: 0 additions & 10 deletions clang/lib/CodeGen/ABIInfoImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,16 +80,6 @@ RValue DefaultABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
Slot);
}

ABIArgInfo CodeGen::coerceToIntArray(QualType Ty, ASTContext &Context,
llvm::LLVMContext &LLVMContext) {
// Alignment and Size are measured in bits.
const uint64_t Size = Context.getTypeSize(Ty);
const uint64_t Alignment = Context.getTypeAlign(Ty);
llvm::Type *IntType = llvm::Type::getIntNTy(LLVMContext, Alignment);
const uint64_t NumElements = (Size + Alignment - 1) / Alignment;
return ABIArgInfo::getDirect(llvm::ArrayType::get(IntType, NumElements));
}

void CodeGen::AssignToArrayRange(CodeGen::CGBuilderTy &Builder,
llvm::Value *Array, llvm::Value *Value,
unsigned FirstIndex, unsigned LastIndex) {
Expand Down
17 changes: 0 additions & 17 deletions clang/lib/CodeGen/ABIInfoImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,23 +33,6 @@ class DefaultABIInfo : public ABIInfo {
AggValueSlot Slot) const override;
};

// Helper for coercing an aggregate argument or return value into an integer
// array of the same size (including padding) and alignment. This alternate
// coercion happens only for the RenderScript ABI and can be removed after
// runtimes that rely on it are no longer supported.
//
// RenderScript assumes that the size of the argument / return value in the IR
// is the same as the size of the corresponding qualified type. This helper
// coerces the aggregate type into an array of the same size (including
// padding). This coercion is used in lieu of expansion of struct members or
// other canonical coercions that return a coerced-type of larger size.
//
// Ty - The argument / return value type
// Context - The associated ASTContext
// LLVMContext - The associated LLVMContext
ABIArgInfo coerceToIntArray(QualType Ty, ASTContext &Context,
llvm::LLVMContext &LLVMContext);

void AssignToArrayRange(CodeGen::CGBuilderTy &Builder, llvm::Value *Array,
llvm::Value *Value, unsigned FirstIndex,
unsigned LastIndex);
Expand Down
Loading