346 changes: 242 additions & 104 deletions bolt/lib/Rewrite/RewriteInstance.cpp

Large diffs are not rendered by default.

54 changes: 44 additions & 10 deletions bolt/test/X86/fragment-lite.s
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,42 @@
# RUN: split-file %s %t
# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown %t/main.s -o %t.o
# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown %t/baz.s -o %t.baz.o
# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown %t/baz2.s -o %t.baz2.o
# RUN: link_fdata %s %t.o %t.main.fdata
# RUN: link_fdata %s %t.baz.o %t.baz.fdata
# RUN: merge-fdata %t.main.fdata %t.baz.fdata > %t.fdata
# RUN: %clang %cflags %t.o %t.baz.o -o %t.exe -Wl,-q
# RUN: link_fdata %s %t.baz2.o %t.baz2.fdata
# RUN: merge-fdata %t.main.fdata %t.baz.fdata %t.baz2.fdata > %t.fdata
# RUN: %clang %cflags %t.o %t.baz.o %t.baz2.o -o %t.exe -Wl,-q
# RUN: llvm-bolt %t.exe -o %t.out --lite=1 --data %t.fdata -v=1 -print-cfg \
# RUN: 2>&1 | FileCheck %s

# CHECK: BOLT-INFO: processing main.cold.1 as a sibling of non-ignored function
# CHECK: BOLT-INFO: processing foo.cold.1/1 as a sibling of non-ignored function
# CHECK: BOLT-INFO: processing bar.cold.1/1 as a sibling of non-ignored function
# CHECK: BOLT-INFO: processing foo.cold.1/1(*2) as a sibling of non-ignored function
# CHECK: BOLT-INFO: processing bar.cold.1/1(*2) as a sibling of non-ignored function
# CHECK: BOLT-INFO: processing baz.cold.1 as a sibling of non-ignored function
# CHECK: BOLT-INFO: processing baz.cold.1/1 as a sibling of non-ignored function
# CHECK: BOLT-INFO: processing baz.cold.1/1(*2) as a sibling of non-ignored function
# CHECK: BOLT-INFO: processing baz.cold.1/2(*2) as a sibling of non-ignored function

# CHECK: Binary Function "main.cold.1" after building cfg
# CHECK: Parent : main

# CHECK: Binary Function "foo.cold.1/1" after building cfg
# CHECK: Binary Function "foo.cold.1/1(*2)" after building cfg
# CHECK: Parent : foo

# CHECK: Binary Function "bar.cold.1/1" after building cfg
# CHECK: Parent : bar/1
# CHECK: Binary Function "bar.cold.1/1(*2)" after building cfg
# CHECK: Parent : bar/1(*2)

# CHECK: Binary Function "baz.cold.1" after building cfg
# CHECK: Parent : baz{{$}}

# CHECK: Binary Function "baz.cold.1/1" after building cfg
# CHECK: Parent : baz/1
# CHECK: Binary Function "baz.cold.1/1(*2)" after building cfg
# CHECK: Parent : baz/1(*2)

# CHECK: Binary Function "baz.cold.1/2(*2)" after building cfg
# CHECK: Parent : baz/2(*2)

#--- main.s
.file "main.s"
.globl main
.type main, %function
main:
Expand Down Expand Up @@ -126,6 +133,7 @@ baz.cold.1:
.size baz.cold.1, .-baz.cold.1

#--- baz.s
.file "baz.s"
.local baz
.type baz, %function
baz:
Expand All @@ -149,3 +157,29 @@ baz.cold.1:
retq
.cfi_endproc
.size baz.cold.1, .-baz.cold.1

#--- baz2.s
.file "baz2.s"
.local baz
.type baz, %function
baz:
.cfi_startproc
# FDATA: 0 [unknown] 0 1 baz/2 0 1 0
cmpl $0x0, %eax
je baz.cold.1
retq
.cfi_endproc
.size baz, .-baz

.section .text.cold
.local baz.cold.1
.type baz.cold.1, %function
baz.cold.1:
.cfi_startproc
pushq %rbp
movq %rsp, %rbp
movl $0x0, %eax
popq %rbp
retq
.cfi_endproc
.size baz.cold.1, .-baz.cold.1
32 changes: 32 additions & 0 deletions bolt/test/X86/register-fragments-bolt-symbols.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Test the heuristics for matching BOLT-added split functions.

# RUN: llvm-mc --filetype=obj --triple x86_64-unknown-unknown %S/cdsplit-symbol-names.s -o %t.main.o
# RUN: llvm-mc --filetype=obj --triple x86_64-unknown-unknown %s -o %t.chain.o
# RUN: link_fdata %S/cdsplit-symbol-names.s %t.main.o %t.fdata
# RUN: sed -i 's|chain|chain/2|g' %t.fdata
# RUN: llvm-strip --strip-unneeded %t.main.o
# RUN: llvm-objcopy --localize-symbol=chain %t.main.o
# RUN: %clang %cflags %t.chain.o %t.main.o -o %t.exe -Wl,-q
# RUN: llvm-bolt %t.exe -o %t.bolt --split-functions --split-strategy=randomN \
# RUN: --reorder-blocks=ext-tsp --enable-bat --bolt-seed=7 --data=%t.fdata
# RUN: llvm-objdump --syms %t.bolt | FileCheck %s --check-prefix=CHECK-SYMS

# RUN: link_fdata %s %t.bolt %t.preagg PREAGG
# PREAGG: B X:0 #chain.cold.0# 1 0
# RUN: perf2bolt %t.bolt -p %t.preagg --pa -o %t.bat.fdata -w %t.bat.yaml -v=1 \
# RUN: | FileCheck %s --check-prefix=CHECK-REGISTER

# CHECK-SYMS: l df *ABS* [[#]] chain.s
# CHECK-SYMS: l F .bolt.org.text [[#]] chain
# CHECK-SYMS: l F .text.cold [[#]] chain.cold.0
# CHECK-SYMS: l F .text [[#]] chain
# CHECK-SYMS: l df *ABS* [[#]] bolt-pseudo.o

# CHECK-REGISTER: BOLT-INFO: marking chain.cold.0/1(*2) as a fragment of chain/2(*2)

.file "chain.s"
.text
.type chain, @function
chain:
ret
.size chain, .-chain
2 changes: 1 addition & 1 deletion clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class UseNullptrCheck : public ClangTidyCheck {
bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
// FIXME this should be CPlusPlus11 but that causes test cases to
// erroneously fail.
return LangOpts.CPlusPlus;
return LangOpts.CPlusPlus || LangOpts.C23;
}
void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,11 @@ void AvoidReturnWithVoidValueCheck::check(
<< BraceInsertionHints.closingBraceFixIt();
}
Diag << FixItHint::CreateRemoval(VoidReturn->getReturnLoc());
if (!Result.Nodes.getNodeAs<FunctionDecl>("function_parent") ||
SurroundingBlock->body_back() != VoidReturn)
const auto *FunctionParent =
Result.Nodes.getNodeAs<FunctionDecl>("function_parent");
if (!FunctionParent ||
(SurroundingBlock && SurroundingBlock->body_back() != VoidReturn))
// If this is not the last statement in a function body, we add a `return`.
Diag << FixItHint::CreateInsertion(SemicolonPos.getLocWithOffset(1),
" return;", true);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,19 +61,21 @@ static void addParantheses(const BinaryOperator *BinOp,
const clang::SourceLocation StartLoc = BinOp->getBeginLoc();
const clang::SourceLocation EndLoc =
clang::Lexer::getLocForEndOfToken(BinOp->getEndLoc(), 0, SM, LangOpts);
if (EndLoc.isInvalid())
return;

Check->diag(StartLoc,
"'%0' has higher precedence than '%1'; add parentheses to "
"explicitly specify the order of operations")
auto Diag =
Check->diag(StartLoc,
"'%0' has higher precedence than '%1'; add parentheses to "
"explicitly specify the order of operations")
<< (Precedence1 > Precedence2 ? BinOp->getOpcodeStr()
: ParentBinOp->getOpcodeStr())
<< (Precedence1 > Precedence2 ? ParentBinOp->getOpcodeStr()
: BinOp->getOpcodeStr())
<< FixItHint::CreateInsertion(StartLoc, "(")
<< FixItHint::CreateInsertion(EndLoc, ")")
<< SourceRange(StartLoc, EndLoc);

if (EndLoc.isValid()) {
Diag << FixItHint::CreateInsertion(StartLoc, "(")
<< FixItHint::CreateInsertion(EndLoc, ")");
}
}

addParantheses(dyn_cast<BinaryOperator>(BinOp->getLHS()->IgnoreImpCasts()),
Expand Down
12 changes: 5 additions & 7 deletions clang-tools-extra/clangd/unittests/FindTargetTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -839,9 +839,7 @@ TEST_F(TargetDeclTest, OverloadExpr) {
[[delete]] x;
}
)cpp";
// Sized deallocation is enabled by default in C++14 onwards.
EXPECT_DECLS("CXXDeleteExpr",
"void operator delete(void *, unsigned long) noexcept");
EXPECT_DECLS("CXXDeleteExpr", "void operator delete(void *) noexcept");
}

TEST_F(TargetDeclTest, DependentExprs) {
Expand All @@ -856,7 +854,7 @@ TEST_F(TargetDeclTest, DependentExprs) {
}
};
)cpp";
EXPECT_DECLS("CXXDependentScopeMemberExpr", "void foo()");
EXPECT_DECLS("MemberExpr", "void foo()");

// Similar to above but base expression involves a function call.
Code = R"cpp(
Expand All @@ -874,7 +872,7 @@ TEST_F(TargetDeclTest, DependentExprs) {
}
};
)cpp";
EXPECT_DECLS("CXXDependentScopeMemberExpr", "void foo()");
EXPECT_DECLS("MemberExpr", "void foo()");

// Similar to above but uses a function pointer.
Code = R"cpp(
Expand All @@ -893,7 +891,7 @@ TEST_F(TargetDeclTest, DependentExprs) {
}
};
)cpp";
EXPECT_DECLS("CXXDependentScopeMemberExpr", "void foo()");
EXPECT_DECLS("MemberExpr", "void foo()");

// Base expression involves a member access into this.
Code = R"cpp(
Expand Down Expand Up @@ -964,7 +962,7 @@ TEST_F(TargetDeclTest, DependentExprs) {
void Foo() { this->[[find]](); }
};
)cpp";
EXPECT_DECLS("CXXDependentScopeMemberExpr", "void find()");
EXPECT_DECLS("MemberExpr", "void find()");
}

TEST_F(TargetDeclTest, DependentTypes) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -621,7 +621,7 @@ sizeof...($TemplateParameter[[Elements]]);
struct $Class_def[[Foo]] {
int $Field_decl[[Waldo]];
void $Method_def[[bar]]() {
$Class[[Foo]]().$Field_dependentName[[Waldo]];
$Class[[Foo]]().$Field[[Waldo]];
}
template $Bracket[[<]]typename $TemplateParameter_def[[U]]$Bracket[[>]]
void $Method_def[[bar1]]() {
Expand Down
27 changes: 17 additions & 10 deletions clang-tools-extra/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -100,13 +100,15 @@ Improvements to clang-tidy
- Improved :program:`run-clang-tidy.py` script. Added argument `-source-filter`
to filter source files from the compilation database, via a RegEx. In a
similar fashion to what `-header-filter` does for header files.

- Improved :program:`check_clang_tidy.py` script. Added argument `-export-fixes`
to aid in clang-tidy and test development.

- Fixed bug where big values for unsigned check options overflowed into negative values
when being printed with ``--dump-config``.
when being printed with `--dump-config`.

- Fixed ``--verify-config`` option not properly parsing checks when using the
literal operator in the ``.clang-tidy`` config.
- Fixed `--verify-config` option not properly parsing checks when using the
literal operator in the `.clang-tidy` config.

New checks
^^^^^^^^^^
Expand Down Expand Up @@ -236,7 +238,7 @@ Changes in existing checks

- Improved :doc:`google-explicit-constructor
<clang-tidy/checks/google/explicit-constructor>` check to better handle
``C++-20`` `explicit(bool)`.
C++20 `explicit(bool)`.

- Improved :doc:`google-global-names-in-headers
<clang-tidy/checks/google/global-names-in-headers>` check by replacing the local
Expand All @@ -249,13 +251,18 @@ Changes in existing checks
check by ignoring other functions with same prefixes as the target specific
functions.

- Improved :doc:`linuxkernel-must-check-errs
<clang-tidy/checks/linuxkernel/must-check-errs>` check documentation to
consistently use the check's proper name.

- Improved :doc:`llvm-header-guard
<clang-tidy/checks/llvm/header-guard>` check by replacing the local
option `HeaderFileExtensions` by the global option of the same name.

- Improved :doc:`misc-const-correctness
<clang-tidy/checks/misc/const-correctness>` check by avoiding infinite recursion
for recursive forwarding reference.
for recursive functions with forwarding reference parameters and reference
variables which refer to themselves.

- Improved :doc:`misc-definitions-in-headers
<clang-tidy/checks/misc/definitions-in-headers>` check by replacing the local
Expand All @@ -281,6 +288,10 @@ Changes in existing checks
don't remove parentheses used in ``sizeof`` calls when they have array index
accesses as arguments.

- Improved :doc:`modernize-use-nullptr
<clang-tidy/checks/modernize/use-nullptr>` check to include support for C23,
which also has introduced the ``nullptr`` keyword.

- Improved :doc:`modernize-use-override
<clang-tidy/checks/modernize/use-override>` check to also remove any trailing
whitespace when deleting the ``virtual`` keyword.
Expand Down Expand Up @@ -336,13 +347,9 @@ Miscellaneous
^^^^^^^^^^^^^

- Fixed incorrect formatting in :program:`clang-apply-replacements` when no
``--format`` option is specified. Now :program:`clang-apply-replacements`
`--format` option is specified. Now :program:`clang-apply-replacements`
applies formatting only with the option.

- Fixed the :doc:`linuxkernel-must-check-errs
<clang-tidy/checks/linuxkernel/must-check-errs>` documentation to consistently
use the check's proper name.

Improvements to include-fixer
-----------------------------

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ modernize-use-nullptr
=====================

The check converts the usage of null pointer constants (e.g. ``NULL``, ``0``)
to use the new C++11 ``nullptr`` keyword.
to use the new C++11 and C23 ``nullptr`` keyword.

Example
-------
Expand Down
45 changes: 21 additions & 24 deletions clang-tools-extra/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -67,33 +67,30 @@ foreach(dep ${LLVM_UTILS_DEPS})
endif()
endforeach()

if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY)
if (NOT WIN32 OR NOT LLVM_LINK_LLVM_DYLIB)
llvm_add_library(
CTTestTidyModule
MODULE clang-tidy/CTTestTidyModule.cpp
PLUGIN_TOOL clang-tidy
DEPENDS clang-tidy-headers)
endif()
if (NOT WIN32 OR NOT LLVM_LINK_LLVM_DYLIB)
llvm_add_library(
CTTestTidyModule
MODULE clang-tidy/CTTestTidyModule.cpp
PLUGIN_TOOL clang-tidy)
endif()

if(CLANG_BUILT_STANDALONE)
# LLVMHello library is needed below
if (EXISTS ${LLVM_MAIN_SRC_DIR}/lib/Transforms/Hello
AND NOT TARGET LLVMHello)
add_subdirectory(${LLVM_MAIN_SRC_DIR}/lib/Transforms/Hello
lib/Transforms/Hello)
endif()
if(CLANG_BUILT_STANDALONE)
# LLVMHello library is needed below
if (EXISTS ${LLVM_MAIN_SRC_DIR}/lib/Transforms/Hello
AND NOT TARGET LLVMHello)
add_subdirectory(${LLVM_MAIN_SRC_DIR}/lib/Transforms/Hello
lib/Transforms/Hello)
endif()
endif()

if(TARGET CTTestTidyModule)
list(APPEND CLANG_TOOLS_TEST_DEPS CTTestTidyModule LLVMHello)
target_include_directories(CTTestTidyModule PUBLIC BEFORE "${CLANG_TOOLS_SOURCE_DIR}")
if(CLANG_PLUGIN_SUPPORT AND (WIN32 OR CYGWIN))
set(LLVM_LINK_COMPONENTS
Support
)
endif()
endif()
if(TARGET CTTestTidyModule)
list(APPEND CLANG_TOOLS_TEST_DEPS CTTestTidyModule LLVMHello)
target_include_directories(CTTestTidyModule PUBLIC BEFORE "${CLANG_TOOLS_SOURCE_DIR}")
if(CLANG_PLUGIN_SUPPORT AND (WIN32 OR CYGWIN))
set(LLVM_LINK_COMPONENTS
Support
)
endif()
endif()

add_lit_testsuite(check-clang-extra "Running clang-tools-extra/test"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,8 @@ struct HeapArray { // Ok, since destruc

HeapArray(HeapArray &&other) : _data(other._data), size(other.size) { // Ok
other._data = nullptr; // Ok
// CHECK-NOTES: [[@LINE-1]]:5: warning: expected assignment source to be of type 'gsl::owner<>'; got 'std::nullptr_t'
// FIXME: This warning is emitted because an ImplicitCastExpr for the NullToPointer conversion isn't created for dependent types.
other.size = 0;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,16 @@ struct S {
// CHECK-MESSAGES: :[[@LINE+1]]:7: warning: declaration of 'operator new' has no matching declaration of 'operator delete' at the same scope
void *operator new(size_t size) noexcept(false);

struct T {
// Sized deallocations are not enabled by default, and so this new/delete pair
// does not match. However, we expect only one warning, for the new, because
// the operator delete is a placement delete and we do not warn on mismatching
// placement operations.
// CHECK-MESSAGES: :[[@LINE+1]]:9: warning: declaration of 'operator new' has no matching declaration of 'operator delete' at the same scope
void *operator new(size_t size) noexcept;
void operator delete(void *ptr, size_t) noexcept; // ok only if sized deallocation is enabled
};

struct U {
void *operator new(size_t size) noexcept;
void operator delete(void *ptr) noexcept;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,8 @@ template <class T>
struct Template {
Template() = default;
Template(const Template &Other) : Field(Other.Field) {}
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
// CHECK-FIXES: Template(const Template &Other) = default;
Template &operator=(const Template &Other);
void foo(const T &t);
int Field;
Expand All @@ -269,8 +271,12 @@ Template<T> &Template<T>::operator=(const Template<T> &Other) {
Field = Other.Field;
return *this;
}
// CHECK-MESSAGES: :[[@LINE-4]]:27: warning: use '= default'
// CHECK-FIXES: Template<T> &Template<T>::operator=(const Template<T> &Other) = default;

Template<int> T1;


// Dependent types.
template <class T>
struct DT1 {
Expand All @@ -284,6 +290,9 @@ DT1<T> &DT1<T>::operator=(const DT1<T> &Other) {
Field = Other.Field;
return *this;
}
// CHECK-MESSAGES: :[[@LINE-4]]:17: warning: use '= default'
// CHECK-FIXES: DT1<T> &DT1<T>::operator=(const DT1<T> &Other) = default;

DT1<int> Dt1;

template <class T>
Expand All @@ -303,6 +312,9 @@ DT2<T> &DT2<T>::operator=(const DT2<T> &Other) {
struct T {
typedef int TT;
};
// CHECK-MESSAGES: :[[@LINE-8]]:17: warning: use '= default'
// CHECK-FIXES: DT2<T> &DT2<T>::operator=(const DT2<T> &Other) = default;

DT2<T> Dt2;

// Default arguments.
Expand Down
139 changes: 139 additions & 0 deletions clang-tools-extra/test/clang-tidy/checkers/modernize/use-nullptr-c23.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
// RUN: %check_clang_tidy %s modernize-use-nullptr %t -- -- -std=c23

#define NULL 0

void test_assignment() {
int *p1 = 0;
// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use nullptr [modernize-use-nullptr]
// CHECK-FIXES: int *p1 = nullptr;
p1 = 0;
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use nullptr
// CHECK-FIXES: p1 = nullptr;

int *p2 = NULL;
// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use nullptr
// CHECK-FIXES: int *p2 = nullptr;

p2 = p1;
// CHECK-FIXES: p2 = p1;

const int null = 0;
int *p3 = &null;

p3 = NULL;
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use nullptr
// CHECK-FIXES: p3 = nullptr;

int *p4 = p3;

int i1 = 0;

int i2 = NULL;

int i3 = null;

int *p5, *p6, *p7;
p5 = p6 = p7 = NULL;
// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: use nullptr
// CHECK-FIXES: p5 = p6 = p7 = nullptr;
}

void test_function(int *p) {}

void test_function_no_ptr_param(int i) {}

void test_function_call() {
test_function(0);
// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: use nullptr
// CHECK-FIXES: test_function(nullptr);

test_function(NULL);
// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: use nullptr
// CHECK-FIXES: test_function(nullptr);

test_function_no_ptr_param(0);
}

char *test_function_return1() {
return 0;
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use nullptr
// CHECK-FIXES: return nullptr;
}

void *test_function_return2() {
return NULL;
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use nullptr
// CHECK-FIXES: return nullptr;
}

int test_function_return4() {
return 0;
}

int test_function_return5() {
return NULL;
}

int *test_function_return_cast1() {
return(int)0;
// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use nullptr
// CHECK-FIXES: return nullptr;
}

int *test_function_return_cast2() {
#define RET return
RET(int)0;
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use nullptr
// CHECK-FIXES: RET nullptr;
#undef RET
}

// Test parentheses expressions resulting in a nullptr.
int *test_parentheses_expression1() {
return(0);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use nullptr
// CHECK-FIXES: return(nullptr);
}

int *test_parentheses_expression2() {
return((int)(0.0f));
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use nullptr
// CHECK-FIXES: return(nullptr);
}

int *test_nested_parentheses_expression() {
return((((0))));
// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use nullptr
// CHECK-FIXES: return((((nullptr))));
}

void test_const_pointers() {
const int *const_p1 = 0;
// CHECK-MESSAGES: :[[@LINE-1]]:25: warning: use nullptr
// CHECK-FIXES: const int *const_p1 = nullptr;
const int *const_p2 = NULL;
// CHECK-MESSAGES: :[[@LINE-1]]:25: warning: use nullptr
// CHECK-FIXES: const int *const_p2 = nullptr;
const int *const_p3 = (int)0;
// CHECK-MESSAGES: :[[@LINE-1]]:25: warning: use nullptr
// CHECK-FIXES: const int *const_p3 = nullptr;
const int *const_p4 = (int)0.0f;
// CHECK-MESSAGES: :[[@LINE-1]]:25: warning: use nullptr
// CHECK-FIXES: const int *const_p4 = nullptr;
}

void test_nested_implicit_cast_expr() {
int func0(void*, void*);
int func1(int, void*, void*);

(double)func1(0, 0, 0);
// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use nullptr
// CHECK-MESSAGES: :[[@LINE-2]]:23: warning: use nullptr
// CHECK-FIXES: (double)func1(0, nullptr, nullptr);
(double)func1(func0(0, 0), 0, 0);
// CHECK-MESSAGES: :[[@LINE-1]]:23: warning: use nullptr
// CHECK-MESSAGES: :[[@LINE-2]]:26: warning: use nullptr
// CHECK-MESSAGES: :[[@LINE-3]]:30: warning: use nullptr
// CHECK-MESSAGES: :[[@LINE-4]]:33: warning: use nullptr
// CHECK-FIXES: (double)func1(func0(nullptr, nullptr), nullptr, nullptr);
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: clang-tidy %s -checks=-*,modernize-use-nullptr -- | count 0
// RUN: clang-tidy %s -checks=-*,modernize-use-nullptr -- -std=c17 | count 0

// Note: this test expects no diagnostics, but FileCheck cannot handle that,
// hence the use of | count 0.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@ int bar(){
return 4;
}

int sink(int);
#define FUN(ARG) (sink(ARG))
#define FUN2(ARG) sink((ARG))
#define FUN3(ARG) sink(ARG)
#define FUN4(ARG) sink(1 + ARG)
#define FUN5(ARG) sink(4 * ARG)

class fun{
public:
int A;
Expand Down Expand Up @@ -117,4 +124,19 @@ void f(){
//CHECK-MESSAGES: :[[@LINE+2]]:94: warning: '/' has higher precedence than '-'; add parentheses to explicitly specify the order of operations [readability-math-missing-parentheses]
//CHECK-FIXES: int q = (1 MACRO_ADD (2 MACRO_MULTIPLY 3)) MACRO_OR ((4 MACRO_AND 5) MACRO_XOR (6 MACRO_SUBTRACT (7 MACRO_DIVIDE 8)));
int q = 1 MACRO_ADD 2 MACRO_MULTIPLY 3 MACRO_OR 4 MACRO_AND 5 MACRO_XOR 6 MACRO_SUBTRACT 7 MACRO_DIVIDE 8; // No warning

//CHECK-MESSAGES: :[[@LINE+1]]:21: warning: '*' has higher precedence than '+'; add parentheses to explicitly specify the order of operations [readability-math-missing-parentheses]
int r = FUN(0 + 1 * 2);

//CHECK-MESSAGES: :[[@LINE+1]]:22: warning: '*' has higher precedence than '+'; add parentheses to explicitly specify the order of operations [readability-math-missing-parentheses]
int s = FUN2(0 + 1 * 2);

//CHECK-MESSAGES: :[[@LINE+1]]:22: warning: '*' has higher precedence than '+'; add parentheses to explicitly specify the order of operations [readability-math-missing-parentheses]
int t = FUN3(0 + 1 * 2);

//CHECK-MESSAGES: :[[@LINE+1]]:18: warning: '*' has higher precedence than '+'; add parentheses to explicitly specify the order of operations [readability-math-missing-parentheses]
int u = FUN4(1 * 2);

//CHECK-MESSAGES: :[[@LINE+1]]:13: warning: '*' has higher precedence than '+'; add parentheses to explicitly specify the order of operations [readability-math-missing-parentheses]
int v = FUN5(0 + 1);
}
2 changes: 1 addition & 1 deletion clang-tools-extra/test/lit.site.cfg.py.in
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ config.python_executable = "@Python3_EXECUTABLE@"
config.target_triple = "@LLVM_TARGET_TRIPLE@"
config.host_triple = "@LLVM_HOST_TRIPLE@"
config.clang_tidy_staticanalyzer = @CLANG_TIDY_ENABLE_STATIC_ANALYZER@
config.has_plugins = @CLANG_PLUGIN_SUPPORT@ & ~@LLVM_INSTALL_TOOLCHAIN_ONLY@
config.has_plugins = @CLANG_PLUGIN_SUPPORT@
# Support substitution of the tools and libs dirs with user parameters. This is
# used when we can't determine the tool dir at configuration time.
config.llvm_tools_dir = lit_config.substitute("@LLVM_TOOLS_DIR@")
Expand Down
1 change: 1 addition & 0 deletions clang/cmake/caches/Release.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ set(LLVM_ENABLE_PROJECTS ${STAGE1_PROJECTS} CACHE STRING "")
# stage2-instrumented and Final Stage Config:
# Options that need to be set in both the instrumented stage (if we are doing
# a pgo build) and the final stage.
set_instrument_and_final_stage_var(CMAKE_POSITION_INDEPENDENT_CODE "ON" STRING)
set_instrument_and_final_stage_var(LLVM_ENABLE_LTO "${LLVM_RELEASE_ENABLE_LTO}" STRING)
if (LLVM_RELEASE_ENABLE_LTO)
set_instrument_and_final_stage_var(LLVM_ENABLE_LLD "ON" BOOL)
Expand Down
11 changes: 8 additions & 3 deletions clang/docs/LanguageExtensions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -711,6 +711,8 @@ even-odd element pair with indices ``i * 2`` and ``i * 2 + 1`` with
power of 2, the vector is widened with neutral elements for the reduction
at the end to the next power of 2.

These reductions support both fixed-sized and scalable vector types.

Example:

.. code-block:: c++
Expand Down Expand Up @@ -1493,6 +1495,7 @@ Conditional ``explicit`` __cpp_conditional_explicit C+
``if consteval`` __cpp_if_consteval C++23 C++20
``static operator()`` __cpp_static_call_operator C++23 C++03
Attributes on Lambda-Expressions C++23 C++11
Attributes on Structured Bindings __cpp_structured_bindings C++26 C++03
``= delete ("should have a reason");`` __cpp_deleted_function C++26 C++03
-------------------------------------------- -------------------------------- ------------- -------------
Designated initializers (N494) C99 C89
Expand Down Expand Up @@ -2928,7 +2931,7 @@ Query for this feature with ``__has_builtin(__builtin_dump_struct)``
``__builtin_shufflevector`` is used to express generic vector
permutation/shuffle/swizzle operations. This builtin is also very important
for the implementation of various target-specific header files like
``<xmmintrin.h>``.
``<xmmintrin.h>``. This builtin can be used within constant expressions.
**Syntax**:
Expand All @@ -2955,7 +2958,7 @@ for the implementation of various target-specific header files like
// Concatenate every other element of 8-element vectors V1 and V2.
__builtin_shufflevector(V1, V2, 0, 2, 4, 6, 8, 10, 12, 14)
// Shuffle v1 with some elements being undefined
// Shuffle v1 with some elements being undefined. Not allowed in constexpr.
__builtin_shufflevector(v1, v1, 3, -1, 1, -1)
**Description**:
Expand All @@ -2968,6 +2971,7 @@ starting with the first vector, continuing into the second vector. Thus, if
``vec1`` is a 4-element vector, index 5 would refer to the second element of
``vec2``. An index of -1 can be used to indicate that the corresponding element
in the returned vector is a don't care and can be optimized by the backend.
Values of -1 are not supported in constant expressions.
The result of ``__builtin_shufflevector`` is a vector with the same element
type as ``vec1``/``vec2`` but that has an element count equal to the number of
Expand All @@ -2982,7 +2986,8 @@ Query for this feature with ``__has_builtin(__builtin_shufflevector)``.
``__builtin_convertvector`` is used to express generic vector
type-conversion operations. The input vector and the output vector
type must have the same number of elements.
type must have the same number of elements. This builtin can be used within
constant expressions.
**Syntax**:
Expand Down
22 changes: 17 additions & 5 deletions clang/docs/LibTooling.rst
Original file line number Diff line number Diff line change
Expand Up @@ -63,15 +63,22 @@ and automatic location of the compilation database using source files paths.
#include "llvm/Support/CommandLine.h"

using namespace clang::tooling;
using namespace llvm;

// Apply a custom category to all command-line options so that they are the
// only ones displayed.
static llvm::cl::OptionCategory MyToolCategory("my-tool options");
static cl::OptionCategory MyToolCategory("my-tool options");

int main(int argc, const char **argv) {
// CommonOptionsParser constructor will parse arguments and create a
// CompilationDatabase. In case of error it will terminate the program.
CommonOptionsParser OptionsParser(argc, argv, MyToolCategory);
// CommonOptionsParser::create will parse arguments and create a
// CompilationDatabase.
auto ExpectedParser = CommonOptionsParser::create(argc, argv, MyToolCategory);
if (!ExpectedParser) {
// Fail gracefully for unsupported options.
llvm::errs() << ExpectedParser.takeError();
return 1;
}
CommonOptionsParser& OptionsParser = ExpectedParser.get();
// Use OptionsParser.getCompilations() and OptionsParser.getSourcePathList()
// to retrieve CompilationDatabase and the list of input file paths.
Expand Down Expand Up @@ -133,7 +140,12 @@ version of this example tool is also checked into the clang tree at
static cl::extrahelp MoreHelp("\nMore help text...\n");

int main(int argc, const char **argv) {
CommonOptionsParser OptionsParser(argc, argv, MyToolCategory);
auto ExpectedParser = CommonOptionsParser::create(argc, argv, MyToolCategory);
if (!ExpectedParser) {
llvm::errs() << ExpectedParser.takeError();
return 1;
}
CommonOptionsParser& OptionsParser = ExpectedParser.get();
ClangTool Tool(OptionsParser.getCompilations(),
OptionsParser.getSourcePathList());
return Tool.run(newFrontendActionFactory<clang::SyntaxOnlyAction>().get());
Expand Down
4 changes: 2 additions & 2 deletions clang/docs/Multilib.rst
Original file line number Diff line number Diff line change
Expand Up @@ -188,9 +188,9 @@ For a more comprehensive example see
- Dir: thumb/v6-m
# List of one or more normalized command line options, as generated by Clang
# from the command line options or from Mappings below.
# Here, if the flags are a superset of {target=thumbv6m-none-unknown-eabi}
# Here, if the flags are a superset of {target=thumbv6m-unknown-none-eabi}
# then this multilib variant will be considered a match.
Flags: [--target=thumbv6m-none-unknown-eabi]
Flags: [--target=thumbv6m-unknown-none-eabi]
# Similarly, a multilib variant targeting Arm v7-M with an FPU (floating
# point unit).
Expand Down
53 changes: 48 additions & 5 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,12 @@ ABI Changes in This Version
MSVC uses a different mangling for these objects, compatibility is not affected.
(#GH85423).

- Fixed Microsoft calling convention for returning certain classes with a
templated constructor. If a class has a templated constructor, it should
be returned indirectly even if it meets all the other requirements for
returning a class in a register. This affects some uses of std::pair.
(#GH86384).

AST Dumping Potentially Breaking Changes
----------------------------------------

Expand Down Expand Up @@ -90,11 +96,6 @@ C++ Language Changes
--------------------
- Implemented ``_BitInt`` literal suffixes ``__wb`` or ``__WB`` as a Clang extension with ``unsigned`` modifiers also allowed. (#GH85223).

C++14 Feature Support
^^^^^^^^^^^^^^^^^^^^^
- Sized deallocation is enabled by default in C++14 onwards. The user may specify
``-fno-sized-deallocation`` to disable it if there are some regressions.

C++17 Feature Support
^^^^^^^^^^^^^^^^^^^^^
- Clang now exposes ``__GCC_DESTRUCTIVE_SIZE`` and ``__GCC_CONSTRUCTIVE_SIZE``
Expand Down Expand Up @@ -148,6 +149,9 @@ C++2c Feature Support

- Implemented `P2573R2: = delete("should have a reason"); <https://wg21.link/P2573R2>`_

- Implemented `P0609R3: Attributes for Structured Bindings <https://wg21.link/P0609R3>`_

- Implemented `P2748R5 Disallow Binding a Returned Glvalue to a Temporary <https://wg21.link/P2748R5>`_.

Resolutions to C++ Defect Reports
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down Expand Up @@ -224,6 +228,7 @@ Non-comprehensive list of changes in this release
- ``__typeof_unqual__`` is available in all C modes as an extension, which behaves
like ``typeof_unqual`` from C23, similar to ``__typeof__`` and ``typeof``.

- ``__builtin_reduce_{add|mul|xor|or|and|min|max}`` builtins now support scalable vectors.

* Shared libraries linked with either the ``-ffast-math``, ``-Ofast``, or
``-funsafe-math-optimizations`` flags will no longer enable flush-to-zero
Expand All @@ -234,6 +239,9 @@ Non-comprehensive list of changes in this release
* ``-fdenormal-fp-math=preserve-sign`` is no longer implied by ``-ffast-math``
on x86 systems.

- Builtins ``__builtin_shufflevector()`` and ``__builtin_convertvector()`` may
now be used within constant expressions.

New Compiler Flags
------------------
- ``-fsanitize=implicit-bitfield-conversion`` checks implicit truncation and
Expand All @@ -248,6 +256,10 @@ New Compiler Flags
- ``-fexperimental-modules-reduced-bmi`` enables the Reduced BMI for C++20 named modules.
See the document of standard C++ modules for details.

- ``-fexperimental-late-parse-attributes`` enables an experimental feature to
allow late parsing certain attributes in specific contexts where they would
not normally be late parsed.

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

Expand Down Expand Up @@ -402,6 +414,18 @@ Improvements to Clang's diagnostics

- Clang now diagnoses requires expressions with explicit object parameters.

- Clang now looks up members of the current instantiation in the template definition context
if the current instantiation has no dependent base classes.

.. code-block:: c++

template<typename T>
struct A {
int f() {
return this->x; // error: no member named 'x' in 'A<T>'
}
};

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

Expand Down Expand Up @@ -448,6 +472,9 @@ Bug Fixes in This Version
- Clang now correctly generates overloads for bit-precise integer types for
builtin operators in C++. Fixes #GH82998.

- Fix crash when destructor definition is preceded with an equals sign.
Fixes (#GH89544).

- When performing mixed arithmetic between ``_Complex`` floating-point types and integers,
Clang now correctly promotes the integer to its corresponding real floating-point
type only rather than to the complex type (e.g. ``_Complex float / int`` is now evaluated
Expand All @@ -463,6 +490,10 @@ Bug Fixes in This Version

- Fixed an assertion failure on invalid InitListExpr in C89 mode (#GH88008).

- Fixed missing destructor calls when we branch from middle of an expression.
This could happen through a branch in stmt-expr or in an expression containing a coroutine
suspension. Fixes (#GH63818) (#GH88478).

- Clang will no longer diagnose an erroneous non-dependent ``switch`` condition
during instantiation, and instead will only diagnose it once, during checking
of the function template.
Expand Down Expand Up @@ -593,6 +624,12 @@ Bug Fixes to C++ Support
- Fixed a use-after-free bug in parsing of type constraints with default arguments that involve lambdas. (#GH67235)
- Fixed bug in which the body of a consteval lambda within a template was not parsed as within an
immediate function context.
- Fix CTAD for ``std::initializer_list``. This allows ``std::initializer_list{1, 2, 3}`` to be deduced as
``std::initializer_list<int>`` as intended.
- Fix a bug on template partial specialization whose template parameter is `decltype(auto)`.
- Fix a bug on template partial specialization with issue on deduction of nontype template parameter
whose type is `decltype(auto)`. Fixes (#GH68885).
- Clang now correctly treats the noexcept-specifier of a friend function to be a complete-class context.

Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down Expand Up @@ -645,6 +682,7 @@ Arm and AArch64 Support
* Arm Cortex-A78AE (cortex-a78ae).
* Arm Cortex-A520AE (cortex-a520ae).
* Arm Cortex-A720AE (cortex-a720ae).
* Arm Cortex-R82AE (cortex-r82ae).
* Arm Neoverse-N3 (neoverse-n3).
* Arm Neoverse-V3 (neoverse-v3).
* Arm Neoverse-V3AE (neoverse-v3ae).
Expand Down Expand Up @@ -704,6 +742,11 @@ AIX Support
WebAssembly Support
^^^^^^^^^^^^^^^^^^^

The -mcpu=generic configuration now enables multivalue feature, which is
standardized and available in all major engines. Enabling multivalue here only
enables the language feature but does not turn on the multivalue ABI (this
enables non-ABI uses of multivalue, like exnref).

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

Expand Down
87 changes: 64 additions & 23 deletions clang/docs/UsersManual.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1452,8 +1452,6 @@ floating point semantic models: precise (the default), strict, and fast.
"fenv_access", "off", "on", "off"
"rounding_mode", "tonearest", "dynamic", "tonearest"
"contract", "on", "off", "fast"
"denormal_fp_math", "IEEE", "IEEE", "IEEE"
"denormal_fp32_math", "IEEE","IEEE", "IEEE"
"support_math_errno", "on", "on", "off"
"no_honor_nans", "off", "off", "on"
"no_honor_infinities", "off", "off", "on"
Expand All @@ -1462,6 +1460,14 @@ floating point semantic models: precise (the default), strict, and fast.
"allow_approximate_fns", "off", "off", "on"
"allow_reassociation", "off", "off", "on"

The ``-ffp-model`` option does not modify the ``fdenormal-fp-math``
setting, but it does have an impact on whether ``crtfastmath.o`` is
linked. Because linking ``crtfastmath.o`` has a global effect on the
program, and because the global denormal handling can be changed in
other ways, the state of ``fdenormal-fp-math`` handling cannot
be assumed in any function based on fp-model. See :ref:`crtfastmath.o`
for more details.

.. option:: -ffast-math

Enable fast-math mode. This option lets the
Expand Down Expand Up @@ -1537,7 +1543,6 @@ floating point semantic models: precise (the default), strict, and fast.
Also, this option resets following options to their target-dependent defaults.

* ``-f[no-]math-errno``
* ``-fdenormal-fp-math=<value>``

There is ambiguity about how ``-ffp-contract``, ``-ffast-math``,
and ``-fno-fast-math`` behave when combined. To keep the value of
Expand All @@ -1560,8 +1565,7 @@ floating point semantic models: precise (the default), strict, and fast.
``-ffp-contract`` setting is determined by the default value of
``-ffp-contract``.

Note: ``-fno-fast-math`` implies ``-fdenormal-fp-math=ieee``.
``-fno-fast-math`` causes ``crtfastmath.o`` to not be linked with code
Note: ``-fno-fast-math`` causes ``crtfastmath.o`` to not be linked with code
unless ``-mdaz-ftz`` is present.

.. option:: -fdenormal-fp-math=<value>
Expand Down Expand Up @@ -1692,9 +1696,7 @@ floating point semantic models: precise (the default), strict, and fast.
* ``-fno-associative-math``
* ``-fno-reciprocal-math``
* ``-fsigned-zeros``
* ``-ftrapping-math``
* ``-ffp-contract=on``
* ``-fdenormal-fp-math=ieee``

There is ambiguity about how ``-ffp-contract``,
``-funsafe-math-optimizations``, and ``-fno-unsafe-math-optimizations``
Expand Down Expand Up @@ -2319,6 +2321,8 @@ are listed below.
on ELF targets when using the integrated assembler. This flag currently
only has an effect on ELF targets.

.. _funique_internal_linkage_names:

.. option:: -f[no]-unique-internal-linkage-names

Controls whether Clang emits a unique (best-effort) symbol name for internal
Expand Down Expand Up @@ -2448,27 +2452,41 @@ usual build cycle when using sample profilers for optimization:
usual build flags that you always build your application with. The only
requirement is that DWARF debug info including source line information is
generated. This DWARF information is important for the profiler to be able
to map instructions back to source line locations.
to map instructions back to source line locations. The usefulness of this
DWARF information can be improved with the ``-fdebug-info-for-profiling``
and ``-funique-internal-linkage-names`` options.

On Linux, ``-g`` or just ``-gline-tables-only`` is sufficient:
On Linux:

.. code-block:: console
$ clang++ -O2 -gline-tables-only code.cc -o code
$ clang++ -O2 -gline-tables-only \
-fdebug-info-for-profiling -funique-internal-linkage-names \
code.cc -o code
While MSVC-style targets default to CodeView debug information, DWARF debug
information is required to generate source-level LLVM profiles. Use
``-gdwarf`` to include DWARF debug information:

.. code-block:: console
.. code-block:: winbatch
> clang-cl /O2 -gdwarf -gline-tables-only ^
/clang:-fdebug-info-for-profiling /clang:-funique-internal-linkage-names ^
code.cc /Fe:code /fuse-ld=lld /link /debug:dwarf
$ clang-cl -O2 -gdwarf -gline-tables-only coff-profile.cpp -fuse-ld=lld -link -debug:dwarf
.. note::

:ref:`-funique-internal-linkage-names <funique_internal_linkage_names>`
generates unique names based on given command-line source file paths. If
your build system uses absolute source paths and these paths may change
between steps 1 and 4, then the uniqued function names may change and result
in unused profile data. Consider omitting this option in such cases.

2. Run the executable under a sampling profiler. The specific profiler
you use does not really matter, as long as its output can be converted
into the format that the LLVM optimizer understands.

Two such profilers are the the Linux Perf profiler
Two such profilers are the Linux Perf profiler
(https://perf.wiki.kernel.org/) and Intel's Sampling Enabling Product (SEP),
available as part of `Intel VTune
<https://software.intel.com/content/www/us/en/develop/tools/oneapi/components/vtune-profiler.html>`_.
Expand All @@ -2482,7 +2500,9 @@ usual build cycle when using sample profilers for optimization:

.. code-block:: console
$ perf record -b ./code
$ perf record -b -e BR_INST_RETIRED.NEAR_TAKEN:uppp ./code
If the event above is unavailable, ``branches:u`` is probably next-best.

Note the use of the ``-b`` flag. This tells Perf to use the Last Branch
Record (LBR) to record call chains. While this is not strictly required,
Expand Down Expand Up @@ -2532,21 +2552,42 @@ usual build cycle when using sample profilers for optimization:
that executes faster than the original one. Note that you are not
required to build the code with the exact same arguments that you
used in the first step. The only requirement is that you build the code
with ``-gline-tables-only`` and ``-fprofile-sample-use``.
with the same debug info options and ``-fprofile-sample-use``.

On Linux:

.. code-block:: console
$ clang++ -O2 -gline-tables-only -fprofile-sample-use=code.prof code.cc -o code
$ clang++ -O2 -gline-tables-only \
-fdebug-info-for-profiling -funique-internal-linkage-names \
-fprofile-sample-use=code.prof code.cc -o code
[OPTIONAL] Sampling-based profiles can have inaccuracies or missing block/
edge counters. The profile inference algorithm (profi) can be used to infer
missing blocks and edge counts, and improve the quality of profile data.
Enable it with ``-fsample-profile-use-profi``.
On Windows:

.. code-block:: console
.. code-block:: winbatch
> clang-cl /O2 -gdwarf -gline-tables-only ^
/clang:-fdebug-info-for-profiling /clang:-funique-internal-linkage-names ^
/fprofile-sample-use=code.prof code.cc /Fe:code /fuse-ld=lld /link /debug:dwarf
[OPTIONAL] Sampling-based profiles can have inaccuracies or missing block/
edge counters. The profile inference algorithm (profi) can be used to infer
missing blocks and edge counts, and improve the quality of profile data.
Enable it with ``-fsample-profile-use-profi``. For example, on Linux:

.. code-block:: console
$ clang++ -fsample-profile-use-profi -O2 -gline-tables-only \
-fdebug-info-for-profiling -funique-internal-linkage-names \
-fprofile-sample-use=code.prof code.cc -o code
On Windows:

.. code-block:: winbatch
$ clang++ -O2 -gline-tables-only -fprofile-sample-use=code.prof \
-fsample-profile-use-profi code.cc -o code
> clang-cl /clang:-fsample-profile-use-profi /O2 -gdwarf -gline-tables-only ^
/clang:-fdebug-info-for-profiling /clang:-funique-internal-linkage-names ^
/fprofile-sample-use=code.prof code.cc /Fe:code /fuse-ld=lld /link /debug:dwarf
Sample Profile Formats
""""""""""""""""""""""
Expand Down
186 changes: 93 additions & 93 deletions clang/docs/analyzer/checkers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1462,6 +1462,99 @@ checker).
Default value of the option is ``true``.
.. _unix-Stream:
unix.Stream (C)
"""""""""""""""
Check C stream handling functions:
``fopen, fdopen, freopen, tmpfile, fclose, fread, fwrite, fgetc, fgets, fputc, fputs, fprintf, fscanf, ungetc, getdelim, getline, fseek, fseeko, ftell, ftello, fflush, rewind, fgetpos, fsetpos, clearerr, feof, ferror, fileno``.
The checker maintains information about the C stream objects (``FILE *``) and
can detect error conditions related to use of streams. The following conditions
are detected:
* The ``FILE *`` pointer passed to the function is NULL (the single exception is
``fflush`` where NULL is allowed).
* Use of stream after close.
* Opened stream is not closed.
* Read from a stream after end-of-file. (This is not a fatal error but reported
by the checker. Stream remains in EOF state and the read operation fails.)
* Use of stream when the file position is indeterminate after a previous failed
operation. Some functions (like ``ferror``, ``clearerr``, ``fseek``) are
allowed in this state.
* Invalid 3rd ("``whence``") argument to ``fseek``.
The stream operations are by this checker usually split into two cases, a success
and a failure case. However, in the case of write operations (like ``fwrite``,
``fprintf`` and even ``fsetpos``) this behavior could produce a large amount of
unwanted reports on projects that don't have error checks around the write
operations, so by default the checker assumes that write operations always succeed.
This behavior can be controlled by the ``Pedantic`` flag: With
``-analyzer-config unix.Stream:Pedantic=true`` the checker will model the
cases where a write operation fails and report situations where this leads to
erroneous behavior. (The default is ``Pedantic=false``, where write operations
are assumed to succeed.)
.. code-block:: c
void test1() {
FILE *p = fopen("foo", "r");
} // warn: opened file is never closed
void test2() {
FILE *p = fopen("foo", "r");
fseek(p, 1, SEEK_SET); // warn: stream pointer might be NULL
fclose(p);
}
void test3() {
FILE *p = fopen("foo", "r");
if (p) {
fseek(p, 1, 3); // warn: third arg should be SEEK_SET, SEEK_END, or SEEK_CUR
fclose(p);
}
}
void test4() {
FILE *p = fopen("foo", "r");
if (!p)
return;
fclose(p);
fclose(p); // warn: stream already closed
}
void test5() {
FILE *p = fopen("foo", "r");
if (!p)
return;
fgetc(p);
if (!ferror(p))
fgetc(p); // warn: possible read after end-of-file
fclose(p);
}
void test6() {
FILE *p = fopen("foo", "r");
if (!p)
return;
fgetc(p);
if (!feof(p))
fgetc(p); // warn: file position may be indeterminate after I/O error
fclose(p);
}
**Limitations**
The checker does not track the correspondence between integer file descriptors
and ``FILE *`` pointers. Operations on standard streams like ``stdin`` are not
treated specially and are therefore often not recognized (because these streams
are usually not opened explicitly by the program, and are global variables).
.. _osx-checkers:
osx
Expand Down Expand Up @@ -3116,99 +3209,6 @@ Check for misuses of stream APIs. Check for misuses of stream APIs: ``fopen, fcl
fclose(F); // warn: closing a previously closed file stream
}
.. _alpha-unix-Stream:
alpha.unix.Stream (C)
"""""""""""""""""""""
Check C stream handling functions:
``fopen, fdopen, freopen, tmpfile, fclose, fread, fwrite, fgetc, fgets, fputc, fputs, fprintf, fscanf, ungetc, getdelim, getline, fseek, fseeko, ftell, ftello, fflush, rewind, fgetpos, fsetpos, clearerr, feof, ferror, fileno``.
The checker maintains information about the C stream objects (``FILE *``) and
can detect error conditions related to use of streams. The following conditions
are detected:
* The ``FILE *`` pointer passed to the function is NULL (the single exception is
``fflush`` where NULL is allowed).
* Use of stream after close.
* Opened stream is not closed.
* Read from a stream after end-of-file. (This is not a fatal error but reported
by the checker. Stream remains in EOF state and the read operation fails.)
* Use of stream when the file position is indeterminate after a previous failed
operation. Some functions (like ``ferror``, ``clearerr``, ``fseek``) are
allowed in this state.
* Invalid 3rd ("``whence``") argument to ``fseek``.
The stream operations are by this checker usually split into two cases, a success
and a failure case. However, in the case of write operations (like ``fwrite``,
``fprintf`` and even ``fsetpos``) this behavior could produce a large amount of
unwanted reports on projects that don't have error checks around the write
operations, so by default the checker assumes that write operations always succeed.
This behavior can be controlled by the ``Pedantic`` flag: With
``-analyzer-config alpha.unix.Stream:Pedantic=true`` the checker will model the
cases where a write operation fails and report situations where this leads to
erroneous behavior. (The default is ``Pedantic=false``, where write operations
are assumed to succeed.)
.. code-block:: c
void test1() {
FILE *p = fopen("foo", "r");
} // warn: opened file is never closed
void test2() {
FILE *p = fopen("foo", "r");
fseek(p, 1, SEEK_SET); // warn: stream pointer might be NULL
fclose(p);
}
void test3() {
FILE *p = fopen("foo", "r");
if (p) {
fseek(p, 1, 3); // warn: third arg should be SEEK_SET, SEEK_END, or SEEK_CUR
fclose(p);
}
}
void test4() {
FILE *p = fopen("foo", "r");
if (!p)
return;
fclose(p);
fclose(p); // warn: stream already closed
}
void test5() {
FILE *p = fopen("foo", "r");
if (!p)
return;
fgetc(p);
if (!ferror(p))
fgetc(p); // warn: possible read after end-of-file
fclose(p);
}
void test6() {
FILE *p = fopen("foo", "r");
if (!p)
return;
fgetc(p);
if (!feof(p))
fgetc(p); // warn: file position may be indeterminate after I/O error
fclose(p);
}
**Limitations**
The checker does not track the correspondence between integer file descriptors
and ``FILE *`` pointers. Operations on standard streams like ``stdin`` are not
treated specially and are therefore often not recognized (because these streams
are usually not opened explicitly by the program, and are global variables).
.. _alpha-unix-cstring-BufferOverlap:
alpha.unix.cstring.BufferOverlap (C)
Expand Down
6 changes: 6 additions & 0 deletions clang/include/clang/AST/ASTNodeTraverser.h
Original file line number Diff line number Diff line change
Expand Up @@ -844,6 +844,12 @@ class ASTNodeTraverser
}
}

void VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *E) {
if (E->hasExplicitTemplateArgs())
for (auto Arg : E->template_arguments())
Visit(Arg.getArgument());
}

void VisitRequiresExpr(const RequiresExpr *E) {
for (auto *D : E->getLocalParameters())
Visit(D);
Expand Down
39 changes: 23 additions & 16 deletions clang/include/clang/AST/DeclContextInternals.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,12 @@ class StoredDeclsList {
/// external declarations.
DeclsAndHasExternalTy Data;

template<typename Fn>
void erase_if(Fn ShouldErase) {
template <typename Fn> DeclListNode::Decls *erase_if(Fn ShouldErase) {
Decls List = Data.getPointer();

if (!List)
return;
return nullptr;

ASTContext &C = getASTContext();
DeclListNode::Decls NewHead = nullptr;
DeclListNode::Decls *NewLast = nullptr;
Expand Down Expand Up @@ -79,6 +80,17 @@ class StoredDeclsList {
Data.setPointer(NewHead);

assert(llvm::none_of(getLookupResult(), ShouldErase) && "Still exists!");

if (!Data.getPointer())
// All declarations are erased.
return nullptr;
else if (NewHead.is<NamedDecl *>())
// The list only contains a declaration, the header itself.
return (DeclListNode::Decls *)&Data;
else {
assert(NewLast && NewLast->is<NamedDecl *>() && "Not the tail?");
return NewLast;
}
}

void erase(NamedDecl *ND) {
Expand Down Expand Up @@ -160,12 +172,16 @@ class StoredDeclsList {

void replaceExternalDecls(ArrayRef<NamedDecl*> Decls) {
// Remove all declarations that are either external or are replaced with
// external declarations.
erase_if([Decls](NamedDecl *ND) {
// external declarations with higher visibilities.
DeclListNode::Decls *Tail = erase_if([Decls](NamedDecl *ND) {
if (ND->isFromASTFile())
return true;
// FIXME: Can we get rid of this loop completely?
for (NamedDecl *D : Decls)
if (D->declarationReplaces(ND, /*IsKnownNewer=*/false))
// Only replace the local declaration if the external declaration has
// higher visibilities.
if (D->getModuleOwnershipKind() <= ND->getModuleOwnershipKind() &&
D->declarationReplaces(ND, /*IsKnownNewer=*/false))
return true;
return false;
});
Expand All @@ -185,24 +201,15 @@ class StoredDeclsList {
DeclsAsList = Node;
}

DeclListNode::Decls Head = Data.getPointer();
if (Head.isNull()) {
if (!Data.getPointer()) {
Data.setPointer(DeclsAsList);
return;
}

// Find the end of the existing list.
// FIXME: It would be possible to preserve information from erase_if to
// avoid this rescan looking for the end of the list.
DeclListNode::Decls *Tail = &Head;
while (DeclListNode *Node = Tail->dyn_cast<DeclListNode *>())
Tail = &Node->Rest;

// Append the Decls.
DeclListNode *Node = C.AllocateDeclListNode(Tail->get<NamedDecl *>());
Node->Rest = DeclsAsList;
*Tail = Node;
Data.setPointer(Head);
}

/// Return the list of all the decls.
Expand Down
2 changes: 2 additions & 0 deletions clang/include/clang/AST/ExprCXX.h
Original file line number Diff line number Diff line change
Expand Up @@ -1482,6 +1482,8 @@ class CXXTemporary {
/// const S &s_ref = S(); // Requires a CXXBindTemporaryExpr.
/// }
/// \endcode
///
/// Destructor might be null if destructor declaration is not valid.
class CXXBindTemporaryExpr : public Expr {
CXXTemporary *Temp = nullptr;
Stmt *SubExpr = nullptr;
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/AST/NestedNameSpecifier.h
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ class NestedNameSpecifierLoc {
explicit operator bool() const { return Qualifier; }

/// Evaluates true when this nested-name-specifier location is
/// empty.
/// non-empty.
bool hasQualifier() const { return Qualifier; }

/// Retrieve the nested-name-specifier to which this instance
Expand Down
91 changes: 64 additions & 27 deletions clang/include/clang/AST/OpenACCClause.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,51 +156,50 @@ class OpenACCSelfClause : public OpenACCClauseWithCondition {
Expr *ConditionExpr, SourceLocation EndLoc);
};

/// Represents a clause that has one or more IntExprs. It does not own the
/// IntExprs, but provides 'children' and other accessors.
class OpenACCClauseWithIntExprs : public OpenACCClauseWithParams {
MutableArrayRef<Expr *> IntExprs;
/// Represents a clause that has one or more expressions associated with it.
class OpenACCClauseWithExprs : public OpenACCClauseWithParams {
MutableArrayRef<Expr *> Exprs;

protected:
OpenACCClauseWithIntExprs(OpenACCClauseKind K, SourceLocation BeginLoc,
SourceLocation LParenLoc, SourceLocation EndLoc)
OpenACCClauseWithExprs(OpenACCClauseKind K, SourceLocation BeginLoc,
SourceLocation LParenLoc, SourceLocation EndLoc)
: OpenACCClauseWithParams(K, BeginLoc, LParenLoc, EndLoc) {}

/// Used only for initialization, the leaf class can initialize this to
/// trailing storage.
void setIntExprs(MutableArrayRef<Expr *> NewIntExprs) {
assert(IntExprs.empty() && "Cannot change IntExprs list");
IntExprs = NewIntExprs;
void setExprs(MutableArrayRef<Expr *> NewExprs) {
assert(Exprs.empty() && "Cannot change Exprs list");
Exprs = NewExprs;
}

/// Gets the entire list of integer expressions, but leave it to the
/// Gets the entire list of expressions, but leave it to the
/// individual clauses to expose this how they'd like.
llvm::ArrayRef<Expr *> getIntExprs() const { return IntExprs; }
llvm::ArrayRef<Expr *> getExprs() const { return Exprs; }

public:
child_range children() {
return child_range(reinterpret_cast<Stmt **>(IntExprs.begin()),
reinterpret_cast<Stmt **>(IntExprs.end()));
return child_range(reinterpret_cast<Stmt **>(Exprs.begin()),
reinterpret_cast<Stmt **>(Exprs.end()));
}

const_child_range children() const {
child_range Children =
const_cast<OpenACCClauseWithIntExprs *>(this)->children();
const_cast<OpenACCClauseWithExprs *>(this)->children();
return const_child_range(Children.begin(), Children.end());
}
};

class OpenACCNumGangsClause final
: public OpenACCClauseWithIntExprs,
: public OpenACCClauseWithExprs,
public llvm::TrailingObjects<OpenACCNumGangsClause, Expr *> {

OpenACCNumGangsClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
ArrayRef<Expr *> IntExprs, SourceLocation EndLoc)
: OpenACCClauseWithIntExprs(OpenACCClauseKind::NumGangs, BeginLoc,
LParenLoc, EndLoc) {
: OpenACCClauseWithExprs(OpenACCClauseKind::NumGangs, BeginLoc, LParenLoc,
EndLoc) {
std::uninitialized_copy(IntExprs.begin(), IntExprs.end(),
getTrailingObjects<Expr *>());
setIntExprs(MutableArrayRef(getTrailingObjects<Expr *>(), IntExprs.size()));
setExprs(MutableArrayRef(getTrailingObjects<Expr *>(), IntExprs.size()));
}

public:
Expand All @@ -209,35 +208,35 @@ class OpenACCNumGangsClause final
ArrayRef<Expr *> IntExprs, SourceLocation EndLoc);

llvm::ArrayRef<Expr *> getIntExprs() {
return OpenACCClauseWithIntExprs::getIntExprs();
return OpenACCClauseWithExprs::getExprs();
}

llvm::ArrayRef<Expr *> getIntExprs() const {
return OpenACCClauseWithIntExprs::getIntExprs();
return OpenACCClauseWithExprs::getExprs();
}
};

/// Represents one of a handful of clauses that have a single integer
/// expression.
class OpenACCClauseWithSingleIntExpr : public OpenACCClauseWithIntExprs {
class OpenACCClauseWithSingleIntExpr : public OpenACCClauseWithExprs {
Expr *IntExpr;

protected:
OpenACCClauseWithSingleIntExpr(OpenACCClauseKind K, SourceLocation BeginLoc,
SourceLocation LParenLoc, Expr *IntExpr,
SourceLocation EndLoc)
: OpenACCClauseWithIntExprs(K, BeginLoc, LParenLoc, EndLoc),
: OpenACCClauseWithExprs(K, BeginLoc, LParenLoc, EndLoc),
IntExpr(IntExpr) {
setIntExprs(MutableArrayRef<Expr *>{&this->IntExpr, 1});
setExprs(MutableArrayRef<Expr *>{&this->IntExpr, 1});
}

public:
bool hasIntExpr() const { return !getIntExprs().empty(); }
bool hasIntExpr() const { return !getExprs().empty(); }
const Expr *getIntExpr() const {
return hasIntExpr() ? getIntExprs()[0] : nullptr;
return hasIntExpr() ? getExprs()[0] : nullptr;
}

Expr *getIntExpr() { return hasIntExpr() ? getIntExprs()[0] : nullptr; };
Expr *getIntExpr() { return hasIntExpr() ? getExprs()[0] : nullptr; };
};

class OpenACCNumWorkersClause : public OpenACCClauseWithSingleIntExpr {
Expand All @@ -261,6 +260,40 @@ class OpenACCVectorLengthClause : public OpenACCClauseWithSingleIntExpr {
Expr *IntExpr, SourceLocation EndLoc);
};

/// Represents a clause with one or more 'var' objects, represented as an expr,
/// as its arguments. Var-list is expected to be stored in trailing storage.
/// For now, we're just storing the original expression in its entirety, unlike
/// OMP which has to do a bunch of work to create a private.
class OpenACCClauseWithVarList : public OpenACCClauseWithExprs {
protected:
OpenACCClauseWithVarList(OpenACCClauseKind K, SourceLocation BeginLoc,
SourceLocation LParenLoc, SourceLocation EndLoc)
: OpenACCClauseWithExprs(K, BeginLoc, LParenLoc, EndLoc) {}

public:
ArrayRef<Expr *> getVarList() { return getExprs(); }
ArrayRef<Expr *> getVarList() const { return getExprs(); }
};

class OpenACCPrivateClause final
: public OpenACCClauseWithVarList,
public llvm::TrailingObjects<OpenACCPrivateClause, Expr *> {

OpenACCPrivateClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
ArrayRef<Expr *> VarList, SourceLocation EndLoc)
: OpenACCClauseWithVarList(OpenACCClauseKind::Private, BeginLoc,
LParenLoc, EndLoc) {
std::uninitialized_copy(VarList.begin(), VarList.end(),
getTrailingObjects<Expr *>());
setExprs(MutableArrayRef(getTrailingObjects<Expr *>(), VarList.size()));
}

public:
static OpenACCPrivateClause *
Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
ArrayRef<Expr *> VarList, SourceLocation EndLoc);
};

template <class Impl> class OpenACCClauseVisitor {
Impl &getDerived() { return static_cast<Impl &>(*this); }

Expand Down Expand Up @@ -299,6 +332,9 @@ template <class Impl> class OpenACCClauseVisitor {
class OpenACCClausePrinter final
: public OpenACCClauseVisitor<OpenACCClausePrinter> {
raw_ostream &OS;
const PrintingPolicy &Policy;

void printExpr(const Expr *E);

public:
void VisitClauseList(ArrayRef<const OpenACCClause *> List) {
Expand All @@ -309,7 +345,8 @@ class OpenACCClausePrinter final
OS << ' ';
}
}
OpenACCClausePrinter(raw_ostream &OS) : OS(OS) {}
OpenACCClausePrinter(raw_ostream &OS, const PrintingPolicy &Policy)
: OS(OS), Policy(Policy) {}

#define VISIT_CLAUSE(CLAUSE_NAME) \
void Visit##CLAUSE_NAME##Clause(const OpenACC##CLAUSE_NAME##Clause &Clause);
Expand Down
8 changes: 6 additions & 2 deletions clang/include/clang/AST/Type.h
Original file line number Diff line number Diff line change
Expand Up @@ -480,7 +480,7 @@ class Qualifiers {
}
void removeCVRQualifiers(unsigned mask) {
assert(!(mask & ~CVRMask) && "bitmask contains non-CVR bits");
Mask &= ~mask;
Mask &= ~static_cast<uint64_t>(mask);
}
void removeCVRQualifiers() {
removeCVRQualifiers(CVRMask);
Expand Down Expand Up @@ -609,7 +609,7 @@ class Qualifiers {
}
void removeFastQualifiers(unsigned mask) {
assert(!(mask & ~FastMask) && "bitmask contains non-fast qualifier bits");
Mask &= ~mask;
Mask &= ~static_cast<uint64_t>(mask);
}
void removeFastQualifiers() {
removeFastQualifiers(FastMask);
Expand Down Expand Up @@ -2378,6 +2378,10 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {
/// 'riscv_rvv_vector_bits' type attribute as VectorType.
QualType getRVVEltType(const ASTContext &Ctx) const;

/// Returns the representative type for the element of a sizeless vector
/// builtin type.
QualType getSizelessVectorEltType(const ASTContext &Ctx) const;

/// Types are partitioned into 3 broad categories (C99 6.2.5p1):
/// object types, function types, and incomplete types.

Expand Down
81 changes: 62 additions & 19 deletions clang/include/clang/Basic/Attr.td
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,49 @@ class AttrSubjectMatcherAggregateRule<AttrSubject subject> {

def SubjectMatcherForNamed : AttrSubjectMatcherAggregateRule<Named>;

// Enumeration specifying what kind of behavior should be used for late
// parsing of attributes.
class LateAttrParseKind <int val> {
int Kind = val;
}

// Never late parsed
def LateAttrParseNever : LateAttrParseKind<0>;

// Standard late attribute parsing
//
// This is language dependent. For example:
//
// * For C++ enables late parsing of a declaration attributes
// * For C does not enable late parsing of attributes
//
def LateAttrParseStandard : LateAttrParseKind<1>;

// Experimental extension to standard late attribute parsing
//
// This extension behaves like `LateAttrParseStandard` but allows
// late parsing attributes in more contexts.
//
// In contexts where `LateAttrParseStandard` attributes are late
// parsed, `LateAttrParseExperimentalExt` attributes will also
// be late parsed.
//
// In contexts that only late parse `LateAttrParseExperimentalExt` attributes
// (see `LateParsedAttrList::lateAttrParseExperimentalExtOnly()`)
//
// * If `-fexperimental-late-parse-attributes`
// (`LangOpts.ExperimentalLateParseAttributes`) is enabled the attribute
// will be late parsed.
// * If `-fexperimental-late-parse-attributes`
// (`LangOpts.ExperimentalLateParseAttributes`) is disabled the attribute
// will **not** be late parsed (i.e parsed immediately).
//
// The following contexts are supported:
//
// * TODO: Add contexts here when they are implemented.
//
def LateAttrParseExperimentalExt : LateAttrParseKind<2>;

class Attr {
// The various ways in which an attribute can be spelled in source
list<Spelling> Spellings;
Expand All @@ -603,8 +646,8 @@ class Attr {
list<Accessor> Accessors = [];
// Specify targets for spellings.
list<TargetSpecificSpelling> TargetSpecificSpellings = [];
// Set to true for attributes with arguments which require delayed parsing.
bit LateParsed = 0;
// Specifies the late parsing kind.
LateAttrParseKind LateParsed = LateAttrParseNever;
// Set to false to prevent an attribute from being propagated from a template
// to the instantiation.
bit Clone = 1;
Expand Down Expand Up @@ -3173,7 +3216,7 @@ def DiagnoseIf : InheritableAttr {
BoolArgument<"ArgDependent", 0, /*fake*/ 1>,
DeclArgument<Named, "Parent", 0, /*fake*/ 1>];
let InheritEvenIfAlreadyPresent = 1;
let LateParsed = 1;
let LateParsed = LateAttrParseStandard;
let AdditionalMembers = [{
bool isError() const { return diagnosticType == DT_Error; }
bool isWarning() const { return diagnosticType == DT_Warning; }
Expand Down Expand Up @@ -3211,7 +3254,7 @@ def ObjCRequiresPropertyDefs : InheritableAttr {
def Unused : InheritableAttr {
let Spellings = [CXX11<"", "maybe_unused", 201603>, GCC<"unused">,
C23<"", "maybe_unused", 202106>];
let Subjects = SubjectList<[Var, ObjCIvar, Type, Enum, EnumConstant, Label,
let Subjects = SubjectList<[Var, Binding, ObjCIvar, Type, Enum, EnumConstant, Label,
Field, ObjCMethod, FunctionLike]>;
let Documentation = [WarnMaybeUnusedDocs];
}
Expand Down Expand Up @@ -3472,7 +3515,7 @@ def AssertCapability : InheritableAttr {
let Spellings = [Clang<"assert_capability", 0>,
Clang<"assert_shared_capability", 0>];
let Subjects = SubjectList<[Function]>;
let LateParsed = 1;
let LateParsed = LateAttrParseStandard;
let TemplateDependent = 1;
let ParseArgumentsAsUnevaluated = 1;
let InheritEvenIfAlreadyPresent = 1;
Expand All @@ -3488,7 +3531,7 @@ def AcquireCapability : InheritableAttr {
GNU<"exclusive_lock_function">,
GNU<"shared_lock_function">];
let Subjects = SubjectList<[Function]>;
let LateParsed = 1;
let LateParsed = LateAttrParseStandard;
let TemplateDependent = 1;
let ParseArgumentsAsUnevaluated = 1;
let InheritEvenIfAlreadyPresent = 1;
Expand All @@ -3504,7 +3547,7 @@ def TryAcquireCapability : InheritableAttr {
Clang<"try_acquire_shared_capability", 0>];
let Subjects = SubjectList<[Function],
ErrorDiag>;
let LateParsed = 1;
let LateParsed = LateAttrParseStandard;
let TemplateDependent = 1;
let ParseArgumentsAsUnevaluated = 1;
let InheritEvenIfAlreadyPresent = 1;
Expand All @@ -3520,7 +3563,7 @@ def ReleaseCapability : InheritableAttr {
Clang<"release_generic_capability", 0>,
Clang<"unlock_function", 0>];
let Subjects = SubjectList<[Function]>;
let LateParsed = 1;
let LateParsed = LateAttrParseStandard;
let TemplateDependent = 1;
let ParseArgumentsAsUnevaluated = 1;
let InheritEvenIfAlreadyPresent = 1;
Expand All @@ -3539,7 +3582,7 @@ def RequiresCapability : InheritableAttr {
Clang<"requires_shared_capability", 0>,
Clang<"shared_locks_required", 0>];
let Args = [VariadicExprArgument<"Args">];
let LateParsed = 1;
let LateParsed = LateAttrParseStandard;
let TemplateDependent = 1;
let ParseArgumentsAsUnevaluated = 1;
let InheritEvenIfAlreadyPresent = 1;
Expand All @@ -3559,7 +3602,7 @@ def NoThreadSafetyAnalysis : InheritableAttr {
def GuardedBy : InheritableAttr {
let Spellings = [GNU<"guarded_by">];
let Args = [ExprArgument<"Arg">];
let LateParsed = 1;
let LateParsed = LateAttrParseStandard;
let TemplateDependent = 1;
let ParseArgumentsAsUnevaluated = 1;
let InheritEvenIfAlreadyPresent = 1;
Expand All @@ -3570,7 +3613,7 @@ def GuardedBy : InheritableAttr {
def PtGuardedBy : InheritableAttr {
let Spellings = [GNU<"pt_guarded_by">];
let Args = [ExprArgument<"Arg">];
let LateParsed = 1;
let LateParsed = LateAttrParseStandard;
let TemplateDependent = 1;
let ParseArgumentsAsUnevaluated = 1;
let InheritEvenIfAlreadyPresent = 1;
Expand All @@ -3581,7 +3624,7 @@ def PtGuardedBy : InheritableAttr {
def AcquiredAfter : InheritableAttr {
let Spellings = [GNU<"acquired_after">];
let Args = [VariadicExprArgument<"Args">];
let LateParsed = 1;
let LateParsed = LateAttrParseStandard;
let TemplateDependent = 1;
let ParseArgumentsAsUnevaluated = 1;
let InheritEvenIfAlreadyPresent = 1;
Expand All @@ -3592,7 +3635,7 @@ def AcquiredAfter : InheritableAttr {
def AcquiredBefore : InheritableAttr {
let Spellings = [GNU<"acquired_before">];
let Args = [VariadicExprArgument<"Args">];
let LateParsed = 1;
let LateParsed = LateAttrParseStandard;
let TemplateDependent = 1;
let ParseArgumentsAsUnevaluated = 1;
let InheritEvenIfAlreadyPresent = 1;
Expand All @@ -3603,7 +3646,7 @@ def AcquiredBefore : InheritableAttr {
def AssertExclusiveLock : InheritableAttr {
let Spellings = [GNU<"assert_exclusive_lock">];
let Args = [VariadicExprArgument<"Args">];
let LateParsed = 1;
let LateParsed = LateAttrParseStandard;
let TemplateDependent = 1;
let ParseArgumentsAsUnevaluated = 1;
let InheritEvenIfAlreadyPresent = 1;
Expand All @@ -3614,7 +3657,7 @@ def AssertExclusiveLock : InheritableAttr {
def AssertSharedLock : InheritableAttr {
let Spellings = [GNU<"assert_shared_lock">];
let Args = [VariadicExprArgument<"Args">];
let LateParsed = 1;
let LateParsed = LateAttrParseStandard;
let TemplateDependent = 1;
let ParseArgumentsAsUnevaluated = 1;
let InheritEvenIfAlreadyPresent = 1;
Expand All @@ -3627,7 +3670,7 @@ def AssertSharedLock : InheritableAttr {
def ExclusiveTrylockFunction : InheritableAttr {
let Spellings = [GNU<"exclusive_trylock_function">];
let Args = [ExprArgument<"SuccessValue">, VariadicExprArgument<"Args">];
let LateParsed = 1;
let LateParsed = LateAttrParseStandard;
let TemplateDependent = 1;
let ParseArgumentsAsUnevaluated = 1;
let InheritEvenIfAlreadyPresent = 1;
Expand All @@ -3640,7 +3683,7 @@ def ExclusiveTrylockFunction : InheritableAttr {
def SharedTrylockFunction : InheritableAttr {
let Spellings = [GNU<"shared_trylock_function">];
let Args = [ExprArgument<"SuccessValue">, VariadicExprArgument<"Args">];
let LateParsed = 1;
let LateParsed = LateAttrParseStandard;
let TemplateDependent = 1;
let ParseArgumentsAsUnevaluated = 1;
let InheritEvenIfAlreadyPresent = 1;
Expand All @@ -3651,7 +3694,7 @@ def SharedTrylockFunction : InheritableAttr {
def LockReturned : InheritableAttr {
let Spellings = [GNU<"lock_returned">];
let Args = [ExprArgument<"Arg">];
let LateParsed = 1;
let LateParsed = LateAttrParseStandard;
let TemplateDependent = 1;
let ParseArgumentsAsUnevaluated = 1;
let Subjects = SubjectList<[Function]>;
Expand All @@ -3661,7 +3704,7 @@ def LockReturned : InheritableAttr {
def LocksExcluded : InheritableAttr {
let Spellings = [GNU<"locks_excluded">];
let Args = [VariadicExprArgument<"Args">];
let LateParsed = 1;
let LateParsed = LateAttrParseStandard;
let TemplateDependent = 1;
let ParseArgumentsAsUnevaluated = 1;
let InheritEvenIfAlreadyPresent = 1;
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Basic/DiagnosticInstallAPIKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def err_no_matching_target : Error<"no matching target found for target variant
def err_unsupported_vendor : Error<"vendor '%0' is not supported: '%1'">;
def err_unsupported_environment : Error<"environment '%0' is not supported: '%1'">;
def err_unsupported_os : Error<"os '%0' is not supported: '%1'">;
def err_cannot_read_alias_list : Error<"could not read alias list '%0': %1">;
def err_cannot_read_input_list : Error<"could not read %select{alias list|filelist}0 '%1': %2">;
} // end of command line category.

let CategoryName = "Verification" in {
Expand Down
14 changes: 14 additions & 0 deletions clang/include/clang/Basic/DiagnosticParseKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,15 @@ def ext_decomp_decl_empty : ExtWarn<
"ISO C++17 does not allow a decomposition group to be empty">,
InGroup<DiagGroup<"empty-decomposition">>;

// C++26 structured bindings
def ext_decl_attrs_on_binding : ExtWarn<
"an attribute specifier sequence attached to a structured binding declaration "
"is a C++2c extension">, InGroup<CXX26>;
def warn_cxx23_compat_decl_attrs_on_binding : Warning<
"an attribute specifier sequence attached to a structured binding declaration "
"is incompatible with C++ standards before C++2c">,
InGroup<CXXPre26Compat>, DefaultIgnore;

/// Objective-C parser diagnostics
def err_expected_minus_or_plus : Error<
"method type specifier must start with '-' or '+'">;
Expand Down Expand Up @@ -1429,13 +1438,18 @@ def err_omp_decl_in_declare_simd_variant : Error<
def err_omp_sink_and_source_iteration_not_allowd: Error<" '%0 %select{sink:|source:}1' must be with '%select{omp_cur_iteration - 1|omp_cur_iteration}1'">;
def err_omp_unknown_map_type : Error<
"incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'">;
def err_omp_more_one_map_type : Error<"map type is already specified">;
def note_previous_map_type_specified_here
: Note<"map type '%0' is previous specified here">;
def err_omp_unknown_map_type_modifier : Error<
"incorrect map type modifier, expected one of: 'always', 'close', 'mapper'"
"%select{|, 'present'|, 'present', 'iterator'}0%select{|, 'ompx_hold'}1">;
def err_omp_map_type_missing : Error<
"missing map type">;
def err_omp_map_type_modifier_missing : Error<
"missing map type modifier">;
def err_omp_map_modifier_specification_list : Error<
"empty modifier-specification-list is not allowed">;
def err_omp_declare_simd_inbranch_notinbranch : Error<
"unexpected '%0' clause, '%1' is specified already">;
def err_omp_expected_clause_argument
Expand Down
14 changes: 14 additions & 0 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,8 @@ def err_invalid_vector_long_long_decl_spec : Error <
"POWER7 or later) to be enabled">;
def err_invalid_vector_long_double_decl_spec : Error<
"cannot use 'long double' with '__vector'">;
def err_invalid_vector_complex_decl_spec : Error<
"cannot use '_Complex' with '__vector'">;
def warn_vector_long_decl_spec_combination : Warning<
"Use of 'long' with '__vector' is deprecated">, InGroup<Deprecated>;

Expand Down Expand Up @@ -9901,6 +9903,9 @@ def warn_format_invalid_annotation : Warning<
def warn_format_P_no_precision : Warning<
"using '%%P' format specifier without precision">,
InGroup<Format>;
def warn_format_P_with_objc_pointer : Warning<
"using '%%P' format specifier with an Objective-C pointer results in dumping runtime object structure, not object value">,
InGroup<Format>;
def warn_printf_ignored_flag: Warning<
"flag '%0' is ignored when flag '%1' is present">,
InGroup<Format>;
Expand Down Expand Up @@ -9950,6 +9955,8 @@ def warn_ret_stack_addr_ref : Warning<
def warn_ret_local_temp_addr_ref : Warning<
"returning %select{address of|reference to}0 local temporary object">,
InGroup<ReturnStackAddress>;
def err_ret_local_temp_ref : Error<
"returning reference to local temporary object">;
def warn_ret_addr_label : Warning<
"returning address of label, which is local">,
InGroup<ReturnStackAddress>;
Expand Down Expand Up @@ -10328,9 +10335,13 @@ def err_shufflevector_nonconstant_argument : Error<
def err_shufflevector_argument_too_large : Error<
"index for __builtin_shufflevector must be less than the total number "
"of vector elements">;
def err_shufflevector_minus_one_is_undefined_behavior_constexpr : Error<
"index for __builtin_shufflevector not within the bounds of the input vectors; index of -1 found at position %0 not permitted in a constexpr context.">;

def err_convertvector_non_vector : Error<
"first argument to __builtin_convertvector must be a vector">;
def err_convertvector_constexpr_unsupported_vector_cast : Error<
"unsupported vector cast from %0 to %1 in a constant expression.">;
def err_builtin_non_vector_type : Error<
"%0 argument to %1 must be of vector type">;
def err_convertvector_incompatible_vector : Error<
Expand Down Expand Up @@ -12296,4 +12307,7 @@ def err_acc_num_gangs_num_args
"OpenACC 'num_gangs' "
"%select{|clause: '%1' directive expects maximum of %2, %3 were "
"provided}0">;
def err_acc_not_a_var_ref
: Error<"OpenACC variable is not a valid variable name, sub-array, array "
"element, or composite variable member">;
} // end of sema component.
1 change: 1 addition & 0 deletions clang/include/clang/Basic/LangOptions.def
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ LANGOPT(ExperimentalLibrary, 1, 0, "enable unstable and experimental library fea
LANGOPT(PointerAuthIntrinsics, 1, 0, "pointer authentication intrinsics")

LANGOPT(DoubleSquareBracketAttributes, 1, 0, "'[[]]' attributes extension for all language standard modes")
LANGOPT(ExperimentalLateParseAttributes, 1, 0, "experimental late parsing of attributes")

COMPATIBLE_LANGOPT(RecoveryAST, 1, 1, "Preserve expressions in AST when encountering errors")
COMPATIBLE_LANGOPT(RecoveryASTType, 1, 1, "Preserve the type in recovery expressions")
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Basic/OpenACCClauses.def
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ VISIT_CLAUSE(If)
VISIT_CLAUSE(Self)
VISIT_CLAUSE(NumGangs)
VISIT_CLAUSE(NumWorkers)
VISIT_CLAUSE(Private)
VISIT_CLAUSE(VectorLength)

#undef VISIT_CLAUSE
2 changes: 1 addition & 1 deletion clang/include/clang/Basic/arm_neon.td
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ def OP_VCVT_BF16_F32_HI_A32
(call "vget_low", $p0))>;

def OP_CVT_F32_BF16
: Op<(bitcast "R", (op "<<", (bitcast "int32_t", $p0),
: Op<(bitcast "R", (op "<<", (cast "int32_t", (bitcast "int16_t", $p0)),
(literal "int32_t", "16")))>;

//===----------------------------------------------------------------------===//
Expand Down
34 changes: 24 additions & 10 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -603,7 +603,6 @@ class MarshallingInfoVisibility<KeyPathAndMacro kpm, code default>
// Key paths that are constant during parsing of options with the same key path prefix.
defvar cplusplus = LangOpts<"CPlusPlus">;
defvar cpp11 = LangOpts<"CPlusPlus11">;
defvar cpp14 = LangOpts<"CPlusPlus14">;
defvar cpp17 = LangOpts<"CPlusPlus17">;
defvar cpp20 = LangOpts<"CPlusPlus20">;
defvar c99 = LangOpts<"C99">;
Expand Down Expand Up @@ -1609,6 +1608,13 @@ defm double_square_bracket_attributes : BoolFOption<"double-square-bracket-attri
LangOpts<"DoubleSquareBracketAttributes">, DefaultTrue, PosFlag<SetTrue>,
NegFlag<SetFalse>>;

defm experimental_late_parse_attributes : BoolFOption<"experimental-late-parse-attributes",
LangOpts<"ExperimentalLateParseAttributes">, DefaultFalse,
PosFlag<SetTrue, [], [ClangOption], "Enable">,
NegFlag<SetFalse, [], [ClangOption], "Disable">,
BothFlags<[], [ClangOption, CC1Option],
" experimental late parsing of attributes">>;

defm autolink : BoolFOption<"autolink",
CodeGenOpts<"Autolink">, DefaultTrue,
NegFlag<SetFalse, [], [ClangOption, CC1Option],
Expand Down Expand Up @@ -2887,6 +2893,17 @@ def flax_vector_conversions : Flag<["-"], "flax-vector-conversions">, Group<f_Gr
def flimited_precision_EQ : Joined<["-"], "flimited-precision=">, Group<f_Group>;
def fapple_link_rtlib : Flag<["-"], "fapple-link-rtlib">, Group<f_Group>,
HelpText<"Force linking the clang builtins runtime library">;

/// ClangIR-specific options - BEGIN
defm clangir : BoolFOption<"clangir",
FrontendOpts<"UseClangIRPipeline">, DefaultFalse,
PosFlag<SetTrue, [], [ClangOption, CC1Option], "Use the ClangIR pipeline to compile">,
NegFlag<SetFalse, [], [ClangOption, CC1Option], "Use the AST -> LLVM pipeline to compile">,
BothFlags<[], [ClangOption, CC1Option], "">>;
def emit_cir : Flag<["-"], "emit-cir">, Visibility<[CC1Option]>,
Group<Action_Group>, HelpText<"Build ASTs and then lower to ClangIR">;
/// ClangIR-specific options - END

def flto_EQ : Joined<["-"], "flto=">,
Visibility<[ClangOption, CLOption, CC1Option, FC1Option, FlangOption]>,
Group<f_Group>,
Expand Down Expand Up @@ -3371,9 +3388,10 @@ defm relaxed_template_template_args : BoolFOption<"relaxed-template-template-arg
"Enable C++17 relaxed template template argument matching">,
NegFlag<SetFalse>>;
defm sized_deallocation : BoolFOption<"sized-deallocation",
LangOpts<"SizedDeallocation">, Default<cpp14.KeyPath>,
PosFlag<SetTrue, [], [], "Enable C++14 sized global deallocation functions">,
NegFlag<SetFalse>, BothFlags<[], [ClangOption, CC1Option]>>;
LangOpts<"SizedDeallocation">, DefaultFalse,
PosFlag<SetTrue, [], [ClangOption, CC1Option],
"Enable C++14 sized global deallocation functions">,
NegFlag<SetFalse>>;
defm aligned_allocation : BoolFOption<"aligned-allocation",
LangOpts<"AlignedAllocation">, Default<cpp17.KeyPath>,
PosFlag<SetTrue, [], [ClangOption], "Enable C++17 aligned allocation functions">,
Expand Down Expand Up @@ -4881,6 +4899,8 @@ def msimd128 : Flag<["-"], "msimd128">, Group<m_wasm_Features_Group>;
def mno_simd128 : Flag<["-"], "mno-simd128">, Group<m_wasm_Features_Group>;
def mrelaxed_simd : Flag<["-"], "mrelaxed-simd">, Group<m_wasm_Features_Group>;
def mno_relaxed_simd : Flag<["-"], "mno-relaxed-simd">, Group<m_wasm_Features_Group>;
def mhalf_precision : Flag<["-"], "mhalf-precision">, Group<m_wasm_Features_Group>;
def mno_half_precision : Flag<["-"], "mno-half-precision">, Group<m_wasm_Features_Group>;
def mnontrapping_fptoint : Flag<["-"], "mnontrapping-fptoint">, Group<m_wasm_Features_Group>;
def mno_nontrapping_fptoint : Flag<["-"], "mno-nontrapping-fptoint">, Group<m_wasm_Features_Group>;
def msign_ext : Flag<["-"], "msign-ext">, Group<m_wasm_Features_Group>;
Expand Down Expand Up @@ -6587,12 +6607,6 @@ def J : JoinedOrSeparate<["-"], "J">,
Group<gfortran_Group>,
Alias<module_dir>;

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

//===----------------------------------------------------------------------===//
// FC1 Options
//===----------------------------------------------------------------------===//
Expand Down
9 changes: 8 additions & 1 deletion clang/include/clang/Frontend/FrontendOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ enum ActionKind {
/// Translate input source into HTML.
EmitHTML,

/// Emit a .cir file
EmitCIR,

/// Emit a .ll file.
EmitLLVM,

Expand Down Expand Up @@ -408,6 +411,10 @@ class FrontendOptions {
LLVM_PREFERRED_TYPE(bool)
unsigned GenReducedBMI : 1;

/// Use Clang IR pipeline to emit code
LLVM_PREFERRED_TYPE(bool)
unsigned UseClangIRPipeline : 1;

CodeCompleteOptions CodeCompleteOpts;

/// Specifies the output format of the AST.
Expand Down Expand Up @@ -590,7 +597,7 @@ class FrontendOptions {
EmitSymbolGraph(false), EmitExtensionSymbolGraphs(false),
EmitSymbolGraphSymbolLabelsForTesting(false),
EmitPrettySymbolGraphs(false), GenReducedBMI(false),
TimeTraceGranularity(500) {}
UseClangIRPipeline(false), TimeTraceGranularity(500) {}

/// getInputKindForExtension - Return the appropriate input kind for a file
/// extension. For example, "c" would return Language::C.
Expand Down
3 changes: 2 additions & 1 deletion clang/include/clang/InstallAPI/FileList.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,10 @@ class FileListReader {
///
/// \param InputBuffer JSON input data.
/// \param Destination Container to load headers into.
/// \param FM Optional File Manager to validate input files exist.
static llvm::Error
loadHeaders(std::unique_ptr<llvm::MemoryBuffer> InputBuffer,
HeaderSeq &Destination);
HeaderSeq &Destination, clang::FileManager *FM = nullptr);

FileListReader() = delete;
};
Expand Down
22 changes: 16 additions & 6 deletions clang/include/clang/Parse/Parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -1398,12 +1398,21 @@ class Parser : public CodeCompletionHandler {
// A list of late-parsed attributes. Used by ParseGNUAttributes.
class LateParsedAttrList: public SmallVector<LateParsedAttribute *, 2> {
public:
LateParsedAttrList(bool PSoon = false) : ParseSoon(PSoon) { }
LateParsedAttrList(bool PSoon = false,
bool LateAttrParseExperimentalExtOnly = false)
: ParseSoon(PSoon),
LateAttrParseExperimentalExtOnly(LateAttrParseExperimentalExtOnly) {}

bool parseSoon() { return ParseSoon; }
/// returns true iff the attribute to be parsed should only be late parsed
/// if it is annotated with `LateAttrParseExperimentalExt`
bool lateAttrParseExperimentalExtOnly() {
return LateAttrParseExperimentalExtOnly;
}

private:
bool ParseSoon; // Are we planning to parse these shortly after creation?
bool ParseSoon; // Are we planning to parse these shortly after creation?
bool LateAttrParseExperimentalExtOnly;
};

/// Contains the lexed tokens of a member function definition
Expand Down Expand Up @@ -3645,11 +3654,12 @@ class Parser : public CodeCompletionHandler {
ExprResult ParseOpenACCIDExpression();
/// Parses the variable list for the `cache` construct.
void ParseOpenACCCacheVarList();

using OpenACCVarParseResult = std::pair<ExprResult, OpenACCParseCanContinue>;
/// Parses a single variable in a variable list for OpenACC.
bool ParseOpenACCVar();
/// Parses the variable list for the variety of clauses that take a var-list,
/// including the optional Special Token listed for some,based on clause type.
bool ParseOpenACCClauseVarList(OpenACCClauseKind Kind);
OpenACCVarParseResult ParseOpenACCVar();
/// Parses the variable list for the variety of places that take a var-list.
llvm::SmallVector<Expr *> ParseOpenACCVarList();
/// Parses any parameters for an OpenACC Clause, including required/optional
/// parens.
OpenACCClauseParseResult
Expand Down
18 changes: 10 additions & 8 deletions clang/include/clang/Sema/DeclSpec.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
#include <optional>

namespace clang {
class ASTContext;
Expand Down Expand Up @@ -1790,6 +1791,7 @@ class DecompositionDeclarator {
struct Binding {
IdentifierInfo *Name;
SourceLocation NameLoc;
std::optional<ParsedAttributes> Attrs;
};

private:
Expand All @@ -1809,15 +1811,15 @@ class DecompositionDeclarator {
: Bindings(nullptr), NumBindings(0), DeleteBindings(false) {}
DecompositionDeclarator(const DecompositionDeclarator &G) = delete;
DecompositionDeclarator &operator=(const DecompositionDeclarator &G) = delete;
~DecompositionDeclarator() {
if (DeleteBindings)
delete[] Bindings;
}
~DecompositionDeclarator() { clear(); }

void clear() {
LSquareLoc = RSquareLoc = SourceLocation();
if (DeleteBindings)
delete[] Bindings;
else
llvm::for_each(llvm::MutableArrayRef(Bindings, NumBindings),
[](Binding &B) { B.Attrs.reset(); });
Bindings = nullptr;
NumBindings = 0;
DeleteBindings = false;
Expand Down Expand Up @@ -2339,10 +2341,10 @@ class Declarator {
}

/// Set the decomposition bindings for this declarator.
void
setDecompositionBindings(SourceLocation LSquareLoc,
ArrayRef<DecompositionDeclarator::Binding> Bindings,
SourceLocation RSquareLoc);
void setDecompositionBindings(
SourceLocation LSquareLoc,
MutableArrayRef<DecompositionDeclarator::Binding> Bindings,
SourceLocation RSquareLoc);

/// AddTypeInfo - Add a chunk to this declarator. Also extend the range to
/// EndLoc, which should be the last token of the chunk.
Expand Down
4 changes: 3 additions & 1 deletion clang/include/clang/Sema/Lookup.h
Original file line number Diff line number Diff line change
Expand Up @@ -499,7 +499,9 @@ class LookupResult {
/// Note that while no result was found in the current instantiation,
/// there were dependent base classes that could not be searched.
void setNotFoundInCurrentInstantiation() {
assert(ResultKind == NotFound && Decls.empty());
assert((ResultKind == NotFound ||
ResultKind == NotFoundInCurrentInstantiation) &&
Decls.empty());
ResultKind = NotFoundInCurrentInstantiation;
}

Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Sema/ParsedAttr.h
Original file line number Diff line number Diff line change
Expand Up @@ -948,6 +948,7 @@ class ParsedAttributes : public ParsedAttributesView {
ParsedAttributes(AttributeFactory &factory) : pool(factory) {}
ParsedAttributes(const ParsedAttributes &) = delete;
ParsedAttributes &operator=(const ParsedAttributes &) = delete;
ParsedAttributes(ParsedAttributes &&G) = default;

AttributePool &getPool() const { return pool; }

Expand Down
40 changes: 19 additions & 21 deletions clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -4097,12 +4097,12 @@ class Sema final : public SemaBase {
SmallVectorImpl<QualType> &Exceptions,
FunctionProtoType::ExceptionSpecInfo &ESI);

/// Add an exception-specification to the given member function
/// (or member function template). The exception-specification was parsed
/// after the method itself was declared.
/// Add an exception-specification to the given member or friend function
/// (or function template). The exception-specification was parsed
/// after the function itself was declared.
void actOnDelayedExceptionSpecification(
Decl *Method, ExceptionSpecificationType EST,
SourceRange SpecificationRange, ArrayRef<ParsedType> DynamicExceptions,
Decl *D, ExceptionSpecificationType EST, SourceRange SpecificationRange,
ArrayRef<ParsedType> DynamicExceptions,
ArrayRef<SourceRange> DynamicExceptionRanges, Expr *NoexceptExpr);

class InheritedConstructorInfo;
Expand Down Expand Up @@ -6978,12 +6978,6 @@ class Sema final : public SemaBase {
SourceLocation TemplateKWLoc,
UnqualifiedId &Member, Decl *ObjCImpDecl);

MemberExpr *BuildMemberExpr(
Expr *Base, bool IsArrow, SourceLocation OpLoc, const CXXScopeSpec *SS,
SourceLocation TemplateKWLoc, ValueDecl *Member, DeclAccessPair FoundDecl,
bool HadMultipleCandidates, const DeclarationNameInfo &MemberNameInfo,
QualType Ty, ExprValueKind VK, ExprObjectKind OK,
const TemplateArgumentListInfo *TemplateArgs = nullptr);
MemberExpr *
BuildMemberExpr(Expr *Base, bool IsArrow, SourceLocation OpLoc,
NestedNameSpecifierLoc NNS, SourceLocation TemplateKWLoc,
Expand Down Expand Up @@ -7472,7 +7466,7 @@ class Sema final : public SemaBase {
bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx,
CXXScopeSpec &SS);
bool LookupParsedName(LookupResult &R, Scope *S, CXXScopeSpec *SS,
bool AllowBuiltinCreation = false,
QualType ObjectType, bool AllowBuiltinCreation = false,
bool EnteringContext = false);
ObjCProtocolDecl *LookupProtocol(
IdentifierInfo *II, SourceLocation IdLoc,
Expand Down Expand Up @@ -8881,11 +8875,13 @@ class Sema final : public SemaBase {
/// functions (but no function templates).
FoundFunctions,
};
bool LookupTemplateName(
LookupResult &R, Scope *S, CXXScopeSpec &SS, QualType ObjectType,
bool EnteringContext, bool &MemberOfUnknownSpecialization,
RequiredTemplateKind RequiredTemplate = SourceLocation(),
AssumedTemplateKind *ATK = nullptr, bool AllowTypoCorrection = true);

bool
LookupTemplateName(LookupResult &R, Scope *S, CXXScopeSpec &SS,
QualType ObjectType, bool EnteringContext,
RequiredTemplateKind RequiredTemplate = SourceLocation(),
AssumedTemplateKind *ATK = nullptr,
bool AllowTypoCorrection = true);

TemplateNameKind isTemplateName(Scope *S, CXXScopeSpec &SS,
bool hasTemplateKeyword,
Expand Down Expand Up @@ -9249,7 +9245,8 @@ class Sema final : public SemaBase {
void NoteTemplateParameterLocation(const NamedDecl &Decl);

ExprResult BuildExpressionFromDeclTemplateArgument(
const TemplateArgument &Arg, QualType ParamType, SourceLocation Loc);
const TemplateArgument &Arg, QualType ParamType, SourceLocation Loc,
NamedDecl *TemplateParam = nullptr);
ExprResult
BuildExpressionFromNonTypeTemplateArgument(const TemplateArgument &Arg,
SourceLocation Loc);
Expand Down Expand Up @@ -9572,9 +9569,10 @@ class Sema final : public SemaBase {

bool isSameOrCompatibleFunctionType(QualType Param, QualType Arg);

TemplateArgumentLoc getTrivialTemplateArgumentLoc(const TemplateArgument &Arg,
QualType NTTPType,
SourceLocation Loc);
TemplateArgumentLoc
getTrivialTemplateArgumentLoc(const TemplateArgument &Arg, QualType NTTPType,
SourceLocation Loc,
NamedDecl *TemplateParam = nullptr);

/// Get a template argument mapping the given template parameter to itself,
/// e.g. for X in \c template<int X>, this would return an expression template
Expand Down
34 changes: 32 additions & 2 deletions clang/include/clang/Sema/SemaOpenACC.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,12 @@ class SemaOpenACC : public SemaBase {
SmallVector<Expr *> IntExprs;
};

struct VarListDetails {
SmallVector<Expr *> VarList;
};

std::variant<std::monostate, DefaultDetails, ConditionDetails,
IntExprDetails>
IntExprDetails, VarListDetails>
Details = std::monostate{};

public:
Expand Down Expand Up @@ -112,6 +116,16 @@ class SemaOpenACC : public SemaBase {
return const_cast<OpenACCParsedClause *>(this)->getIntExprs();
}

ArrayRef<Expr *> getVarList() {
assert(ClauseKind == OpenACCClauseKind::Private &&
"Parsed clause kind does not have a var-list");
return std::get<VarListDetails>(Details).VarList;
}

ArrayRef<Expr *> getVarList() const {
return const_cast<OpenACCParsedClause *>(this)->getVarList();
}

void setLParenLoc(SourceLocation EndLoc) { LParenLoc = EndLoc; }
void setEndLoc(SourceLocation EndLoc) { ClauseRange.setEnd(EndLoc); }

Expand Down Expand Up @@ -147,7 +161,19 @@ class SemaOpenACC : public SemaBase {
ClauseKind == OpenACCClauseKind::NumWorkers ||
ClauseKind == OpenACCClauseKind::VectorLength) &&
"Parsed clause kind does not have a int exprs");
Details = IntExprDetails{IntExprs};
Details = IntExprDetails{std::move(IntExprs)};
}

void setVarListDetails(ArrayRef<Expr *> VarList) {
assert(ClauseKind == OpenACCClauseKind::Private &&
"Parsed clause kind does not have a var-list");
Details = VarListDetails{{VarList.begin(), VarList.end()}};
}

void setVarListDetails(llvm::SmallVector<Expr *> &&VarList) {
assert(ClauseKind == OpenACCClauseKind::Private &&
"Parsed clause kind does not have a var-list");
Details = VarListDetails{std::move(VarList)};
}
};

Expand Down Expand Up @@ -194,6 +220,10 @@ class SemaOpenACC : public SemaBase {
ExprResult ActOnIntExpr(OpenACCDirectiveKind DK, OpenACCClauseKind CK,
SourceLocation Loc, Expr *IntExpr);

/// Called when encountering a 'var' for OpenACC, ensures it is actually a
/// declaration reference to a variable of the correct type.
ExprResult ActOnVar(Expr *VarExpr);

/// Checks and creates an Array Section used in an OpenACC construct/clause.
ExprResult ActOnArraySectionExpr(Expr *Base, SourceLocation LBLoc,
Expr *LowerBound,
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Serialization/ASTRecordReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,9 @@ class ASTRecordReader
/// Read an OpenMP children, advancing Idx.
void readOMPChildren(OMPChildren *Data);

/// Read a list of Exprs used for a var-list.
llvm::SmallVector<Expr *> readOpenACCVarList();

/// Read an OpenACC clause, advancing Idx.
OpenACCClause *readOpenACCClause();

Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Serialization/ASTRecordWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#define LLVM_CLANG_SERIALIZATION_ASTRECORDWRITER_H

#include "clang/AST/AbstractBasicWriter.h"
#include "clang/AST/OpenACCClause.h"
#include "clang/AST/OpenMPClause.h"
#include "clang/Serialization/ASTWriter.h"
#include "clang/Serialization/SourceLocationEncoding.h"
Expand Down Expand Up @@ -293,6 +294,8 @@ class ASTRecordWriter
/// Writes data related to the OpenMP directives.
void writeOMPChildren(OMPChildren *Data);

void writeOpenACCVarList(const OpenACCClauseWithVarList *C);

/// Writes out a single OpenACC Clause.
void writeOpenACCClause(const OpenACCClause *C);

Expand Down
35 changes: 32 additions & 3 deletions clang/include/clang/Serialization/ASTWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ class StoredDeclsList;
class SwitchCase;
class Token;

namespace SrcMgr {
class FileInfo;
} // namespace SrcMgr

/// Writes an AST file containing the contents of a translation unit.
///
/// The ASTWriter class produces a bitstream containing the serialized
Expand Down Expand Up @@ -490,6 +494,11 @@ class ASTWriter : public ASTDeserializationListener,
/// during \c SourceManager serialization.
void computeNonAffectingInputFiles();

/// Some affecting files can be included from files that are not affecting.
/// This function erases source locations pointing into such files.
SourceLocation getAffectingIncludeLoc(const SourceManager &SourceMgr,
const SrcMgr::FileInfo &File);

/// Returns an adjusted \c FileID, accounting for any non-affecting input
/// files.
FileID getAdjustedFileID(FileID FID) const;
Expand Down Expand Up @@ -525,6 +534,7 @@ class ASTWriter : public ASTDeserializationListener,

/// Calculate hash of the pcm content.
std::pair<ASTFileSignature, ASTFileSignature> createSignature() const;
ASTFileSignature createSignatureForNamedModule() const;

void WriteInputFiles(SourceManager &SourceMgr, HeaderSearchOptions &HSOpts);
void WriteSourceManagerBlock(SourceManager &SourceMgr,
Expand Down Expand Up @@ -885,6 +895,8 @@ class ASTWriter : public ASTDeserializationListener,
/// AST and semantic-analysis consumer that generates a
/// precompiled header from the parsed source code.
class PCHGenerator : public SemaConsumer {
void anchor() override;

Preprocessor &PP;
std::string OutputFile;
std::string isysroot;
Expand Down Expand Up @@ -928,17 +940,34 @@ class PCHGenerator : public SemaConsumer {
bool hasEmittedPCH() const { return Buffer->IsComplete; }
};

class ReducedBMIGenerator : public PCHGenerator {
class CXX20ModulesGenerator : public PCHGenerator {
void anchor() override;

protected:
virtual Module *getEmittingModule(ASTContext &Ctx) override;

CXX20ModulesGenerator(Preprocessor &PP, InMemoryModuleCache &ModuleCache,
StringRef OutputFile, bool GeneratingReducedBMI);

public:
ReducedBMIGenerator(Preprocessor &PP, InMemoryModuleCache &ModuleCache,
StringRef OutputFile);
CXX20ModulesGenerator(Preprocessor &PP, InMemoryModuleCache &ModuleCache,
StringRef OutputFile)
: CXX20ModulesGenerator(PP, ModuleCache, OutputFile,
/*GeneratingReducedBMI=*/false) {}

void HandleTranslationUnit(ASTContext &Ctx) override;
};

class ReducedBMIGenerator : public CXX20ModulesGenerator {
void anchor() override;

public:
ReducedBMIGenerator(Preprocessor &PP, InMemoryModuleCache &ModuleCache,
StringRef OutputFile)
: CXX20ModulesGenerator(PP, ModuleCache, OutputFile,
/*GeneratingReducedBMI=*/true) {}
};

/// If we can elide the definition of \param D in reduced BMI.
///
/// Generally, we can elide the definition of a declaration if it won't affect
Expand Down
31 changes: 16 additions & 15 deletions clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
Original file line number Diff line number Diff line change
Expand Up @@ -563,6 +563,20 @@ def MismatchedDeallocatorChecker : Checker<"MismatchedDeallocator">,
Dependencies<[DynamicMemoryModeling]>,
Documentation<HasDocumentation>;

// This must appear before StdCLibraryFunctionsChecker because a dependency.
def StreamChecker : Checker<"Stream">,
HelpText<"Check stream handling functions">,
WeakDependencies<[NonNullParamChecker]>,
CheckerOptions<[
CmdLineOption<Boolean,
"Pedantic",
"If false, assume that stream operations which are often not "
"checked for error do not fail.",
"false",
InAlpha>
]>,
Documentation<HasDocumentation>;

def StdCLibraryFunctionsChecker : Checker<"StdCLibraryFunctions">,
HelpText<"Check for invalid arguments of C standard library functions, "
"and apply relations between arguments and return value">,
Expand All @@ -581,7 +595,7 @@ def StdCLibraryFunctionsChecker : Checker<"StdCLibraryFunctions">,
"true",
InAlpha>
]>,
WeakDependencies<[CallAndMessageChecker, NonNullParamChecker]>,
WeakDependencies<[CallAndMessageChecker, NonNullParamChecker, StreamChecker]>,
Documentation<HasDocumentation>;

def VforkChecker : Checker<"Vfork">,
Expand All @@ -601,20 +615,6 @@ def PthreadLockChecker : Checker<"PthreadLock">,
Dependencies<[PthreadLockBase]>,
Documentation<HasDocumentation>;

def StreamChecker : Checker<"Stream">,
HelpText<"Check stream handling functions">,
WeakDependencies<[NonNullParamChecker]>,
CheckerOptions<[
CmdLineOption<Boolean,
"Pedantic",
"If false, assume that stream operations which are often not "
"checked for error do not fail."
"fail.",
"false",
InAlpha>
]>,
Documentation<HasDocumentation>;

def SimpleStreamChecker : Checker<"SimpleStream">,
HelpText<"Check for misuses of stream APIs">,
Documentation<HasDocumentation>;
Expand Down Expand Up @@ -1628,6 +1628,7 @@ def TaintTesterChecker : Checker<"TaintTest">,
def StreamTesterChecker : Checker<"StreamTester">,
HelpText<"Add test functions to StreamChecker for test and debugging "
"purposes.">,
WeakDependencies<[StreamChecker]>,
Documentation<NotDocumented>;

def ErrnoTesterChecker : Checker<"ErrnoTest">,
Expand Down
15 changes: 10 additions & 5 deletions clang/include/clang/Tooling/CommonOptionsParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,17 +49,22 @@ namespace tooling {
/// using namespace clang::tooling;
/// using namespace llvm;
///
/// static cl::OptionCategory MyToolCategory("My tool options");
/// static cl::OptionCategory MyToolCategory("my-tool options");
/// static cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage);
/// static cl::extrahelp MoreHelp("\nMore help text...\n");
/// static cl::opt<bool> YourOwnOption(...);
/// ...
///
/// int main(int argc, const char **argv) {
/// CommonOptionsParser OptionsParser(argc, argv, MyToolCategory);
/// auto ExpectedParser =
/// CommonOptionsParser::create(argc, argv, MyToolCategory);
/// if (!ExpectedParser) {
/// llvm::errs() << ExpectedParser.takeError();
/// return 1;
/// }
/// CommonOptionsParser& OptionsParser = ExpectedParser.get();
/// ClangTool Tool(OptionsParser.getCompilations(),
/// OptionsParser.getSourcePathList());
/// return Tool.run(newFrontendActionFactory<SyntaxOnlyAction>().get());
/// return Tool.run(
/// newFrontendActionFactory<clang::SyntaxOnlyAction>().get());
/// }
/// \endcode
class CommonOptionsParser {
Expand Down
Loading