354 changes: 177 additions & 177 deletions clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp

Large diffs are not rendered by default.

17 changes: 8 additions & 9 deletions clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,13 +93,12 @@ void ConstCorrectnessCheck::registerMatchers(MatchFinder *Finder) {
// shall be run.
const auto FunctionScope =
functionDecl(
hasBody(
compoundStmt(forEachDescendant(
declStmt(containsAnyDeclaration(
LocalValDecl.bind("local-value")),
unless(has(decompositionDecl())))
.bind("decl-stmt")))
.bind("scope")))
hasBody(stmt(forEachDescendant(
declStmt(containsAnyDeclaration(
LocalValDecl.bind("local-value")),
unless(has(decompositionDecl())))
.bind("decl-stmt")))
.bind("scope")))
.bind("function-decl");

Finder->addMatcher(FunctionScope, this);
Expand All @@ -109,7 +108,7 @@ void ConstCorrectnessCheck::registerMatchers(MatchFinder *Finder) {
enum class VariableCategory { Value, Reference, Pointer };

void ConstCorrectnessCheck::check(const MatchFinder::MatchResult &Result) {
const auto *LocalScope = Result.Nodes.getNodeAs<CompoundStmt>("scope");
const auto *LocalScope = Result.Nodes.getNodeAs<Stmt>("scope");
const auto *Variable = Result.Nodes.getNodeAs<VarDecl>("local-value");
const auto *Function = Result.Nodes.getNodeAs<FunctionDecl>("function-decl");

Expand Down Expand Up @@ -198,7 +197,7 @@ void ConstCorrectnessCheck::check(const MatchFinder::MatchResult &Result) {
}
}

void ConstCorrectnessCheck::registerScope(const CompoundStmt *LocalScope,
void ConstCorrectnessCheck::registerScope(const Stmt *LocalScope,
ASTContext *Context) {
auto &Analyzer = ScopesCache[LocalScope];
if (!Analyzer)
Expand Down
4 changes: 2 additions & 2 deletions clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@ class ConstCorrectnessCheck : public ClangTidyCheck {
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;

private:
void registerScope(const CompoundStmt *LocalScope, ASTContext *Context);
void registerScope(const Stmt *LocalScope, ASTContext *Context);

using MutationAnalyzer = std::unique_ptr<ExprMutationAnalyzer>;
llvm::DenseMap<const CompoundStmt *, MutationAnalyzer> ScopesCache;
llvm::DenseMap<const Stmt *, MutationAnalyzer> ScopesCache;
llvm::DenseSet<SourceLocation> TemplateDiagnosticsCache;

const bool AnalyzeValues;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,65 +119,72 @@ void UnnecessaryValueParamCheck::check(const MatchFinder::MatchResult &Result) {
}
}

const size_t Index = llvm::find(Function->parameters(), Param) -
Function->parameters().begin();
handleConstRefFix(*Function, *Param, *Result.Context);
}

void UnnecessaryValueParamCheck::registerPPCallbacks(
const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
Inserter.registerPreprocessor(PP);
}

void UnnecessaryValueParamCheck::storeOptions(
ClangTidyOptions::OptionMap &Opts) {
Options.store(Opts, "IncludeStyle", Inserter.getStyle());
Options.store(Opts, "AllowedTypes",
utils::options::serializeStringList(AllowedTypes));
}

void UnnecessaryValueParamCheck::onEndOfTranslationUnit() {
MutationAnalyzerCache.clear();
}

void UnnecessaryValueParamCheck::handleConstRefFix(const FunctionDecl &Function,
const ParmVarDecl &Param,
ASTContext &Context) {
const size_t Index =
llvm::find(Function.parameters(), &Param) - Function.parameters().begin();
const bool IsConstQualified =
Param.getType().getCanonicalType().isConstQualified();

auto Diag =
diag(Param->getLocation(),
diag(Param.getLocation(),
"the %select{|const qualified }0parameter %1 is copied for each "
"invocation%select{ but only used as a const reference|}0; consider "
"making it a %select{const |}0reference")
<< IsConstQualified << paramNameOrIndex(Param->getName(), Index);
<< IsConstQualified << paramNameOrIndex(Param.getName(), Index);
// Do not propose fixes when:
// 1. the ParmVarDecl is in a macro, since we cannot place them correctly
// 2. the function is virtual as it might break overrides
// 3. the function is referenced outside of a call expression within the
// compilation unit as the signature change could introduce build errors.
// 4. the function is an explicit template/ specialization.
const auto *Method = llvm::dyn_cast<CXXMethodDecl>(Function);
if (Param->getBeginLoc().isMacroID() || (Method && Method->isVirtual()) ||
isReferencedOutsideOfCallExpr(*Function, *Result.Context) ||
Function->getTemplateSpecializationKind() == TSK_ExplicitSpecialization)
const auto *Method = llvm::dyn_cast<CXXMethodDecl>(&Function);
if (Param.getBeginLoc().isMacroID() || (Method && Method->isVirtual()) ||
isReferencedOutsideOfCallExpr(Function, Context) ||
Function.getTemplateSpecializationKind() == TSK_ExplicitSpecialization)
return;
for (const auto *FunctionDecl = Function; FunctionDecl != nullptr;
for (const auto *FunctionDecl = &Function; FunctionDecl != nullptr;
FunctionDecl = FunctionDecl->getPreviousDecl()) {
const auto &CurrentParam = *FunctionDecl->getParamDecl(Index);
Diag << utils::fixit::changeVarDeclToReference(CurrentParam,
*Result.Context);
Diag << utils::fixit::changeVarDeclToReference(CurrentParam, Context);
// The parameter of each declaration needs to be checked individually as to
// whether it is const or not as constness can differ between definition and
// declaration.
if (!CurrentParam.getType().getCanonicalType().isConstQualified()) {
if (std::optional<FixItHint> Fix = utils::fixit::addQualifierToVarDecl(
CurrentParam, *Result.Context, DeclSpec::TQ::TQ_const))
CurrentParam, Context, DeclSpec::TQ::TQ_const))
Diag << *Fix;
}
}
}

void UnnecessaryValueParamCheck::registerPPCallbacks(
const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
Inserter.registerPreprocessor(PP);
}

void UnnecessaryValueParamCheck::storeOptions(
ClangTidyOptions::OptionMap &Opts) {
Options.store(Opts, "IncludeStyle", Inserter.getStyle());
Options.store(Opts, "AllowedTypes",
utils::options::serializeStringList(AllowedTypes));
}

void UnnecessaryValueParamCheck::onEndOfTranslationUnit() {
MutationAnalyzerCache.clear();
}

void UnnecessaryValueParamCheck::handleMoveFix(const ParmVarDecl &Var,
void UnnecessaryValueParamCheck::handleMoveFix(const ParmVarDecl &Param,
const DeclRefExpr &CopyArgument,
const ASTContext &Context) {
ASTContext &Context) {
auto Diag = diag(CopyArgument.getBeginLoc(),
"parameter %0 is passed by value and only copied once; "
"consider moving it to avoid unnecessary copies")
<< &Var;
<< &Param;
// Do not propose fixes in macros since we cannot place them correctly.
if (CopyArgument.getBeginLoc().isMacroID())
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,16 @@ class UnnecessaryValueParamCheck : public ClangTidyCheck {
void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
void onEndOfTranslationUnit() override;

private:
void handleMoveFix(const ParmVarDecl &Var, const DeclRefExpr &CopyArgument,
const ASTContext &Context);
protected:
// Create diagnostics. These are virtual so that derived classes can change
// behaviour.
virtual void handleMoveFix(const ParmVarDecl &Param,
const DeclRefExpr &CopyArgument,
ASTContext &Context);
virtual void handleConstRefFix(const FunctionDecl &Function,
const ParmVarDecl &Param, ASTContext &Context);

private:
ExprMutationAnalyzer::Memoized MutationAnalyzerCache;
utils::IncludeInserter Inserter;
const std::vector<StringRef> AllowedTypes;
Expand Down
323 changes: 183 additions & 140 deletions clang-tools-extra/clang-tidy/tool/run-clang-tidy.py

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion clang-tools-extra/clang-tidy/utils/ASTUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ bool areStatementsIdentical(const Stmt *FirstStmt, const Stmt *SecondStmt,
if (FirstStmt == SecondStmt)
return true;

if (FirstStmt->getStmtClass() != FirstStmt->getStmtClass())
if (FirstStmt->getStmtClass() != SecondStmt->getStmtClass())
return false;

if (isa<Expr>(FirstStmt) && isa<Expr>(SecondStmt)) {
Expand Down
10 changes: 5 additions & 5 deletions clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,10 @@ bool isStandardPointerConvertible(QualType From, QualType To) {
if (RD->isCompleteDefinition() &&
isBaseOf(From->getPointeeType().getTypePtr(),
To->getPointeeType().getTypePtr())) {
return true;
// If B is an inaccessible or ambiguous base class of D, a program
// that necessitates this conversion is ill-formed
return isUnambiguousPublicBaseClass(From->getPointeeType().getTypePtr(),
To->getPointeeType().getTypePtr());
}
}

Expand Down Expand Up @@ -375,10 +378,7 @@ bool ExceptionAnalyzer::ExceptionInfo::filterByCatch(
isPointerOrPointerToMember(ExceptionCanTy->getTypePtr())) {
// A standard pointer conversion not involving conversions to pointers to
// private or protected or ambiguous classes ...
if (isStandardPointerConvertible(ExceptionCanTy, HandlerCanTy) &&
isUnambiguousPublicBaseClass(
ExceptionCanTy->getTypePtr()->getPointeeType().getTypePtr(),
HandlerCanTy->getTypePtr()->getPointeeType().getTypePtr())) {
if (isStandardPointerConvertible(ExceptionCanTy, HandlerCanTy)) {
TypesToDelete.push_back(ExceptionTy);
}
// A function pointer conversion ...
Expand Down
20 changes: 20 additions & 0 deletions clang-tools-extra/clangd/IncludeCleaner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,26 @@ computeIncludeCleanerFindings(ParsedAST &AST, bool AnalyzeAngledIncludes) {
Ref.RT != include_cleaner::RefType::Explicit)
return;

// Check if we have any headers with the same spelling, in edge cases
// like `#include_next "foo.h"`, the user can't ever include the
// physical foo.h, but can have a spelling that refers to it.
// We postpone this check because spelling a header for every usage is
// expensive.
std::string Spelling = include_cleaner::spellHeader(
{Providers.front(), AST.getPreprocessor().getHeaderSearchInfo(),
MainFile});
for (auto *Inc :
ConvertedIncludes.match(include_cleaner::Header{Spelling})) {
Satisfied = true;
auto HeaderID =
AST.getIncludeStructure().getID(&Inc->Resolved->getFileEntry());
assert(HeaderID.has_value() &&
"ConvertedIncludes only contains resolved includes.");
Used.insert(*HeaderID);
}
if (Satisfied)
return;

// We actually always want to map usages to their spellings, but
// spelling locations can point into preamble section. Using these
// offsets could lead into crashes in presence of stale preambles. Hence
Expand Down
22 changes: 22 additions & 0 deletions clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -644,6 +644,28 @@ TEST(IncludeCleaner, ResourceDirIsIgnored) {
EXPECT_THAT(Findings.MissingIncludes, IsEmpty());
}

TEST(IncludeCleaner, DifferentHeaderSameSpelling) {
// `foo` is declared in foo_inner/foo.h, but there's no way to spell it
// directly. Make sure we don't generate unusued/missing include findings in
// such cases.
auto TU = TestTU::withCode(R"cpp(
#include <foo.h>
void baz() {
foo();
}
)cpp");
TU.AdditionalFiles["foo/foo.h"] = guard("#include_next <foo.h>");
TU.AdditionalFiles["foo_inner/foo.h"] = guard(R"cpp(
void foo();
)cpp");
TU.ExtraArgs.push_back("-Ifoo");
TU.ExtraArgs.push_back("-Ifoo_inner");

auto AST = TU.build();
auto Findings = computeIncludeCleanerFindings(AST);
EXPECT_THAT(Findings.UnusedIncludes, IsEmpty());
EXPECT_THAT(Findings.MissingIncludes, IsEmpty());
}
} // namespace
} // namespace clangd
} // namespace clang
421 changes: 0 additions & 421 deletions clang-tools-extra/docs/ReleaseNotes.rst

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
.. title:: clang-tidy - clang-analyzer-cplusplus.Move
.. meta::
:http-equiv=refresh: 5;URL=https://clang.llvm.org/docs/analyzer/checkers.html#cplusplus-move

clang-analyzer-cplusplus.Move
=============================

Find use-after-move bugs in C++.

The clang-analyzer-cplusplus.Move check is an alias of
Clang Static Analyzer cplusplus.Move.
The `clang-analyzer-cplusplus.Move` check is an alias, please see
`Clang Static Analyzer Available Checkers
<https://clang.llvm.org/docs/analyzer/checkers.html#cplusplus-move>`_
for more information.
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
.. title:: clang-tidy - clang-analyzer-optin.taint.TaintedAlloc
.. meta::
:http-equiv=refresh: 5;URL=https://clang.llvm.org/docs/analyzer/checkers.html#optin-taint-taintedalloc

clang-analyzer-optin.taint.TaintedAlloc
=======================================

Check for memory allocations, where the size parameter might be a tainted
(attacker controlled) value.

The `clang-analyzer-optin.taint.TaintedAlloc` check is an alias, please see
`Clang Static Analyzer Available Checkers
<https://clang.llvm.org/docs/analyzer/checkers.html#optin-taint-taintedalloc>`_
for more information.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
.. title:: clang-tidy - clang-analyzer-security.PutenvStackArray

clang-analyzer-security.PutenvStackArray
========================================

Finds calls to the function 'putenv' which pass a pointer to an automatic
(stack-allocated) array as the argument.

The clang-analyzer-security.PutenvStackArray check is an alias of
Clang Static Analyzer security.PutenvStackArray.
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
.. title:: clang-tidy - clang-analyzer-unix.BlockInCriticalSection
.. meta::
:http-equiv=refresh: 5;URL=https://clang.llvm.org/docs/analyzer/checkers.html#unix-blockincriticalsection

clang-analyzer-unix.BlockInCriticalSection
==========================================

Check for calls to blocking functions inside a critical section.

The `clang-analyzer-unix.BlockInCriticalSection` check is an alias, please see
`Clang Static Analyzer Available Checkers
<https://clang.llvm.org/docs/analyzer/checkers.html#unix-blockincriticalsection>`_
for more information.
10 changes: 7 additions & 3 deletions clang-tools-extra/docs/clang-tidy/checks/list.rst
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ Clang-Tidy Checks
:doc:`bugprone-not-null-terminated-result <bugprone/not-null-terminated-result>`, "Yes"
:doc:`bugprone-optional-value-conversion <bugprone/optional-value-conversion>`, "Yes"
:doc:`bugprone-parent-virtual-call <bugprone/parent-virtual-call>`, "Yes"
:doc:`bugprone-pointer-arithmetic-on-polymorphic-object <bugprone/pointer-arithmetic-on-polymorphic-object>`,
:doc:`bugprone-posix-return <bugprone/posix-return>`, "Yes"
:doc:`bugprone-redundant-branch-condition <bugprone/redundant-branch-condition>`, "Yes"
:doc:`bugprone-reserved-identifier <bugprone/reserved-identifier>`, "Yes"
Expand Down Expand Up @@ -158,7 +159,6 @@ Clang-Tidy Checks
:doc:`bugprone-unused-raii <bugprone/unused-raii>`, "Yes"
:doc:`bugprone-unused-return-value <bugprone/unused-return-value>`,
:doc:`bugprone-use-after-move <bugprone/use-after-move>`,
:doc:`bugprone-pointer-arithmetic-on-polymorphic-object <bugprone/pointer-arithmetic-on-polymorphic-object>`,
:doc:`bugprone-virtual-near-miss <bugprone/virtual-near-miss>`, "Yes"
:doc:`cert-dcl50-cpp <cert/dcl50-cpp>`,
:doc:`cert-dcl58-cpp <cert/dcl58-cpp>`,
Expand Down Expand Up @@ -269,7 +269,7 @@ Clang-Tidy Checks
:doc:`misc-unused-parameters <misc/unused-parameters>`, "Yes"
:doc:`misc-unused-using-decls <misc/unused-using-decls>`, "Yes"
:doc:`misc-use-anonymous-namespace <misc/use-anonymous-namespace>`,
:doc:`misc-use-internal-linkage <misc/use-internal-linkage>`,
:doc:`misc-use-internal-linkage <misc/use-internal-linkage>`, "Yes"
:doc:`modernize-avoid-bind <modernize/avoid-bind>`, "Yes"
:doc:`modernize-avoid-c-arrays <modernize/avoid-c-arrays>`,
:doc:`modernize-concat-nested-namespaces <modernize/concat-nested-namespaces>`, "Yes"
Expand Down Expand Up @@ -409,6 +409,7 @@ Check aliases
:doc:`bugprone-narrowing-conversions <bugprone/narrowing-conversions>`, :doc:`cppcoreguidelines-narrowing-conversions <cppcoreguidelines/narrowing-conversions>`,
:doc:`cert-con36-c <cert/con36-c>`, :doc:`bugprone-spuriously-wake-up-functions <bugprone/spuriously-wake-up-functions>`,
:doc:`cert-con54-cpp <cert/con54-cpp>`, :doc:`bugprone-spuriously-wake-up-functions <bugprone/spuriously-wake-up-functions>`,
:doc:`cert-ctr56-cpp <cert/ctr56-cpp>`, :doc:`bugprone-pointer-arithmetic-on-polymorphic-object <bugprone/pointer-arithmetic-on-polymorphic-object>`,
:doc:`cert-dcl03-c <cert/dcl03-c>`, :doc:`misc-static-assert <misc/static-assert>`, "Yes"
:doc:`cert-dcl16-c <cert/dcl16-c>`, :doc:`readability-uppercase-literal-suffix <readability/uppercase-literal-suffix>`, "Yes"
:doc:`cert-dcl37-c <cert/dcl37-c>`, :doc:`bugprone-reserved-identifier <bugprone/reserved-identifier>`, "Yes"
Expand Down Expand Up @@ -448,7 +449,7 @@ Check aliases
:doc:`clang-analyzer-core.uninitialized.UndefReturn <clang-analyzer/core.uninitialized.UndefReturn>`, `Clang Static Analyzer core.uninitialized.UndefReturn <https://clang.llvm.org/docs/analyzer/checkers.html#core-uninitialized-undefreturn>`_,
:doc:`clang-analyzer-cplusplus.ArrayDelete <clang-analyzer/cplusplus.ArrayDelete>`, `Clang Static Analyzer cplusplus.ArrayDelete <https://clang.llvm.org/docs/analyzer/checkers.html#cplusplus-arraydelete>`_,
:doc:`clang-analyzer-cplusplus.InnerPointer <clang-analyzer/cplusplus.InnerPointer>`, `Clang Static Analyzer cplusplus.InnerPointer <https://clang.llvm.org/docs/analyzer/checkers.html#cplusplus-innerpointer>`_,
:doc:`clang-analyzer-cplusplus.Move <clang-analyzer/cplusplus.Move>`, Clang Static Analyzer cplusplus.Move,
:doc:`clang-analyzer-cplusplus.Move <clang-analyzer/cplusplus.Move>`, `Clang Static Analyzer cplusplus.Move <https://clang.llvm.org/docs/analyzer/checkers.html#cplusplus-move>`_,
:doc:`clang-analyzer-cplusplus.NewDelete <clang-analyzer/cplusplus.NewDelete>`, `Clang Static Analyzer cplusplus.NewDelete <https://clang.llvm.org/docs/analyzer/checkers.html#cplusplus-newdelete>`_,
:doc:`clang-analyzer-cplusplus.NewDeleteLeaks <clang-analyzer/cplusplus.NewDeleteLeaks>`, `Clang Static Analyzer cplusplus.NewDeleteLeaks <https://clang.llvm.org/docs/analyzer/checkers.html#cplusplus-newdeleteleaks>`_,
:doc:`clang-analyzer-cplusplus.PlacementNew <clang-analyzer/cplusplus.PlacementNew>`, `Clang Static Analyzer cplusplus.PlacementNew <https://clang.llvm.org/docs/analyzer/checkers.html#cplusplus-placementnew>`_,
Expand All @@ -471,6 +472,7 @@ Check aliases
:doc:`clang-analyzer-optin.performance.GCDAntipattern <clang-analyzer/optin.performance.GCDAntipattern>`, `Clang Static Analyzer optin.performance.GCDAntipattern <https://clang.llvm.org/docs/analyzer/checkers.html#optin-performance-gcdantipattern>`_,
:doc:`clang-analyzer-optin.performance.Padding <clang-analyzer/optin.performance.Padding>`, `Clang Static Analyzer optin.performance.Padding <https://clang.llvm.org/docs/analyzer/checkers.html#optin-performance-padding>`_,
:doc:`clang-analyzer-optin.portability.UnixAPI <clang-analyzer/optin.portability.UnixAPI>`, `Clang Static Analyzer optin.portability.UnixAPI <https://clang.llvm.org/docs/analyzer/checkers.html#optin-portability-unixapi>`_,
:doc:`clang-analyzer-optin.taint.TaintedAlloc <clang-analyzer/optin.taint.TaintedAlloc>`, `Clang Static Analyzer optin.taint.TaintedAlloc <https://clang.llvm.org/docs/analyzer/checkers.html#optin-taint-taintedalloc>`_,
:doc:`clang-analyzer-osx.API <clang-analyzer/osx.API>`, `Clang Static Analyzer osx.API <https://clang.llvm.org/docs/analyzer/checkers.html#osx-api>`_,
:doc:`clang-analyzer-osx.MIG <clang-analyzer/osx.MIG>`, Clang Static Analyzer osx.MIG,
:doc:`clang-analyzer-osx.NumberObjectConversion <clang-analyzer/osx.NumberObjectConversion>`, `Clang Static Analyzer osx.NumberObjectConversion <https://clang.llvm.org/docs/analyzer/checkers.html#osx-numberobjectconversion>`_,
Expand Down Expand Up @@ -501,6 +503,7 @@ Check aliases
:doc:`clang-analyzer-osx.coreFoundation.containers.OutOfBounds <clang-analyzer/osx.coreFoundation.containers.OutOfBounds>`, `Clang Static Analyzer osx.coreFoundation.containers.OutOfBounds <https://clang.llvm.org/docs/analyzer/checkers.html#osx-corefoundation-containers-outofbounds>`_,
:doc:`clang-analyzer-osx.coreFoundation.containers.PointerSizedValues <clang-analyzer/osx.coreFoundation.containers.PointerSizedValues>`, `Clang Static Analyzer osx.coreFoundation.containers.PointerSizedValues <https://clang.llvm.org/docs/analyzer/checkers.html#osx-corefoundation-containers-pointersizedvalues>`_,
:doc:`clang-analyzer-security.FloatLoopCounter <clang-analyzer/security.FloatLoopCounter>`, `Clang Static Analyzer security.FloatLoopCounter <https://clang.llvm.org/docs/analyzer/checkers.html#security-floatloopcounter>`_,
:doc:`clang-analyzer-security.PutenvStackArray <clang-analyzer/security.PutenvStackArray>`, Clang Static Analyzer security.PutenvStackArray,
:doc:`clang-analyzer-security.SetgidSetuidOrder <clang-analyzer/security.SetgidSetuidOrder>`, Clang Static Analyzer security.SetgidSetuidOrder,
:doc:`clang-analyzer-security.cert.env.InvalidPtr <clang-analyzer/security.cert.env.InvalidPtr>`, `Clang Static Analyzer security.cert.env.InvalidPtr <https://clang.llvm.org/docs/analyzer/checkers.html#security-cert-env-invalidptr>`_,
:doc:`clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling <clang-analyzer/security.insecureAPI.DeprecatedOrUnsafeBufferHandling>`, `Clang Static Analyzer security.insecureAPI.DeprecatedOrUnsafeBufferHandling <https://clang.llvm.org/docs/analyzer/checkers.html#security-insecureapi-deprecatedorunsafebufferhandling>`_,
Expand All @@ -517,6 +520,7 @@ Check aliases
:doc:`clang-analyzer-security.insecureAPI.strcpy <clang-analyzer/security.insecureAPI.strcpy>`, `Clang Static Analyzer security.insecureAPI.strcpy <https://clang.llvm.org/docs/analyzer/checkers.html#security-insecureapi-strcpy>`_,
:doc:`clang-analyzer-security.insecureAPI.vfork <clang-analyzer/security.insecureAPI.vfork>`, `Clang Static Analyzer security.insecureAPI.vfork <https://clang.llvm.org/docs/analyzer/checkers.html#security-insecureapi-vfork>`_,
:doc:`clang-analyzer-unix.API <clang-analyzer/unix.API>`, `Clang Static Analyzer unix.API <https://clang.llvm.org/docs/analyzer/checkers.html#unix-api>`_,
:doc:`clang-analyzer-unix.BlockInCriticalSection <clang-analyzer/unix.BlockInCriticalSection>`, `Clang Static Analyzer unix.BlockInCriticalSection <https://clang.llvm.org/docs/analyzer/checkers.html#unix-blockincriticalsection>`_,
:doc:`clang-analyzer-unix.Errno <clang-analyzer/unix.Errno>`, `Clang Static Analyzer unix.Errno <https://clang.llvm.org/docs/analyzer/checkers.html#unix-errno>`_,
:doc:`clang-analyzer-unix.Malloc <clang-analyzer/unix.Malloc>`, `Clang Static Analyzer unix.Malloc <https://clang.llvm.org/docs/analyzer/checkers.html#unix-malloc>`_,
:doc:`clang-analyzer-unix.MallocSizeof <clang-analyzer/unix.MallocSizeof>`, `Clang Static Analyzer unix.MallocSizeof <https://clang.llvm.org/docs/analyzer/checkers.html#unix-mallocsizeof>`_,
Expand Down
17 changes: 14 additions & 3 deletions clang-tools-extra/include-cleaner/lib/Analysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,20 @@ analyze(llvm::ArrayRef<Decl *> ASTRoots,
}
if (!Satisfied && !Providers.empty() &&
Ref.RT == RefType::Explicit &&
!HeaderFilter(Providers.front().resolvedPath()))
Missing.insert(spellHeader(
{Providers.front(), PP.getHeaderSearchInfo(), MainFile}));
!HeaderFilter(Providers.front().resolvedPath())) {
// Check if we have any headers with the same spelling, in edge
// cases like `#include_next "foo.h"`, the user can't ever
// include the physical foo.h, but can have a spelling that
// refers to it.
auto Spelling = spellHeader(
{Providers.front(), PP.getHeaderSearchInfo(), MainFile});
for (const Include *I : Inc.match(Header{Spelling})) {
Used.insert(I);
Satisfied = true;
}
if (!Satisfied)
Missing.insert(std::move(Spelling));
}
});

AnalysisResults Results;
Expand Down
26 changes: 26 additions & 0 deletions clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "clang-include-cleaner/Record.h"
#include "clang-include-cleaner/Types.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclBase.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/SourceLocation.h"
Expand Down Expand Up @@ -296,6 +297,31 @@ TEST_F(AnalyzeTest, ResourceDirIsIgnored) {
EXPECT_THAT(Results.Missing, testing::IsEmpty());
}

TEST_F(AnalyzeTest, DifferentHeaderSameSpelling) {
Inputs.ExtraArgs.push_back("-Ifoo");
Inputs.ExtraArgs.push_back("-Ifoo_inner");
// `foo` is declared in foo_inner/foo.h, but there's no way to spell it
// directly. Make sure we don't generate unusued/missing include findings in
// such cases.
Inputs.Code = R"cpp(
#include <foo.h>
void baz() {
foo();
}
)cpp";
Inputs.ExtraFiles["foo/foo.h"] = guard("#include_next <foo.h>");
Inputs.ExtraFiles["foo_inner/foo.h"] = guard(R"cpp(
void foo();
)cpp");
TestAST AST(Inputs);
std::vector<Decl *> DeclsInTU;
for (auto *D : AST.context().getTranslationUnitDecl()->decls())
DeclsInTU.push_back(D);
auto Results = analyze(DeclsInTU, {}, PP.Includes, &PI, AST.preprocessor());
EXPECT_THAT(Results.Unused, testing::IsEmpty());
EXPECT_THAT(Results.Missing, testing::IsEmpty());
}

TEST(FixIncludes, Basic) {
llvm::StringRef Code = R"cpp(#include "d.h"
#include "a.h"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -756,3 +756,21 @@ struct test_implicit_throw {
};

}}

void pointer_exception_can_not_escape_with_const_void_handler() noexcept {
// CHECK-MESSAGES-NOT: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'pointer_exception_can_not_escape_with_const_void_handler' which should not throw exceptions
const int value = 42;
try {
throw &value;
} catch (const void *) {
}
}

void pointer_exception_can_not_escape_with_void_handler() noexcept {
// CHECK-MESSAGES-NOT: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'pointer_exception_can_not_escape_with_void_handler' which should not throw exceptions
int value = 42;
try {
throw &value;
} catch (void *) {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// RUN: misc-const-correctness.TransformValues: true, \
// RUN: misc-const-correctness.WarnPointersAsValues: false, \
// RUN: misc-const-correctness.TransformPointersAsValues: false \
// RUN: }}" -- -fno-delayed-template-parsing
// RUN: }}" -- -fno-delayed-template-parsing -fexceptions

// ------- Provide test samples for primitive builtins ---------
// - every 'p_*' variable is a 'potential_const_*' variable
Expand Down Expand Up @@ -56,6 +56,15 @@ void some_function(double np_arg0, wchar_t np_arg1) {
np_local6--;
}

int function_try_block() try {
int p_local0 = 0;
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'int' can be declared 'const'
// CHECK-FIXES: int const p_local0
return p_local0;
} catch (...) {
return 0;
}

void nested_scopes() {
int p_local0 = 2;
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'int' can be declared 'const'
Expand Down
2 changes: 2 additions & 0 deletions clang/cmake/caches/Fuchsia-stage2.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,7 @@ foreach(target armv6m-unknown-eabi;armv7m-unknown-eabi;armv8m.main-unknown-eabi)
endforeach()
set(RUNTIMES_${target}_LLVM_LIBC_FULL_BUILD ON CACHE BOOL "")
set(RUNTIMES_${target}_LIBC_ENABLE_USE_BY_CLANG ON CACHE BOOL "")
set(RUNTIMES_${target}_LIBC_USE_NEW_HEADER_GEN OFF CACHE BOOL "")
set(RUNTIMES_${target}_LIBCXX_ABI_VERSION 2 CACHE STRING "")
set(RUNTIMES_${target}_LIBCXX_CXX_ABI none CACHE STRING "")
set(RUNTIMES_${target}_LIBCXX_ENABLE_SHARED OFF CACHE BOOL "")
Expand Down Expand Up @@ -385,6 +386,7 @@ foreach(target riscv32-unknown-elf)
endforeach()
set(RUNTIMES_${target}_LLVM_LIBC_FULL_BUILD ON CACHE BOOL "")
set(RUNTIMES_${target}_LIBC_ENABLE_USE_BY_CLANG ON CACHE BOOL "")
set(RUNTIMES_${target}_LIBC_USE_NEW_HEADER_GEN OFF CACHE BOOL "")
set(RUNTIMES_${target}_LIBCXX_ABI_VERSION 2 CACHE STRING "")
set(RUNTIMES_${target}_LIBCXX_CXX_ABI none CACHE STRING "")
set(RUNTIMES_${target}_LIBCXX_ENABLE_SHARED OFF CACHE BOOL "")
Expand Down
74 changes: 74 additions & 0 deletions clang/docs/ClangNVLinkWrapper.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
====================
Clang nvlink Wrapper
====================

.. contents::
:local:

.. _clang-nvlink-wrapper:

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

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

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

Usage
=====

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

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

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

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

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

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

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

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

.. code-block:: c++

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

.. code-block:: c++

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

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

Expand Down
1,165 changes: 17 additions & 1,148 deletions clang/docs/ReleaseNotes.rst

Large diffs are not rendered by default.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

/// Whether to not follow the AAPCS that enforces volatile bit-field access width to be
/// according to the field declaring type width.
CODEGENOPT(AAPCSBitfieldWidth, 1, 1)
Expand Down
5 changes: 0 additions & 5 deletions clang/include/clang/Basic/DiagnosticLexKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -952,11 +952,6 @@ def warn_module_conflict : Warning<
InGroup<ModuleConflict>;

// C++20 modules
def err_module_decl_cannot_be_macros : Error<
"the module name in a module%select{| partition}0 declaration cannot contain "
"an object-like macro %1">;
def err_unxepected_paren_in_module_decl : Error<
"unexpected '(' after the module name in a module%select{| partition}0 declaration">;
def err_header_import_semi_in_macro : Error<
"semicolon terminating header import declaration cannot be produced "
"by a macro">;
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Basic/DiagnosticParseKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -1260,6 +1260,9 @@ def warn_pragma_intrinsic_builtin : Warning<
def warn_pragma_unused_expected_var : Warning<
"expected '#pragma unused' argument to be a variable name">,
InGroup<IgnoredPragmas>;
// - #pragma mc_func
def err_pragma_mc_func_not_supported :
Error<"#pragma mc_func is not supported">;
// - #pragma init_seg
def warn_pragma_init_seg_unsupported_target : Warning<
"'#pragma init_seg' is only supported when targeting a "
Expand Down
17 changes: 12 additions & 5 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -942,13 +942,19 @@ def warn_ptrauth_auth_null_pointer :
InGroup<PtrAuthNullPointers>;
def err_ptrauth_string_not_literal : Error<
"argument must be a string literal%select{| of char type}0">;
def err_ptrauth_type_disc_undiscriminated : Error<
"cannot pass undiscriminated type %0 to "
"'__builtin_ptrauth_type_discriminator'">;

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

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

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

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

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

def err_tls_var_aligned_over_maximum : Error<
"alignment (%0) of thread-local variable %1 is greater than the maximum supported "
Expand Down Expand Up @@ -5165,7 +5175,7 @@ def warn_cxx11_compat_variable_template : Warning<
InGroup<CXXPre14Compat>, DefaultIgnore;
def err_template_variable_noparams : Error<
"extraneous 'template<>' in declaration of variable %0">;
def err_template_member : Error<"member %0 declared as a template">;
def err_template_member : Error<"non-static data member %0 cannot be declared as a template">;
def err_member_with_template_arguments : Error<"member %0 cannot have template arguments">;
def err_template_member_noparams : Error<
"extraneous 'template<>' in declaration of member %0">;
Expand Down Expand Up @@ -7596,9 +7606,6 @@ def err_nested_non_static_member_use : Error<
def warn_cxx98_compat_non_static_member_use : Warning<
"use of non-static data member %0 in an unevaluated context is "
"incompatible with C++98">, InGroup<CXX98Compat>, DefaultIgnore;
def err_form_ptr_to_member_from_parenthesized_expr : Error<
"cannot form pointer to member from a parenthesized expression; "
"did you mean to remove the parentheses?">;
def err_invalid_incomplete_type_use : Error<
"invalid use of incomplete type %0">;
def err_builtin_func_cast_more_than_one_arg : Error<
Expand Down
2 changes: 2 additions & 0 deletions clang/include/clang/Basic/Features.def
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,11 @@ FEATURE(ptrauth_calls, LangOpts.PointerAuthCalls)
FEATURE(ptrauth_returns, LangOpts.PointerAuthReturns)
FEATURE(ptrauth_vtable_pointer_address_discrimination, LangOpts.PointerAuthVTPtrAddressDiscrimination)
FEATURE(ptrauth_vtable_pointer_type_discrimination, LangOpts.PointerAuthVTPtrTypeDiscrimination)
FEATURE(ptrauth_type_info_vtable_pointer_discrimination, LangOpts.PointerAuthTypeInfoVTPtrDiscrimination)
FEATURE(ptrauth_member_function_pointer_type_discrimination, LangOpts.PointerAuthCalls)
FEATURE(ptrauth_init_fini, LangOpts.PointerAuthInitFini)
FEATURE(ptrauth_function_pointer_type_discrimination, LangOpts.PointerAuthFunctionTypeDiscrimination)
FEATURE(ptrauth_indirect_gotos, LangOpts.PointerAuthIndirectGotos)
EXTENSION(swiftcc,
PP.getTargetInfo().checkCallingConvention(CC_Swift) ==
clang::TargetInfo::CCCR_OK)
Expand Down
24 changes: 3 additions & 21 deletions clang/include/clang/Basic/IdentifierTable.h
Original file line number Diff line number Diff line change
Expand Up @@ -180,10 +180,6 @@ class alignas(IdentifierInfoAlignment) IdentifierInfo {
LLVM_PREFERRED_TYPE(bool)
unsigned IsModulesImport : 1;

// True if this is the 'module' contextual keyword.
LLVM_PREFERRED_TYPE(bool)
unsigned IsModulesDecl : 1;

// True if this is a mangled OpenMP variant name.
LLVM_PREFERRED_TYPE(bool)
unsigned IsMangledOpenMPVariantName : 1;
Expand All @@ -200,7 +196,7 @@ class alignas(IdentifierInfoAlignment) IdentifierInfo {
LLVM_PREFERRED_TYPE(bool)
unsigned IsFinal : 1;

// 21 bits left in a 64-bit word.
// 22 bits left in a 64-bit word.

// Managed by the language front-end.
void *FETokenInfo = nullptr;
Expand All @@ -216,8 +212,8 @@ class alignas(IdentifierInfoAlignment) IdentifierInfo {
IsCPPOperatorKeyword(false), NeedsHandleIdentifier(false),
IsFromAST(false), ChangedAfterLoad(false), FEChangedAfterLoad(false),
RevertedTokenID(false), OutOfDate(false), IsModulesImport(false),
IsModulesDecl(false), IsMangledOpenMPVariantName(false),
IsDeprecatedMacro(false), IsRestrictExpansion(false), IsFinal(false) {}
IsMangledOpenMPVariantName(false), IsDeprecatedMacro(false),
IsRestrictExpansion(false), IsFinal(false) {}

public:
IdentifierInfo(const IdentifierInfo &) = delete;
Expand Down Expand Up @@ -524,18 +520,6 @@ class alignas(IdentifierInfoAlignment) IdentifierInfo {
RecomputeNeedsHandleIdentifier();
}

/// Determine whether this is the contextual keyword \c module.
bool isModulesDeclaration() const { return IsModulesDecl; }

/// Set whether this identifier is the contextual keyword \c module.
void setModulesDeclaration(bool I) {
IsModulesDecl = I;
if (I)
NeedsHandleIdentifier = true;
else
RecomputeNeedsHandleIdentifier();
}

/// Determine whether this is the mangled name of an OpenMP variant.
bool isMangledOpenMPVariantName() const { return IsMangledOpenMPVariantName; }

Expand Down Expand Up @@ -756,8 +740,6 @@ class IdentifierTable {
// If this is the 'import' contextual keyword, mark it as such.
if (Name == "import")
II->setModulesImport(true);
else if (Name == "module")
II->setModulesDeclaration(true);

return *II;
}
Expand Down
2 changes: 2 additions & 0 deletions clang/include/clang/Basic/LangOptions.def
Original file line number Diff line number Diff line change
Expand Up @@ -165,9 +165,11 @@ LANGOPT(ExperimentalLibrary, 1, 0, "enable unstable and experimental library fea
LANGOPT(PointerAuthIntrinsics, 1, 0, "pointer authentication intrinsics")
LANGOPT(PointerAuthCalls , 1, 0, "function pointer authentication")
LANGOPT(PointerAuthReturns, 1, 0, "return pointer authentication")
LANGOPT(PointerAuthIndirectGotos, 1, 0, "indirect gotos pointer authentication")
LANGOPT(PointerAuthAuthTraps, 1, 0, "pointer authentication failure traps")
LANGOPT(PointerAuthVTPtrAddressDiscrimination, 1, 0, "incorporate address discrimination in authenticated vtable pointers")
LANGOPT(PointerAuthVTPtrTypeDiscrimination, 1, 0, "incorporate type discrimination in authenticated vtable pointers")
LANGOPT(PointerAuthTypeInfoVTPtrDiscrimination, 1, 0, "incorporate type and address discrimination in authenticated vtable pointers for std::type_info")
LANGOPT(PointerAuthInitFini, 1, 0, "sign function pointers in init/fini arrays")
BENIGN_LANGOPT(PointerAuthFunctionTypeDiscrimination, 1, 0,
"Use type discrimination when signing function pointers")
Expand Down
11 changes: 11 additions & 0 deletions clang/include/clang/Basic/PointerAuthOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ namespace clang {

constexpr unsigned PointerAuthKeyNone = -1;

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

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

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

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

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

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

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

} // end namespace clang
Expand Down
5 changes: 2 additions & 3 deletions clang/include/clang/Basic/TokenKinds.def
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,8 @@ ALIAS("__is_same_as", __is_same, KEYCXX)
KEYWORD(__private_extern__ , KEYALL)
KEYWORD(__module_private__ , KEYALL)

UNARY_EXPR_OR_TYPE_TRAIT(__builtin_ptrauth_type_discriminator, PtrAuthTypeDiscriminator, KEYALL)

// Extension that will be enabled for Microsoft, Borland and PS4, but can be
// disabled via '-fno-declspec'.
KEYWORD(__declspec , 0)
Expand Down Expand Up @@ -1003,9 +1005,6 @@ ANNOTATION(module_include)
ANNOTATION(module_begin)
ANNOTATION(module_end)

// Annotations for C++, Clang and Objective-C named modules.
ANNOTATION(module_name)

// Annotation for a header_name token that has been looked up and transformed
// into the name of a header unit.
ANNOTATION(header_unit)
Expand Down
64 changes: 32 additions & 32 deletions clang/include/clang/Basic/arm_neon.td
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ def SPLATQ : WInst<"splat_laneq", ".(!Q)I",
"UcUsUicsilPcPsfQUcQUsQUiQcQsQiQPcQPsQflUlQlQUlhdQhQdPlQPl"> {
let isLaneQ = 1;
}
let TargetGuard = "bf16" in {
let TargetGuard = "bf16,neon" in {
def SPLAT_BF : WInst<"splat_lane", ".(!q)I", "bQb">;
def SPLATQ_BF : WInst<"splat_laneq", ".(!Q)I", "bQb"> {
let isLaneQ = 1;
Expand Down Expand Up @@ -323,7 +323,7 @@ def VMLSL : SOpInst<"vmlsl", "(>Q)(>Q)..", "csiUcUsUi", OP_MLSL>;
def VQDMULH : SInst<"vqdmulh", "...", "siQsQi">;
def VQRDMULH : SInst<"vqrdmulh", "...", "siQsQi">;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

#endif
28 changes: 24 additions & 4 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -3232,6 +3232,10 @@ def fimplicit_module_maps : Flag <["-"], "fimplicit-module-maps">, Group<f_Group
Visibility<[ClangOption, CC1Option, CLOption]>,
HelpText<"Implicitly search the file system for module map files.">,
MarshallingInfoFlag<HeaderSearchOpts<"ImplicitModuleMaps">>;
defm modulemap_allow_subdirectory_search : BoolFOption <"modulemap-allow-subdirectory-search",
HeaderSearchOpts<"AllowModuleMapSubdirectorySearch">, DefaultTrue,
PosFlag<SetTrue, [], [], "Allow to search for module maps in subdirectories of search paths">,
NegFlag<SetFalse>, BothFlags<[NoXarchOption], [ClangOption, CC1Option]>>;
defm modules : BoolFOption<"modules",
LangOpts<"Modules">, Default<fcxx_modules.KeyPath>,
PosFlag<SetTrue, [], [ClangOption, CC1Option],
Expand Down Expand Up @@ -3998,6 +4002,10 @@ def ftime_trace_granularity_EQ : Joined<["-"], "ftime-trace-granularity=">, Grou
HelpText<"Minimum time granularity (in microseconds) traced by time profiler">,
Visibility<[ClangOption, CC1Option, CLOption, DXCOption]>,
MarshallingInfoInt<FrontendOpts<"TimeTraceGranularity">, "500u">;
def ftime_trace_verbose : Joined<["-"], "ftime-trace-verbose">, Group<f_Group>,
HelpText<"Make time trace capture verbose event details (e.g. source filenames). This can increase the size of the output by 2-3 times">,
Visibility<[ClangOption, CC1Option, CLOption, DXCOption]>,
MarshallingInfoFlag<FrontendOpts<"TimeTraceVerbose">>;
def ftime_trace_EQ : Joined<["-"], "ftime-trace=">, Group<f_Group>,
HelpText<"Similar to -ftime-trace. Specify the JSON file or a directory which will contain the JSON file">,
Visibility<[ClangOption, CC1Option, CLOption, DXCOption]>,
Expand Down Expand Up @@ -4245,9 +4253,13 @@ defm ptrauth_vtable_pointer_address_discrimination :
OptInCC1FFlag<"ptrauth-vtable-pointer-address-discrimination", "Enable address discrimination of vtable pointers">;
defm ptrauth_vtable_pointer_type_discrimination :
OptInCC1FFlag<"ptrauth-vtable-pointer-type-discrimination", "Enable type discrimination of vtable pointers">;
defm ptrauth_type_info_vtable_pointer_discrimination :
OptInCC1FFlag<"ptrauth-type-info-vtable-pointer-discrimination", "Enable type and address discrimination of vtable pointer of std::type_info">;
defm ptrauth_init_fini : OptInCC1FFlag<"ptrauth-init-fini", "Enable signing of function pointers in init/fini arrays">;
defm ptrauth_function_pointer_type_discrimination : OptInCC1FFlag<"ptrauth-function-pointer-type-discrimination",
"Enable type discrimination on C function pointers">;
defm ptrauth_indirect_gotos : OptInCC1FFlag<"ptrauth-indirect-gotos",
"Enable signing and authentication of indirect goto targets">;
}

def fenable_matrix : Flag<["-"], "fenable-matrix">, Group<f_Group>,
Expand Down Expand Up @@ -5077,6 +5089,11 @@ def mspe : Flag<["-"], "mspe">, Group<m_ppc_Features_Group>;
def mno_spe : Flag<["-"], "mno-spe">, Group<m_ppc_Features_Group>;
def mefpu2 : Flag<["-"], "mefpu2">, Group<m_ppc_Features_Group>;
} // let Flags = [TargetSpecific]
def msave_reg_params : Flag<["-"], "msave-reg-params">, Group<m_Group>,
Flags<[TargetSpecific]>,
Visibility<[ClangOption, CC1Option]>,
HelpText<"Save arguments passed by registers to ABI-defined stack positions">,
MarshallingInfoFlag<CodeGenOpts<"SaveRegParams">>;
def mabi_EQ_quadword_atomics : Flag<["-"], "mabi=quadword-atomics">,
Group<m_Group>, Visibility<[ClangOption, CC1Option]>,
HelpText<"Enable quadword atomics ABI on AIX (AIX PPC64 only). Uses lqarx/stqcx. instructions.">,
Expand Down Expand Up @@ -5549,10 +5566,6 @@ def pg : Flag<["-"], "pg">, HelpText<"Enable mcount instrumentation">,
MarshallingInfoFlag<CodeGenOpts<"InstrumentForProfiling">>;
def pipe : Flag<["-", "--"], "pipe">,
HelpText<"Use pipes between commands, when possible">;
// Facebook T92898286
def post_link_optimize : Flag<["--"], "post-link-optimize">,
HelpText<"Apply post-link optimizations using BOLT">;
// End Facebook T92898286
def prebind__all__twolevel__modules : Flag<["-"], "prebind_all_twolevel_modules">;
def prebind : Flag<["-"], "prebind">;
def preload : Flag<["-"], "preload">;
Expand Down Expand Up @@ -8082,6 +8095,13 @@ def source_date_epoch : Separate<["-"], "source-date-epoch">,

} // let Visibility = [CC1Option]

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

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

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

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

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

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

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

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

/// AddPath - Add the \p Path path to the specified \p Group list.
void AddPath(StringRef Path, frontend::IncludeDirGroup Group,
Expand Down
83 changes: 5 additions & 78 deletions clang/include/clang/Lex/Preprocessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -615,6 +615,10 @@ class Preprocessor {

ModuleDeclSeq ModuleDeclState;

/// Whether the module import expects an identifier next. Otherwise,
/// it expects a '.' or ';'.
bool ModuleImportExpectsIdentifier = false;

/// The identifier and source location of the currently-active
/// \#pragma clang arc_cf_code_audited begin.
std::pair<IdentifierInfo *, SourceLocation> PragmaARCCFCodeAuditedInfo;
Expand Down Expand Up @@ -1740,14 +1744,11 @@ class Preprocessor {
/// Lex a token, forming a header-name token if possible.
bool LexHeaderName(Token &Result, bool AllowMacroExpansion = true);

/// Lex a module name or a partition name.
bool LexModuleName(Token &Result, bool IsImport);

/// Lex the parameters for an #embed directive, returns nullopt on error.
std::optional<LexEmbedParametersResult> LexEmbedParameters(Token &Current,
bool ForHasEmbed);

bool LexAfterModuleImport(Token &Result);
bool LexAfterModuleDecl(Token &Result);
void CollectPpImportSuffix(SmallVectorImpl<Token> &Toks);

void makeModuleVisible(Module *M, SourceLocation Loc);
Expand Down Expand Up @@ -3038,9 +3039,6 @@ class Preprocessor {
static bool CLK_LexAfterModuleImport(Preprocessor &P, Token &Result) {
return P.LexAfterModuleImport(Result);
}
static bool CLK_LexAfterModuleDecl(Preprocessor &P, Token &Result) {
return P.LexAfterModuleDecl(Result);
}
};

/// Abstract base class that describes a handler that will receive
Expand Down Expand Up @@ -3073,77 +3071,6 @@ struct EmbedAnnotationData {
/// Registry of pragma handlers added by plugins
using PragmaHandlerRegistry = llvm::Registry<PragmaHandler>;

/// Represents module or partition name token sequance.
///
/// module-name:
/// module-name-qualifier[opt] identifier
///
/// partition-name: [C++20]
/// : module-name-qualifier[opt] identifier
///
/// module-name-qualifier
/// module-name-qualifier[opt] identifier .
///
/// This class can only be created by the preprocessor and guarantees that the
/// two source array being contiguous in memory and only contains 3 kind of
/// tokens (identifier, '.' and ':'). And only available when the preprocessor
/// returns annot_module_name token.
///
/// For exmaple:
///
/// export module m.n:c.d
///
/// The module name array has 3 tokens ['m', '.', 'n'].
/// The partition name array has 4 tokens [':', 'c', '.', 'd'].
///
/// When import a partition in a named module fragment (Eg. import :part1;),
/// the module name array will be empty, and the partition name array has 2
/// tokens.
///
/// When we meet a private-module-fragment (Eg. module :private;), preprocessor
/// will not return a annot_module_name token, but will return 2 separate tokens
/// [':', 'kw_private'].

class ModuleNameInfo {
friend class Preprocessor;
ArrayRef<Token> ModuleName;
ArrayRef<Token> PartitionName;

ModuleNameInfo(ArrayRef<Token> AnnotToks, std::optional<unsigned> ColonIndex);

public:
/// Return the contiguous token array.
ArrayRef<Token> getTokens() const {
if (ModuleName.empty())
return PartitionName;
if (PartitionName.empty())
return ModuleName;
return ArrayRef(ModuleName.begin(), PartitionName.end());
}
bool hasModuleName() const { return !ModuleName.empty(); }
bool hasPartitionName() const { return !PartitionName.empty(); }
ArrayRef<Token> getModuleName() const { return ModuleName; }
ArrayRef<Token> getPartitionName() const { return PartitionName; }
Token getColonToken() const {
assert(hasPartitionName() && "Do not have a partition name");
return getPartitionName().front();
}

/// Under the standard C++ Modules, the dot is just part of the module name,
/// and not a real hierarchy separator. Flatten such module names now.
std::string getFlatName() const;

/// Build a module id path from the contiguous token array, both include
/// module name and partition name.
void getModuleIdPath(
SmallVectorImpl<std::pair<IdentifierInfo *, SourceLocation>> &Path) const;

/// Build a module id path from \param ModuleName.
static void getModuleIdPath(
ArrayRef<Token> ModuleName,
SmallVectorImpl<std::pair<IdentifierInfo *, SourceLocation>> &Path);
};

} // namespace clang

#endif // LLVM_CLANG_LEX_PREPROCESSOR_H
5 changes: 5 additions & 0 deletions clang/include/clang/Lex/PreprocessorOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,10 @@ class PreprocessorOptions {
/// If set, the UNIX timestamp specified by SOURCE_DATE_EPOCH.
std::optional<uint64_t> SourceDateEpoch;

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

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

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

Expand Down
3 changes: 0 additions & 3 deletions clang/include/clang/Lex/Token.h
Original file line number Diff line number Diff line change
Expand Up @@ -235,9 +235,6 @@ class Token {
assert(isAnnotation() && "Used AnnotVal on non-annotation token");
return PtrData;
}
template <class T> T getAnnotationValueAs() const {
return static_cast<T>(getAnnotationValue());
}
void setAnnotationValue(void *val) {
assert(isAnnotation() && "Used AnnotVal on non-annotation token");
PtrData = val;
Expand Down
5 changes: 4 additions & 1 deletion clang/include/clang/Parse/Parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ class Parser : public CodeCompletionHandler {
std::unique_ptr<PragmaHandler> MaxTokensHerePragmaHandler;
std::unique_ptr<PragmaHandler> MaxTokensTotalPragmaHandler;
std::unique_ptr<PragmaHandler> RISCVPragmaHandler;
std::unique_ptr<PragmaHandler> MCFuncPragmaHandler;

std::unique_ptr<CommentHandler> CommentSemaHandler;

Expand Down Expand Up @@ -3876,7 +3877,7 @@ class Parser : public CodeCompletionHandler {
}

bool ParseModuleName(
SourceLocation UseLoc, ArrayRef<Token> ModuleName,
SourceLocation UseLoc,
SmallVectorImpl<std::pair<IdentifierInfo *, SourceLocation>> &Path,
bool IsImport);

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

ExprResult ParseBuiltinPtrauthTypeDiscriminator();

//===--------------------------------------------------------------------===//
// Preprocessor code-completion pass-through
void CodeCompleteDirective(bool InConditional) override;
Expand Down
2 changes: 2 additions & 0 deletions clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -3456,6 +3456,8 @@ class Sema final : public SemaBase {
TemplateIdAnnotation *TemplateId,
bool IsMemberSpecialization);

bool checkPointerAuthEnabled(SourceLocation Loc, SourceRange Range);

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

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

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

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

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

#ifndef LLVM_CLANG_SERIALIZATION_OBJECTFILEPCHCONTAINERREADER_H
#define LLVM_CLANG_SERIALIZATION_OBJECTFILEPCHCONTAINERREADER_H

#include "clang/Frontend/PCHContainerOperations.h"

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

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

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

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

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

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

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

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

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

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

void convertTopLevelItems(std::optional<Context> Ctx,
Expand Down
6 changes: 2 additions & 4 deletions clang/lib/AST/ASTConcept.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,9 @@ CreateUnsatisfiedConstraintRecord(const ASTContext &C,
else {
auto &SubstitutionDiagnostic =
*Detail.get<std::pair<SourceLocation, StringRef> *>();
unsigned MessageSize = SubstitutionDiagnostic.second.size();
char *Mem = new (C) char[MessageSize];
memcpy(Mem, SubstitutionDiagnostic.second.data(), MessageSize);
StringRef Message = C.backupStr(SubstitutionDiagnostic.second);
auto *NewSubstDiag = new (C) std::pair<SourceLocation, StringRef>(
SubstitutionDiagnostic.first, StringRef(Mem, MessageSize));
SubstitutionDiagnostic.first, Message);
new (TrailingObject) UnsatisfiedConstraintRecord(NewSubstDiag);
}
}
Expand Down
13 changes: 8 additions & 5 deletions clang/lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3363,6 +3363,7 @@ static void encodeTypeForFunctionPointerAuth(const ASTContext &Ctx,
#include "clang/Basic/RISCVVTypes.def"
llvm_unreachable("not yet implemented");
}
llvm_unreachable("should never get here");
}
case Type::Record: {
const RecordDecl *RD = T->getAs<RecordType>()->getDecl();
Expand Down Expand Up @@ -3407,7 +3408,7 @@ static void encodeTypeForFunctionPointerAuth(const ASTContext &Ctx,
}
}

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

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

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

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

if (!ConflictingDecls.empty()) {
// In case of unnamed enums, we try to find an existing similar one, if none
// was found, perform the import always.
// Structural in-equivalence is not detected in this way here, but it may
// be found when the parent decl is imported (if the enum is part of a
// class). To make this totally exact a more difficult solution is needed.
if (SearchName && !ConflictingDecls.empty()) {
ExpectedName NameOrErr = Importer.HandleNameConflict(
SearchName, DC, IDNS, ConflictingDecls.data(),
ConflictingDecls.size());
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/AST/DeclCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -675,6 +675,9 @@ bool CXXRecordDecl::hasSubobjectAtOffsetZeroOfEmptyBaseType(
if (!IsFirstField && !FD->isZeroSize(Ctx))
continue;

if (FD->isInvalidDecl())
continue;

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

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

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

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

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

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

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

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

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

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

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

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

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

Function *ByteCodeEmitter::compileFunc(const FunctionDecl *FuncDecl) {
Expand Down
15 changes: 6 additions & 9 deletions clang/lib/AST/Interp/Compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1698,10 +1698,8 @@ bool Compiler<Emitter>::VisitUnaryExprOrTypeTraitExpr(
if (Kind == UETT_VectorElements) {
if (const auto *VT = E->getTypeOfArgument()->getAs<VectorType>())
return this->emitConst(VT->getNumElements(), E);

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

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

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

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

return BS.destroyLocals();
Expand Down Expand Up @@ -3689,6 +3683,9 @@ VarCreationState Compiler<Emitter>::visitVarDecl(const VarDecl *VD, bool Topleve
const Expr *Init = VD->getInit();
std::optional<PrimType> VarT = classify(VD->getType());

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

if (Context::shouldBeGloballyIndexed(VD)) {
auto checkDecl = [&]() -> bool {
bool NeedsOp = !Toplevel && VD->isLocalVarDecl() && VD->isStaticLocal();
Expand Down
10 changes: 6 additions & 4 deletions clang/lib/AST/Interp/Descriptor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,8 @@ static void initField(Block *B, std::byte *Ptr, bool IsConst, bool IsMutable,
}

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

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

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

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

public:
FunctionPointer(const Function *Func) : Func(Func), Valid(true) {
assert(Func);
}
FunctionPointer() = default;
FunctionPointer(const Function *Func) : Func(Func), Valid(true) {}

FunctionPointer(uintptr_t IntVal = 0, const Descriptor *Desc = nullptr)
FunctionPointer(uintptr_t IntVal, const Descriptor *Desc = nullptr)
: Func(reinterpret_cast<const Function *>(IntVal)), Valid(false) {}

const Function *getFunction() const { return Func; }
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/AST/Interp/Interp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ bool CheckConstant(InterpState &S, CodePtr OpPC, const Descriptor *Desc) {
}

static bool CheckConstant(InterpState &S, CodePtr OpPC, const Pointer &Ptr) {
if (Ptr.isIntegralPointer())
if (!Ptr.isBlockPointer())
return true;
return CheckConstant(S, OpPC, Ptr.getDeclDesc());
}
Expand Down
25 changes: 23 additions & 2 deletions clang/lib/AST/Interp/Interp.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,10 +187,15 @@ template <typename T>
bool CheckDivRem(InterpState &S, CodePtr OpPC, const T &LHS, const T &RHS) {
if (RHS.isZero()) {
const auto *Op = cast<BinaryOperator>(S.Current->getExpr(OpPC));
if constexpr (std::is_same_v<T, Floating>) {
S.CCEDiag(Op, diag::note_expr_divide_by_zero)
<< Op->getRHS()->getSourceRange();
return true;
}

S.FFDiag(Op, diag::note_expr_divide_by_zero)
<< Op->getRHS()->getSourceRange();
if constexpr (!std::is_same_v<T, Floating>)
return false;
return false;
}

if (LHS.isSigned() && LHS.isMin() && RHS.isNegative() && RHS.isMinusOne()) {
Expand Down Expand Up @@ -2736,6 +2741,15 @@ inline bool InvalidDeclRef(InterpState &S, CodePtr OpPC,
return CheckDeclRef(S, OpPC, DR);
}

inline bool SizelessVectorElementSize(InterpState &S, CodePtr OpPC) {
if (S.inConstantContext()) {
const SourceRange &ArgRange = S.Current->getRange(OpPC);
const Expr *E = S.Current->getExpr(OpPC);
S.CCEDiag(E, diag::note_constexpr_non_const_vectorelements) << ArgRange;
}
return false;
}

inline bool Assume(InterpState &S, CodePtr OpPC) {
const auto Val = S.Stk.pop<Boolean>();

Expand Down Expand Up @@ -2797,6 +2811,13 @@ inline bool DecayPtr(InterpState &S, CodePtr OpPC) {
using ToT = typename PrimConv<TOut>::T;

const FromT &OldPtr = S.Stk.pop<FromT>();

if constexpr (std::is_same_v<FromT, FunctionPointer> &&
std::is_same_v<ToT, Pointer>) {
S.Stk.push<Pointer>(OldPtr.getFunction());
return true;
}

S.Stk.push<ToT>(ToT(OldPtr.getIntegerRepresentation(), nullptr));
return true;
}
Expand Down
Loading