63 changes: 41 additions & 22 deletions clang-tools-extra/clangd/ModulesBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "clang/Frontend/FrontendAction.h"
#include "clang/Frontend/FrontendActions.h"
#include "clang/Serialization/ASTReader.h"
#include "clang/Serialization/InMemoryModuleCache.h"

namespace clang {
namespace clangd {
Expand Down Expand Up @@ -127,50 +128,68 @@ struct ModuleFile {
std::string ModuleFilePath;
};

bool IsModuleFileUpToDate(
PathRef ModuleFilePath,
const PrerequisiteModules &RequisiteModules) {
IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
CompilerInstance::createDiagnostics(new DiagnosticOptions());

bool IsModuleFileUpToDate(PathRef ModuleFilePath,
const PrerequisiteModules &RequisiteModules,
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) {
auto HSOpts = std::make_shared<HeaderSearchOptions>();
RequisiteModules.adjustHeaderSearchOptions(*HSOpts);
HSOpts->ForceCheckCXX20ModulesInputFiles = true;
HSOpts->ValidateASTInputFilesContent = true;

clang::clangd::IgnoreDiagnostics IgnoreDiags;
IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
CompilerInstance::createDiagnostics(new DiagnosticOptions, &IgnoreDiags,
/*ShouldOwnClient=*/false);

LangOptions LangOpts;
LangOpts.SkipODRCheckInGMF = true;

FileManager FileMgr(FileSystemOptions(), VFS);

SourceManager SourceMgr(*Diags, FileMgr);

HeaderSearch HeaderInfo(HSOpts, SourceMgr, *Diags, LangOpts,
/*Target=*/nullptr);

TrivialModuleLoader ModuleLoader;
Preprocessor PP(std::make_shared<PreprocessorOptions>(), *Diags, LangOpts,
SourceMgr, HeaderInfo, ModuleLoader);

IntrusiveRefCntPtr<InMemoryModuleCache> ModuleCache = new InMemoryModuleCache;
PCHContainerOperations PCHOperations;
std::unique_ptr<ASTUnit> Unit = ASTUnit::LoadFromASTFile(
ModuleFilePath.str(), PCHOperations.getRawReader(), ASTUnit::LoadASTOnly,
Diags, FileSystemOptions(), std::move(HSOpts));
ASTReader Reader(PP, *ModuleCache, /*ASTContext=*/nullptr,
PCHOperations.getRawReader(), {});

if (!Unit)
return false;
// We don't need any listener here. By default it will use a validator
// listener.
Reader.setListener(nullptr);

auto Reader = Unit->getASTReader();
if (!Reader)
if (Reader.ReadAST(ModuleFilePath, serialization::MK_MainFile,
SourceLocation(),
ASTReader::ARR_None) != ASTReader::Success)
return false;

bool UpToDate = true;
Reader->getModuleManager().visit([&](serialization::ModuleFile &MF) -> bool {
Reader->visitInputFiles(
Reader.getModuleManager().visit([&](serialization::ModuleFile &MF) -> bool {
Reader.visitInputFiles(
MF, /*IncludeSystem=*/false, /*Complain=*/false,
[&](const serialization::InputFile &IF, bool isSystem) {
if (!IF.getFile() || IF.isOutOfDate())
UpToDate = false;
});

return !UpToDate;
});

return UpToDate;
}

bool IsModuleFilesUpToDate(
llvm::SmallVector<PathRef> ModuleFilePaths,
const PrerequisiteModules &RequisiteModules) {
return llvm::all_of(ModuleFilePaths, [&RequisiteModules](auto ModuleFilePath) {
return IsModuleFileUpToDate(ModuleFilePath, RequisiteModules);
});
const PrerequisiteModules &RequisiteModules,
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) {
return llvm::all_of(
ModuleFilePaths, [&RequisiteModules, VFS](auto ModuleFilePath) {
return IsModuleFileUpToDate(ModuleFilePath, RequisiteModules, VFS);
});
}

// StandalonePrerequisiteModules - stands for PrerequisiteModules for which all
Expand Down Expand Up @@ -347,7 +366,7 @@ bool StandalonePrerequisiteModules::canReuse(
SmallVector<StringRef> BMIPaths;
for (auto &MF : RequiredModules)
BMIPaths.push_back(MF.ModuleFilePath);
return IsModuleFilesUpToDate(BMIPaths, *this);
return IsModuleFilesUpToDate(BMIPaths, *this, VFS);
}

} // namespace clangd
Expand Down
21 changes: 19 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 @@ -157,6 +163,11 @@ Changes in existing checks
<clang-tidy/checks/bugprone/posix-return>` check to support integer literals
as LHS and posix call as RHS of comparison.

- Improved :doc:`bugprone-return-const-ref-from-parameter
<clang-tidy/checks/bugprone/return-const-ref-from-parameter>` check to
diagnose potential dangling references when returning a ``const &`` parameter
by using the conditional operator ``cond ? var1 : var2``.

- Improved :doc:`bugprone-sizeof-expression
<clang-tidy/checks/bugprone/sizeof-expression>` check to find suspicious
usages of ``sizeof()``, ``alignof()``, and ``offsetof()`` when adding or
Expand Down Expand Up @@ -210,6 +221,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 +258,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 @@ -27,6 +27,10 @@ int const &f3(TConstRef a) { return a; }
int const &f4(TConst &a) { return a; }
// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: returning a constant reference parameter

int const &f5(TConst &a) { return true ? a : a; }
// CHECK-MESSAGES: :[[@LINE-1]]:42: warning: returning a constant reference parameter
// CHECK-MESSAGES: :[[@LINE-2]]:46: warning: returning a constant reference parameter

template <typename T>
const T& tf1(const T &a) { return a; }
// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: returning a constant reference parameter
Expand All @@ -47,6 +51,11 @@ template <typename T>
const T& itf4(typename ConstRef<T>::type a) { return a; }
// CHECK-MESSAGES: :[[@LINE-1]]:54: warning: returning a constant reference parameter

template <typename T>
const T& itf5(const T &a) { return true ? a : a; }
// CHECK-MESSAGES: :[[@LINE-1]]:43: warning: returning a constant reference parameter
// CHECK-MESSAGES: :[[@LINE-2]]:47: warning: returning a constant reference parameter

void instantiate(const int &param, const float &paramf, int &mut_param, float &mut_paramf) {
itf1(0);
itf1(param);
Expand Down
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
5 changes: 0 additions & 5 deletions clang/docs/ClangFormat.rst
Original file line number Diff line number Diff line change
Expand Up @@ -363,8 +363,3 @@ those as well).

These commands use the file paths shown in the diff output
so they will only work from the root of the repository.

Current State of Clang Format for LLVM
======================================

The following table :doc:`ClangFormattedStatus` shows the current status of clang-formatting for the entire LLVM source tree.
8,536 changes: 0 additions & 8,536 deletions clang/docs/ClangFormattedStatus.rst

This file was deleted.

3 changes: 0 additions & 3 deletions clang/docs/ClangLinkerWrapper.rst
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,11 @@ only for the linker wrapper will be forwarded to the wrapped linker job.
USAGE: clang-linker-wrapper [options] -- <options to passed to the linker>
OPTIONS:
--bitcode-library=<kind>-<triple>-<arch>=<path>
Extra bitcode library to link
--cuda-path=<dir> Set the system CUDA path
--device-debug Use debugging
--device-linker=<value> or <triple>=<value>
Arguments to pass to the device linker invocation
--dry-run Print program arguments without running
--embed-bitcode Embed linked bitcode in the module
--help-hidden Display all available options
--help Display available options (--help-hidden for more)
--host-triple=<triple> Triple to use for the host compilation
Expand Down
535 changes: 535 additions & 0 deletions clang/docs/FunctionEffectAnalysis.rst

Large diffs are not rendered by default.

81 changes: 73 additions & 8 deletions clang/docs/RealtimeSanitizer.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,22 @@ RealtimeSanitizer (a.k.a. RTSan) is a real-time safety testing tool for C and C+
projects. RTSan can be used to detect real-time violations, i.e. calls to methods
that are not safe for use in functions with deterministic run time requirements.
RTSan considers any function marked with the ``[[clang::nonblocking]]`` attribute
to be a real-time function. If RTSan detects a call to ``malloc``, ``free``,
``pthread_mutex_lock``, or anything else that could have a non-deterministic
execution time in a function marked ``[[clang::nonblocking]]``
to be a real-time function. At run-time, if RTSan detects a call to ``malloc``,
``free``, ``pthread_mutex_lock``, or anything else that could have a
non-deterministic execution time in a function marked ``[[clang::nonblocking]]``
RTSan raises an error.

RTSan performs its analysis at run-time but shares the ``[[clang::nonblocking]]``
attribute with the :doc:`FunctionEffectAnalysis` system, which operates at
compile-time to detect potential real-time safety violations. For comprehensive
detection of real-time safety issues, it is recommended to use both systems together.

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 +188,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 +203,43 @@ Some issues with flags can be debugged using the ``verbosity=$NUM`` flag:
misspelled_flag
...
Disabling
---------
Disabling and suppressing
-------------------------

There are multiple ways to disable error reporting when using RealtimeSanitizer.

In some circumstances, you may want to suppress error reporting in a specific scope.
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

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.
* - 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 +273,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
56 changes: 53 additions & 3 deletions 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 @@ -134,7 +140,7 @@ C++ Specific Potentially Breaking Changes
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
applied on a parameter of a function that returns void. This was previously
ignored and had no effect. (#GH107556)

.. code-block:: c++
Expand Down Expand Up @@ -316,6 +322,11 @@ Modified Compiler Flags
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 All @@ -327,6 +338,19 @@ Removed Compiler Flags
Attribute Changes in Clang
--------------------------

- The ``swift_attr`` can now be applied to types. To make it possible to use imported APIs
in Swift safely there has to be a way to annotate individual parameters and result types
with relevant attributes that indicate that e.g. a block is called on a particular actor
or it accepts a Sendable or global-actor (i.e. ``@MainActor``) isolated parameter.

For example:

.. code-block:: objc
@interface MyService
-(void) handle: (void (^ __attribute__((swift_attr("@Sendable"))))(id)) handler;
@end
- Clang now disallows more than one ``__attribute__((ownership_returns(class, idx)))`` with
different class names attached to one function.

Expand Down Expand Up @@ -458,7 +482,8 @@ Bug Fixes in This Version
- Fixed a crash using ``__array_rank`` on 64-bit targets. (#GH113044).
- The warning emitted for an unsupported register variable type now points to
the unsupported type instead of the ``register`` keyword (#GH109776).
- Fixed a crash when emit ctor for global variant with flexible array init (#GH113187).
- Fixed a crash when emit ctor for global variant with flexible array init (#GH113187).
- Fixed a crash when GNU statement expression contains invalid statement (#GH113468).

Bug Fixes to Compiler Builtins
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down Expand Up @@ -560,7 +585,10 @@ 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)
- Clang now correctly ignores previous partial specializations of member templates explicitly specialized for
an implicitly instantiated class template specialization. (#GH51051)

Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down Expand Up @@ -628,6 +656,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 @@ -642,6 +674,7 @@ X86 Support

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

Arm and AArch64 Support
^^^^^^^^^^^^^^^^^^^^^^^
Expand Down Expand Up @@ -690,6 +723,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 @@ -717,6 +759,8 @@ AST Matchers

- Fixed a crash when traverse lambda expr with invalid captures. (#GH106444)

- Fixed ``isInstantiated`` and ``isInTemplateInstantiation`` to also match for variable templates. (#GH110666)

- Ensure ``hasName`` matches template specializations across inline namespaces,
making `matchesNodeFullSlow` and `matchesNodeFullFast` consistent.

Expand Down Expand Up @@ -773,6 +817,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
2 changes: 1 addition & 1 deletion 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 Expand Up @@ -92,7 +93,6 @@ Using Clang Tools
ClangCheck
ClangFormat
ClangFormatStyleOptions
ClangFormattedStatus
ClangLinkerWrapper
ClangNVLinkWrapper
ClangOffloadBundler
Expand Down
8,827 changes: 0 additions & 8,827 deletions clang/docs/tools/clang-formatted-files.txt

This file was deleted.

19 changes: 10 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 @@ -1719,8 +1719,15 @@ class ASTContext : public RefCountedBase<ASTContext> {
QualType getInjectedClassNameType(CXXRecordDecl *Decl, QualType TST) const;

QualType getAttributedType(attr::Kind attrKind, QualType modifiedType,
QualType equivalentType,
const Attr *attr = nullptr) const;

QualType getAttributedType(const Attr *attr, QualType modifiedType,
QualType equivalentType) const;

QualType getAttributedType(NullabilityKind nullability, QualType modifiedType,
QualType equivalentType);

QualType getBTFTagAttributedType(const BTFTypeTagAttr *BTFAttr,
QualType Wrapped) const;

Expand Down Expand Up @@ -1778,13 +1785,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 +1796,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
1 change: 1 addition & 0 deletions clang/include/clang/AST/PropertiesBase.td
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ def APValue : PropertyType { let PassByReference = 1; }
def APValueKind : EnumPropertyType<"APValue::ValueKind">;
def ArraySizeModifier : EnumPropertyType<"ArraySizeModifier">;
def AttrKind : EnumPropertyType<"attr::Kind">;
def Attr : PropertyType<"const Attr *">;
def AutoTypeKeyword : EnumPropertyType;
def Bool : PropertyType<"bool">;
def BuiltinTypeKind : EnumPropertyType<"BuiltinType::Kind">;
Expand Down
42 changes: 17 additions & 25 deletions clang/include/clang/AST/Type.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ class ValueDecl;
class TagDecl;
class TemplateParameterList;
class Type;
class Attr;

enum {
TypeAlignmentInBits = 4,
Expand Down Expand Up @@ -6130,21 +6131,29 @@ class AttributedType : public Type, public llvm::FoldingSetNode {
private:
friend class ASTContext; // ASTContext creates these

const Attr *Attribute;

QualType ModifiedType;
QualType EquivalentType;

AttributedType(QualType canon, attr::Kind attrKind, QualType modified,
QualType equivalent)
: Type(Attributed, canon, equivalent->getDependence()),
ModifiedType(modified), EquivalentType(equivalent) {
AttributedTypeBits.AttrKind = attrKind;
}
: AttributedType(canon, attrKind, nullptr, modified, equivalent) {}

AttributedType(QualType canon, const Attr *attr, QualType modified,
QualType equivalent);

private:
AttributedType(QualType canon, attr::Kind attrKind, const Attr *attr,
QualType modified, QualType equivalent);

public:
Kind getAttrKind() const {
return static_cast<Kind>(AttributedTypeBits.AttrKind);
}

const Attr *getAttr() const { return Attribute; }

QualType getModifiedType() const { return ModifiedType; }
QualType getEquivalentType() const { return EquivalentType; }

Expand Down Expand Up @@ -6176,25 +6185,6 @@ class AttributedType : public Type, public llvm::FoldingSetNode {

std::optional<NullabilityKind> getImmediateNullability() const;

/// Retrieve the attribute kind corresponding to the given
/// nullability kind.
static Kind getNullabilityAttrKind(NullabilityKind kind) {
switch (kind) {
case NullabilityKind::NonNull:
return attr::TypeNonNull;

case NullabilityKind::Nullable:
return attr::TypeNullable;

case NullabilityKind::NullableResult:
return attr::TypeNullableResult;

case NullabilityKind::Unspecified:
return attr::TypeNullUnspecified;
}
llvm_unreachable("Unknown nullability kind.");
}

/// Strip off the top-level nullability annotation on the given
/// type, if it's there.
///
Expand All @@ -6207,14 +6197,16 @@ class AttributedType : public Type, public llvm::FoldingSetNode {
static std::optional<NullabilityKind> stripOuterNullability(QualType &T);

void Profile(llvm::FoldingSetNodeID &ID) {
Profile(ID, getAttrKind(), ModifiedType, EquivalentType);
Profile(ID, getAttrKind(), ModifiedType, EquivalentType, Attribute);
}

static void Profile(llvm::FoldingSetNodeID &ID, Kind attrKind,
QualType modified, QualType equivalent) {
QualType modified, QualType equivalent,
const Attr *attr) {
ID.AddInteger(attrKind);
ID.AddPointer(modified.getAsOpaquePtr());
ID.AddPointer(equivalent.getAsOpaquePtr());
ID.AddPointer(attr);
}

static bool classof(const Type *T) {
Expand Down
8 changes: 6 additions & 2 deletions clang/include/clang/AST/TypeProperties.td
Original file line number Diff line number Diff line change
Expand Up @@ -668,12 +668,16 @@ let Class = AttributedType in {
def : Property<"equivalentType", QualType> {
let Read = [{ node->getEquivalentType() }];
}
def : Property<"attribute", AttrKind> {
def : Property<"attrKind", AttrKind> {
let Read = [{ node->getAttrKind() }];
}
def : Property<"attribute", Attr> {
let Read = [{ node->getAttr() }];
}

def : Creator<[{
return ctx.getAttributedType(attribute, modifiedType, equivalentType);
return ctx.getAttributedType(attrKind, modifiedType,
equivalentType, attribute);
}]>;
}

Expand Down
9 changes: 5 additions & 4 deletions clang/include/clang/ASTMatchers/ASTMatchers.h
Original file line number Diff line number Diff line change
Expand Up @@ -6750,7 +6750,8 @@ AST_POLYMORPHIC_MATCHER(isTemplateInstantiation,
/// matches 'A(int) {...};' and 'A(unsigned) {...}'.
AST_MATCHER_FUNCTION(internal::Matcher<Decl>, isInstantiated) {
auto IsInstantiation = decl(anyOf(cxxRecordDecl(isTemplateInstantiation()),
functionDecl(isTemplateInstantiation())));
functionDecl(isTemplateInstantiation()),
varDecl(isTemplateInstantiation())));
return decl(anyOf(IsInstantiation, hasAncestor(IsInstantiation)));
}

Expand All @@ -6769,9 +6770,9 @@ AST_MATCHER_FUNCTION(internal::Matcher<Decl>, isInstantiated) {
/// will NOT match j += 42; as it's shared between the template definition and
/// instantiation.
AST_MATCHER_FUNCTION(internal::Matcher<Stmt>, isInTemplateInstantiation) {
return stmt(
hasAncestor(decl(anyOf(cxxRecordDecl(isTemplateInstantiation()),
functionDecl(isTemplateInstantiation())))));
return stmt(hasAncestor(decl(anyOf(cxxRecordDecl(isTemplateInstantiation()),
functionDecl(isTemplateInstantiation()),
varDecl(isTemplateInstantiation())))));
}

/// Matches explicit template specializations of function, class, or
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
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
11 changes: 1 addition & 10 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 Expand Up @@ -2847,7 +2838,7 @@ def SwiftAsyncName : InheritableAttr {
let Documentation = [SwiftAsyncNameDocs];
}

def SwiftAttr : InheritableAttr {
def SwiftAttr : DeclOrTypeAttr {
let Spellings = [GNU<"swift_attr">];
let Args = [StringArgument<"Attribute">];
let Documentation = [SwiftAttrDocs];
Expand Down
47 changes: 22 additions & 25 deletions clang/include/clang/Basic/AttrDocs.td
Original file line number Diff line number Diff line change
Expand Up @@ -3702,20 +3702,32 @@ user-declared functions. For example:

.. code-block:: c++

#include <map>
#include <string>

using namespace std::literals;

// Returns m[key] if key is present, or default_value if not.
template<typename T, typename U>
const U &get_or_default(const std::map<T, U> &m [[clang::lifetimebound]],
const T &key, /* note, not lifetimebound */
const U &default_value [[clang::lifetimebound]]);
const U &default_value [[clang::lifetimebound]]) {
if (auto iter = m.find(key); iter != m.end()) return iter->second;
else return default_value;
}

std::map<std::string, std::string> m;
// warning: temporary "bar"s that might be bound to local reference 'val'
// will be destroyed at the end of the full-expression
const std::string &val = get_or_default(m, "foo"s, "bar"s);
int main() {
std::map<std::string, std::string> m;
// warning: temporary bound to local reference 'val1' will be destroyed
// at the end of the full-expression
const std::string &val1 = get_or_default(m, "foo"s, "bar"s);

// No warning in this case.
std::string def_val = "bar"s;
const std::string &val = get_or_default(m, "foo"s, def_val);
// No warning in this case.
std::string def_val = "bar"s;
const std::string &val2 = get_or_default(m, "foo"s, def_val);

return 0;
}

The attribute can be applied to the implicit ``this`` parameter of a member
function by writing the attribute after the function type:
Expand Down Expand Up @@ -4495,8 +4507,8 @@ def SwiftAttrDocs : Documentation {
let Heading = "swift_attr";
let Content = [{
The ``swift_attr`` provides a Swift-specific annotation for the declaration
to which the attribute appertains to. It can be used on any declaration
in Clang. This kind of annotation is ignored by Clang as it doesn't have any
or type to which the attribute appertains to. It can be used on any declaration
or type in Clang. This kind of annotation is ignored by Clang as it doesn't have any
semantic meaning in languages supported by Clang. The Swift compiler can
interpret these annotations according to its own rules when importing C or
Objective-C declarations.
Expand Down Expand Up @@ -5831,21 +5843,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
2 changes: 1 addition & 1 deletion clang/include/clang/Basic/BuiltinsAMDGPU.def
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ TARGET_BUILTIN(__builtin_amdgcn_dot4_f32_bf8_bf8, "fUiUif", "nc", "dot11-insts")
//===----------------------------------------------------------------------===//
TARGET_BUILTIN(__builtin_amdgcn_permlane16, "UiUiUiUiUiIbIb", "nc", "gfx10-insts")
TARGET_BUILTIN(__builtin_amdgcn_permlanex16, "UiUiUiUiUiIbIb", "nc", "gfx10-insts")
TARGET_BUILTIN(__builtin_amdgcn_mov_dpp8, "UiUiIUi", "nc", "gfx10-insts")
TARGET_BUILTIN(__builtin_amdgcn_mov_dpp8, "UiUiIUi", "nct", "gfx10-insts")
TARGET_BUILTIN(__builtin_amdgcn_s_ttracedata_imm, "vIs", "n", "gfx10-insts")

//===----------------------------------------------------------------------===//
Expand Down
4 changes: 4 additions & 0 deletions clang/include/clang/Basic/BuiltinsBase.td
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ def ConstIgnoringExceptions : Attribute<"g">;
// This function requires a specific header or an explicit declaration.
def RequireDeclaration : Attribute<"h">;

// FIXME: Why is this not simply the min_vector_width attribute?
// Vector has to be at least N bits wide.
class RequiredVectorWidth<int N> : IndexedAttribute<"V", N>;

class PrintfFormat<int I> : IndexedAttribute<"p", I>;
class VPrintfFormat<int I> : IndexedAttribute<"P", I>;
class ScanfFormat<int I> : IndexedAttribute<"s", I>;
Expand Down
130 changes: 4 additions & 126 deletions clang/include/clang/Basic/BuiltinsX86.def
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,6 @@
# define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANG, FEATURE) BUILTIN(ID, TYPE, ATTRS)
#endif

// Undefined Values
//
TARGET_BUILTIN(__builtin_ia32_undef128, "V2d", "ncV:128:", "")
TARGET_BUILTIN(__builtin_ia32_undef256, "V4d", "ncV:256:", "")
TARGET_BUILTIN(__builtin_ia32_undef512, "V8d", "ncV:512:", "")

// FLAGS
//
TARGET_BUILTIN(__builtin_ia32_readeflags_u32, "Ui", "n", "")
TARGET_BUILTIN(__builtin_ia32_writeeflags_u32, "vUi", "n", "")

// MMX
//
// All MMX instructions will be generated via builtins. Any MMX vector
Expand All @@ -46,113 +35,8 @@ TARGET_BUILTIN(__builtin_ia32_writeeflags_u32, "vUi", "n", "")
// argument and our prior approach of using a #define to the current built-in
// doesn't work in the presence of re-declaration of _mm_prefetch for windows.
TARGET_BUILTIN(_mm_prefetch, "vcC*i", "nc", "mmx")
TARGET_BUILTIN(__builtin_ia32_emms, "v", "n", "mmx")
TARGET_BUILTIN(__builtin_ia32_vec_ext_v4hi, "sV4sIi", "ncV:64:", "sse")
TARGET_BUILTIN(__builtin_ia32_vec_set_v4hi, "V4sV4ssIi", "ncV:64:", "sse")

// SSE intrinsics.
TARGET_BUILTIN(__builtin_ia32_comieq, "iV4fV4f", "ncV:128:", "sse")
TARGET_BUILTIN(__builtin_ia32_comilt, "iV4fV4f", "ncV:128:", "sse")
TARGET_BUILTIN(__builtin_ia32_comile, "iV4fV4f", "ncV:128:", "sse")
TARGET_BUILTIN(__builtin_ia32_comigt, "iV4fV4f", "ncV:128:", "sse")
TARGET_BUILTIN(__builtin_ia32_comige, "iV4fV4f", "ncV:128:", "sse")
TARGET_BUILTIN(__builtin_ia32_comineq, "iV4fV4f", "ncV:128:", "sse")
TARGET_BUILTIN(__builtin_ia32_ucomieq, "iV4fV4f", "ncV:128:", "sse")
TARGET_BUILTIN(__builtin_ia32_ucomilt, "iV4fV4f", "ncV:128:", "sse")
TARGET_BUILTIN(__builtin_ia32_ucomile, "iV4fV4f", "ncV:128:", "sse")
TARGET_BUILTIN(__builtin_ia32_ucomigt, "iV4fV4f", "ncV:128:", "sse")
TARGET_BUILTIN(__builtin_ia32_ucomige, "iV4fV4f", "ncV:128:", "sse")
TARGET_BUILTIN(__builtin_ia32_ucomineq, "iV4fV4f", "ncV:128:", "sse")

TARGET_BUILTIN(__builtin_ia32_comisdeq, "iV2dV2d", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_comisdlt, "iV2dV2d", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_comisdle, "iV2dV2d", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_comisdgt, "iV2dV2d", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_comisdge, "iV2dV2d", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_comisdneq, "iV2dV2d", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_ucomisdeq, "iV2dV2d", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_ucomisdlt, "iV2dV2d", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_ucomisdle, "iV2dV2d", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_ucomisdgt, "iV2dV2d", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_ucomisdge, "iV2dV2d", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_ucomisdneq, "iV2dV2d", "ncV:128:", "sse2")

TARGET_BUILTIN(__builtin_ia32_cmpeqps, "V4fV4fV4f", "ncV:128:", "sse")
TARGET_BUILTIN(__builtin_ia32_cmpltps, "V4fV4fV4f", "ncV:128:", "sse")
TARGET_BUILTIN(__builtin_ia32_cmpleps, "V4fV4fV4f", "ncV:128:", "sse")
TARGET_BUILTIN(__builtin_ia32_cmpunordps, "V4fV4fV4f", "ncV:128:", "sse")
TARGET_BUILTIN(__builtin_ia32_cmpneqps, "V4fV4fV4f", "ncV:128:", "sse")
TARGET_BUILTIN(__builtin_ia32_cmpnltps, "V4fV4fV4f", "ncV:128:", "sse")
TARGET_BUILTIN(__builtin_ia32_cmpnleps, "V4fV4fV4f", "ncV:128:", "sse")
TARGET_BUILTIN(__builtin_ia32_cmpordps, "V4fV4fV4f", "ncV:128:", "sse")
TARGET_BUILTIN(__builtin_ia32_cmpeqss, "V4fV4fV4f", "ncV:128:", "sse")
TARGET_BUILTIN(__builtin_ia32_cmpltss, "V4fV4fV4f", "ncV:128:", "sse")
TARGET_BUILTIN(__builtin_ia32_cmpless, "V4fV4fV4f", "ncV:128:", "sse")
TARGET_BUILTIN(__builtin_ia32_cmpunordss, "V4fV4fV4f", "ncV:128:", "sse")
TARGET_BUILTIN(__builtin_ia32_cmpneqss, "V4fV4fV4f", "ncV:128:", "sse")
TARGET_BUILTIN(__builtin_ia32_cmpnltss, "V4fV4fV4f", "ncV:128:", "sse")
TARGET_BUILTIN(__builtin_ia32_cmpnless, "V4fV4fV4f", "ncV:128:", "sse")
TARGET_BUILTIN(__builtin_ia32_cmpordss, "V4fV4fV4f", "ncV:128:", "sse")
TARGET_BUILTIN(__builtin_ia32_minps, "V4fV4fV4f", "ncV:128:", "sse")
TARGET_BUILTIN(__builtin_ia32_maxps, "V4fV4fV4f", "ncV:128:", "sse")
TARGET_BUILTIN(__builtin_ia32_minss, "V4fV4fV4f", "ncV:128:", "sse")
TARGET_BUILTIN(__builtin_ia32_maxss, "V4fV4fV4f", "ncV:128:", "sse")
TARGET_BUILTIN(__builtin_ia32_cmpps, "V4fV4fV4fIc", "ncV:128:", "sse")
TARGET_BUILTIN(__builtin_ia32_cmpss, "V4fV4fV4fIc", "ncV:128:", "sse")

TARGET_BUILTIN(__builtin_ia32_cmpeqpd, "V2dV2dV2d", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_cmpltpd, "V2dV2dV2d", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_cmplepd, "V2dV2dV2d", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_cmpunordpd, "V2dV2dV2d", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_cmpneqpd, "V2dV2dV2d", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_cmpnltpd, "V2dV2dV2d", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_cmpnlepd, "V2dV2dV2d", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_cmpordpd, "V2dV2dV2d", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_cmpeqsd, "V2dV2dV2d", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_cmpltsd, "V2dV2dV2d", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_cmplesd, "V2dV2dV2d", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_cmpunordsd, "V2dV2dV2d", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_cmpneqsd, "V2dV2dV2d", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_cmpnltsd, "V2dV2dV2d", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_cmpnlesd, "V2dV2dV2d", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_cmpordsd, "V2dV2dV2d", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_cmpsd, "V2dV2dV2dIc", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_cmppd, "V2dV2dV2dIc", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_minpd, "V2dV2dV2d", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_maxpd, "V2dV2dV2d", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_minsd, "V2dV2dV2d", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_maxsd, "V2dV2dV2d", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_pmulhw128, "V8sV8sV8s", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_pavgb128, "V16cV16cV16c", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_pavgw128, "V8sV8sV8s", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_packsswb128, "V16cV8sV8s", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_packssdw128, "V8sV4iV4i", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_packuswb128, "V16cV8sV8s", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_pmulhuw128, "V8sV8sV8s", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_vec_ext_v2di, "OiV2OiIi", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_vec_ext_v4si, "iV4iIi", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_vec_ext_v4sf, "fV4fIi", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_vec_ext_v8hi, "sV8sIi", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_vec_set_v8hi, "V8sV8ssIi", "ncV:128:", "sse2")

TARGET_BUILTIN(__builtin_ia32_addsubps, "V4fV4fV4f", "ncV:128:", "sse3")
TARGET_BUILTIN(__builtin_ia32_addsubpd, "V2dV2dV2d", "ncV:128:", "sse3")
TARGET_BUILTIN(__builtin_ia32_haddps, "V4fV4fV4f", "ncV:128:", "sse3")
TARGET_BUILTIN(__builtin_ia32_haddpd, "V2dV2dV2d", "ncV:128:", "sse3")
TARGET_BUILTIN(__builtin_ia32_hsubps, "V4fV4fV4f", "ncV:128:", "sse3")
TARGET_BUILTIN(__builtin_ia32_hsubpd, "V2dV2dV2d", "ncV:128:", "sse3")
TARGET_BUILTIN(__builtin_ia32_phaddw128, "V8sV8sV8s", "ncV:128:", "ssse3")
TARGET_BUILTIN(__builtin_ia32_phaddd128, "V4iV4iV4i", "ncV:128:", "ssse3")
TARGET_BUILTIN(__builtin_ia32_phaddsw128, "V8sV8sV8s", "ncV:128:", "ssse3")
TARGET_BUILTIN(__builtin_ia32_phsubw128, "V8sV8sV8s", "ncV:128:", "ssse3")
TARGET_BUILTIN(__builtin_ia32_phsubd128, "V4iV4iV4i", "ncV:128:", "ssse3")
TARGET_BUILTIN(__builtin_ia32_phsubsw128, "V8sV8sV8s", "ncV:128:", "ssse3")
TARGET_BUILTIN(__builtin_ia32_pmaddubsw128, "V8sV16cV16c", "ncV:128:", "ssse3")
TARGET_BUILTIN(__builtin_ia32_pmulhrsw128, "V8sV8sV8s", "ncV:128:", "ssse3")
TARGET_BUILTIN(__builtin_ia32_pshufb128, "V16cV16cV16c", "ncV:128:", "ssse3")
TARGET_BUILTIN(__builtin_ia32_psignb128, "V16cV16cV16c", "ncV:128:", "ssse3")
TARGET_BUILTIN(__builtin_ia32_psignw128, "V8sV8sV8s", "ncV:128:", "ssse3")
TARGET_BUILTIN(__builtin_ia32_psignd128, "V4iV4iV4i", "ncV:128:", "ssse3")

TARGET_BUILTIN(__builtin_ia32_ldmxcsr, "vUi", "n", "sse")
TARGET_HEADER_BUILTIN(_mm_setcsr, "vUi", "nh",XMMINTRIN_H, ALL_LANGUAGES, "sse")
Expand Down Expand Up @@ -316,16 +200,6 @@ TARGET_BUILTIN(__builtin_ia32_pclmulqdq256, "V4OiV4OiV4OiIc", "ncV:256:", "vpclm
TARGET_BUILTIN(__builtin_ia32_pclmulqdq512, "V8OiV8OiV8OiIc", "ncV:512:", "avx512f,evex512,vpclmulqdq")

// AVX
TARGET_BUILTIN(__builtin_ia32_addsubpd256, "V4dV4dV4d", "ncV:256:", "avx")
TARGET_BUILTIN(__builtin_ia32_addsubps256, "V8fV8fV8f", "ncV:256:", "avx")
TARGET_BUILTIN(__builtin_ia32_haddpd256, "V4dV4dV4d", "ncV:256:", "avx")
TARGET_BUILTIN(__builtin_ia32_hsubps256, "V8fV8fV8f", "ncV:256:", "avx")
TARGET_BUILTIN(__builtin_ia32_hsubpd256, "V4dV4dV4d", "ncV:256:", "avx")
TARGET_BUILTIN(__builtin_ia32_haddps256, "V8fV8fV8f", "ncV:256:", "avx")
TARGET_BUILTIN(__builtin_ia32_maxpd256, "V4dV4dV4d", "ncV:256:", "avx")
TARGET_BUILTIN(__builtin_ia32_maxps256, "V8fV8fV8f", "ncV:256:", "avx")
TARGET_BUILTIN(__builtin_ia32_minpd256, "V4dV4dV4d", "ncV:256:", "avx")
TARGET_BUILTIN(__builtin_ia32_minps256, "V8fV8fV8f", "ncV:256:", "avx")
TARGET_BUILTIN(__builtin_ia32_vpermilvarpd, "V2dV2dV2Oi", "ncV:256:", "avx")
TARGET_BUILTIN(__builtin_ia32_vpermilvarps, "V4fV4fV4i", "ncV:256:", "avx")
TARGET_BUILTIN(__builtin_ia32_vpermilvarpd256, "V4dV4dV4Oi", "ncV:256:", "avx")
Expand Down Expand Up @@ -2179,6 +2053,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
137 changes: 137 additions & 0 deletions clang/include/clang/Basic/BuiltinsX86.td
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
//===--- BuiltinsX86.td - X86 Builtin function database ---------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file defines the X86-specific builtin function database.
//
//===----------------------------------------------------------------------===//

include "clang/Basic/BuiltinsBase.td"

class X86Builtin<string prototype> : TargetBuiltin {
let Spellings = ["__builtin_ia32_" # NAME];
let Prototype = prototype;
}

// Undefined Values
def undef128 : X86Builtin<"_Vector<2, double>()"> {
let Attributes = [Const, NoThrow, RequiredVectorWidth<128>];
}

def undef256 : X86Builtin<"_Vector<4, double>()"> {
let Attributes = [Const, NoThrow, RequiredVectorWidth<256>];
}

def undef512 : X86Builtin<"_Vector<8, double>()"> {
let Attributes = [Const, NoThrow, RequiredVectorWidth<512>];
}

// FLAGS
def readeflags_u32 : X86Builtin<"unsigned int()"> {
let Attributes = [NoThrow];
}

def writeeflags_u32 : X86Builtin<"void(unsigned int)"> {
let Attributes = [NoThrow];
}

// MMX
//
// All MMX instructions will be generated via builtins. Any MMX vector
// types (<1 x i64>, <2 x i32>, etc.) that aren't used by these builtins will be
// expanded by the back-end.

def emms : X86Builtin<"void()"> {
let Attributes = [NoThrow];
let Features = "mmx";
}

let Attributes = [NoThrow, Const, RequiredVectorWidth<64>], Features = "sse" in {
def vec_ext_v4hi : X86Builtin<"short(_Vector<4, short>, _Constant int)">;
def vec_set_v4hi : X86Builtin<"_Vector<4, short>(_Vector<4, short>, short, _Constant int)">;
}

// SSE intrinsics
let Attributes = [Const, NoThrow, RequiredVectorWidth<128>] in {
foreach Cmp = ["eq", "lt", "le", "gt", "ge", "neq"] in {
let Features = "sse" in {
def comi#Cmp : X86Builtin<"int(_Vector<4, float>, _Vector<4, float>)">;
def ucomi#Cmp : X86Builtin<"int(_Vector<4, float>, _Vector<4, float>)">;
}
let Features = "sse2" in {
def comisd#Cmp : X86Builtin<"int(_Vector<2, double>, _Vector<2, double>)">;
def ucomisd#Cmp : X86Builtin<"int(_Vector<2, double>, _Vector<2, double>)">;
}
}

foreach Cmp = ["cmpeq", "cmplt", "cmple", "cmpunord", "cmpneq", "cmpnlt",
"cmpnle", "cmpord", "min", "max"] in {
let Features = "sse" in {
def Cmp#ps : X86Builtin<"_Vector<4, float>(_Vector<4, float>, _Vector<4, float>)">;
def Cmp#ss : X86Builtin<"_Vector<4, float>(_Vector<4, float>, _Vector<4, float>)">;
}
let Features = "sse2" in {
def Cmp#pd : X86Builtin<"_Vector<2, double>(_Vector<2, double>, _Vector<2, double>)">;
def Cmp#sd : X86Builtin<"_Vector<2, double>(_Vector<2, double>, _Vector<2, double>)">;
}
}

let Features = "sse" in {
def cmpps : X86Builtin<"_Vector<4, float>(_Vector<4, float>, _Vector<4, float>, _Constant char)">;
def cmpss : X86Builtin<"_Vector<4, float>(_Vector<4, float>, _Vector<4, float>, _Constant char)">;
}

let Features = "sse2" in {
def cmppd : X86Builtin<"_Vector<2, double>(_Vector<2, double>, _Vector<2, double>, _Constant char)">;
def cmpsd : X86Builtin<"_Vector<2, double>(_Vector<2, double>, _Vector<2, double>, _Constant char)">;
}

let Features = "sse2" in {
def pmulhw128 : X86Builtin<"_Vector<8, short>(_Vector<8, short>, _Vector<8, short>)">;
def pavgb128 : X86Builtin<"_Vector<16, char>(_Vector<16, char>, _Vector<16, char>)">;
def pavgw128 : X86Builtin<"_Vector<8, short>(_Vector<8, short>, _Vector<8, short>)">;
def packsswb128 : X86Builtin<"_Vector<16, char>(_Vector<8, short>, _Vector<8, short>)">;
def packssdw128 : X86Builtin<"_Vector<8, short>(_Vector<4, int>, _Vector<4, int>)">;
def packuswb128 : X86Builtin<"_Vector<16, char>(_Vector<8, short>, _Vector<8, short>)">;
def pmulhuw128 : X86Builtin<"_Vector<8, short>(_Vector<8, short>, _Vector<8, short>)">;
def vec_ext_v2di : X86Builtin<"long long int(_Vector<2, long long int>, _Constant int)">;
def vec_ext_v4si : X86Builtin<"int(_Vector<4, int>, _Constant int)">;
def vec_ext_v4sf : X86Builtin<"float(_Vector<4, float>, _Constant int)">;
def vec_ext_v8hi : X86Builtin<"short(_Vector<8, short>, _Constant int)">;
def vec_set_v8hi : X86Builtin<"_Vector<8, short>(_Vector<8, short>, short, _Constant int)">;
}

let Features = "sse3" in {
foreach Op = ["addsub", "hadd", "hsub"] in {
def Op#ps : X86Builtin<"_Vector<4, float>(_Vector<4, float>, _Vector<4, float>)">;
def Op#pd : X86Builtin<"_Vector<2, double>(_Vector<2, double>, _Vector<2, double>)">;
}
}

let Features = "ssse3" in {
foreach Op = ["phadd", "phsub"] in {
def Op#w128 : X86Builtin<"_Vector<8, short>(_Vector<8, short>, _Vector<8, short>)">;
def Op#sw128 : X86Builtin<"_Vector<8, short>(_Vector<8, short>, _Vector<8, short>)">;
def Op#d128 : X86Builtin<"_Vector<4, int>(_Vector<4, int>, _Vector<4, int>)">;
}

def pmaddubsw128 : X86Builtin<"_Vector<8, short>(_Vector<16, char>, _Vector<16, char>)">;
def pmulhrsw128 : X86Builtin<"_Vector<8, short>(_Vector<8, short>, _Vector<8, short>)">;
def pshufb128 : X86Builtin<"_Vector<16, char>(_Vector<16, char>, _Vector<16, char>)">;
def psignb128 : X86Builtin<"_Vector<16, char>(_Vector<16, char>, _Vector<16, char>)">;
def psignw128 : X86Builtin<"_Vector<8, short>(_Vector<8, short>, _Vector<8, short>)">;
def psignd128 : X86Builtin<"_Vector<4, int>(_Vector<4, int>, _Vector<4, int>)">;
}
}

// AVX
let Attributes = [Const, NoThrow, RequiredVectorWidth<256>], Features = "avx" in {
foreach Op = ["addsub", "hadd", "hsub", "max", "min"] in {
def Op#pd256 : X86Builtin<"_Vector<4, double>(_Vector<4, double>, _Vector<4, double>)">;
def Op#ps256 : X86Builtin<"_Vector<8, float>(_Vector<8, float>, _Vector<8, float>)">;
}
}
6 changes: 6 additions & 0 deletions clang/include/clang/Basic/BuiltinsX86_64.def
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,12 @@ TARGET_BUILTIN(__builtin_ia32_cmpccxadd64, "SLLiv*SLLiSLLiIi", "n", "cmpccxadd")
// AMX_FP16 FP16
TARGET_BUILTIN(__builtin_ia32_tdpfp16ps, "vIUcIUcIUc", "n", "amx-fp16")

// AMX FP8
TARGET_BUILTIN(__builtin_ia32_tdpbf8ps, "vIUcUIcUIc", "n", "amx-fp8")
TARGET_BUILTIN(__builtin_ia32_tdpbhf8ps, "vIUcUIcUIc", "n", "amx-fp8")
TARGET_BUILTIN(__builtin_ia32_tdphbf8ps, "vIUcUIcUIc", "n", "amx-fp8")
TARGET_BUILTIN(__builtin_ia32_tdphf8ps, "vIUcUIcUIc", "n", "amx-fp8")

// RAO-INT
TARGET_BUILTIN(__builtin_ia32_aadd64, "vv*SOi", "n", "raoint")
TARGET_BUILTIN(__builtin_ia32_aand64, "vv*SOi", "n", "raoint")
Expand Down
4 changes: 4 additions & 0 deletions clang/include/clang/Basic/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ clang_tablegen(BuiltinsRISCV.inc -gen-clang-builtins
SOURCE BuiltinsRISCV.td
TARGET ClangBuiltinsRISCV)

clang_tablegen(BuiltinsX86.inc -gen-clang-builtins
SOURCE BuiltinsX86.td
TARGET ClangBuiltinsX86)

# ARM NEON and MVE
clang_tablegen(arm_neon.inc -gen-arm-neon-sema
SOURCE arm_neon.td
Expand Down
4 changes: 4 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
3 changes: 1 addition & 2 deletions 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 Expand Up @@ -431,7 +430,7 @@ LANGOPT(ApplePragmaPack, 1, 0, "Apple gcc-compatible #pragma pack handling")

LANGOPT(XLPragmaPack, 1, 0, "IBM XL #pragma pack handling")

LANGOPT(RetainCommentsFromSystemHeaders, 1, 0, "retain documentation comments from system headers in the AST")
COMPATIBLE_LANGOPT(RetainCommentsFromSystemHeaders, 1, 0, "retain documentation comments from system headers in the AST")

LANGOPT(APINotes, 1, 0, "use external API notes")
LANGOPT(APINotesModules, 1, 0, "use module-based external API notes")
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
2 changes: 2 additions & 0 deletions clang/include/clang/Basic/TargetBuiltins.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ namespace clang {
LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1,
#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
#include "clang/Basic/BuiltinsX86.def"
#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
#include "clang/Basic/BuiltinsX86.inc"
FirstX86_64Builtin,
LastX86CommonBuiltin = FirstX86_64Builtin - 1,
#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
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
19 changes: 15 additions & 4 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 @@ -4673,7 +4672,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 @@ -5633,6 +5633,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 @@ -5645,6 +5646,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 @@ -6290,6 +6294,8 @@ def mamx_fp16 : Flag<["-"], "mamx-fp16">, Group<m_x86_Features_Group>;
def mno_amx_fp16 : Flag<["-"], "mno-amx-fp16">, Group<m_x86_Features_Group>;
def mamx_int8 : Flag<["-"], "mamx-int8">, Group<m_x86_Features_Group>;
def mno_amx_int8 : Flag<["-"], "mno-amx-int8">, Group<m_x86_Features_Group>;
def mamx_fp8 : Flag<["-"], "mamx-fp8">, Group<m_x86_Features_Group>;
def mno_amx_fp8 : Flag<["-"], "mno-amx-fp8">, Group<m_x86_Features_Group>;
def mamx_tile : Flag<["-"], "mamx-tile">, Group<m_x86_Features_Group>;
def mno_amx_tile : Flag<["-"], "mno-amx-tile">, Group<m_x86_Features_Group>;
def mcmpccxadd : Flag<["-"], "mcmpccxadd">, Group<m_x86_Features_Group>;
Expand Down Expand Up @@ -6787,6 +6793,10 @@ def flang_deprecated_no_hlfir : Flag<["-"], "flang-deprecated-no-hlfir">,
Flags<[HelpHidden]>, Visibility<[FlangOption, FC1Option]>,
HelpText<"Do not use HLFIR lowering (deprecated)">;

def flang_experimental_integer_overflow : Flag<["-"], "flang-experimental-integer-overflow">,
Flags<[HelpHidden]>, Visibility<[FlangOption, FC1Option]>,
HelpText<"Add nsw flag to internal operations such as do-variable increment (experimental)">;

//===----------------------------------------------------------------------===//
// FLangOption + CoreOption + NoXarchOption
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -7350,6 +7360,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 @@ -8110,11 +8121,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
8 changes: 7 additions & 1 deletion clang/include/clang/Index/USRGeneration.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
namespace clang {
class ASTContext;
class Decl;
class LangOptions;
class MacroDefinitionRecord;
class Module;
class SourceLocation;
Expand All @@ -30,6 +31,8 @@ static inline StringRef getUSRSpacePrefix() {
/// Generate a USR for a Decl, including the USR prefix.
/// \returns true if the results should be ignored, false otherwise.
bool generateUSRForDecl(const Decl *D, SmallVectorImpl<char> &Buf);
bool generateUSRForDecl(const Decl *D, SmallVectorImpl<char> &Buf,
const LangOptions &LangOpts);

/// Generate a USR fragment for an Objective-C class.
void generateUSRForObjCClass(StringRef Cls, raw_ostream &OS,
Expand Down Expand Up @@ -75,7 +78,10 @@ bool generateUSRForMacro(StringRef MacroName, SourceLocation Loc,
/// Generates a USR for a type.
///
/// \return true on error, false on success.
bool generateUSRForType(QualType T, ASTContext &Ctx, SmallVectorImpl<char> &Buf);
bool generateUSRForType(QualType T, ASTContext &Ctx,
SmallVectorImpl<char> &Buf);
bool generateUSRForType(QualType T, ASTContext &Ctx, SmallVectorImpl<char> &Buf,
const LangOptions &LangOpts);

/// Generate a USR for a module, including the USR prefix.
/// \returns true on error, false on success.
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
3 changes: 3 additions & 0 deletions clang/include/clang/Sema/SemaAMDGPU.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ class SemaAMDGPU : public SemaBase {

bool CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);

bool checkMovDPPFunctionCall(CallExpr *TheCall, unsigned NumArgs,
unsigned NumDataArgs);

/// Create an AMDGPUWavesPerEUAttr attribute.
AMDGPUFlatWorkGroupSizeAttr *
CreateAMDGPUFlatWorkGroupSizeAttr(const AttributeCommonInfo &CI, Expr *Min,
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: 5 additions & 1 deletion clang/include/clang/Sema/SemaObjC.h
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,10 @@ class SemaObjC : public SemaBase {
ParsedAttributesView ArgAttrs;
};

ParmVarDecl *ActOnMethodParmDeclaration(Scope *S, ObjCArgInfo &ArgInfo,
int ParamIndex,
bool MethodDefinition);

Decl *ActOnMethodDeclaration(
Scope *S,
SourceLocation BeginLoc, // location of the + or -.
Expand All @@ -359,7 +363,7 @@ class SemaObjC : public SemaBase {
ArrayRef<SourceLocation> SelectorLocs, Selector Sel,
// optional arguments. The number of types/arguments is obtained
// from the Sel.getNumArgs().
ObjCArgInfo *ArgInfo, DeclaratorChunk::ParamInfo *CParamInfo,
ParmVarDecl **ArgInfo, DeclaratorChunk::ParamInfo *CParamInfo,
unsigned CNumArgs, // c-style args
const ParsedAttributesView &AttrList, tok::ObjCKeywordKind MethodImplKind,
bool isVariadic, bool MethodDefinition);
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 = 512;
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
2 changes: 2 additions & 0 deletions clang/include/clang/Serialization/ASTRecordWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ class ASTRecordWriter
AddStmt(const_cast<Stmt*>(S));
}

void writeAttr(const Attr *A) { AddAttr(A); }

/// Write an BTFTypeTagAttr object.
void writeBTFTypeTagAttr(const BTFTypeTagAttr *A) { AddAttr(A); }

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
Loading